initial checkin of network communication
authorChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Fri, 17 Nov 2006 12:48:03 +0000 (12:48 +0000)
committerChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Fri, 17 Nov 2006 12:48:03 +0000 (12:48 +0000)
[r8385]

ir/net/Makefile.in [new file with mode: 0644]
ir/net/firmnet.c [new file with mode: 0644]
ir/net/firmnet.h [new file with mode: 0644]
ir/net/firmnet_t.h [new file with mode: 0644]

diff --git a/ir/net/Makefile.in b/ir/net/Makefile.in
new file mode 100644 (file)
index 0000000..abc71cb
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Project:     libFIRM
+# File name:   ir/debug/Makefile.in
+# Purpose:
+# Author:      Boris Boesler, Till Riedel
+# Modified by:
+# Created:
+# CVS-ID:      $Id$
+# Copyright:   (c) 1999-2003 Universität Karlsruhe
+# Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+#
+
+top_srcdir := @top_srcdir@
+srcdir = @srcdir@
+topdir = ../..
+subdir := ir/net
+
+INSTALL_HEADERS = firmnet.h
+
+SOURCES = $(INSTALL_HEADERS)
+
+SOURCES += Makefile.in firmnet.c
+
+include $(topdir)/MakeRules
+
+CPPFLAGS += -I$(top_srcdir)/ir/ident -I$(top_srcdir)/ir/ir -I$(top_srcdir)/ir/tv \
+        -I$(top_srcdir)/ir/tr -I$(top_srcdir)/ir/common -I$(top_srcdir)/ir/ana \
+        -I$(top_srcdir)/ir/st -I$(top_srcdir)/ir/adt -I$(top_srcdir)/ir/external \
+        -I$(topdir)/ir/config
+
+include $(top_srcdir)/MakeTargets
+
+all: subdir.o
diff --git a/ir/net/firmnet.c b/ir/net/firmnet.c
new file mode 100644 (file)
index 0000000..50af0b0
--- /dev/null
@@ -0,0 +1,127 @@
+#include "firmnet_t.h"
+
+#ifdef _WIN32
+static int winsock_init(void) {
+       WORD wVersionRequested;
+       WSADATA wsaData;
+       int err;
+
+       wVersionRequested = MAKEWORD( 2, 2 );
+
+       err = WSAStartup( wVersionRequested, &wsaData );
+       if ( err != 0 ) {
+               /* Tell the user that we could not find a usable */
+               /* WinSock DLL.                                  */
+               return 0;
+       }
+
+       /* Confirm that the WinSock DLL supports 2.2.*/
+       /* Note that if the DLL supports versions greater    */
+       /* than 2.2 in addition to 2.2, it will still return */
+       /* 2.2 in wVersion since that is the version we      */
+       /* requested.                                        */
+
+       if ( LOBYTE( wsaData.wVersion ) != 2 ||
+               HIBYTE( wsaData.wVersion ) != 2 ) {
+                       /* Tell the user that we could not find a usable */
+                       /* WinSock DLL.                                  */
+                       WSACleanup( );
+                       return 0;
+       }
+       return 1;
+}
+#endif /* _WIN32 */
+
+int firmnet_connect_tcp(const char *host, uint16_t port)
+{
+       struct hostent     *phe;
+       struct protoent    *ppe;
+       struct sockaddr_in sin;
+       int s;
+
+#ifdef _WIN32
+       winsock_init();
+#endif
+
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_port   = htons(port);
+
+       if ((phe = gethostbyname(host)))
+               memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
+       else if((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
+               fprintf(stderr, "cannot get host entry for %s", host);
+               return -1;
+       }
+
+       ppe = getprotobyname("tcp");
+       ERRNO_CHECK_RETURN(s = socket(PF_INET, SOCK_STREAM, ppe->p_proto), <, 0, -1);
+       ERRNO_CHECK_RETURN(connect(s, (struct sockaddr *) &sin, sizeof(sin)), <, 0, -1);
+
+       return s;
+}
+
+void firmnet_close_socket(int fd) {
+#ifdef _WIN32
+       closesocket(fd);
+#else /* _WIN32 */
+       close(fd);
+#endif /* _WIN32 */
+}
+
+/**
+ * Send message of size @p n from buffer @p buf to file descriptor @p fd.
+ * @param fd   The file descriptor, the message should be send to.
+ * @param buf  The buffer containing the message
+ * @param n    The length of the message.
+ * @return Number of bytes written or -1 on failure.
+ */
+ssize_t firmnet_send(int fd, const void *buf, size_t n)
+{
+       ssize_t    res;
+       size_t     bytes_written = 0;
+       const char *data = buf;
+
+       do {
+               res = send(fd, &data[bytes_written], n - bytes_written, 0);
+               if (res < 0) {
+                       if (errno != EAGAIN)
+                               return -1;
+                       continue;
+               }
+
+               bytes_written += res;
+
+       } while (bytes_written < n);
+
+       return n;
+}
+
+/**
+ * Try to read some bytes but block until a certain amount is read.
+ * @param fd The file descriptor.
+ * @param buf The buffer to read into.
+ * @param try The amount of bytes to try to read.
+ * @param at_least block until this many bytes are read.
+ * @return The number of bytes read or -1 on error.
+ */
+ssize_t firmnet_recv(int fd, void *buf, size_t try, size_t at_least)
+{
+       ssize_t res;
+       size_t  bytes_read = 0;
+       char   *data       = buf;
+
+       do {
+               res = recv(fd, &data[bytes_read], try - bytes_read, 0);
+               if (res <= 0) {
+                       if (res == 0 || errno != EAGAIN)
+                               return -1;
+                       continue;
+               }
+
+               bytes_read += res;
+
+       } while (bytes_read < at_least);
+
+       return bytes_read;
+}
diff --git a/ir/net/firmnet.h b/ir/net/firmnet.h
new file mode 100644 (file)
index 0000000..5108709
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _FIRMNET_H_
+#define _FIRMNET_H_
+
+#ifdef _WIN32
+#include <winsock.h>
+#include <io.h>
+
+#else /* _WIN32 */
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <unistd.h>
+#endif /* _WIN32 */
+
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _MSC_VER
+
+typedef size_t                         ssize_t;
+typedef unsigned __int16       uint16_t;
+typedef unsigned __int32       uint32_t;
+
+#else /* _MSC_VER */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#endif /* _MSC_VER */
+
+/**
+ * Establishes a TCP/IP connection to @p host at port @p port.
+ * @param host Hostname to connect to
+ * @param port Port number
+ * @return The file descriptor on success, -1 otherwise
+ */
+int firmnet_connect_tcp(const char *host, uint16_t port);
+
+/**
+ * Closes connection established on socket @p fd.
+ * @param fd The file descriptor identifying the connection
+ */
+void firmnet_close_socket(int fd);
+
+/**
+ * Send message of size @p n from buffer @p buf to file descriptor @p fd.
+ * @param fd   The file descriptor, the message should be send to.
+ * @param buf  The buffer containing the message
+ * @param n    The length of the message.
+ * @return Number of bytes written or -1 on failure.
+ */
+ssize_t firmnet_send(int fd, const void *buf, size_t n);
+
+/**
+ * Try to read some bytes but block until a certain amount is read.
+ * @param fd The file descriptor.
+ * @param buf The buffer to read into.
+ * @param try The amount of bytes to try to read.
+ * @param at_least block until this many bytes are read.
+ * @return The number of bytes read or -1 on error.
+ */
+ssize_t firmnet_recv(int fd, void *buf, size_t try, size_t at_least);
+
+#endif /* _FIRMNET_H_ */
diff --git a/ir/net/firmnet_t.h b/ir/net/firmnet_t.h
new file mode 100644 (file)
index 0000000..c0557f7
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef _FIRMNET_T_H_
+#define _FIRMNET_T_H_
+
+#include "firmnet.h"
+
+#define BASIC_ERR_CHECK(expr,op,cond,fmt,last) \
+{ \
+       int res; \
+       if((res = (expr)) op cond) { \
+       fprintf(stderr, "%s(%d): %d = %s(%d): ", \
+       __FILE__, __LINE__, res, #expr, cond); \
+       lpp_print_err fmt; \
+       fprintf(stderr, "\n"); \
+       last; \
+       } \
+}
+
+#define BASIC_ERRNO_CHECK(expr,op,cond,last) \
+{ \
+       int _basic_errno_check_res = (expr); \
+       if(_basic_errno_check_res op cond) { \
+       fprintf(stderr, "%s(%d): %d = %s(%d): %s\n", \
+       __FILE__, __LINE__, _basic_errno_check_res, #expr, cond, strerror(errno)); \
+       last; \
+       } \
+}
+
+#define ERR_CHECK_RETURN(expr, op, cond, fmt, retval) \
+       BASIC_ERR_CHECK(expr, op, cond, fmt, return retval)
+
+#define ERRNO_CHECK_RETURN(expr, op, cond, retval) \
+       BASIC_ERRNO_CHECK(expr, op, cond, return retval)
+
+#define ERR_CHECK_RETURN_VOID(expr, op, cond, fmt) \
+       BASIC_ERR_CHECK(expr, op, cond, fmt, return)
+
+#define ERRNO_CHECK_RETURN_VOID(expr, op, cond) \
+       BASIC_ERRNO_CHECK(expr, op, cond, return)
+
+#define ERR_CHECK(expr, op, cond, fmt) \
+       BASIC_ERR_CHECK(expr, op, cond, fmt, (void) 0)
+
+#define ERRNO_CHECK(expr, op, cond) \
+       BASIC_ERRNO_CHECK(expr, op, cond, (void) 0)
+
+#endif /* _FIRMNET_T_H_ */