aboutsummaryrefslogtreecommitdiff
path: root/src/lib/sockio-c.c
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2008-09-06 20:47:14 +0000
committerdos-reis <gdr@axiomatics.org>2008-09-06 20:47:14 +0000
commit95440288d1c686ceda247fcf606576deb8367d0a (patch)
tree48b3b2b3c64cd2400db5826bf4f5617ec9572eee /src/lib/sockio-c.c
parentc8bfb04b762ad0e33272fd082457aa524d542fca (diff)
downloadopen-axiom-95440288d1c686ceda247fcf606576deb8367d0a.tar.gz
* 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.
Diffstat (limited to 'src/lib/sockio-c.c')
-rw-r--r--src/lib/sockio-c.c128
1 files changed, 87 insertions, 41 deletions
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;