1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
--- smalltalk-3.1.orig/configure.ac
+++ smalltalk-3.1/configure.ac
@@ -298,7 +298,7 @@
symlink mkdtemp)
AC_CHECK_FUNCS_ONCE(gethostname memcpy memmove sighold uname usleep lstat \
grantpt popen getrusage gettimeofday fork strchr utimes utime readlink \
- sigsetmask alarm select mprotect madvise waitpid \
+ sigsetmask alarm select mprotect madvise waitpid accept4 \
setsid spawnl nanosleep pread pwrite _NSGetExecutablePath)
GST_FUNC_LRINT
--- smalltalk-3.1.orig/lib-src/socketx.h
+++ smalltalk-3.1/lib-src/socketx.h
@@ -93,7 +93,7 @@
}
#define FD_TO_SOCKET(fd) ((SOCKET) _get_osfhandle ((fd)))
-#define SOCKET_TO_FD(fh) (_open_osfhandle ((HANDLE) (fh), O_RDWR | O_BINARY))
+#define SOCKET_TO_FD(fh) (_open_osfhandle ((long) (fh), O_RDWR | O_BINARY))
#undef close
#define close win_close
--- smalltalk-3.1.orig/packages/sockets/sockets.c
+++ smalltalk-3.1/packages/sockets/sockets.c
@@ -245,29 +245,55 @@
-static int
-mySocket (int domain, int type, int protocol)
+#if defined SOCK_CLOEXEC && !defined __MSVCRT__
+/* 0 = unknown, 1 = yes, -1 = no. */
+static mst_Boolean have_sock_cloexec;
+
+/* Return 0 if the operation failed and an error can be returned
+ by the caller. */
+static inline int
+check_have_sock_cloexec (int fh, int expected_errno)
{
- int fd;
-#if defined __MSVCRT__
- SOCKET fh = socket (domain, type, protocol);
- fd = SOCKET_TO_FD (fh);
-
- /* Do not do FD_CLOEXEC under MinGW. */
- SetHandleInformation (fh, HANDLE_FLAG_INHERIT, 0);
+ if (have_sock_cloexec == 0 && (fh >= 0 || errno == expected_errno))
+ have_sock_cloexec = (fh >= 0 ? 1 : -1);
+ return (have_sock_cloexec != 0);
+}
+#endif
-#elif defined SOCK_CLOEXEC
- fd = socket (domain, type | SOCK_CLOEXEC, protocol);
+static void
+socket_set_cloexec (SOCKET fh)
+{
+ if (fh == SOCKET_ERROR)
+ return;
+#if defined __MSVCRT__
+ /* Do not do FD_CLOEXEC under MinGW. */
+ SetHandleInformation ((HANDLE) fh, HANDLE_FLAG_INHERIT, 0);
#else
- fd = socket (domain, type, protocol);
-#ifdef FD_CLOEXEC
- if (fd != -1)
- fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ fcntl (fh, F_SETFD, fcntl (fh, F_GETFD, 0) | FD_CLOEXEC);
#endif
+}
+
+static int
+mySocket (int domain, int type, int protocol)
+{
+ SOCKET fh = SOCKET_ERROR;
+
+#if defined SOCK_CLOEXEC && !defined __MSVCRT__
+ if (have_sock_cloexec >= 0)
+ {
+ fh = socket (domain, type | SOCK_CLOEXEC, protocol);
+ if (!check_have_sock_cloexec (fh, EINVAL))
+ return -1;
+ }
#endif
+ if (fh == SOCKET_ERROR)
+ {
+ fh = socket (domain, type, protocol);
+ socket_set_cloexec (fh);
+ }
- return fd;
+ return fh == SOCKET_ERROR ? -1 : SOCKET_TO_FD (fh);
}
@@ -287,10 +313,12 @@
}
/* Same as connect, but forces the socket to be in non-blocking mode */
-static void
+static int
myConnect (int fd, struct sockaddr *sockaddr, int len)
{
SOCKET sock = FD_TO_SOCKET (fd);
+ int rc;
+
#ifdef __MSVCRT__
unsigned long iMode = 1;
ioctlsocket (sock, FIONBIO, &iMode);
@@ -303,16 +331,35 @@
#endif
fix_sockaddr (sockaddr);
- connect (sock, sockaddr, len);
- if (is_socket_error (EINPROGRESS) || is_socket_error (EWOULDBLOCK))
- errno = 0;
+ rc = connect (sock, sockaddr, len);
+ if (rc == 0 || is_socket_error (EINPROGRESS) || is_socket_error (EWOULDBLOCK))
+ {
+ errno = 0;
+ return 0;
+ }
+ else
+ return -1;
}
static int
myAccept (int fd, struct sockaddr *addr, int *addrlen)
{
- SOCKET r = accept (FD_TO_SOCKET (fd), addr, addrlen);
- return r == SOCKET_ERROR ? -1 : SOCKET_TO_FD (r);
+ SOCKET fh = SOCKET_ERROR;
+#if defined SOCK_CLOEXEC && defined HAVE_ACCEPT4 && !defined __MSVCRT__
+ if (have_sock_cloexec >= 0)
+ {
+ fh = accept4 (FD_TO_SOCKET (fd), addr, addrlen, SOCK_CLOEXEC);
+ if (!check_have_sock_cloexec (fh, ENOSYS))
+ return -1;
+ }
+#endif
+ if (fh == SOCKET_ERROR)
+ {
+ fh = accept (FD_TO_SOCKET (fd), addr, addrlen);
+ socket_set_cloexec (fh);
+ }
+
+ return fh == SOCKET_ERROR ? -1 : SOCKET_TO_FD (fh);
}
static int
--- smalltalk-3.1.orig/packages/sockets/AbstractSocketImpl.st
+++ smalltalk-3.1/packages/sockets/AbstractSocketImpl.st
@@ -75,7 +75,7 @@
create: addressClass protocolFamily
type: self socketType
protocol: self protocol.
- File checkError.
+ descriptor < 0 ifTrue: [ File checkError ].
^self on: descriptor
]
@@ -93,6 +93,7 @@
accept: fd
peer: peer
addrLen: addrLen.
+ newFD < 0 ifTrue: [ File checkError: self soError ].
^(implementationClass on: newFD)
hasBeenBound;
hasBeenConnectedTo: peer;
@@ -108,11 +109,10 @@
addr := ipAddress port: port.
(fd := self fd) isNil ifTrue: [ ^self ].
- [self
+ [(self
bind: fd
to: addr
- addrLen: addr size.
- File checkError]
+ addrLen: addr size) < 0 ifTrue: [File checkError: self soError] ]
ifCurtailed: [self close].
self isOpen ifTrue: [self hasBeenBound]
]
@@ -519,11 +519,10 @@
addr := ipAddress port: port.
[(fd := self fd) isNil ifTrue: [ ^self ].
- self
+ (self
connect: fd
to: addr
- addrLen: addr size.
- File checkError]
+ addrLen: addr size) < 0 ifTrue: [File checkError: self soError] ]
ifCurtailed: [self close].
"connect does not block, so wait for"
|