Author: mturk
Date: Fri Jul 15 06:50:02 2011
New Revision: 1146978
URL: http://svn.apache.org/viewvc?rev=1146978&view=rev
Log:
Make sure we don't use fd if release destroyed descriptor
Modified:
commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.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=1146978&r1=1146977&r2=1146978&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 Fri Jul 15
06:50:02 2011
@@ -25,13 +25,13 @@
#include <poll.h>
#include <sys/un.h>
-ACR_INLINE(int) _retain_sd(acr_sd_t *sd)
+ACR_INLINE(int) retain_sd(acr_sd_t *sd)
{
AcrAtomic32Inc(&sd->refs);
return sd->s;
}
-ACR_INLINE(void) _release_sd(acr_sd_t *sd)
+ACR_INLINE(void) release_sd(acr_sd_t *sd)
{
if (AcrAtomic32Dec(&sd->refs) == 0) {
/* Socket was closed while we were
@@ -40,7 +40,10 @@ ACR_INLINE(void) _release_sd(acr_sd_t *s
* we have to do it here.
*/
AcrFree(sd);
+ return 0;
}
+ else
+ return 1;
}
ACR_NET_EXPORT(jlong, SocketDescriptor, socket0)(JNI_STDARGS, jint saf,
@@ -159,12 +162,12 @@ ACR_NET_EXPORT(jint, SocketDescriptor, s
how = SHUT_WR;
else
how = SHUT_RDWR;
- sd = _retain_sd(fd);
+ sd = retain_sd(fd);
if (shutdown(fd->s, how) == -1)
rc = ACR_GET_NETOS_ERROR();
- _release_sd(fd);
if (how != 1)
fd->flags |= ACR_DT_HITEOF;
+ release_sd(fd);
return rc;
}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c?rev=1146978&r1=1146977&r2=1146978&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c Fri Jul
15 06:50:02 2011
@@ -34,13 +34,13 @@
#define SOCKADDR_RELEASE(BA, SA) \
AcrReleaseArrayCritical(env, (BA), (SA))
-ACR_INLINE(int) _retain_sd(acr_sd_t *sd)
+ACR_INLINE(int) retain_sd(acr_sd_t *sd)
{
AcrAtomic32Inc(&sd->refs);
return sd->s;
}
-ACR_INLINE(void) _release_sd(acr_sd_t *sd)
+ACR_INLINE(int) release_sd(acr_sd_t *sd)
{
if (AcrAtomic32Dec(&sd->refs) == 0) {
/* Socket was closed while we were
@@ -49,7 +49,10 @@ ACR_INLINE(void) _release_sd(acr_sd_t *s
* we have to do it here.
*/
AcrFree(sd);
+ return 0;
}
+ else
+ return 1;
}
ACR_NET_EXPORT(jint, LocalDescriptor, close0)(JNI_STDARGS, jlong fp)
@@ -85,12 +88,12 @@ ACR_NET_EXPORT(jint, LocalDescriptor, sh
how = SHUT_WR;
else
how = SHUT_RDWR;
- sd = _retain_sd(fd);
+ sd = retain_sd(fd);
if (shutdown(sd, how) == -1)
rc = ACR_GET_NETOS_ERROR();
if (how != 1)
fd->flags |= ACR_DT_HITEOF;
- _release_sd(fd);
+ release_sd(fd);
return rc;
}
@@ -284,7 +287,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
acr_sockaddr_t *ca = SOCKADDR_CAST(cb);
acr_sd_t *fd = J2P(fp, acr_sd_t *);
- sd = _retain_sd(fd);
+ sd = retain_sd(fd);
if (timeout == 0)
timeout = fd->timeout;
if (timeout > 0 && (fd->flags & ACR_DT_NONBLOCK) == 0) {
@@ -321,7 +324,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
}
}
finally:
- _release_sd(fd);
+ release_sd(fd);
return rc;
}
@@ -370,7 +373,7 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
flags |= SOCK_NONBLOCK;
# endif
#endif
- ad = _retain_sd(fd);
+ ad = retain_sd(fd);
memset(&aa, 0, sizeof(aa));
aalen = ISIZEOF(struct sockaddr_un);
do {
@@ -380,7 +383,10 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
sd = accept(ad, (struct sockaddr *)&aa.sa, &aalen);
#endif
} while (sd == -1 && errno == EINTR);
- _release_sd(fd);
+ if (release_sd(fd) == 0 && sd != -1) {
+ sd = -1;
+ errno = ENOTSOCK;
+ }
if (sd == -1) {
ACR_THROW_NET_ERRNO();
return 0;
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=1146978&r1=1146977&r2=1146978&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 Fri Jul
15 06:50:02 2011
@@ -21,21 +21,32 @@
#include "acr/unsafe.h"
#include "acr/port.h"
#include "arch_opts.h"
+#include "arch_sync.h"
-ACR_NET_EXPORT(jint, SocketDescriptor, close0)(JNI_STDARGS, jint fd)
+#define SOCKADDR_CAST(BA) \
+ (acr_sockaddr_t *)AcrGetArrayCritical(env, (BA))
+#define SOCKADDR_RELEASE(BA, SA) \
+ AcrReleaseArrayCritical(env, (BA), (SA))
+
+ACR_INLINE(SOCKET) retain_sd(acr_sd_t *sd)
{
- if (closesocket(I2SOCK(fd)) == -1)
- return ACR_GET_OS_ERROR();
- else
- return 0;
+ AcrAtomic32Inc(&sd->refs);
+ return sd->s;
}
-ACR_NET_EXPORT(jint, SocketDescriptor, sendz0)(JNI_STDARGS, jint fd)
+ACR_INLINE(int) release_sd(acr_sd_t *sd)
{
- if (send(I2SOCK(fd), (const char *)&fd, 0, 0) == -1)
- return ACR_GET_OS_ERROR();
- else
+ if (AcrAtomic32Dec(&sd->refs) == 0) {
+ /* Socket was closed while we were
+ * executing the native method.
+ * Since Socket didn't free the fd
+ * we have to do it here.
+ */
+ AcrFree(sd);
return 0;
+ }
+ else
+ return 1;
}
ACR_NET_EXPORT(jboolean, SocketAddress, haveipv6)(JNI_STDARGS)
@@ -50,3 +61,145 @@ ACR_NET_EXPORT(jboolean, SocketAddress,
else
return JNI_FALSE;
}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, close0)(JNI_STDARGS, jlong fp)
+{
+ int rc = 0;
+ SOCKET sd;
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ if (fd == 0)
+ return ACR_EBADF;
+ sd = fd->s;
+ if (fd->pob != 0) {
+ /* Close TransmitFile overlapped struct */
+ SAFE_CLOSE_HANDLE(fd->pob->hEvent);
+ AcrFree(fd->pob);
+ fd->pob = 0;
+ }
+ if (sd != INVALID_SOCKET) {
+ fd->s = INVALID_SOCKET;
+ if (closesocket(sd) == SOCKET_ERROR)
+ rc = ACR_GET_NETOS_ERROR();
+ fd->s = INVALID_SOCKET;
+ }
+ if (AcrAtomic32Dec(&fd->refs) == 0)
+ AcrFree(fd);
+ return rc;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, shutdown0)(JNI_STDARGS, jlong fp,
+ jint how)
+{
+ int rc = 0;
+ SOCKET sd;
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ if (fd == 0)
+ return ACR_EBADF;
+ if (how == 0)
+ how = SD_RECEIVE;
+ else if (how == 1)
+ how = SD_SEND;
+ else
+ how = SD_BOTH;
+ sd = retain_sd(fd);
+ if (shutdown(fd->s, how) == SOCKET_ERROR)
+ rc = ACR_GET_NETOS_ERROR();
+ if (how != 1)
+ fd->flags |= ACR_DT_HITEOF;
+ release_sd(fd);
+ return rc;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, sendz0)(JNI_STDARGS, jlong fp)
+{
+ char dummy = 0;
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ if (send(fd->s, &dummy, 0, 0) == SOCKET_ERROR)
+ return ACR_GET_NETOS_ERROR();
+ else
+ return 0;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, block0)(JNI_STDARGS, jlong fp, jboolean
on)
+{
+ int rc;
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ if (on == JNI_TRUE) {
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+ int zero = 0;
+ if ((rc = AcrNonblock(fd->s, 0)) != 0)
+ return rc;
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ fd->timeout = -1;
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+ }
+ else {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->s, 1)) != 0)
+ return rc;
+ if (fd->timeout < 0)
+ fd->timeout = 0;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
+ return 0;
+}
+
+ACR_NET_EXPORT(jboolean, SocketDescriptor, isBlocking0)(JNI_STDARGS, jlong fp)
+{
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, tmset0)(JNI_STDARGS, jlong fp, jint
timeout)
+{
+ int rc = 0;
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ if (timeout == 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->s, 1)) != 0)
+ return rc;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
+ else if (timeout > 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->s, 1)) != 0)
+ return rc;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ if (fd->timeout != timeout) {
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&timeout, (socklen_t)sizeof(timeout));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&timeout, (socklen_t)sizeof(timeout));
+ }
+ }
+ else if (timeout < 0) {
+ int zero = 0;
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+ if ((rc = AcrNonblock(fd->s, 0)) != 0)
+ return rc;
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ }
+ fd->timeout = timeout;
+ return 0;
+}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c?rev=1146978&r1=1146977&r2=1146978&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c Fri Jul
15 06:50:02 2011
@@ -41,13 +41,13 @@
#define SOCKADDR_RELEASE(BA, SA) \
AcrReleaseArrayCritical(env, (BA), (SA))
-ACR_INLINE(SOCKET) _retain_sd(acr_sd_t *sd)
+ACR_INLINE(SOCKET) retain_sd(acr_sd_t *sd)
{
AcrAtomic32Inc(&sd->refs);
return sd->s;
}
-ACR_INLINE(void) _release_sd(acr_sd_t *sd)
+ACR_INLINE(int) release_sd(acr_sd_t *sd)
{
if (AcrAtomic32Dec(&sd->refs) == 0) {
/* Socket was closed while we were
@@ -56,7 +56,10 @@ ACR_INLINE(void) _release_sd(acr_sd_t *s
* we have to do it here.
*/
AcrFree(sd);
+ return 0;
}
+ else
+ return 1;
}
ACR_NET_EXPORT(jint, LocalDescriptor, close0)(JNI_STDARGS, jlong fp)
@@ -76,7 +79,7 @@ ACR_NET_EXPORT(jint, LocalDescriptor, cl
}
if (sd != INVALID_SOCKET) {
fd->s = INVALID_SOCKET;
- if (fd->socketfname) {
+ if (fd->socketfname != 0) {
DeleteFileW(fd->socketfname);
AcrFree(fd->socketfname);
fd->socketfname = 0;
@@ -105,10 +108,12 @@ ACR_NET_EXPORT(jint, LocalDescriptor, sh
how = SD_SEND;
else
how = SD_BOTH;
- sd = _retain_sd(fd);
+ sd = retain_sd(fd);
if (shutdown(fd->s, how) == SOCKET_ERROR)
rc = ACR_GET_NETOS_ERROR();
- _release_sd(fd);
+ if (how != 1)
+ fd->flags |= ACR_DT_HITEOF;
+ release_sd(fd);
return rc;
}
@@ -295,7 +300,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
if (timeout == 0)
timeout = fd->timeout;
- sd = _retain_sd(fd);
+ sd = retain_sd(fd);
if (timeout > 0 && (fd->flags & ACR_DT_NONBLOCK) == 0) {
/* Turn the socket to non-blocking mode
* for the duration of the connect call.
@@ -324,7 +329,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
}
}
finally:
- _release_sd(fd);
+ release_sd(fd);
return rc;
}
@@ -418,9 +423,13 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
acr_sd_t *fd = J2P(fp, acr_sd_t *);
memset(&sa, 0, sizeof(sa));
- ad = _retain_sd(fd);
+ ad = retain_sd(fd);
sd = accept(ad, 0, 0);
- _release_sd(fd);
+ if (release_sd(fd) == 0 && sd != INVALID_SOCKET) {
+ /* XXX: Can this happen ? */
+ sd = INVALID_SOCKET;
+ WSASetLastError(WSAENOTSOCK);
+ }
if (sd == INVALID_SOCKET) {
ACR_THROW_NET_ERRNO();
return 0;