OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_ut_sa.c versions 1.16 and 1.17
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/l2/l2_ut_sa.c 1.16 -> 1.17

--- l2_ut_sa.c   2001/10/26 10:59:47     1.16
+++ l2_ut_sa.c   2001/10/31 21:26:11     1.17
@@ -69,6 +69,11 @@
 #define ssize_t long
 #endif
 
+/* backward compatibility for O_NONBLOCK */
+#if !defined(O_NONBLOCK) && defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
 /* system call structure declaration macros */
 #define SA_SC_DECLARE_0(rc_t, fn) \
     struct { \
@@ -492,7 +497,7 @@
         if (cpHost[0] == '[') {
             /* IPv6 address (see RFC2732) */
 #ifndef AF_INET6
-            return SA_ERR_ARG;
+            return SA_ERR_IMP;
 #else
             bIPv6 = TRUE;
             cpHost++;
@@ -607,6 +612,15 @@
     if (saa == NULL || sabuf == NULL || salen == 0)
         return SA_ERR_ARG;
 
+    /* make sure we import only supported addresses */
+    if (!(   sabuf->sa_family == AF_LOCAL
+          || sabuf->sa_family == AF_INET
+#ifdef AF_INET6
+          || sabuf->sa_family == AF_INET6
+#endif
+         ))
+        return SA_ERR_USE;
+
     /* create result address structure */
     if (saa->saBuf != NULL)
         free(saa->saBuf);
@@ -1054,6 +1068,61 @@
     return SA_OK;
 }
 
+/* configure socket option */
+sa_rc_t sa_option(sa_t *sa, sa_option_t id, ...)
+{
+    sa_rc_t rv;
+    va_list ap;
+
+    /* argument sanity check(s) */
+    if (sa == NULL)
+        return SA_ERR_ARG;
+
+    /* process option */
+    rv = SA_OK;
+    va_start(ap, id);
+    switch (id) {
+        case SA_OPTION_NAGLE: {
+            /* enable/disable Nagle's Algorithm (see RFC898) */
+#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
+            int mode = ((int)va_arg(ap, int) ? 1 : 0);
+            if (sa->fdSocket == -1) {
+                rv = SA_ERR_USE;
+                break;
+            }
+            if (setsockopt(sa->fdSocket, IPPROTO_TCP, TCP_NODELAY, 
+                           (void *)&mode, sizeof(mode)) < 0)
+                rv = SA_ERR_SYS;
+#else
+            rv = SA_ERR_IMP;
+#endif
+            break;
+        }
+        case SA_OPTION_NONBLOCK: {
+            /* enable/disable non-blocking I/O mode */
+            int flags;
+            int mode = (int)va_arg(ap, int);
+            if ((flags = fcntl(sa->fdSocket, F_GETFL, 0)) < 0) {
+                rv = SA_ERR_SYS;
+                break;
+            }
+            if (mode == 0)
+                flags &= ~(O_NONBLOCK);
+            else
+                flags |= O_NONBLOCK;
+            if (fcntl(sa->fdSocket, F_SETFL, flags) < 0)
+                rv = SA_ERR_SYS;
+            break;
+        }
+        default: {
+            rv = SA_ERR_ARG;
+        }
+    }
+    va_end(ap);
+
+    return rv;
+}
+
 /* override system call */
 sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx)
 {
@@ -1451,14 +1520,12 @@
     if (sa->fdSocket == -1)
         return SA_ERR_USE;
 
-    /* trigger a write buffer flush */
-    if (sa->nWriteLen > 0)
-        sa_flush(sa);
-
     /* perform read operation */
     rv = SA_OK;
     if (sa->nReadSize == 0) {
         /* user-space unbuffered I/O */
+        if (sa->nWriteLen > 0)
+            sa_flush(sa);
         res = sa_read_raw(sa, cpBuf, nBufReq);
         if (res == 0)
             rv = SA_ERR_EOF;
@@ -1487,6 +1554,8 @@
                     res     += sa->nReadLen;
                     sa->nReadLen = 0;
                 }
+                if (sa->nWriteLen > 0)
+                    sa_flush(sa);
                 if (nBufReq >= sa->nReadSize) {
                     /* buffer is too small at all, so read directly */
                     n = sa_read_raw(sa, cpBuf, nBufReq);
@@ -1916,6 +1985,7 @@
     else if (rv == SA_ERR_EOF) sz = "End Of Communication";
     else if (rv == SA_ERR_TMT) sz = "Communication Timeout";
     else if (rv == SA_ERR_SYS) sz = "Operating System Error";
+    else if (rv == SA_ERR_IMP) sz = "Implementation Not Available";
     else if (rv == SA_ERR_INT) sz = "Internal Error";
     else                       sz = "Invalid Result Code";
     return sz;

CVSTrac 2.0.1