diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 18 | ||||
-rw-r--r-- | src/include/sockio.h | 13 | ||||
-rw-r--r-- | src/interp/sys-os.boot | 20 | ||||
-rw-r--r-- | src/lib/sockio-c.c | 128 |
4 files changed, 133 insertions, 46 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2ac47896..dc93a3c5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,23 @@ 2008-09-06 Gabriel Dos Reis <gdr@cs.tamu.edu> + * interp/sys-os.boot (openIP4ClientStreamSocket): New. + (readFromStreamSocket): Likewise. + (writeToStreamSocket): Likewise. + (closeSocket): Likewise. + * include/sockio.h: Include <arpa/inet.h> + (oa_open_ip4_client_stream_socket): Declare. + (oa_socket_write): Likewise. + (oa_socket_read): Likewise. + * lib/sockio-c.c (openaxiom_unload_socket_module): New. + (openaxiom_load_socket_module): Tidy. + (openaxiom_socket_is_invalid): New. + (is_invalid_socket): Use it. + (oa_open_ip4_client_stream_socket): Define. + (oa_socket_read): Likewise. + (oa_socket_write): Likewise. + +2008-09-06 Gabriel Dos Reis <gdr@cs.tamu.edu> + * lib/cfuns-c.c (oa_unlink): Tidy. 2008-09-05 Gabriel Dos Reis <gdr@cs.tamu.edu> diff --git a/src/include/sockio.h b/src/include/sockio.h index 50fe3287..15202d93 100644 --- a/src/include/sockio.h +++ b/src/include/sockio.h @@ -40,11 +40,14 @@ #ifdef __MINGW32__ # include <winsock2.h> +# define OPENAXIOM_INVALID_SOCKET INVALID_SOCKET #else # include <sys/types.h> # include <sys/socket.h> # include <netinet/in.h> +# include <arpa/inet.h> # include <sys/un.h> +# define OPENAXIOM_INVALID_SOCKET (-1) #endif #include "openaxiom-c-macros.h" @@ -61,7 +64,7 @@ typedef SOCKET openaxiom_socket; #else typedef int openaxiom_socket; #endif - +typedef int openaxiom_port; typedef struct openaxiom_sio { openaxiom_socket socket; /* descriptor of this socket I/O endpoint. */ @@ -82,6 +85,13 @@ typedef struct openaxiom_sio { OPENAXIOM_EXPORT int oa_open_local_client_stream_socket(const char*); OPENAXIOM_EXPORT int oa_open_local_server_stream_socket(const char*); +OPENAXIOM_EXPORT openaxiom_socket +oa_open_ip4_client_stream_socket(const char*, openaxiom_port); +OPENAXIOM_EXPORT int oa_socket_write(openaxiom_socket, + const openaxiom_byte*, int); +OPENAXIOM_EXPORT int oa_socket_read(openaxiom_socket, + openaxiom_byte*, int); +OPENAXIOM_EXPORT void oa_close_socket(openaxiom_socket); OPENAXIOM_EXPORT int oa_filedesc_write(int, const openaxiom_byte*, int); OPENAXIOM_EXPORT int oa_filedesc_read(int, openaxiom_byte*, int); @@ -104,7 +114,6 @@ OPENAXIOM_EXPORT int open_server(const char*); OPENAXIOM_EXPORT int accept_connection(openaxiom_sio*); OPENAXIOM_EXPORT int sselect(int, fd_set*, fd_set*, fd_set*, void*); OPENAXIOM_EXPORT void close_socket(openaxiom_socket, const char*); -OPENAXIOM_EXPORT void axiom_close_socket(openaxiom_socket); OPENAXIOM_EXPORT int get_int(openaxiom_sio*); OPENAXIOM_EXPORT double get_float(openaxiom_sio*); diff --git a/src/interp/sys-os.boot b/src/interp/sys-os.boot index 85e9523d..9f22adf0 100644 --- a/src/interp/sys-os.boot +++ b/src/interp/sys-os.boot @@ -72,15 +72,29 @@ import writeToFileHandle for import closeFileHandle for oa__filedesc__close: int -> int -- -1: failure; otherwise 0. +import getEnv for + oa__getenv: string -> string + --% Local IPC socket support import openLocalClientStreamSocket for oa__open__local__client__stream__socket: string -> int -- -1: failure ---% OpenAxiom subsystem socket support +--% INET socket stream support -import getEnv for - oa__getenv: string -> string +import openIP4ClientStreamSocket for + oa__open__ip4__client__stream__socket: (string,int) -> int + +import readFromStreamSocket for + oa__socket__read: (int,string,int) -> int + +import writeToStreamSocket for + oa__socket__write: (int,string,int) -> int + +import closeSocket for + oa__close__socket: int -> int + +--% OpenAxiom subsystem socket support ++ socket interface import openServer for diff --git a/src/lib/sockio-c.c b/src/lib/sockio-c.c index 9fcd8cca..2f93b254 100644 --- a/src/lib/sockio-c.c +++ b/src/lib/sockio-c.c @@ -48,6 +48,7 @@ #include <string.h> #include <signal.h> +#include "cfuns.h" #include "sockio.h" #include "com.h" #include "bsdsignal.h" @@ -109,11 +110,24 @@ openaxiom_sleep(int n) #endif } +/* Non zero if the host system module support for socket is activated. + This is needed only for MS platforms. */ +static int openaxiom_socket_module_loaded = 0; + /* Windows require some handshaking with the WinSock DLL before we can even think about talking about sockets. */ static void -openaxiom_load_socket_module() +openaxiom_unload_socket_module(void) +{ +#ifdef __WIN32__ + WSACleanup(); + openaxiom_socket_moduler_loaded = 0; +#endif +} + +static void +openaxiom_load_socket_module(void) { #ifdef __WIN32__ WSADATA wsaData; @@ -123,22 +137,25 @@ openaxiom_load_socket_module() perror("could not find suitable WinSock DLL."); exit(WSAGetLastError()); } + + atexit(&openaxiom_unload_socket_module); if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) { perror("could not find suitable WinSock DLL."); - WSACleanup(); exit(WSAGetLastError()); } #endif + openaxiom_socket_module_loaded = 1; } /* Get a socket identifier to a local server. We take whatever protocol is the default for the address family in the SOCK_STREAM type. */ static inline openaxiom_socket -openaxiom_communication_link(int family) +openaxiom_socket_stream_link(int family) { - openaxiom_load_socket_module(); + if (!openaxiom_socket_module_loaded) + openaxiom_load_socket_module(); return socket(family, SOCK_STREAM, 0); } @@ -146,15 +163,21 @@ openaxiom_communication_link(int family) /* Returns 1 if SOCKET is an invalid socket. Otherwise return 0. */ static inline int -is_invalid_socket(const openaxiom_sio* s) +openaxiom_socket_is_invalid(openaxiom_socket sock) { #ifdef __WIN32__ - return s->socket == INVALID_SOCKET; + return sock == INVALID_SOCKET; #else - return s->socket < 0; + return sock < 0; #endif } +static inline int +is_invalid_socket(const openaxiom_sio* s) +{ + return openaxiom_socket_is_invalid(s->socket); +} + /* Returns 1 if SOCKET is a valid socket. Otherwise return 0. */ static inline int @@ -174,36 +197,17 @@ is_valid_socket(const openaxiom_sio* s) any other file descriptor function. Furthermore, Windows requires cleanup. */ -void -openaxiom_close_socket(openaxiom_socket s) +OPENAXIOM_EXPORT void +oa_close_socket(openaxiom_socket s) { #ifdef __WIN32__ shutdown(s, SD_BOTH); closesocket(s); - WSACleanup(); #else close(s); #endif } -/* It is idiomatic in the Unix/POSIX world to use the standard - read() and write() functions on sockets. However, in the Windows - world, that is invalid. Consequently, portability suggests that - we restrict ourselves to the POSIX standard functions recv() and - send(). */ - -static inline int -openaxiom_write(openaxiom_sio* s, const openaxiom_byte* buf, size_t n) -{ - return send(s->socket, buf, n, 0); -} - -static inline int -openaxiom_read(openaxiom_sio* s, openaxiom_byte* buf, size_t n) -{ - return recv(s->socket, buf, n, 0); -} - /* Local IPC Socket: On POSIX systems, this is just the Local IPC Socket. On Windows, we Windows Named Pipes. @@ -304,6 +308,50 @@ oa_filedesc_close(int desc) #endif } +/* IP sockets. +*/ + +OPENAXIOM_EXPORT openaxiom_socket +oa_open_ip4_client_stream_socket(const char* addr, openaxiom_port port) +{ + struct sockaddr_in server; + openaxiom_socket sock = openaxiom_socket_stream_link(AF_INET); + if (openaxiom_socket_is_invalid(sock)) + return OPENAXIOM_INVALID_SOCKET; + memset(&server, 0, sizeof server); + server.sin_family = AF_INET; + if (inet_pton(AF_INET, addr, &server.sin_addr) <= 0) { + fflush(stderr); + oa_close_socket(sock); + return OPENAXIOM_INVALID_SOCKET; + } + server.sin_port = htons(port); + if (connect(sock, (struct sockaddr*)&server, sizeof server) < 0) { + fflush(stderr); + oa_close_socket(sock); + return OPENAXIOM_INVALID_SOCKET; + } + return sock; +} + +/* It is idiomatic in the Unix/POSIX world to use the standard + read() and write() functions on sockets. However, in the Windows + world, that is invalid. Consequently, portability suggests that + we restrict ourselves to the POSIX standard functions recv() and + send(). */ + +OPENAXIOM_EXPORT int +oa_socket_read(openaxiom_socket sock, openaxiom_byte* buf, int size) +{ + return recv(sock, buf, size, 0); +} + +OPENAXIOM_EXPORT int +oa_socket_write(openaxiom_socket sock, const openaxiom_byte* buf, int size) +{ + return send(sock, buf, size, 0); +} + /* Return 1 is the last call was cancelled. */ @@ -379,12 +427,12 @@ sread(openaxiom_sio* sock, openaxiom_byte* buf, int buf_size, const char *msg) char err_msg[256]; errno = 0; do { - ret_val = openaxiom_read(sock, buf, buf_size); + ret_val = oa_socket_read(sock->socket, buf, buf_size); } while (ret_val == -1 && openaxiom_syscall_was_cancelled()); if (ret_val == 0) { FD_CLR(sock->socket, &socket_mask); purpose_table[sock->purpose] = NULL; - openaxiom_close_socket(sock->socket); + oa_close_socket(sock->socket); return wait_for_client_read(sock, buf, buf_size, msg); } if (ret_val == -1) { @@ -405,13 +453,13 @@ swrite(openaxiom_sio* sock, const openaxiom_byte* buf, int buf_size, char err_msg[256]; errno = 0; socket_closed = 0; - ret_val = openaxiom_write(sock, buf, buf_size); + ret_val = oa_socket_write(sock->socket, buf, buf_size); if (ret_val == -1) { if (socket_closed) { FD_CLR(sock->socket, &socket_mask); purpose_table[sock->purpose] = NULL; /* printf(" closing socket %d\n", sock->socket); */ - openaxiom_close_socket(sock->socket); + oa_close_socket(sock->socket); return wait_for_client_write(sock, buf, buf_size, msg); } else { if (msg) { @@ -820,7 +868,7 @@ send_signal(openaxiom_sio *sock, int sig) FD_CLR(sock->socket, &socket_mask); purpose_table[sock->purpose] = NULL; /* printf(" closing socket %d\n", sock->socket); */ - openaxiom_close_socket(sock->socket); + oa_close_socket(sock->socket); return wait_for_client_kill(sock, sig); } return ret_val; @@ -866,7 +914,7 @@ connect_to_local_server_new(char *server_name, int purpose, int time_out) return NULL; } - sock->socket = openaxiom_communication_link(OPENAXIOM_AF_LOCAL); + sock->socket = openaxiom_socket_stream_link(OPENAXIOM_AF_LOCAL); if (is_invalid_socket(sock)) { perror("opening client socket"); free(sock); @@ -920,7 +968,7 @@ connect_to_local_server(char *server_name, int purpose, int time_out) sock->purpose = purpose; /* create the socket */ - sock->socket = openaxiom_communication_link(OPENAXIOM_AF_LOCAL); + sock->socket = openaxiom_socket_stream_link(OPENAXIOM_AF_LOCAL); if (is_invalid_socket(sock)) { perror("opening client socket"); free(sock); @@ -1013,10 +1061,8 @@ make_server_number(void) OPENAXIOM_EXPORT void close_socket(openaxiom_socket socket_num, const char *name) { - openaxiom_close_socket(socket_num); -#ifndef RTplatform - unlink(name); -#endif + oa_close_socket(socket_num); + oa_unlink(name); } OPENAXIOM_EXPORT int @@ -1053,7 +1099,7 @@ open_server(const char* server_name) return -2; /* create the socket internet socket */ server[0].socket = 0; -/* server[0].socket = openaxiom_communication_link(AF_INET); +/* server[0].socket = openaxiom_socket_stream_link(AF_INET); if (is_invalid_socket(&server[0])) { server[0].socket = 0; } else { @@ -1078,7 +1124,7 @@ open_server(const char* server_name) listen(server[0].socket,5); } */ /* Next create the local domain socket */ - server[1].socket = openaxiom_communication_link(OPENAXIOM_AF_LOCAL); + server[1].socket = openaxiom_socket_stream_link(OPENAXIOM_AF_LOCAL); if (is_invalid_socket(&server[1])) { perror("opening local server socket"); server[1].socket = 0; |