summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wolf/network/network.h17
-rw-r--r--src/GNUmakefile6
-rw-r--r--src/network/network_unix.c46
-rw-r--r--tests/network/test1_unix.c19
-rw-r--r--tests/network/test2_unix.c15
-rw-r--r--tests/network/test_proactor.c20
6 files changed, 86 insertions, 37 deletions
diff --git a/include/wolf/network/network.h b/include/wolf/network/network.h
index b98723f..29e9ce2 100644
--- a/include/wolf/network/network.h
+++ b/include/wolf/network/network.h
@@ -35,9 +35,18 @@ extern "C" {
#include "port/sys.h"
+#include "errors.h"
+
+#if defined LINUX
+#include <sys/socket.h> /* for sockaddr_storage */
+#include <netinet/in.h> /* for sockaddr_in */
+#else
+#error Check includes first!
+#endif
+
/**
* helper union to avoid anti-aliasing warnings in old network functions like getpeername,
- * use instead of struct sockaddr_storage when declaring socket address variables which need
+ * used instead of struct sockaddr_storage when declaring socket address variables which need
* proper alignment
*/
typedef union wolf_network_sockaddr_union_t {
@@ -49,6 +58,12 @@ typedef union wolf_network_sockaddr_union_t {
struct sockaddr addr;
} wolf_network_sockaddr_union_t;
+/**
+ * Set a file descriptor non-blocking, Unix-specific, and more important, doesn't
+ * work on all kind of descriptors!
+ */
+wolf_error_t wolf_network_set_nonblocking( int fd );
+
#ifdef __cplusplus
}
#endif
diff --git a/src/GNUmakefile b/src/GNUmakefile
index f8a4707..39add1c 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -30,11 +30,15 @@ DAEMON_OBJS = \
SERVICE_OBJS = \
service/service.o
+NETWORK_OBJS = \
+ network/network_unix.o
+
OBJS = \
$(THREADING_OBJS) \
$(PORT_OBJS) \
$(LOG_OBJS) \
- $(DAEMON_OBJS)
+ $(DAEMON_OBJS) \
+ $(NETWORK_OBJS)
CATALOG_NAME = libwolf
diff --git a/src/network/network_unix.c b/src/network/network_unix.c
new file mode 100644
index 0000000..41c8313
--- /dev/null
+++ b/src/network/network_unix.c
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2008 Andreas Baumann <abaumann@yahoo.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "port/sys.h"
+#include "port/sys_internal.h"
+
+#include "errors.h"
+#include "log/log.h"
+#include "log/messages.h"
+
+#include "network/network.h"
+
+#include "port/unistd.h"
+#include <fcntl.h> /* for fcntl and F_* flags */
+
+wolf_error_t wolf_network_set_nonblocking( int fd ) {
+ int flags;
+
+ flags = fcntl( fd, F_GETFL, 0 /* ignored */ );
+ if( flags < 0 ) {
+ return WOLF_ERR_INTERNAL;
+ }
+
+ flags |= O_NONBLOCK;
+
+ flags = fcntl( fd, F_SETFL, flags );
+ if( flags < 0 ) {
+ return WOLF_ERR_INTERNAL;
+ }
+
+ return WOLF_OK;
+}
diff --git a/tests/network/test1_unix.c b/tests/network/test1_unix.c
index 27faaaa..28a5426 100644
--- a/tests/network/test1_unix.c
+++ b/tests/network/test1_unix.c
@@ -14,24 +14,12 @@
#include <unistd.h> /* for close */
#include <errno.h> /* for errno */
-#include <fcntl.h> /* for fcntl */
#include <sys/select.h> /* for select */
#include <assert.h> /* for assertions */
#include <signal.h> /* for signal */
#define DEBUG 0
-static bool wolf_network_sock_nonblocking( int fd ) {
- int flags;
-
- flags = fcntl( fd, F_GETFL, 0 /* ignored */ );
- if( flags < 0 ) return false;
- flags |= O_NONBLOCK;
- flags = fcntl( fd, F_SETFL, flags );
- if( flags < 0 ) return false;
- return true;
-}
-
#if DEBUG
static char *fd_set_to_string( fd_set *fd, int min_fd, int max_fd, char *buf, size_t buflen ) {
int i;
@@ -130,8 +118,7 @@ int main( int argc, char *argv[] ) {
}
/* set socket non-blocking for asynchronous connect */
- if( !wolf_network_sock_nonblocking( fd ) ) {
- fprintf( stderr, "set nonblocking failed for socket: %s (%d)\n", strerror( errno ), errno );
+ if( wolf_network_set_nonblocking( fd ) != WOLF_OK ) {
goto FAIL;
}
@@ -245,11 +232,11 @@ CONNECTED:
fprintf( stderr, "Connected to %s, port %s (peer: %s, %s)\n", host, service,
peer_hostname, peer_service );
- if( !wolf_network_sock_nonblocking( STDIN_FILENO ) ) {
+ if( wolf_network_set_nonblocking( STDIN_FILENO ) != WOLF_OK ) {
(void)close( fd );
goto FAIL;
}
- if( !wolf_network_sock_nonblocking( STDOUT_FILENO ) ) {
+ if( !wolf_network_set_nonblocking( STDOUT_FILENO ) != WOLF_OK ) {
fprintf( stderr, "set nonblocking failed for stdout: %s (%d)\n", strerror( errno ), errno );
goto FAIL;
}
diff --git a/tests/network/test2_unix.c b/tests/network/test2_unix.c
index 3964c93..dcb468c 100644
--- a/tests/network/test2_unix.c
+++ b/tests/network/test2_unix.c
@@ -13,7 +13,6 @@
#include <unistd.h> /* for close */
#include <errno.h> /* for errno */
-#include <fcntl.h> /* for fcntl */
#include <sys/select.h> /* for select */
#include <assert.h> /* for assertions */
#include <signal.h> /* for signal */
@@ -23,17 +22,6 @@
#define MAX_ACCEPT_IDLE_TIMEOUT 4
#define MAX_IDLE_TIMEOUT 10
-static bool wolf_network_sock_nonblocking( int fd ) {
- int flags;
-
- flags = fcntl( fd, F_GETFL, 0 /* ignored */ );
- if( flags < 0 ) return false;
- flags |= O_NONBLOCK;
- flags = fcntl( fd, F_SETFL, flags );
- if( flags < 0 ) return false;
- return true;
-}
-
#if DEBUG
static char *fd_set_to_string( fd_set *fd, int min_fd, int max_fd, char *buf, size_t buflen ) {
int i;
@@ -156,8 +144,7 @@ int main( int argc, char* argv[] ) {
}
/* set socket non-blocking for accepts (Stevens 15.6) */
- if( !wolf_network_sock_nonblocking( serv_fd ) ) {
- fprintf( stderr, "set nonblocking failed for server socket: %s (%d)\n", strerror( errno ), errno );
+ if( wolf_network_set_nonblocking( serv_fd ) != WOLF_OK ) {
goto FAIL;
}
diff --git a/tests/network/test_proactor.c b/tests/network/test_proactor.c
index fc44b13..2d998cc 100644
--- a/tests/network/test_proactor.c
+++ b/tests/network/test_proactor.c
@@ -19,8 +19,13 @@ typedef struct wolf_asio_completion_dispatcher_t *wolf_asio_completion_dispatche
* - the Acceptor: accepts new connections arsynchronously
* - the Protocol Handler: handles all the communication with the
* other peer, it should never do long synchronous work!
+ * - per operation there is one specialized handler, so we can pass
+ * aynchronous request data to it
*/
-typedef void(*wolf_asio_completion_handler_f)( void );
+typedef void(*wolf_asio_write_completion_handler_f)( void );
+typedef void(*wolf_asio_read_completion_handler_f)( void );
+typedef void(*wolf_asio_accept_completion_handler_f)( void );
+typedef void(*wolf_asio_connect_completion_handler_f)( void );
/* Asynchronous Operation Processor (asio_proc):
* - performs the asynchronous opreation on behalf of the application,
@@ -51,14 +56,19 @@ wolf_error_t wolf_asio_proc_free( wolf_asio_proc_p proc );
wolf_error_t wolf_asio_proc_write( wolf_asio_proc_p proc,
char *buf,
- size_t buflen );
+ size_t buflen,
+ wolf_asio_write_completion_handler_f completion_handler );
wolf_error_t wolf_asio_proc_read( wolf_asio_proc_p proc,
char *buf,
- size_t buflen );
+ size_t buflen,
+ wolf_asio_read_completion_handler_f completion_handler );
wolf_error_t wolf_asio_proc_accept( wolf_asio_proc_p proc,
- wolf_asio_completion_handler_f completion_handler );
+ wolf_asio_accept_completion_handler_f completion_handler );
+
+wolf_error_t wolf_asio_proc_connect( wolf_asio_proc_p proc,
+ wolf_asio_connect_completion_handler_f completion_handler );
/**
* Acceptor
@@ -125,7 +135,7 @@ wolf_error_t wolf_asio_proc_free( wolf_asio_proc_p proc ) {
}
wolf_error_t wolf_asio_proc_accept( wolf_asio_proc_p proc,
- wolf_asio_completion_handler_f completion_handler ) {
+ wolf_asio_accept_completion_handler_f completion_handler ) {
WOLF_UNUSED( proc );
WOLF_UNUSED( completion_handler );