initial load of upstream version 1.06.32
[xmlrpc-c] / lib / abyss / src / socket.c
diff --git a/lib/abyss/src/socket.c b/lib/abyss/src/socket.c
new file mode 100644 (file)
index 0000000..7868542
--- /dev/null
@@ -0,0 +1,230 @@
+/*============================================================================
+  socket.c
+==============================================================================
+  Implementation of TSocket class: A generic socket over which one can
+  transport an HTTP stream or manage HTTP connections
+============================================================================*/
+
+#include <sys/types.h>
+#include <assert.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mallocvar.h"
+#include "xmlrpc-c/util_int.h"
+#include "xmlrpc-c/abyss.h"
+#include "xmlrpc-c/util_int.h"
+#ifdef WIN32
+  #include "socket_win.h"
+#else
+  #include "socket_unix.h"
+#endif
+#include "socket.h"
+
+
+#ifdef WIN32
+  #include "socket_win.h"
+#else
+  #include "socket_unix.h"
+#endif
+
+#include "socket.h"
+
+
+static void
+socketOsInit(abyss_bool * const succeededP) {
+
+#ifdef WIN32
+    SocketWinInit(succeededP);
+#else
+    SocketUnixInit(succeededP);
+#endif
+}
+
+
+
+static void
+socketOsTerm(void) {
+
+#ifdef WIN32
+    SocketWinTerm();
+#else
+    SocketUnixTerm();
+#endif
+}
+    
+
+
+abyss_bool SocketTraceIsActive;
+
+abyss_bool
+SocketInit(void) {
+    abyss_bool retval;
+
+    socketOsInit(&retval);
+
+    SocketTraceIsActive = (getenv("ABYSS_TRACE_SOCKET") != NULL);
+    if (SocketTraceIsActive)
+        fprintf(stderr, "Abyss socket layer will trace socket traffic "
+                "due to ABYSS_TRACE_SOCKET environment variable\n");
+
+    return retval;
+}
+
+
+
+void
+SocketTerm(void) {
+
+    socketOsTerm();
+}
+
+
+
+/* SocketCreate() is not exported to the Abyss user.  It is meant to
+   be used by an implementation-specific TSocket generator which is
+   exported to the Abyss user, e.g. SocketCreateUnix() in
+   socket_unix.c
+
+   The TSocket generator functions are the _only_ user-accessible
+   functions that are particular to an implementation.
+*/
+
+static uint const socketSignature = 0x060609;
+
+void
+SocketCreate(const struct TSocketVtbl * const vtblP,
+             void *                     const implP,
+             TSocket **                 const socketPP) {
+
+    TSocket * socketP;
+
+    MALLOCVAR(socketP);
+
+    if (socketP) {
+        socketP->implP = implP;
+        socketP->vtbl = *vtblP;
+        socketP->signature = socketSignature;
+        *socketPP = socketP;
+    }
+}
+
+
+
+void
+SocketDestroy(TSocket * const socketP) {
+
+    assert(socketP->signature == socketSignature);
+
+    socketP->vtbl.destroy(socketP);
+
+    socketP->signature = 0;  /* For debuggability */
+
+    free(socketP);
+}
+
+
+
+void
+SocketWrite(TSocket *             const socketP,
+            const unsigned char * const buffer,
+            uint32_t              const len,
+            abyss_bool *          const failedP) {
+
+    (*socketP->vtbl.write)(socketP, buffer, len, failedP );
+}
+
+
+
+uint32_t
+SocketRead(TSocket *       const socketP, 
+           unsigned char * const buffer, 
+           uint32_t        const len) {
+    
+    return (*socketP->vtbl.read)(socketP, buffer, len);
+}
+
+
+
+abyss_bool
+SocketConnect(TSocket * const socketP,
+              TIPAddr * const addrP,
+              uint16_t  const portNumber) {
+
+    return (*socketP->vtbl.connect)(socketP, addrP, portNumber);
+}
+
+
+
+abyss_bool
+SocketBind(TSocket * const socketP,
+           TIPAddr * const addrP,
+           uint16_t  const portNumber) {
+
+    return (*socketP->vtbl.bind)(socketP, addrP, portNumber);
+}
+
+
+
+abyss_bool
+SocketListen(TSocket * const socketP,
+             uint32_t  const backlog) {
+
+    return (*socketP->vtbl.listen)(socketP, backlog);
+}
+
+
+
+void
+SocketAccept(TSocket *    const listenSocketP,
+             abyss_bool * const connectedP,
+             abyss_bool * const failedP,
+             TSocket **   const acceptedSocketPP,
+             TIPAddr *    const ipAddrP) {
+
+    (*listenSocketP->vtbl.accept)(listenSocketP,
+                                  connectedP,
+                                  failedP,
+                                  acceptedSocketPP,
+                                  ipAddrP);
+}
+
+
+
+uint32_t
+SocketWait(TSocket *  const socketP,
+           abyss_bool const rd,
+           abyss_bool const wr,
+           uint32_t   const timems) {
+
+    return (*socketP->vtbl.wait)(socketP, rd, wr, timems);
+}
+
+
+
+uint32_t
+SocketAvailableReadBytes(TSocket * const socketP) {
+
+    return (*socketP->vtbl.availableReadBytes)(socketP);
+}
+
+
+
+void
+SocketGetPeerName(TSocket *    const socketP,
+                  TIPAddr *    const ipAddrP,
+                  uint16_t *   const portNumberP,
+                  abyss_bool * const successP) {
+
+    (*socketP->vtbl.getPeerName)(socketP, ipAddrP, portNumberP, successP);
+}
+
+
+
+uint32_t
+SocketError(TSocket * const socketP) {
+
+    return (*socketP->vtbl.error)(socketP);
+}