From efca491e4c19868a68a099638552f9ba431dca4b Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Wed, 20 Mar 2013 05:34:51 +0100 Subject: move thread and socket code to "common" subdir --- Makefile.am | 2 +- common/Makefile.am | 15 ++ common/socket.c | 392 ++++++++++++++++++++++++++++++++++++++++ common/socket.h | 65 +++++++ common/thread.c | 83 +++++++++ common/thread.h | 45 +++++ configure.ac | 1 + tools/Makefile.am | 6 +- tools/idevicedebugserverproxy.c | 4 +- tools/socket.c | 392 ---------------------------------------- tools/socket.h | 65 ------- tools/thread.c | 47 ----- tools/thread.h | 38 ---- 13 files changed, 606 insertions(+), 549 deletions(-) create mode 100644 common/Makefile.am create mode 100644 common/socket.c create mode 100644 common/socket.h create mode 100644 common/thread.c create mode 100644 common/thread.h delete mode 100644 tools/socket.c delete mode 100644 tools/socket.h delete mode 100644 tools/thread.c delete mode 100644 tools/thread.h diff --git a/Makefile.am b/Makefile.am index d342323..c2644e4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src include $(CYTHON_SUB) $(DEV_SUB) tools docs +SUBDIRS = common src include $(CYTHON_SUB) $(DEV_SUB) tools docs DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100644 index 0000000..dfa6852 --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libplist_LIBS) ${libpthread_LIBS} + +noinst_LTLIBRARIES = libinternalcommon.la +libinternalcommon_la_LIBADD = +libinternalcommon_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined +libinternalcommon_la_SOURCES = \ + socket.c socket.h \ + thread.c thread.h + +if WIN32 +libinternalcommon_la_LIBADD += -lole32 +endif diff --git a/common/socket.c b/common/socket.c new file mode 100644 index 0000000..c35de33 --- /dev/null +++ b/common/socket.c @@ -0,0 +1,392 @@ +/* + * socket.c + * + * Copyright (c) 2012 Martin Szulecki All Rights Reserved. + * Copyright (c) 2012 Nikias Bassen All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#include +static int wsa_init = 0; +#else +#include +#include +#include +#include +#include +#endif +#include "socket.h" + +#define RECV_TIMEOUT 20000 + +static int verbose = 0; + +void socket_set_verbose(int level) +{ + verbose = level; +} + +#ifndef WIN32 +int socket_create_unix(const char *filename) +{ + struct sockaddr_un name; + int sock; + size_t size; + + // remove if still present + unlink(filename); + + /* Create the socket. */ + sock = socket(PF_LOCAL, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket"); + return -1; + } + + /* Bind a name to the socket. */ + name.sun_family = AF_LOCAL; + strncpy(name.sun_path, filename, sizeof(name.sun_path)); + name.sun_path[sizeof(name.sun_path) - 1] = '\0'; + + /* The size of the address is + the offset of the start of the filename, + plus its length, + plus one for the terminating null byte. + Alternatively you can just do: + size = SUN_LEN (&name); + */ + size = (offsetof(struct sockaddr_un, sun_path) + + strlen(name.sun_path) + 1); + + if (bind(sock, (struct sockaddr *) &name, size) < 0) { + perror("bind"); + socket_close(sock); + return -1; + } + + if (listen(sock, 10) < 0) { + perror("listen"); + socket_close(sock); + return -1; + } + + return sock; +} + +int socket_connect_unix(const char *filename) +{ + struct sockaddr_un name; + int sfd = -1; + size_t size; + struct stat fst; + + // check if socket file exists... + if (stat(filename, &fst) != 0) { + if (verbose >= 2) + fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename, + strerror(errno)); + return -1; + } + // ... and if it is a unix domain socket + if (!S_ISSOCK(fst.st_mode)) { + if (verbose >= 2) + fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__, + filename); + return -1; + } + // make a new socket + if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { + if (verbose >= 2) + fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno)); + return -1; + } + // and connect to 'filename' + name.sun_family = AF_LOCAL; + strncpy(name.sun_path, filename, sizeof(name.sun_path)); + name.sun_path[sizeof(name.sun_path) - 1] = 0; + + size = (offsetof(struct sockaddr_un, sun_path) + + strlen(name.sun_path) + 1); + + if (connect(sfd, (struct sockaddr *) &name, size) < 0) { + socket_close(sfd); + if (verbose >= 2) + fprintf(stderr, "%s: connect: %s\n", __func__, + strerror(errno)); + return -1; + } + + return sfd; +} +#endif + +int socket_create(uint16_t port) +{ + int sfd = -1; + int yes = 1; +#ifdef WIN32 + WSADATA wsa_data; + if (!wsa_init) { + if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) { + fprintf(stderr, "WSAStartup failed!\n"); + ExitProcess(-1); + } + wsa_init = 1; + } +#endif + struct sockaddr_in saddr; + + if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { + perror("socket()"); + return -1; + } + + if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) { + perror("setsockopt()"); + socket_close(sfd); + return -1; + } + + memset((void *) &saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = htons(port); + + if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) { + perror("bind()"); + socket_close(sfd); + return -1; + } + + if (listen(sfd, 1) == -1) { + perror("listen()"); + socket_close(sfd); + return -1; + } + + return sfd; +} + +int socket_connect(const char *addr, uint16_t port) +{ + int sfd = -1; + int yes = 1; + struct hostent *hp; + struct sockaddr_in saddr; +#ifdef WIN32 + WSADATA wsa_data; + if (!wsa_init) { + if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) { + fprintf(stderr, "WSAStartup failed!\n"); + ExitProcess(-1); + } + wsa_init = 1; + } +#endif + + if (!addr) { + errno = EINVAL; + return -1; + } + + if ((hp = gethostbyname(addr)) == NULL) { + if (verbose >= 2) + fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr); + return -1; + } + + if (!hp->h_addr) { + if (verbose >= 2) + fprintf(stderr, "%s: gethostbyname returned NULL address!\n", + __func__); + return -1; + } + + if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { + perror("socket()"); + return -1; + } + + if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) { + perror("setsockopt()"); + socket_close(sfd); + return -1; + } + + memset((void *) &saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr; + saddr.sin_port = htons(port); + + if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { + perror("connect"); + socket_close(sfd); + return -2; + } + + return sfd; +} + +int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout) +{ + fd_set fds; + int sret; + int eagain; + struct timeval to; + struct timeval *pto; + + if (fd <= 0) { + if (verbose >= 2) + fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd); + return -1; + } + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + if (timeout > 0) { + to.tv_sec = (time_t) (timeout / 1000); + to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000); + pto = &to; + } else { + pto = NULL; + } + + sret = -1; + + do { + eagain = 0; + switch (fdm) { + case FDM_READ: + sret = select(fd + 1, &fds, NULL, NULL, pto); + break; + case FDM_WRITE: + sret = select(fd + 1, NULL, &fds, NULL, pto); + break; + case FDM_EXCEPT: + sret = select(fd + 1, NULL, NULL, &fds, pto); + break; + default: + return -1; + } + + if (sret < 0) { + switch (errno) { + case EINTR: + // interrupt signal in select + if (verbose >= 2) + fprintf(stderr, "%s: EINTR\n", __func__); + eagain = 1; + break; + case EAGAIN: + if (verbose >= 2) + fprintf(stderr, "%s: EAGAIN\n", __func__); + break; + default: + if (verbose >= 2) + fprintf(stderr, "%s: select failed: %s\n", __func__, + strerror(errno)); + return -1; + } + } + } while (eagain); + + return sret; +} + +int socket_accept(int fd, uint16_t port) +{ +#ifdef WIN32 + int addr_len; +#else + socklen_t addr_len; +#endif + int result; + struct sockaddr_in addr; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + addr_len = sizeof(addr); + result = accept(fd, (struct sockaddr*)&addr, &addr_len); + + return result; +} + +int socket_shutdown(int fd, int how) +{ + return shutdown(fd, how); +} + +int socket_close(int fd) { +#ifdef WIN32 + return closesocket(fd); +#else + return close(fd); +#endif +} + +int socket_receive(int fd, void *data, size_t length) +{ + return socket_receive_timeout(fd, data, length, 0, RECV_TIMEOUT); +} + +int socket_peek(int fd, void *data, size_t length) +{ + return socket_receive_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT); +} + +int socket_receive_timeout(int fd, void *data, size_t length, int flags, + unsigned int timeout) +{ + int res; + int result; + + // check if data is available + res = socket_check_fd(fd, FDM_READ, timeout); + if (res <= 0) { + return res; + } + // if we get here, there _is_ data available + result = recv(fd, data, length, flags); + if (res > 0 && result == 0) { + // but this is an error condition + if (verbose >= 3) + fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd); + return -EAGAIN; + } + if (result < 0) { + return -errno; + } + return result; +} + +int socket_send(int fd, void *data, size_t length) +{ + return send(fd, data, length, 0); +} diff --git a/common/socket.h b/common/socket.h new file mode 100644 index 0000000..c2b2599 --- /dev/null +++ b/common/socket.h @@ -0,0 +1,65 @@ +/* + * socket.h + * + * Copyright (c) 2012 Martin Szulecki All Rights Reserved. + * Copyright (c) 2012 Nikias Bassen All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SOCKET_SOCKET_H +#define __SOCKET_SOCKET_H + +#include +#include + +enum fd_mode { + FDM_READ, + FDM_WRITE, + FDM_EXCEPT +}; +typedef enum fd_mode fd_mode; + +#ifdef WIN32 +#include +#define SHUT_RD SD_READ +#define SHUT_WR SD_WRITE +#define SHUT_RDWR SD_BOTH +#else +#include +#endif + +#ifndef WIN32 +int socket_create_unix(const char *filename); +int socket_connect_unix(const char *filename); +#endif +int socket_create(uint16_t port); +int socket_connect(const char *addr, uint16_t port); +int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout); +int socket_accept(int fd, uint16_t port); + +int socket_shutdown(int fd, int how); +int socket_close(int fd); + +int socket_receive(int fd, void *data, size_t size); +int socket_peek(int fd, void *data, size_t size); +int socket_receive_timeout(int fd, void *data, size_t size, int flags, + unsigned int timeout); + +int socket_send(int fd, void *data, size_t size); + +void socket_set_verbose(int level); + +#endif /* __SOCKET_SOCKET_H */ diff --git a/common/thread.c b/common/thread.c new file mode 100644 index 0000000..2cf4321 --- /dev/null +++ b/common/thread.c @@ -0,0 +1,83 @@ +/* + * thread.c + * + * Copyright (c) 2012 Martin Szulecki All Rights Reserved. + * Copyright (c) 2012 Nikias Bassen All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "thread.h" + +int thread_create(thread_t *thread, thread_func_t thread_func, void* data) +{ +#ifdef WIN32 + HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL); + if (th == NULL) { + return -1; + } + *thread = th; + return 0; +#else + int res = pthread_create(thread, NULL, thread_func, data); + return res; +#endif +} + +void thread_join(thread_t thread) +{ + /* wait for thread to complete */ +#ifdef WIN32 + WaitForSingleObject(thread, INFINITE); +#else + pthread_join(thread, NULL); +#endif +} + +void mutex_init(mutex_t* mutex) +{ +#ifdef WIN32 + InitializeCriticalSection(mutex); +#else + pthread_mutex_init(mutex, NULL); +#endif +} + +void mutex_destroy(mutex_t* mutex) +{ +#ifdef WIN32 + DeleteCriticalSection(mutex); +#else + pthread_mutex_destroy(mutex); +#endif +} + +void mutex_lock(mutex_t* mutex) +{ +#ifdef WIN32 + EnterCriticalSection(mutex); +#else + pthread_mutex_lock(mutex); +#endif +} + +void mutex_unlock(mutex_t* mutex) +{ +#ifdef WIN32 + LeaveCriticalSection(mutex); +#else + pthread_mutex_unlock(mutex); +#endif +} diff --git a/common/thread.h b/common/thread.h new file mode 100644 index 0000000..e74ee74 --- /dev/null +++ b/common/thread.h @@ -0,0 +1,45 @@ +/* + * thread.h + * + * Copyright (c) 2012 Martin Szulecki All Rights Reserved. + * Copyright (c) 2012 Nikias Bassen All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __THREAD_H +#define __THREAD_H + +#ifdef WIN32 +#include +typedef HANDLE thread_t; +typedef CRITICAL_SECTION mutex_t; +#else +#include +typedef pthread_t thread_t; +typedef pthread_mutex_t mutex_t; +#endif + +typedef void* (*thread_func_t)(void* data); + +int thread_create(thread_t* thread, thread_func_t thread_func, void* data); +void thread_join(thread_t thread); + +void mutex_init(mutex_t* mutex); +void mutex_destroy(mutex_t* mutex); +void mutex_lock(mutex_t* mutex); +void mutex_unlock(mutex_t* mutex); + +#endif diff --git a/configure.ac b/configure.ac index cf644a8..57cd233 100644 --- a/configure.ac +++ b/configure.ac @@ -223,6 +223,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_OUTPUT([ Makefile +common/Makefile src/Makefile include/Makefile dev/Makefile diff --git a/tools/Makefile.am b/tools/Makefile.am index 5b07a5e..57445d8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -60,14 +60,12 @@ ideviceprovision_CFLAGS = $(AM_CFLAGS) ideviceprovision_LDFLAGS = $(AM_LDFLAGS) ideviceprovision_LDADD = ../src/libimobiledevice.la -idevicedebugserverproxy_SOURCES = idevicedebugserverproxy.c socket.c thread.c +idevicedebugserverproxy_SOURCES = idevicedebugserverproxy.c idevicedebugserverproxy_CFLAGS = $(AM_CFLAGS) idevicedebugserverproxy_LDFLAGS = $(AM_LDFLAGS) -idevicedebugserverproxy_LDADD = ../src/libimobiledevice.la +idevicedebugserverproxy_LDADD = $(top_srcdir)/common/libinternalcommon.la ../src/libimobiledevice.la idevicediagnostics_SOURCES = idevicediagnostics.c idevicediagnostics_CFLAGS = $(AM_CFLAGS) idevicediagnostics_LDFLAGS = $(AM_LDFLAGS) idevicediagnostics_LDADD = ../src/libimobiledevice.la - -EXTRA_DIST = socket.h thread.h diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c index 3a25ebc..baf3cd7 100644 --- a/tools/idevicedebugserverproxy.c +++ b/tools/idevicedebugserverproxy.c @@ -28,8 +28,8 @@ #include #include -#include "socket.h" -#include "thread.h" +#include "common/socket.h" +#include "common/thread.h" #define info(...) fprintf(stdout, __VA_ARGS__); fflush(stdout) #define debug(...) if(debug_mode) fprintf(stdout, __VA_ARGS__) diff --git a/tools/socket.c b/tools/socket.c deleted file mode 100644 index c35de33..0000000 --- a/tools/socket.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * socket.c - * - * Copyright (c) 2012 Martin Szulecki All Rights Reserved. - * Copyright (c) 2012 Nikias Bassen All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#include -static int wsa_init = 0; -#else -#include -#include -#include -#include -#include -#endif -#include "socket.h" - -#define RECV_TIMEOUT 20000 - -static int verbose = 0; - -void socket_set_verbose(int level) -{ - verbose = level; -} - -#ifndef WIN32 -int socket_create_unix(const char *filename) -{ - struct sockaddr_un name; - int sock; - size_t size; - - // remove if still present - unlink(filename); - - /* Create the socket. */ - sock = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket"); - return -1; - } - - /* Bind a name to the socket. */ - name.sun_family = AF_LOCAL; - strncpy(name.sun_path, filename, sizeof(name.sun_path)); - name.sun_path[sizeof(name.sun_path) - 1] = '\0'; - - /* The size of the address is - the offset of the start of the filename, - plus its length, - plus one for the terminating null byte. - Alternatively you can just do: - size = SUN_LEN (&name); - */ - size = (offsetof(struct sockaddr_un, sun_path) - + strlen(name.sun_path) + 1); - - if (bind(sock, (struct sockaddr *) &name, size) < 0) { - perror("bind"); - socket_close(sock); - return -1; - } - - if (listen(sock, 10) < 0) { - perror("listen"); - socket_close(sock); - return -1; - } - - return sock; -} - -int socket_connect_unix(const char *filename) -{ - struct sockaddr_un name; - int sfd = -1; - size_t size; - struct stat fst; - - // check if socket file exists... - if (stat(filename, &fst) != 0) { - if (verbose >= 2) - fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename, - strerror(errno)); - return -1; - } - // ... and if it is a unix domain socket - if (!S_ISSOCK(fst.st_mode)) { - if (verbose >= 2) - fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__, - filename); - return -1; - } - // make a new socket - if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { - if (verbose >= 2) - fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno)); - return -1; - } - // and connect to 'filename' - name.sun_family = AF_LOCAL; - strncpy(name.sun_path, filename, sizeof(name.sun_path)); - name.sun_path[sizeof(name.sun_path) - 1] = 0; - - size = (offsetof(struct sockaddr_un, sun_path) - + strlen(name.sun_path) + 1); - - if (connect(sfd, (struct sockaddr *) &name, size) < 0) { - socket_close(sfd); - if (verbose >= 2) - fprintf(stderr, "%s: connect: %s\n", __func__, - strerror(errno)); - return -1; - } - - return sfd; -} -#endif - -int socket_create(uint16_t port) -{ - int sfd = -1; - int yes = 1; -#ifdef WIN32 - WSADATA wsa_data; - if (!wsa_init) { - if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) { - fprintf(stderr, "WSAStartup failed!\n"); - ExitProcess(-1); - } - wsa_init = 1; - } -#endif - struct sockaddr_in saddr; - - if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { - perror("socket()"); - return -1; - } - - if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) { - perror("setsockopt()"); - socket_close(sfd); - return -1; - } - - memset((void *) &saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - saddr.sin_port = htons(port); - - if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) { - perror("bind()"); - socket_close(sfd); - return -1; - } - - if (listen(sfd, 1) == -1) { - perror("listen()"); - socket_close(sfd); - return -1; - } - - return sfd; -} - -int socket_connect(const char *addr, uint16_t port) -{ - int sfd = -1; - int yes = 1; - struct hostent *hp; - struct sockaddr_in saddr; -#ifdef WIN32 - WSADATA wsa_data; - if (!wsa_init) { - if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) { - fprintf(stderr, "WSAStartup failed!\n"); - ExitProcess(-1); - } - wsa_init = 1; - } -#endif - - if (!addr) { - errno = EINVAL; - return -1; - } - - if ((hp = gethostbyname(addr)) == NULL) { - if (verbose >= 2) - fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr); - return -1; - } - - if (!hp->h_addr) { - if (verbose >= 2) - fprintf(stderr, "%s: gethostbyname returned NULL address!\n", - __func__); - return -1; - } - - if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { - perror("socket()"); - return -1; - } - - if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) { - perror("setsockopt()"); - socket_close(sfd); - return -1; - } - - memset((void *) &saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr; - saddr.sin_port = htons(port); - - if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { - perror("connect"); - socket_close(sfd); - return -2; - } - - return sfd; -} - -int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout) -{ - fd_set fds; - int sret; - int eagain; - struct timeval to; - struct timeval *pto; - - if (fd <= 0) { - if (verbose >= 2) - fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd); - return -1; - } - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - if (timeout > 0) { - to.tv_sec = (time_t) (timeout / 1000); - to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000); - pto = &to; - } else { - pto = NULL; - } - - sret = -1; - - do { - eagain = 0; - switch (fdm) { - case FDM_READ: - sret = select(fd + 1, &fds, NULL, NULL, pto); - break; - case FDM_WRITE: - sret = select(fd + 1, NULL, &fds, NULL, pto); - break; - case FDM_EXCEPT: - sret = select(fd + 1, NULL, NULL, &fds, pto); - break; - default: - return -1; - } - - if (sret < 0) { - switch (errno) { - case EINTR: - // interrupt signal in select - if (verbose >= 2) - fprintf(stderr, "%s: EINTR\n", __func__); - eagain = 1; - break; - case EAGAIN: - if (verbose >= 2) - fprintf(stderr, "%s: EAGAIN\n", __func__); - break; - default: - if (verbose >= 2) - fprintf(stderr, "%s: select failed: %s\n", __func__, - strerror(errno)); - return -1; - } - } - } while (eagain); - - return sret; -} - -int socket_accept(int fd, uint16_t port) -{ -#ifdef WIN32 - int addr_len; -#else - socklen_t addr_len; -#endif - int result; - struct sockaddr_in addr; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(port); - - addr_len = sizeof(addr); - result = accept(fd, (struct sockaddr*)&addr, &addr_len); - - return result; -} - -int socket_shutdown(int fd, int how) -{ - return shutdown(fd, how); -} - -int socket_close(int fd) { -#ifdef WIN32 - return closesocket(fd); -#else - return close(fd); -#endif -} - -int socket_receive(int fd, void *data, size_t length) -{ - return socket_receive_timeout(fd, data, length, 0, RECV_TIMEOUT); -} - -int socket_peek(int fd, void *data, size_t length) -{ - return socket_receive_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT); -} - -int socket_receive_timeout(int fd, void *data, size_t length, int flags, - unsigned int timeout) -{ - int res; - int result; - - // check if data is available - res = socket_check_fd(fd, FDM_READ, timeout); - if (res <= 0) { - return res; - } - // if we get here, there _is_ data available - result = recv(fd, data, length, flags); - if (res > 0 && result == 0) { - // but this is an error condition - if (verbose >= 3) - fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd); - return -EAGAIN; - } - if (result < 0) { - return -errno; - } - return result; -} - -int socket_send(int fd, void *data, size_t length) -{ - return send(fd, data, length, 0); -} diff --git a/tools/socket.h b/tools/socket.h deleted file mode 100644 index c2b2599..0000000 --- a/tools/socket.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * socket.h - * - * Copyright (c) 2012 Martin Szulecki All Rights Reserved. - * Copyright (c) 2012 Nikias Bassen All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __SOCKET_SOCKET_H -#define __SOCKET_SOCKET_H - -#include -#include - -enum fd_mode { - FDM_READ, - FDM_WRITE, - FDM_EXCEPT -}; -typedef enum fd_mode fd_mode; - -#ifdef WIN32 -#include -#define SHUT_RD SD_READ -#define SHUT_WR SD_WRITE -#define SHUT_RDWR SD_BOTH -#else -#include -#endif - -#ifndef WIN32 -int socket_create_unix(const char *filename); -int socket_connect_unix(const char *filename); -#endif -int socket_create(uint16_t port); -int socket_connect(const char *addr, uint16_t port); -int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout); -int socket_accept(int fd, uint16_t port); - -int socket_shutdown(int fd, int how); -int socket_close(int fd); - -int socket_receive(int fd, void *data, size_t size); -int socket_peek(int fd, void *data, size_t size); -int socket_receive_timeout(int fd, void *data, size_t size, int flags, - unsigned int timeout); - -int socket_send(int fd, void *data, size_t size); - -void socket_set_verbose(int level); - -#endif /* __SOCKET_SOCKET_H */ diff --git a/tools/thread.c b/tools/thread.c deleted file mode 100644 index f077243..0000000 --- a/tools/thread.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * thread.c - * - * Copyright (c) 2012 Martin Szulecki All Rights Reserved. - * Copyright (c) 2012 Nikias Bassen All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "thread.h" - -int thread_create(thread_t *thread, thread_func_t thread_func, void* data) -{ -#ifdef WIN32 - HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL); - if (th == NULL) { - return -1; - } - *thread = th; - return 0; -#else - int res = pthread_create(thread, NULL, thread_func, data); - return res; -#endif -} - -void thread_join(thread_t thread) -{ - /* wait for thread to complete */ -#ifdef WIN32 - WaitForSingleObject(thread, INFINITE); -#else - pthread_join(thread, NULL); -#endif -} diff --git a/tools/thread.h b/tools/thread.h deleted file mode 100644 index 983eeb5..0000000 --- a/tools/thread.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * thread.h - * - * Copyright (c) 2012 Martin Szulecki All Rights Reserved. - * Copyright (c) 2012 Nikias Bassen All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __THREAD_H -#define __THREAD_H - -#ifdef WIN32 -#include -typedef HANDLE thread_t; -#else -#include -typedef pthread_t thread_t; -#endif - -typedef void* (*thread_func_t)(void* data); - -int thread_create(thread_t* thread, thread_func_t thread_func, void* data); -void thread_join(thread_t thread); - -#endif -- cgit v1.1-32-gdbae