1 /*============================================================================
3 ==============================================================================
4 Implementation of TSocket class: A generic socket over which one can
5 transport an HTTP stream or manage HTTP connections
6 ============================================================================*/
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
15 #include "mallocvar.h"
16 #include "xmlrpc-c/util_int.h"
17 #include "xmlrpc-c/abyss.h"
18 #include "xmlrpc-c/util_int.h"
20 #include "socket_win.h"
22 #include "socket_unix.h"
28 #include "socket_win.h"
30 #include "socket_unix.h"
37 socketOsInit(abyss_bool * const succeededP) {
40 SocketWinInit(succeededP);
42 SocketUnixInit(succeededP);
60 abyss_bool SocketTraceIsActive;
66 socketOsInit(&retval);
68 SocketTraceIsActive = (getenv("ABYSS_TRACE_SOCKET") != NULL);
69 if (SocketTraceIsActive)
70 fprintf(stderr, "Abyss socket layer will trace socket traffic "
71 "due to ABYSS_TRACE_SOCKET environment variable\n");
86 /* SocketCreate() is not exported to the Abyss user. It is meant to
87 be used by an implementation-specific TSocket generator which is
88 exported to the Abyss user, e.g. SocketCreateUnix() in
91 The TSocket generator functions are the _only_ user-accessible
92 functions that are particular to an implementation.
95 static uint const socketSignature = 0x060609;
98 SocketCreate(const struct TSocketVtbl * const vtblP,
100 TSocket ** const socketPP) {
107 socketP->implP = implP;
108 socketP->vtbl = *vtblP;
109 socketP->signature = socketSignature;
117 SocketDestroy(TSocket * const socketP) {
119 assert(socketP->signature == socketSignature);
121 socketP->vtbl.destroy(socketP);
123 socketP->signature = 0; /* For debuggability */
131 SocketWrite(TSocket * const socketP,
132 const unsigned char * const buffer,
134 abyss_bool * const failedP) {
136 (*socketP->vtbl.write)(socketP, buffer, len, failedP );
142 SocketRead(TSocket * const socketP,
143 unsigned char * const buffer,
144 uint32_t const len) {
146 return (*socketP->vtbl.read)(socketP, buffer, len);
152 SocketConnect(TSocket * const socketP,
153 TIPAddr * const addrP,
154 uint16_t const portNumber) {
156 return (*socketP->vtbl.connect)(socketP, addrP, portNumber);
162 SocketBind(TSocket * const socketP,
163 TIPAddr * const addrP,
164 uint16_t const portNumber) {
166 return (*socketP->vtbl.bind)(socketP, addrP, portNumber);
172 SocketListen(TSocket * const socketP,
173 uint32_t const backlog) {
175 return (*socketP->vtbl.listen)(socketP, backlog);
181 SocketAccept(TSocket * const listenSocketP,
182 abyss_bool * const connectedP,
183 abyss_bool * const failedP,
184 TSocket ** const acceptedSocketPP,
185 TIPAddr * const ipAddrP) {
187 (*listenSocketP->vtbl.accept)(listenSocketP,
197 SocketWait(TSocket * const socketP,
200 uint32_t const timems) {
202 return (*socketP->vtbl.wait)(socketP, rd, wr, timems);
208 SocketAvailableReadBytes(TSocket * const socketP) {
210 return (*socketP->vtbl.availableReadBytes)(socketP);
216 SocketGetPeerName(TSocket * const socketP,
217 TIPAddr * const ipAddrP,
218 uint16_t * const portNumberP,
219 abyss_bool * const successP) {
221 (*socketP->vtbl.getPeerName)(socketP, ipAddrP, portNumberP, successP);
227 SocketError(TSocket * const socketP) {
229 return (*socketP->vtbl.error)(socketP);