Author: mturk
Date: Mon Jul 18 05:39:30 2011
New Revision: 1147750

URL: http://svn.apache.org/viewvc?rev=1147750&view=rev
Log:
Implement basic Win32 accept/connect natives

Modified:
    commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c
    commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c?rev=1147750&r1=1147749&r2=1147750&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c Mon Jul 18 
05:39:30 2011
@@ -273,7 +273,7 @@ ACR_NET_EXPORT(jint, SocketServerEndpoin
                                                   jbyteArray ba,
                                                   jint backlog)
 {
-    static char any[16] = { 0 }; /* big enough for IPv4 or IPv6 */    
+    static char any[16] = { 0 }; /* big enough for IPv4 or IPv6 */
     int rc = 0;
     int on = 1;
     acr_sockaddr_t *aa = SOCKADDR_CAST(ba);
@@ -336,6 +336,10 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
 #endif
     } while (sd == -1 && errno == EINTR);
     if (AcrSdRelease(fd) == 0 && sd != -1) {
+        /* SocketServerEndpoint was closed although
+         * the socket was accepted.
+         */
+        r_close(sd);
         sd = -1;
         errno = ENOTSOCK;
     }
@@ -431,7 +435,7 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
 #if defined(DEBUG) || defined(_DEBUG)
     if (aa.addrlen != (int)aalen) {
         ACR_DEBUG_TRACE("Address length missmatch. Expected %d, found %d\n", 
aa.addrlen, (int)aalen);
-    }    
+    }
 #endif
     aa.salen   = aa.iplen;
     aa.family  = aa.sa.sin.sin_family;
@@ -454,8 +458,10 @@ ACR_NET_EXPORT(jint, SocketEndpoint, con
     if (timeout > 0 && !ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
         /* Turn the socket to non-blocking mode
          */
-        if ((rc = AcrNonblock(sd, 1)) != 0)
+        if ((rc = AcrNonblock(sd, 1)) != 0) {
+            SOCKADDR_RELEASE(cb, ca);
             goto finally;
+        }
     }
     do {
         /* Restartable connect */
@@ -471,11 +477,11 @@ ACR_NET_EXPORT(jint, SocketEndpoint, con
                 rc = AcrWaitIO(fd->s, timeout, POLLOUT);
 #if defined(SO_ERROR)
                 if (rc == 0) {
-                    int       err;
+                    int       err = 0;
                     socklen_t len = sizeof(err);
-                    if (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&err, 
&len) == -1);
+                    if (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&err, 
&len) == -1)
                         rc = errno;
-                    if (err != 0)
+                    else if (err != 0)
                         rc = err;
                 }
 #endif

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c?rev=1147750&r1=1147749&r2=1147750&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c Mon Jul 
18 05:39:30 2011
@@ -16,6 +16,7 @@
 
 #include "acr/jnitypes.h"
 #include "acr/error.h"
+#include "acr/debug.h"
 #include "acr/memory.h"
 #include "acr/netapi.h"
 #include "acr/unsafe.h"
@@ -247,3 +248,199 @@ ACR_NET_EXPORT(jlong, SocketDescriptor, 
     }
     return P2J(sp);
 }
+
+ACR_NET_EXPORT(jint, SocketServerEndpoint, bind0)(JNI_STDARGS, jlong fp,
+                                                  jbyteArray ba,
+                                                  jint backlog)
+{
+    static char any[16] = { 0 }; /* big enough for IPv4 or IPv6 */
+    int rc = 0;
+    int on = 1;
+    acr_sockaddr_t *aa = SOCKADDR_CAST(ba);
+    acr_sd_t *fd       = J2P(fp, acr_sd_t *);
+
+    if (bind(fd->s, (const struct sockaddr *)&aa->sa, aa->salen) == -1) {
+        /* bind failed.
+         */
+        rc = ACR_GET_NETOS_ERROR();
+        goto finally;
+    }
+    /* Check for ephemeral port and "any" address.
+     * The provided byte array is duplicate of the original
+     * so it can be modified.
+     */
+    if (aa->port == 0 || memcmp(&aa->sa.sin.sin_addr, any, aa->iplen) == 0) {
+        /* Get the real address for the bound socket.
+         */
+        if ((rc = AcrGetLocalAddr(fd, aa)) != 0)
+            goto finally;
+    }
+    if (listen(fd->s, backlog) == -1) {
+        rc = ACR_GET_NETOS_ERROR();
+        goto finally;
+    }
+    /* We need to set the SO_REUSEADDR after listen call.
+     */
+    if (setsockopt(fd->s, SOL_SOCKET, SO_REUSEADDR, (void *)&on, SSIZEOF(int)) 
!= 0)
+        rc = ACR_GET_NETOS_ERROR();
+finally:
+    SOCKADDR_RELEASE(ba, aa);
+    return rc;
+}
+
+ACR_NET_EXPORT(jlong, SocketServerEndpoint, accept0)(JNI_STDARGS, jlong fp,
+                                                     jbyteArray ra,
+                                                     jboolean block)
+{
+    SOCKET ad;
+    SOCKET sd;
+    int    rc;
+    acr_sockaddr_t  aa;
+    socklen_t       aalen;
+    acr_sd_t *fd  = J2P(fp, acr_sd_t *);
+    acr_sd_t *sp;
+
+    memset(&aa, 0, sizeof(aa));
+    aalen = SSIZEOF(acr_sockaddr_t);
+
+    ad = AcrSdRetain(fd);
+    sd = accept(ad,  (struct sockaddr *)&aa.sa, &aalen);
+    if (AcrSdRelease(fd) == 0 && sd != INVALID_SOCKET) {
+        /* SocketServerEndpoint was closed although
+         * the socket was accepted.
+         */
+        closesocket(sd);
+        sd = INVALID_SOCKET;
+        ACR_SET_NETOS_ERROR(ACR_ENOTSOCK);
+    }
+    if (sd == INVALID_SOCKET) {
+        ACR_THROW_NET_ERRNO();
+        return 0;
+    }
+    if (ACR_HASFLAG(fd, ACR_TCP_NODELAY)) {
+        int on = 1;
+        if (setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, 
SSIZEOF(int)) != 0) {
+            rc = ACR_GET_NETOS_ERROR();
+            closesocket(sd);
+            ACR_THROW_NET_ERROR(rc);
+            return 0;
+        }
+    }
+    if (block == JNI_FALSE) {
+        rc = 0;
+        if (!ACR_HASFLAG(fd, ACR_SO_NONBLOCK))
+            rc = AcrNonblock(sd, 1);
+        if (rc != 0) {
+            closesocket(sd);
+            ACR_THROW_NET_ERROR(rc);
+            return 0;
+        }
+    }
+    else if (ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
+        /* We have nonblocking acceptor and need
+         * blocking socket
+         */
+        rc = AcrNonblock(sd, 0);
+        if (rc != 0) {
+            closesocket(sd);
+            ACR_THROW_NET_ERROR(rc);
+            return 0;
+        }
+    }
+    if ((sp = ACR_TALLOC(acr_sd_t)) == 0) {
+        closesocket(sd);
+        return 0;
+    }
+    sp->type    = ACR_DT_SOCKET;
+    /* Inherit nodelay flag.
+     * It's always valid cause we either inherit or explicitly set that flag.
+     */
+    sp->flags   = fd->flags & ACR_TCP_NODELAY;
+    /* Inherit timeout */
+    sp->timeout = fd->timeout;
+    sp->refs    = 1;
+    sp->s       = sd;
+    if (block == JNI_FALSE) {
+        ACR_SETFLAG(sp, ACR_SO_NONBLOCK);
+        if (sp->timeout < 0)
+            sp->timeout = 0;
+    }
+    else {
+        ACR_CLRFLAG(sp, ACR_SO_NONBLOCK);
+        if (sp->timeout == 0)
+            sp->timeout = -1;
+    }
+    switch (aa.sa.sin.sin_family) {
+        case AF_INET:
+            aa.addrlen = 16;
+            aa.iplen   = ISIZEOF(struct in_addr);
+        break;
+        case AF_INET6:
+            aa.addrlen = 46;
+            aa.iplen   = ISIZEOF(struct in6_addr);
+        default:
+#if defined(DEBUG) || defined(_DEBUG)
+            ACR_DEBUG_TRACE("Unexpected address family %d\n", aa.family);
+#endif
+        break;
+    }
+#if defined(DEBUG) || defined(_DEBUG)
+    if (aa.addrlen != (int)aalen) {
+        ACR_DEBUG_TRACE("Address length missmatch. Expected %d, found %d\n", 
aa.addrlen, (int)aalen);
+    }
+#endif
+    aa.salen   = aa.iplen;
+    aa.family  = aa.sa.sin.sin_family;
+    aa.port    = ntohs(aa.sa.sin.sin_port);
+    (*env)->SetByteArrayRegion(env, ra, 0, ISIZEOF(acr_sockaddr_t), (jbyte 
*)&aa);
+    return P2J(sp);
+}
+
+ACR_NET_EXPORT(jint, SocketEndpoint, connect0)(JNI_STDARGS, jlong fp,
+                                              jbyteArray cb, jint timeout)
+{
+    int rc;
+    SOCKET sd;
+    acr_sockaddr_t *ca = SOCKADDR_CAST(cb);
+    acr_sd_t       *fd = J2P(fp, acr_sd_t *);
+
+    if (timeout == 0)
+        timeout = fd->timeout;
+    sd = AcrSdRetain(fd);
+    if (timeout > 0 && !ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
+        /* Turn the socket to non-blocking mode
+         * for the duration of the connect call.
+         */
+        if ((rc = AcrNonblock(sd, 1)) != 0) {
+            SOCKADDR_RELEASE(cb, ca);
+            goto finally;
+        }
+    }
+    rc = connect(sd, (const struct sockaddr *)&ca->sa.sin, ca->salen);
+    if (rc == SOCKET_ERROR)
+        rc = ACR_GET_NETOS_ERROR();
+    SOCKADDR_RELEASE(cb, ca);
+    if (rc != 0) {
+        if (timeout > 0) {
+            if (rc == WSAEINPROGRESS || rc == WSAEALREADY || rc == 
WSAEWOULDBLOCK) {
+                rc = AcrWaitIO(sd, timeout, FD_CONNECT);
+#if 0
+                /* We have already check the error in AcrWaitIo call. */
+                if (rc == 0) {
+                    int err = 0;
+                    int len = ISIZEOF(err);
+                    if (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&err, 
&len) == -1)
+                        rc = ACR_GET_NETOS_ERROR();
+                    else if (err != 0)
+                        rc = err;
+                }
+#endif
+            }
+            if (!ACR_HASFLAG(fd, ACR_SO_NONBLOCK))
+                 AcrNonblock(sd, 0);
+        }
+    }
+finally:
+    AcrSdRelease(fd);
+    return rc;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c?rev=1147750&r1=1147749&r2=1147750&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c Mon Jul 18 
05:39:30 2011
@@ -497,30 +497,44 @@ AcrDrainSocket(SOCKET sd)
 int
 AcrWaitIO(SOCKET sd, int timeout, int events)
 {
-    int            rc;
+    int             rc;
     struct timeval  tv;
     struct timeval *tp = 0;
-    fd_set rdset, wrset;
+    fd_set rdset, wrset, exset;
 
     FD_ZERO(&rdset);
     FD_ZERO(&wrset);
+    FD_ZERO(&exset);
 
     if (events & FD_READ) {
         FD_SET(sd, &rdset);
     }
-    if (events & FD_WRITE) {
+    if (events & (FD_WRITE | FD_CONNECT)) {
         FD_SET(sd, &wrset);
     }
+    if (events & FD_CONNECT) {
+        FD_SET(sd, &exset);
+    }
     if (timeout > 0) {
         tp = &tv;
         tp->tv_sec  = (long)(timeout / 1000);
         tp->tv_usec = (long)(timeout % 1000) * 1000;
     }
-    rc = select(1, &rdset, &wrset, 0, tp);
+    rc = select(1, &rdset, &wrset, &exset, tp);
     if (rc == SOCKET_ERROR)
         return ACR_GET_NETOS_ERROR();
     else if (rc == 0)
         return ACR_TIMEUP;
+    else {
+        if ((events & FD_CONNECT) != 0 && FD_ISSET(sd, &exset)) {
+            int err = 0;
+            int len = ISIZEOF(err);
+            if (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&err, &len) == -1)
+                rc = ACR_GET_NETOS_ERROR();
+            else if (err != 0)
+                rc = err;
+        }
+    }
     return 0;
 }
 

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c?rev=1147750&r1=1147749&r2=1147750&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c Mon Jul 18 
05:39:30 2011
@@ -189,7 +189,7 @@ inet_ntop6(const unsigned char *src, cha
     /*
      * Check for overflow, copy, and we're done.
      */
-    if (strlcpy(dst, tmp, size) >= size) {
+    if (size < (int)strlcpy(dst, tmp, size)) {
         ACR_SET_OS_ERROR(ACR_ENOSPC);
         return 0;
     }


Reply via email to