aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog18
-rw-r--r--src/include/sockio.h13
-rw-r--r--src/interp/sys-os.boot20
-rw-r--r--src/lib/sockio-c.c128
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;