--- a/Socket.st Fri Nov 18 21:28:24 2016 +0000
+++ b/Socket.st Fri Nov 18 22:45:12 2016 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
@@ -1626,10 +1628,6 @@
^ self getPeer
!
-primSocketLocalPort:aSocket
- ^ self port
-!
-
sendData: aStringOrByteArray
"Send all of the data in the given array, even if it requires multiple calls to send it all.
Return the number of bytes sent."
@@ -1643,21 +1641,11 @@
"Modified: / 04-06-2007 / 21:23:19 / cg"
!
-socketHandle
- ^ self
-!
-
waitForConnectionUntil:aTimestamp
"return true if connected"
self readWaitWithTimeoutMs: (aTimestamp millisecondDeltaFrom:Timestamp now).
^ self isConnected
-!
-
-waitForData
- self readWait
-
- "Created: / 04-06-2007 / 21:28:40 / cg"
! !
!Socket methodsFor:'accepting connections'!
@@ -1704,6 +1692,7 @@
"
self newTCP bindAnonymously; listenFor:1; yourself
+ self newTCP bindAnonymously; port
"
!
@@ -1805,17 +1794,17 @@
|ok error socketAddress|
handle isNil ifTrue:[
- ^ self errorNotOpen
+ ^ self errorNotOpen
].
socketAddress := aSocketAddress.
socketAddress isNil ifTrue:[
- "ok, get a all zero socket address, so it is for anyHost
- and the port will be assigned"
- socketAddress := self socketAddressClass new.
+ "ok, get a all zero socket address, so it is for anyHost
+ and the port will be assigned"
+ socketAddress := self socketAddressClass new.
].
domain == #'AF_INET6' ifTrue:[
- "accept also IPv4 connections on IPv6 sockets (this is off by default fow windows"
- self setSocketOption:#'IPV6_V6ONLY' argument:false argument:nil.
+ "accept also IPv4 connections on IPv6 sockets (this is off by default for windows"
+ self setSocketOption:#'IPV6_V6ONLY' argument:false argument:nil.
].
ok := false.
@@ -1829,52 +1818,52 @@
int sockAddrOffs;
if (fp == nil) {
- goto getOutOfHere;
+ goto getOutOfHere;
}
if (! __isBytes(socketAddress)) {
- error = __mkSmallInteger(-1);
- goto getOutOfHere;
+ error = __mkSmallInteger(-1);
+ goto getOutOfHere;
}
/* get the socket-address */
if (__isNonNilObject(socketAddress)){
- int nIndex;
- OBJ cls = __qClass(socketAddress);
-
- sockAddrOffs = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
- nIndex = __qSize(socketAddress) - OHDR_SIZE;
- sockaddr_size = nIndex - sockAddrOffs;
- if (sockaddr_size > sizeof(sa)) {
- error=__mkSmallInteger(-2);
- goto getOutOfHere;
- }
- memcpy(&sa, __byteArrayVal(socketAddress) + sockAddrOffs, sockaddr_size);
+ int nIndex;
+ OBJ cls = __qClass(socketAddress);
+
+ sockAddrOffs = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
+ nIndex = __qSize(socketAddress) - OHDR_SIZE;
+ sockaddr_size = nIndex - sockAddrOffs;
+ if (sockaddr_size > sizeof(sa)) {
+ error=__mkSmallInteger(-2);
+ goto getOutOfHere;
+ }
+ memcpy(&sa, __byteArrayVal(socketAddress) + sockAddrOffs, sockaddr_size);
}
sock = SOCKET_FROM_FILE_OBJECT(fp);
# ifdef SO_REUSEADDR
if (reuse == true) {
- int on = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
- DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
- }
+ int on = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
+ DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
+ }
}
# endif /* SO_REUSEADDR */
# ifdef BIND_BLOCKS
# ifdef DO_WRAP_CALLS
do {
- __threadErrno = 0;
- ret = STX_WSA_NOINT_CALL3("bind", bind, sock, &sa, sockaddr_size);
+ __threadErrno = 0;
+ ret = STX_WSA_NOINT_CALL3("bind", bind, sock, &sa, sockaddr_size);
} while ((ret < 0) && (__threadErrno == EINTR));
if (ret < 0) {
- errno = __threadErrno;
+ errno = __threadErrno;
}
# else
__BEGIN_INTERRUPTABLE__
do {
- ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
+ ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
} while ((ret < 0) && (errno == EINTR));
__END_INTERRUPTABLE__
# endif
@@ -1884,68 +1873,68 @@
# endif
if (ret < 0) {
# ifdef __win32__
- if (errno == 0) {
- errno = WSAGetLastError();
- }
+ if (errno == 0) {
+ errno = WSAGetLastError();
+ }
# endif
- DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
- error = __INST(lastErrorNumber) = __MKSMALLINT(errno);
- goto getOutOfHere;
+ DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
+ error = __INST(lastErrorNumber) = __MKSMALLINT(errno);
+ goto getOutOfHere;
} else {
- ok = true;
+ ok = true;
}
#endif /* NO_SOCKET */
getOutOfHere: ;
%}.
ok ~~ true ifTrue:[
- |errorHolder errorString|
-
- error isInteger ifTrue:[
- errorHolder := OperatingSystem errorHolderForNumber:error.
- errorString := errorHolder errorString.
- ] ifFalse:[
- errorString := error.
- ].
- OpenError newException
- errorString:('cannot bind socket to address: %1 (%2)'
- bindWith:socketAddress
- with:errorString);
- errorCode:error;
- osErrorHolder:errorHolder;
- parameter:self;
- raiseRequest.
- "maybe someone catches the error and binds to some other port..."
- ^ true.
+ |errorHolder errorString|
+
+ error isInteger ifTrue:[
+ errorHolder := OperatingSystem errorHolderForNumber:error.
+ errorString := errorHolder errorString.
+ ] ifFalse:[
+ errorString := error.
+ ].
+ OpenError newException
+ errorString:('cannot bind socket to address: %1 (%2)'
+ bindWith:socketAddress
+ with:errorString);
+ errorCode:error;
+ osErrorHolder:errorHolder;
+ parameter:self;
+ raiseRequest.
+ "maybe someone catches the error and binds to some other port..."
+ ^ true.
].
port := socketAddress port.
port == 0 ifTrue:[
- "this is a bind to a random port, now we can get the real port"
- port := self getFullSocketAddress port.
+ "this is a bind to a random port, now we can get the real port"
+ port := self getFullSocketAddress port.
].
^ true
"
(Socket domain:#'AF_INET' type:#stream)
- bindTo:(IPSocketAddress anyHost port:445) reuseAddress:false;
- yourself.
+ bindTo:(IPSocketAddress anyHost port:445) reuseAddress:false;
+ yourself.
(Socket domain:#'AF_INET' type:#stream)
- bindTo:139 reuseAddress:false;
- yourself.
+ bindTo:139 reuseAddress:false;
+ yourself.
(Socket domain:#'AF_INET6' type:#stream)
- bindTo:nil reuseAddress:false;
- yourself.
+ bindTo:nil reuseAddress:false;
+ yourself.
(Socket domain:#'AF_INET' type:#stream)
- bindTo:(IPSocketAddress localHost port:2122) reuseAddress:false;
- yourself.
+ bindTo:(IPSocketAddress localHost port:2122) reuseAddress:false;
+ yourself.
(Socket domain:#'AF_UNIX' type:#stream)
- bindTo:nil reuseAddress:false;
- yourself.
+ bindTo:nil reuseAddress:false;
+ yourself.
"
!
@@ -3621,7 +3610,7 @@
|domainName domainCode typeCode error newHandle|
handle notNil ifTrue:[
- ^ self errorAlreadyOpen
+ ^ self errorAlreadyOpen
].
domainName := SocketAddress domainCodeFromName:domainArg.
domainCode := OperatingSystem domainCodeOf:domainName.
@@ -3643,19 +3632,19 @@
# endif
if (! __isSmallInteger(domainCode)) {
- error = @symbol(badArgument1);
- goto out;
+ error = @symbol(badArgument1);
+ goto out;
}
if (! __isSmallInteger(typeCode)) {
- error = @symbol(badArgument2);
- goto out;
+ error = @symbol(badArgument2);
+ goto out;
}
if (protocolNumber != nil) {
- if (!__isSmallInteger(protocolNumber)) {
- error = @symbol(badArgument3);
- goto out;
- }
- proto = __intVal(protocolNumber);
+ if (!__isSmallInteger(protocolNumber)) {
+ error = @symbol(badArgument3);
+ goto out;
+ }
+ proto = __intVal(protocolNumber);
}
/*
@@ -3667,91 +3656,91 @@
# ifdef __win32__
sock = WSASocket(dom, typ, proto, 0, 0, noInheritFlag);
if (sock == INVALID_SOCKET && noInheritFlag) {
- // tried to open socket with WSA_FLAG_NO_HANDLE_INHERIT
- // This fails on older windows versions, e.g. Windows XP
- sock = WSASocket(dom, typ, proto, 0, 0, 0);
- if (sock != INVALID_SOCKET) {
- // no error without WSA_FLAG_NO_HANDLE_INHERIT,
- // never use this flag again!
- noInheritFlag = 0;
- }
+ // tried to open socket with WSA_FLAG_NO_HANDLE_INHERIT
+ // This fails on older windows versions, e.g. Windows XP
+ sock = WSASocket(dom, typ, proto, 0, 0, 0);
+ if (sock != INVALID_SOCKET) {
+ // no error without WSA_FLAG_NO_HANDLE_INHERIT,
+ // never use this flag again!
+ noInheritFlag = 0;
+ }
}
if (sock == INVALID_SOCKET) {
- errno = WSAGetLastError();
+ errno = WSAGetLastError();
# else // !__win32__
sock = socket(dom, typ, proto);
# if defined(EPROTONOSUPPORT) /* for SGI */
if ((sock < 0) && (proto != 0) && (errno == EPROTONOSUPPORT)) {
- DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
- proto = 0;
- sock = socket(dom, typ, 0);
+ DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
+ proto = 0;
+ sock = socket(dom, typ, 0);
}
# endif
if (sock < 0) {
# endif // !__win32__
- DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=%d) call failed errno=%d\n", dom, typ, proto, errno));
- error = __MKSMALLINT(errno);
+ DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=%d) call failed errno=%d\n", dom, typ, proto, errno));
+ error = __MKSMALLINT(errno);
} else {
# if defined(SET_LINGER_WHEN_CREATING_SOCKET) && defined(SO_LINGER)
- {
- struct linger l;
-
- l.l_onoff = 1;
- l.l_linger = 30;
- setsockopt( sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
- }
+ {
+ struct linger l;
+
+ l.l_onoff = 1;
+ l.l_linger = 30;
+ setsockopt(sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
+ }
# endif
# ifdef __win32__
- /*
- * make it blocking
- */
- {
- unsigned long zero = 0;
- ioctlsocket(sock, FIONBIO, &zero);
- }
- {
+ /*
+ * make it blocking
+ */
+ {
+ unsigned long zero = 0;
+ ioctlsocket(sock, FIONBIO, &zero);
+ }
+ {
# if 0 && (defined( __BORLANDC__ ) || defined( __MINGW__ ))
- /*
- * make it a FILE *
- */
- __stxWrapApiEnterCritical();
- _fd = _open_osfhandle((long)sock, 0);
- __stxWrapApiLeaveCritical();
+ /*
+ * make it a FILE *
+ */
+ __stxWrapApiEnterCritical();
+ _fd = _open_osfhandle((long)sock, 0);
+ __stxWrapApiLeaveCritical();
# else
- _fd = (int)sock;
+ _fd = (int)sock;
# endif
- DBGPRINTF(("SOCKET: sock=%d fd=%d\n", sock, _fd));
- }
+ DBGPRINTF(("SOCKET: sock=%d fd=%d\n", sock, _fd));
+ }
# else // !__win32__
- fp = fdopen(sock, "r+");
- if (! fp) {
- DBGPRINTF(("SOCKET: fdopen call failed\n"));
- error = __MKSMALLINT(errno);
- __BEGIN_INTERRUPTABLE__
- closesocket(sock);
- DBGFPRINTF((stderr, "SOCKET: fdopen failed (%d)\n", sock));
- __END_INTERRUPTABLE__
- goto out;
- }
+ fp = fdopen(sock, "r+");
+ if (! fp) {
+ DBGPRINTF(("SOCKET: fdopen call failed\n"));
+ error = __MKSMALLINT(errno);
+ __BEGIN_INTERRUPTABLE__
+ closesocket(sock);
+ DBGFPRINTF((stderr, "SOCKET: fdopen failed (%d)\n", sock));
+ __END_INTERRUPTABLE__
+ goto out;
+ }
# endif // !__win32__
- if (@global(FileOpenTrace) == true) {
+ if (@global(FileOpenTrace) == true) {
# ifdef __win32__
- console_fprintf(stderr, "fdopen [Socket create] -> fd: %d (H: %"_lx_")\n", (INT)_fd, (INT)sock);
+ console_fprintf(stderr, "fdopen [Socket create] -> fd: %d (H: %"_lx_")\n", (INT)_fd, (INT)sock);
# else
- console_fprintf(stderr, "fdopen [Socket] -> %"_lx_" (fd: %d)\n", (INT)fp, sock);
+ console_fprintf(stderr, "fdopen [Socket] -> %"_lx_" (fd: %d)\n", (INT)fp, sock);
# endif
- }
+ }
# ifdef __win32__
- __externalAddressVal(newHandle) = _fd;
- __INST(handleType) = @symbol(socketHandle);
+ __externalAddressVal(newHandle) = _fd;
+ __INST(handleType) = @symbol(socketHandle);
# else
- __externalAddressVal(newHandle) = fp;
- __INST(handleType) = @symbol(socketFilePointer);
+ __externalAddressVal(newHandle) = fp;
+ __INST(handleType) = @symbol(socketFilePointer);
# endif
}
#endif
@@ -3760,15 +3749,15 @@
"all ok?"
handleType notNil ifTrue:[
- handle := newHandle.
- domain := domainArg.
- socketType := typeArg.
- self registerForFinalization.
- ^ self.
+ handle := newHandle.
+ domain := domainArg.
+ socketType := typeArg.
+ self registerForFinalization.
+ ^ self.
].
error isInteger ifTrue:[
- lastErrorNumber := error.
- ^ self openError:error.
+ lastErrorNumber := error.
+ ^ self openError:error.
].
^ self primitiveFailed:error.
@@ -3778,6 +3767,7 @@
"
! !
+
!Socket methodsFor:'specials'!
linger:anIntegerOrNil
@@ -4053,6 +4043,7 @@
^ self setSocketOption:#'TCP_NODELAY' argument:aBoolean argument:nil.
! !
+
!Socket methodsFor:'waiting'!
waitForNewConnectionOrDataOnAny:otherConnections timeout:timeoutSeconds