OSSP CVS Repository

ossp - Difference in ossp-pkg/sa/sa.c versions 1.10 and 1.11
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/sa/sa.c 1.10 -> 1.11

--- sa.c 2001/10/07 14:16:47     1.10
+++ sa.c 2001/10/07 15:21:17     1.11
@@ -59,6 +59,105 @@
     socklen_t        slBuf;       /* the length of "struct sockaddr_xx" */
 };
 
+/* system call structure declaration macros */
+#define SA_SC_DECLARE_0(rc_t, fn) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(void); \
+                rc_t (*ctx)(void *); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+#define SA_SC_DECLARE_1(rc_t, fn, a1_t) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(a1_t); \
+                rc_t (*ctx)(void *, a1_t); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+#define SA_SC_DECLARE_2(rc_t, fn, a1_t, a2_t) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(a1_t, a2_t); \
+                rc_t (*ctx)(void *, a1_t, a2_t); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+#define SA_SC_DECLARE_3(rc_t, fn, a1_t, a2_t, a3_t) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(a1_t, a2_t, a3_t); \
+                rc_t (*ctx)(void *, a1_t, a2_t, a3_t); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+#define SA_SC_DECLARE_4(rc_t, fn, a1_t, a2_t, a3_t, a4_t) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(a1_t, a2_t, a3_t, a4_t); \
+                rc_t (*ctx)(void *, a1_t, a2_t, a3_t, a4_t); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+#define SA_SC_DECLARE_5(rc_t, fn, a1_t, a2_t, a3_t, a4_t, a5_t) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(a1_t, a2_t, a3_t, a4_t, a5_t); \
+                rc_t (*ctx)(void *, a1_t, a2_t, a3_t, a4_t, a5_t); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+#define SA_SC_DECLARE_6(rc_t, fn, a1_t, a2_t, a3_t, a4_t, a5_t, a6_t) \
+    struct { \
+        union { void (*any)(); \
+                rc_t (*std)(a1_t, a2_t, a3_t, a4_t, a5_t, a6_t); \
+                rc_t (*ctx)(void *, a1_t, a2_t, a3_t, a4_t, a5_t, a6_t); } fptr; \
+        void *fctx; \
+    } sc_##fn;
+
+/* system call structure assignment macro */
+#define SA_SC_ASSIGN(sa, fn, ptr, ctx) \
+    do { \
+        (sa)->scSysCall.sc_##fn.fptr.any = (void (*)())(ptr); \
+        (sa)->scSysCall.sc_##fn.fctx = (ctx); \
+    } while(0)
+
+/* system call function call macros */
+#define SA_SC_CALL_0(sa, fn) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)() )
+#define SA_SC_CALL_1(sa, fn, a1) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx, a1) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)(a1) )
+#define SA_SC_CALL_2(sa, fn, a1, a2) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx, a1, a2) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)(a1, a2) )
+#define SA_SC_CALL_3(sa, fn, a1, a2, a3) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx, a1, a2, a3) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)(a1, a2, a3) )
+#define SA_SC_CALL_4(sa, fn, a1, a2, a3, a4) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx, a1, a2, a3, a4) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)(a1, a2, a3, a4) )
+#define SA_SC_CALL_5(sa, fn, a1, a2, a3, a4, a5) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx, a1, a2, a3, a4, a5) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)(a1, a2, a3, a4, a5) )
+#define SA_SC_CALL_6(sa, fn, a1, a2, a3, a4, a5, a6) \
+    (   (sa)->scSysCall.sc_##fn.fctx != NULL \
+     ? ((sa)->scSysCall.sc_##fn.fptr.ctx)((sa)->scSysCall.sc_##fn.fctx, a1, a2, a3, a4, a5, a6) \
+     : ((sa)->scSysCall.sc_##fn.fptr.std)(a1, a2, a3, a4, a5, a6) )
+
+/* system call table */
+typedef struct {
+    SA_SC_DECLARE_3(int, connect, int, const struct sockaddr *, socklen_t)
+    SA_SC_DECLARE_3(int, accept, int, struct sockaddr *, socklen_t *)
+    SA_SC_DECLARE_5(int, select, int, fd_set *, fd_set *, fd_set *, struct timeval *)
+    SA_SC_DECLARE_3(ssize_t, read, int, void *, size_t)
+    SA_SC_DECLARE_3(ssize_t, write, int, const void *, size_t)
+    SA_SC_DECLARE_6(ssize_t, recvfrom, int, void *, size_t, int, struct sockaddr *, socklen_t *)
+    SA_SC_DECLARE_6(ssize_t, sendto, int, const void *, size_t, int, const struct sockaddr *, socklen_t)
+} sa_syscall_tab_t;
+ 
 /* socket abstraction object */
 struct sa_st {
     sa_type_t        eType;       /* socket type (stream or datagram) */
@@ -73,6 +172,7 @@
     char             szError[256];
     char             szErrorInfo[128];
     sa_rc_t          rvErrorInfo;
+    sa_syscall_tab_t scSysCall;
 };
 
 /* boolean values */
@@ -681,21 +781,34 @@
     /* allocate and initialize socket object */
     if ((sa = (sa_t *)malloc(sizeof(sa_t))) == NULL)
         return SA_ERR_MEM;
-    sa->eType             = SA_TYPE_STREAM;
-    sa->fdSocket          = -1;
+
+    /* init object attributes */
+    sa->eType          = SA_TYPE_STREAM;
+    sa->fdSocket       = -1;
+    sa->nReadLen       = 0;
+    sa->nReadSize      = 0;
+    sa->cpReadBuf      = NULL;
+    sa->nWriteLen      = 0;
+    sa->nWriteSize     = 0;
+    sa->cpWriteBuf     = NULL;
+    sa->szError[0]     = '\0';
+    sa->szErrorInfo[0] = '\0';
+    sa->rvErrorInfo    = SA_OK;
+
+    /* init timeval object attributes */
     for (i = 0; i < (sizeof(sa->tvTimeout)/sizeof(sa->tvTimeout[0])); i++) {
         sa->tvTimeout[i].tv_sec  = 0;
         sa->tvTimeout[i].tv_usec = 0;
     }
-    sa->nReadLen          = 0;
-    sa->nReadSize         = 0;
-    sa->cpReadBuf         = NULL;
-    sa->nWriteLen         = 0;
-    sa->nWriteSize        = 0;
-    sa->cpWriteBuf        = NULL;
-    sa->szError[0]        = '\0';
-    sa->szErrorInfo[0]    = '\0';
-    sa->rvErrorInfo       = SA_OK;
+
+    /* init syscall object attributes */
+    SA_SC_ASSIGN(sa, connect,  connect,  NULL);
+    SA_SC_ASSIGN(sa, accept,   accept,   NULL);
+    SA_SC_ASSIGN(sa, select,   select,   NULL);
+    SA_SC_ASSIGN(sa, read,     read,     NULL);
+    SA_SC_ASSIGN(sa, write,    write,    NULL);
+    SA_SC_ASSIGN(sa, recvfrom, recvfrom, NULL);
+    SA_SC_ASSIGN(sa, sendto,   sendto,   NULL);
 
     /* pass object to caller */
     *sap = sa;
@@ -817,6 +930,30 @@
     return SA_OK;
 }
 
+/* override system call */
+sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx)
+{
+    if (sa == NULL || fptr == NULL)
+        return SA_ERR_ARG;
+    if (id == SA_SYSCALL_CONNECT)
+        SA_SC_ASSIGN(sa, connect, fptr, fctx); 
+    else if (id == SA_SYSCALL_ACCEPT)
+        SA_SC_ASSIGN(sa, accept, fptr, fctx); 
+    else if (id == SA_SYSCALL_SELECT)
+        SA_SC_ASSIGN(sa, select, fptr, fctx); 
+    else if (id == SA_SYSCALL_READ)
+        SA_SC_ASSIGN(sa, read, fptr, fctx); 
+    else if (id == SA_SYSCALL_WRITE)
+        SA_SC_ASSIGN(sa, write, fptr, fctx); 
+    else if (id == SA_SYSCALL_RECVFROM)
+        SA_SC_ASSIGN(sa, recvfrom, fptr, fctx); 
+    else if (id == SA_SYSCALL_SENDTO)
+        SA_SC_ASSIGN(sa, sendto, fptr, fctx); 
+    else
+        return SA_ERR_ARG;
+    return SA_OK;
+}
+
 /* bind socket to a local address */
 sa_rc_t sa_bind(sa_t *sa, sa_addr_t *laddr)
 {
@@ -869,7 +1006,7 @@
     rv = SA_OK;
     if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) {
         /* standard/non-timeout-aware connect operation */
-        if (connect(sa->fdSocket, raddr->saBuf, raddr->slBuf) < 0)
+        if (SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf) < 0)
             rv = SA_ERR_SYS;
     }
     else {
@@ -881,7 +1018,7 @@
         fcntl(sa->fdSocket, F_SETFL, flags|O_NONBLOCK);
 
         /* perform the connect operation */
-        if ((n = connect(sa->fdSocket, raddr->saBuf, raddr->slBuf)) < 0) {
+        if ((n = SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf)) < 0) {
             if (errno != EINPROGRESS) {
                 error = errno;
                 goto done;
@@ -898,8 +1035,8 @@
         FD_SET(sa->fdSocket, &rset);
         FD_SET(sa->fdSocket, &wset);
         do {
-            n = select(sa->fdSocket+1, &rset, &wset, NULL,
-                       &sa->tvTimeout[SA_TIMEOUT_CONNECT]);
+            n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &rset, &wset, NULL,
+                             &sa->tvTimeout[SA_TIMEOUT_CONNECT]);
         } while (n == -1 && errno == EINTR);
 
         /* decide on return semantic */
@@ -985,8 +1122,8 @@
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
-            n = select(sa->fdSocket+1, &fds, NULL, NULL,
-                       &sa->tvTimeout[SA_TIMEOUT_ACCEPT]);
+            n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &fds, NULL, NULL,
+                             &sa->tvTimeout[SA_TIMEOUT_ACCEPT]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;
@@ -996,7 +1133,7 @@
 
     /* perform accept operation on underlying socket */
     sa_len = sizeof(sa_buf);
-    if ((s = accept(sa->fdSocket, (struct sockaddr *)&sa_buf, &sa_len)) == -1)
+    if ((s = SA_SC_CALL_3(sa, accept, sa->fdSocket, (struct sockaddr *)&sa_buf, &sa_len)) == -1)
         return SA_ERR_SYS;
 
     /* create result address object */
@@ -1122,8 +1259,8 @@
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
-            rv = select(sa->fdSocket+1, &fds, NULL, NULL, 
-                        &sa->tvTimeout[SA_TIMEOUT_READ]);
+            rv = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &fds, NULL, NULL, 
+                              &sa->tvTimeout[SA_TIMEOUT_READ]);
         } while (rv == -1 && errno == EINTR);
         if (rv == 0) {
             errno = ETIMEDOUT;
@@ -1133,7 +1270,7 @@
 
     /* perform read operation on underlying socket */
     do {
-        rv = read(sa->fdSocket, cpBuf, nBufLen);
+        rv = SA_SC_CALL_3(sa, read, sa->fdSocket, cpBuf, nBufLen);
     } while (rv == -1 && errno == EINTR);
 
     return rv;
@@ -1281,8 +1418,8 @@
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
-            rv = select(sa->fdSocket+1, NULL, &fds, NULL, 
-                        &sa->tvTimeout[SA_TIMEOUT_WRITE]);
+            rv = SA_SC_CALL_5(sa, select, sa->fdSocket+1, NULL, &fds, NULL, 
+                              &sa->tvTimeout[SA_TIMEOUT_WRITE]);
         } while (rv == -1 && errno == EINTR);
         if (rv == 0) {
             errno = ETIMEDOUT;
@@ -1292,7 +1429,7 @@
 
     /* perform write operation on underlying socket */
     do {
-        rv = write(sa->fdSocket, cpBuf, nBufLen);
+        rv = SA_SC_CALL_3(sa, write, sa->fdSocket, cpBuf, nBufLen);
     } while (rv == -1 && errno == EINTR);
 
     return rv;
@@ -1492,8 +1629,8 @@
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
-            n = select(sa->fdSocket+1, &fds, NULL, NULL, 
-                       &sa->tvTimeout[SA_TIMEOUT_RECV]);
+            n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &fds, NULL, NULL, 
+                             &sa->tvTimeout[SA_TIMEOUT_RECV]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;
@@ -1503,8 +1640,8 @@
 
     /* perform receive operation on underlying socket */
     sa_len = sizeof(sa_buf);
-    if ((n = recvfrom(sa->fdSocket, buf, buflen, 0, 
-                      (struct sockaddr *)&sa_buf, &sa_len)) == -1)
+    if ((n = SA_SC_CALL_6(sa, recvfrom, sa->fdSocket, buf, buflen, 0, 
+                          (struct sockaddr *)&sa_buf, &sa_len)) == -1)
         return SA_ERR_SYS;
 
     /* create result address object */
@@ -1548,8 +1685,8 @@
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
-            n = select(sa->fdSocket+1, NULL, &fds, NULL, 
-                       &sa->tvTimeout[SA_TIMEOUT_SEND]);
+            n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, NULL, &fds, NULL, 
+                             &sa->tvTimeout[SA_TIMEOUT_SEND]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;
@@ -1558,7 +1695,7 @@
     }
 
     /* perform send operation on underlying socket */
-    if ((n = sendto(sa->fdSocket, buf, buflen, 0, raddr->saBuf, raddr->slBuf)) == -1)
+    if ((n = SA_SC_CALL_6(sa, sendto, sa->fdSocket, buf, buflen, 0, raddr->saBuf, raddr->slBuf)) == -1)
         return SA_ERR_SYS;
 
     /* pass actual number of sent bytes to caller */

CVSTrac 2.0.1