--- a/Socket.st Mon Jun 04 21:31:38 2007 +0200
+++ b/Socket.st Mon Jun 04 21:40:58 2007 +0200
@@ -1515,6 +1515,12 @@
^ self canReadWithoutBlocking
!
+destroy
+ self close
+
+ "Created: / 04-06-2007 / 21:29:03 / cg"
+!
+
listenOn:aPortNr
self listenOn:aPortNr backlogSize:5
@@ -1528,167 +1534,72 @@
"Created: / 31-05-2007 / 17:59:47 / cg"
!
-peerName
- "return my peer (i.e. ipAddr + port);
- May return nil if not yet setup completely."
-
- ^ self getPeer
-!
-
-primSocketLocalPort:aSocket
- ^ port
+7 / 17:59:53 / cg"
!
-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."
-
- "An experimental version use on slow lines: Longer timeout and smaller writes to try to avoid spurious timeouts."
-
- |remaining nWritten|
-
-Transcript show:'>> '; showCR:aStringOrByteArray.
+mber
- remaining := aStringOrByteArray size.
- [remaining > 0] whileTrue:[
- nWritten := self nextPutBytes:remaining from:aStringOrByteArray startingAt:1.
- remaining := remaining - nWritten.
- ].
- ^ aStringOrByteArray size.
+ "Created: / 31-05-2007 / 17:59:47 / cg"
+!
-"/ | bytesSent bytesToSend count |
-"/ bytesToSend := aStringOrByteArray size.
-"/ bytesSent := 0.
-"/ [bytesSent < bytesToSend] whileTrue: [
-"/ (self waitForSendDoneFor: 60)
-"/ ifFalse: [ConnectionTimedOut signal: 'send data timeout; data not sent'].
-"/ count := self primSocket: socketHandle
-"/ sendData: aStringOrByteArray
-"/ startIndex: bytesSent + 1
-"/ count: (bytesToSend - bytesSent min: 5000).
-"/ bytesSent := bytesSent + count].
-"/
-"/ ^ bytesSent
+/ cg"
!
setOption: optionName value: optionValue
optionName = 'TCP_NODELAY' ifTrue:[
+ ^ self setTCPNoDelay:optionValue
+ ].
+ ^ self setSocketOption:optionName argument:optionValue argument:nil
+
+ "Modified: / 04-06-2007 / 21:23:19 / cg"
+!
+
+Option: optionName value: optionValue
+ optionName = 'TCP_NODELAY' ifTrue:[
^ self setTCPNoDelay:optionValue
].
self error:'unimplemented socketoption' mayProceed:true
!
-socketHandle
- ^ self
+nValue
+ optionName = 'TCP_NODELAY' ifTrue:[
+ ^ self setTCPNoDelay:optionValue
+ ].
+ self error:'unimplemented socketoption' mayProceed:true
!
-waitForConnectionUntil:aMillisecondClockValue
- self shouldImplement.
+waitForData
+ self readWait
+
+ "Created: / 04-06-2007 / 21:28:40 / cg"
! !
!Socket methodsFor:'closing'!
-shutDown
- "shutDown and close the socket"
-
- self shutdown:2.
- self close
+emented socketoption' mayProceed:true
!
-shutDownInput
- "shutDown the input side of the socket.
- Any read on the socket will signal end-of-file from now on.
+Until:aMillisecondClockValue
+ self shouldImplement.
+!
+
+et will signal end-of-file from now on.
The other side MAY be informed, that no more data will be accepted
(e.g. setting the TCP-Windowsize to 0)"
self shutdown:0.
-!
-
-shutDownOutput
- "shutDown the output side of the socket.
- Any write to the socket will signal end-of-file from now on.
- The other side will get a end-of-file condition,
- after the last buffered data has been read"
-
- self shutdown:1.
! !
!Socket methodsFor:'datagram transmission'!
-receiveBuffer:aDataBuffer start:startIndex for:nBytes
- "receive data
- Return the number of bytes received, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
- instance variable.
- The thread blocks until data arrives - you may want to wait before
- receiving, using #readWait or #readWaitWithTimeout:."
-
- |nReceived|
-
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
-
- if (fp != nil) {
- SOCKET sock;
- int objSize, offs;
- int n;
- char *extPtr;
- unsigned char *buffer;
- unsigned char *allocatedBuffer;
- int flags = 0;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-
- if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
- if (__isSmallInteger(nBytes)) {
- if (__intVal(nBytes) < objSize) {
- objSize = __intVal(nBytes);
- }
- }
+on.
+ The other side will get a end-of-file condition,
+ after the last buffered data has been read"
-# ifdef DO_WRAP_CALLS
- if (extPtr) {
- buffer = extPtr + offs;
- } else {
- allocatedBuffer = buffer = (char *)malloc(objSize);
- }
-
- do {
- __threadErrno = 0;
- n = STX_WSA_CALL4("recv", recv, sock, buffer, objSize, flags);
- } while ((n < 0) && (__threadErrno == EINTR));
+ self shutdown:1.
+!
- if (allocatedBuffer) {
- if (n > 0) {
- bcopy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, n);
- }
- free(allocatedBuffer);
- }
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- if (extPtr) {
- n = recv(sock, extPtr + offs, objSize, flags);
- } else {
- n = recv(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, flags);
- }
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-# endif
-
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- nReceived = __MKSMALLINT(n);
- }
-#endif
-bad: ;
-%}.
- nReceived notNil ifTrue:[
- nReceived < 0 ifTrue:[
- 'Socket [warning]: ' infoPrint.
- (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
+tErrorNumber) infoPrintCR.
].
^ nReceived
].
@@ -1698,231 +1609,20 @@
self primitiveFailed
!
-receiveFrom:anAddressBuffer buffer:aDataBuffer
- "receive datagramm data - put address of originating host into
- anAddressBuffer, data into aBuffer.
- Both must be ByteArray-like. The addressBuffer must
- provide space for a valid address for my domain (i.e. for inet, a 4-byte byteArray).
- Return the number of bytes received, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
+On error, the unix error code is left in the lastErrorNumber
instance variable."
^ self receiveFrom:anAddressBuffer buffer:aDataBuffer start:1 for:(aDataBuffer size)
!
-receiveFrom:anAddressBuffer buffer:aDataBuffer start:startIndex for:nBytes
- "receive datagramm data
- - put address of originating host into anAddressBuffer, data into aBuffer.
- For backward compatibility, the addressBuffer may be a non-SocketAddress;
- then, it must be a byteArray with appropriate size for the addressBytes.
-
- Return the number of bytes received, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
- instance variable.
- The thread blocks until data arrives - you may want to wait before
- receiving, using #readWait or #readWaitWithTimeout:."
-
- |domainClass addr addrLen nReceived|
-
- domainClass := self class socketAddressClassForDomain:domain.
- domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
- ].
- (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
- anAddressBuffer class == domainClass ifFalse:[
- ^ self error:'addressBuffer class mismatch (domain)'.
- ].
- addr := anAddressBuffer.
- ] ifFalse:[
- anAddressBuffer notNil ifTrue:[
- addr := domainClass new.
- ].
- ].
-
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
-
- if (fp != nil) {
- SOCKET sock;
- int objSize;
- union sockaddr_u sa;
- unsigned int alen = 0;
- int n, offs;
- int flags = 0;
- char *extPtr;
- unsigned char *allocatedBuffer = NULL;
- unsigned char *buffer = NULL;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-
- if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
- if (__isSmallInteger(nBytes)) {
- if (__intVal(nBytes) < objSize) {
- objSize = __intVal(nBytes);
- }
- }
-# ifdef DO_WRAP_CALLS
- if (extPtr) {
- buffer = extPtr + offs;
- } else {
- allocatedBuffer = buffer = (char *)malloc(objSize);
- }
-
- do {
- __threadErrno = 0;
- alen = sizeof(sa);
- n = STX_WSA_CALL6("recvfrom", recvfrom, sock, buffer, objSize, flags, (struct sockaddr *)&sa, &alen);
- } while ((n < 0) && (__threadErrno == EINTR));
-
- if (allocatedBuffer) {
- if (n > 0) {
- bcopy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, n);
- }
- free(allocatedBuffer);
- }
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- alen = sizeof(sa);
- if (extPtr) {
- n = recvfrom(sock, extPtr + offs, objSize, flags, (struct sockaddr *) &sa, &alen);
- } else {
- n = recvfrom(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, flags, (struct sockaddr *) &sa, &alen);
- }
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-# endif
-
- if (n >= 0) {
- if (__isNonNilObject(addr)) {
- char *addrPtr;
- OBJ oClass;
- int nInstVars, nInstBytes, objSize;
-
- oClass = __qClass(addr);
- if (! __isBytes(addr) )
- goto bad;
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
- objSize = __qSize(addr) - nInstBytes;
- addrPtr = (char *)__InstPtr(addr) + nInstBytes;
- if (objSize < alen)
- goto bad;
-
- /*
- * extract the datagrams address
- */
- bcopy((char *)&sa, addrPtr, alen);
- addrLen = __MKSMALLINT(alen);
- }
- }
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- nReceived = __MKSMALLINT(n);
- }
-#endif
-bad: ;
-%}.
- nReceived notNil ifTrue:[
- nReceived < 0 ifTrue:[
- 'Socket [warning]: ' infoPrint.
- (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
- ].
- addrLen notNil ifTrue:[
- (addr == anAddressBuffer) ifFalse:[
- self obsoleteFeatureWarning:'please use a socketAddress argument'.
-
- " can be a ByteArray for backward compatibility "
- anAddressBuffer replaceFrom:1 to:addrLen with:(addr hostAddress).
- ].
- ].
- ^ nReceived
- ].
- "
- arrive here if you try to receive into an invalid buffer
- (i.e. not ByteArray-like),
+not ByteArray-like),
or if the addressBuffer is nonNil AND not a SocketAddress/ByteArray
or if the addressBuffer is nonNil AND too small.
"
self primitiveFailed
!
-sendBuffer:aDataBuffer start:startIndex for:nBytes flags:flags
- "send data.
- Both must be ByteArray-like. The bytes in the addressBuffer must
- be a valid address for my domain (i.e. for inet, a 4-byte byteArray).
- Return the number of bytes transmitted, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
- instance variable."
-
- |nReceived portNo|
-
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
-
- if ((fp != nil)
- && __isSmallInteger(startIndex)
- && __isSmallInteger(nBytes)) {
- SOCKET sock;
- int objSize;
- int n;
- char *extPtr;
- int _flags = 0;
- int offs;
- unsigned long norder;
- unsigned char *buffer;
- unsigned char *allocatedBuffer;
-
- _flags = __longIntVal(flags);
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-
- if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
- if (__isSmallInteger(nBytes)) {
- if (__intVal(nBytes) < objSize) {
- objSize = __intVal(nBytes);
- }
- }
-
-# ifdef DGRAM_DEBUG
- console_printf("sending %d bytes ...\n", nBytes);
-# endif
-
-#ifdef DO_WRAP_CALLS
- if (extPtr) {
- buffer = extPtr + offs;
- } else {
- allocatedBuffer = buffer = (char *)malloc(objSize);
- bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, objSize);
- }
-
- do {
- __threadErrno = 0;
- n = STX_WSA_CALL4("send", send, sock, buffer, objSize, _flags);
- } while ((n < 0) && (__threadErrno == EINTR));
-
- if (allocatedBuffer) {
- free(allocatedBuffer);
- }
-#else
- __BEGIN_INTERRUPTABLE__
- do {
- if (extPtr) {
- n = send(sock, extPtr + offs, objSize, _flags);
- } else {
- n = send(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, _flags);
- }
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-#endif
-
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- RETURN (__MKSMALLINT(n));
+RETURN (__MKSMALLINT(n));
}
#endif
bad: ;
@@ -1933,158 +1633,28 @@
self primitiveFailed
!
-sendTo:anAddressBuffer buffer:buffer
- "send datagramm data - fetch address of destination host from
- anAddressBuffer, data from aDataBuffer.
- Both must be ByteArray-like. The bytes in the addressBuffer must
- be a valid address for my domain (i.e. for inet, a 4-byte byteArray).
- Return the number of bytes transmitted, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
+er
instance variable.
Flags is currently ignored; it is there for ST-80 compatibility."
^ self sendTo:anAddressBuffer buffer:buffer start:1 for:buffer size flags:0
!
-sendTo:anAddressBuffer buffer:buffer start:startIndex for:count
- "send datagramm data - fetch address of destination host from
- anAddressBuffer, data from aDataBuffer.
- Both must be ByteArray-like. The bytes in the addressBuffer must
- be a valid address for my domain (i.e. for inet, a 4-byte byteArray).
- Return the number of bytes transmitted, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
- instance variable.
+instance variable.
Flags is currently ignored; it is there for ST-80 compatibility."
^ self sendTo:anAddressBuffer buffer:buffer start:startIndex for:count flags:0
-!
-
-sendTo:anAddressBuffer buffer:aDataBuffer start:startIndex for:nBytes flags:flags
- "send datagramm data - fetch address of destination host from
- anAddressBuffer, data from aDataBuffer starting at startIndex,
- sending count bytes.
- Both must be ByteArray-like. The bytes in the addressBuffer must
- be a valid address for my domain (i.e. for inet, a 4-byte byteArray).
- Return the number of bytes transmitted, or a negative number on error.
- On error, the unix error code is left in the lastErrorNumber
- instance variable."
-
- |domainClass addr|
-
- domainClass := self class socketAddressClassForDomain:domain.
- domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
- ].
-
- (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
- addr := anAddressBuffer.
- ] ifFalse:[
- anAddressBuffer isByteArray ifFalse:[
- ^ self error:'bad socketAddress argument'
- ].
- addr := domainClass hostAddress:anAddressBuffer.
- ].
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
-
- if ((fp != nil)
- && __isSmallInteger(startIndex)
- && __isSmallInteger(nBytes)) {
- SOCKET sock;
- int objSize;
- struct sockaddr *sockaddr_ptr;
- union sockaddr_u sa;
- int alen = 0;
- int sockAddrOffs, sockaddr_size;
- int n;
- char *extPtr;
- int _flags = 0;
- int offs;
- unsigned long norder;
- unsigned char *buffer;
- unsigned char *allocatedBuffer;
-
- _flags = __longIntVal(flags);
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-
- if (! __isBytes(addr)) {
- sockaddr_size = 0;
- sockaddr_ptr = (struct sockaddr *)0;
- } else {
- int nIndex;
- OBJ cls;
-
- sockAddrOffs = 0;
- if ((cls = __qClass(addr)) != @global(ByteArray))
- sockAddrOffs += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
- nIndex = __qSize(addr) - OHDR_SIZE;
- sockaddr_size = nIndex - sockAddrOffs;
- if (sockaddr_size > sizeof(sa)) {
- console_fprintf(stderr, "Socket [warning]: bad socketAddr\n");
- goto bad;
- }
- bcopy((__byteArrayVal(addr) + sockAddrOffs), &sa, sockaddr_size);
- sockaddr_ptr = (struct sockaddr *)(&sa);
- }
-
- if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
- if (__isSmallInteger(nBytes)) {
- if (__intVal(nBytes) < objSize) {
- objSize = __intVal(nBytes);
- }
- }
-
-#ifdef DO_WRAP_CALLS
- if (extPtr) {
- buffer = extPtr + offs;
- } else {
- allocatedBuffer = buffer = (char *)malloc(objSize);
- bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, objSize);
- }
-
- do {
- __threadErrno = 0;
- n = STX_WSA_CALL6("sendto", sendto, sock, buffer, objSize, _flags, sockaddr_ptr, sockaddr_size);
- } while ((n < 0) && (__threadErrno == EINTR));
-
- if (allocatedBuffer) {
- free(allocatedBuffer);
- }
-#else
- __BEGIN_INTERRUPTABLE__
- do {
- if (extPtr) {
- n = sendto(sock, extPtr + offs, objSize, _flags, sockaddr_ptr, sockaddr_size);
- } else {
- n = sendto(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, _flags, sockaddr_ptr, sockaddr_size);
- }
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-#endif
-
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- RETURN (__MKSMALLINT(n));
- }
-#endif
-bad: ;
-%}.
- "
- arrive here if you try to send from an invalid buffer
- (i.e. not ByteArray-like),
- or if the addressBuffer is nonNil AND not a ByteArray/String
- or if the addressBuffer is nonNil AND too small.
- "
- self primitiveFailed
! !
!Socket methodsFor:'low level'!
-bindAnonymously
- "bind to any address. A free port will be allocated.
- Our own socket address will be determined after conection set up.
+if the addressBuffer is nonNil AND not a ByteArray/String
+ or if the addressBuffer is nonNil AND too small.
+ "
+ self primitiveFailed
+!
+
+n socket address will be determined after conection set up.
This is the default after the socket has been created"
^ self
@@ -2093,7 +1663,7 @@
reuseAddress:false
!
-bindAnonymouslyToAddress:addressString
+ndAnonymouslyToAddress:addressString
"bind to address addressString.
A free port will be allocated"
@@ -2103,9 +1673,7 @@
reuseAddress:false
!
-bindTo:aSocketAddress
- "ST80 compatible bind, expecting a socketAddress argument.
- The socketAddress object (an instance of SocketAddress)
+ess)
is supposed to respond to #portOrName and #address requests."
^ self bindTo:(aSocketAddress portOrName)
@@ -2113,13 +1681,7 @@
reuseAddress:true
!
-bindTo:portNrOrNameString address:addressString
- "low level bind - returns true if ok, false otherwise.
- Currently only non-address binding is supported;
- i.e. the address must always be nil.
-
- The interpretation of portNrOrName depends on the domain:
- inet domain uses (4byte) byteArray like internet numbers,
+s,
unix domain uses pathname strings,
others use whatever will come up in the future
"
@@ -2128,153 +1690,11 @@
bindTo:portNrOrNameString
address:addressString
reuseAddress:true
-!
-
-bindTo:portNrOrNameOrNil address:hostOrPathNameOrSocketAddrOrNil reuseAddress:reuse
- "low level bind - returns true if ok, false otherwise.
- Currently only non-address binding is supported;
- i.e. address must always be nil.
-
- The interpretation of portNrOrName depends on the domain:
- inet domain uses (4byte) byteArray like internet numbers,
- unix domain uses pathname strings,
- others use whatever will come up in the future
-
- The reuse boolean argument controls if the SO_REUSEADDR socket option
- is to be set (to avoid the 'bind: address in use' error).
- "
-
- |ok addr addrName domainClass|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-
- domainClass := self class socketAddressClassForDomain:domain.
- domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
- ].
-
- " backward compatibility: support for byteArray and string arg "
-
- hostOrPathNameOrSocketAddrOrNil isNil ifTrue:[
- addr := domainClass anyHost.
- ] ifFalse:[
- hostOrPathNameOrSocketAddrOrNil isString ifTrue:[
- addr := domainClass hostName:hostOrPathNameOrSocketAddrOrNil.
- addrName := hostOrPathNameOrSocketAddrOrNil.
- ] ifFalse:[
- (hostOrPathNameOrSocketAddrOrNil isKindOf:SocketAddress) ifTrue:[
- addr := hostOrPathNameOrSocketAddrOrNil.
- ] ifFalse:[
- hostOrPathNameOrSocketAddrOrNil isByteArray ifFalse:[
- ^ self error:'bad host (socketAddress) argument'
- ].
- addr := domainClass hostAddress:hostOrPathNameOrSocketAddrOrNil.
- ].
- ].
- ].
- portNrOrNameOrNil notNil ifTrue:[
- addr port:portNrOrNameOrNil.
- ].
- (portNrOrNameOrNil isNil or:[portNrOrNameOrNil == 0]) ifTrue:[
- addr := addr copy.
- ].
-
-%{ /* STACK: 100000 */
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
-
- if (! __isBytes(addr)) {
- addr = nil;
- console_fprintf(stderr, "Socket [warning]: bad sddr\n");
- RETURN (false);
- }
- if (fp != nil) {
- SOCKET sock;
- union sockaddr_u sa;
- int sockaddr_size;
- int ret;
- int sockAddrOffs;
-
- {
- int nIndex;
- OBJ cls;
+! !
- sockAddrOffs = 0;
- if ((cls = __qClass(addr)) != @global(ByteArray))
- sockAddrOffs += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
- nIndex = __qSize(addr) - OHDR_SIZE;
- sockaddr_size = nIndex - sockAddrOffs;
- if (sockaddr_size > sizeof(sa)) {
- console_fprintf(stderr, "Socket: bad socketAddr\n");
- RETURN (false);
- }
- bcopy((__byteArrayVal(addr) + sockAddrOffs), &sa, 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"));
- }
- }
-# endif /* SO_REUSEADDR */
+!Socket protectedMethodsFor:'low level'!
-# ifdef BIND_BLOCKS
-# ifdef DO_WRAP_CALLS
- do {
- __threadErrno = 0;
- ret = STX_WSA_CALL3("bind", bind, sock, &sa, sockaddr_size);
- } while ((ret < 0) && (__threadErrno == EINTR));
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-# endif
-# else
- ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
-# endif
- if (ret < 0) {
- DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- RETURN (false);
- } else {
- ok = true;
-
- if (! __isSmallInteger(portNrOrNameOrNil)
- || (portNrOrNameOrNil == __MKSMALLINT(0))) {
- unsigned int alen = sockaddr_size;
-
- /*
- * anonymous port - get the actual portNr
- */
- if (getsockname(sock, (struct sockaddr *)&sa, &alen) < 0) {
-# ifdef WIN32
- errno = WSAGetLastError();
-# endif
- console_fprintf(stderr, "SOCKET: cannot get socketname: %d\n", errno);
- }
- bcopy(&sa, (__byteArrayVal(addr) + sockAddrOffs), alen);
- }
- }
- }
-#endif /* NO_SOCKET */
-
-getOutOfHere: ;
-%}.
- ok ~~ true ifTrue:[
- ^ false
- ].
-
- peer := addr.
- port := addr port.
+dr port.
peerName := addrName.
^ true
@@ -2286,87 +1706,15 @@
"
! !
-!Socket protectedMethodsFor:'low level'!
-
-closeFile
- "low level close"
-
-%{ /* NOCONTEXT */
-#ifndef NO_SOCKET
- OBJ t;
-
- t = __INST(filePointer);
- if (t != nil) {
- FILE *fp;
- SOCKET sock;
- int fd;
-
- __INST(filePointer) = nil;
- fp = __FILEVal(t);
- fd = fileno(fp);
- sock = SOCKET_FROM_FD(fd);
+!Socket methodsFor:'low level'!
-# ifdef xxDO_WRAP_CALLS
- { int ret;
-
- do {
- __threadErrno = 0;
- ret = STX_C_CALL1("fclose", fclose, fp);
- } while ((ret < 0) && (__threadErrno == EINTR));
-
-# ifdef WIN32
- do {
- __threadErrno = 0;
- ret = STX_WSA_CALL1("closesocket", closesocket, sock);
- } while ((ret < 0) && (__threadErrno == EINTR));
- closesocket(sock);
-# endif
- }
-# else /* !DO_WRAP_CALLS */
-
- DBGFPRINTF((stderr, "SOCKET: fflush %x (%d %d)\n", fp, fileno(fp), sock));
- fflush(fp);
-
-# if defined(CLOSESOCKET_BEFORE_FCLOSE)
- DBGFPRINTF((stderr, "SOCKET: closesocket (%d)\n", sock));
+TF((stderr, "SOCKET: closesocket (%d)\n", sock));
closesocket(sock);
# endif
- if ((@global(FileOpenTrace) == true) || __debugging__) {
- console_fprintf(stderr, "SOCKET: fclose %x (%d %d)\n", fp, fileno(fp), sock);
- }
- fclose(fp);
-
-# if defined(CLOSESOCKET_AFTER_FCLOSE)
- DBGFPRINTF((stderr, "SOCKET: closesocket (%d)\n", sock));
- closesocket(sock);
-# endif
-# endif /* !DO_WRAP_CALLS */
- }
-#endif /* NO_SOCKET */
-%}
-! !
-
-!Socket methodsFor:'low level'!
+# endif /*
+!
-getSocketError
- "get the SO_ERROR form the socket, which indicates the
- result of an asynchronous operation"
-
-%{
-#ifndef NO_SOCKET
- OBJ fp;
- int err;
-
- fp = __INST(filePointer);
- if (fp == nil) {
- err = EBADF;
- } else {
- unsigned int sz;
- SOCKET sock;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
- sz = sizeof(err);
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
+opt(sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
# ifdef WIN32
errno = WSAGetLastError();
# endif
@@ -2379,51 +1727,18 @@
%}
!
-listenFor:aNumber
- "same as listenWithBacklog: - for ST-80 compatibility"
-
- ^ self listenWithBacklog:aNumber
-!
-
-listenWithBacklog:aNumber
- "start listening; return true if ok, false on error"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int ret;
-
- if (! __isSmallInteger(aNumber)) {
- DBGPRINTF(("SOCKET: invalid arg\n"));
- RETURN (false);
+;
+ }
}
- sock = SOCKET_FROM_FILE_OBJECT(fp);
+ RETURN(__MKSMALLINT(err));
+#endif
+%}
+! !
-#ifdef LISTEN_BLOCKS
-# ifdef DO_WRAP_CALLS
- do {
- __threadErrno = 0;
- ret = STX_WSA_CALL2("listen", listen, sock, __intVal(aNumber));
- } while ((ret < 0) && (__threadErrno == EINTR));
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- ret = listen(sock, __intVal(aNumber));
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-# endif
-#else
- ret = listen(sock, __intVal(aNumber));
-#endif
+!Socket protectedMethodsFor:'low level'!
- if (ret < 0) {
- DBGPRINTF(("SOCKET: listen call failed errno=%d\n", errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
+rrorNumber) = __MKSMALLINT(errno);
RETURN (false);
}
#else
@@ -2434,187 +1749,9 @@
^ true
! !
-!Socket protectedMethodsFor:'low level'!
-
-setSocketOption:option argument:arg1 argument:arg2
- |ok|
-
-%{ /* STACK: 32000 */
- OBJ fp = __INST(filePointer);
-
- if (fp != nil) {
- SOCKET sock;
- int opt = -1;
- int level = -1;
- int usize = -1;
- int ret;
- union u {
- BOOL u_bool;
- int u_int;
- struct linger u_linger;
- } u;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-
-# ifdef SO_BROADCAST
- if (option == @symbol(SO_BROADCAST)) {
- /* Enables transmission and receipt of broadcast messages on the socket. */
- opt = SO_BROADCAST;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_BROADCAST */
-
-# ifdef SO_CONDITIONAL
-# if 0
- if (option == @symbol(SO_CONDITIONAL)) {
- /* Enables sockets to delay the acknowledgment of a connection until after the WSAAccept condition function is called. */
- opt = SO_CONDITIONAL;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif
-# endif /* SO_CONDITIONAL */
-
-# ifdef SO_DEBUG
- if (option == @symbol(SO_DEBUG)) {
- /* Records debugging information. */
- opt = SO_DEBUG;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_DEBUG */
-
-# ifdef SO_DONTLINGER
- if (option == @symbol(SO_DONTLINGER)) {
- /* Does not block close waiting for unsent data to be sent.
- Setting this option is equivalent to setting SO_LINGER with l_onoff set to zero. */
- opt = SO_DONTLINGER;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_DONTLINGER */
-
-# ifdef SO_DONTROUTE
- if (option == @symbol(SO_DONTROUTE)) {
- /* Does not route: sends directly to interface.
- Succeeds but is ignored on AF_INET sockets;
- fails on AF_INET6 sockets with WSAENOPROTOOPT.
- Not supported on ATM sockets (results in an error). */
- opt = SO_DONTROUTE;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_DONTROUTE */
+!Socket methodsFor:'low level'!
-# ifdef SO_KEEPALIVE
- if (option == @symbol(SO_KEEPALIVE)) {
- /* Sends keep-alives. Not supported on ATM sockets (results in an error). */
- opt = SO_KEEPALIVE;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_KEEPALIVE */
-
-# ifdef SO_LINGER
- if (option == @symbol(SO_LINGER)) {
- /* Lingers on close if unsent data is present. */
- opt = SO_LINGER;
- level = SOL_SOCKET;
- usize = sizeof(u.u_linger);
- if (arg1 == true) u.u_linger.l_onoff = TRUE;
- else if (arg1 == false) u.u_linger.l_onoff = FALSE;
- else goto argError;
- if (arg2 == nil) u.u_linger.l_linger = 0;
- else if (__isSmallInteger(arg2))u.u_linger.l_linger = __intVal(arg2);
- else goto argError;
- DBGPRINTF(("SOCKET: SO_LINGER %d %d\n", u.u_linger.l_onoff, u.u_linger.l_linger));
- }
-# endif /* SO_LINGER */
-
-# ifdef SO_OOBINLINE
- if (option == @symbol(SO_OOBINLINE)) {
- /* Receives OOB data in the normal data stream. */
- opt = SO_OOBINLINE;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_OOBINLINE */
-
-# ifdef SO_RCVBUF
- if (option == @symbol(SO_RCVBUF)) {
- /* Specifies the total per-socket buffer space reserved for receives.
- This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window. */
- opt = SO_RCVBUF;
- level = SOL_SOCKET;
- usize = sizeof(u.u_int);
- if (__isSmallInteger(arg1))u.u_int = __intVal(arg1);
- else goto argError;
- }
-# endif /* SO_RCVBUF */
-
-# ifdef SO_SNDBUF
- if (option == @symbol(SO_SNDBUF)) {
- /* Specifies the total per-socket buffer space reserved for sends.
- This is unrelated to SO_MAX_MSG_SIZE or the size of a TCP window. */
- opt = SO_SNDBUF;
- level = SOL_SOCKET;
- usize = sizeof(u.u_int);
- if (__isSmallInteger(arg1))u.u_int = __intVal(arg1);
- else goto argError;
- }
-# endif /* SO_SNDBUF */
-
-# ifdef SO_REUSEADDR
- if (option == @symbol(SO_REUSEADDR)) {
- /* Allows the socket to be bound to an address that is already in use. */
- opt = SO_REUSEADDR;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_OOBINLINE */
-
-# ifdef SO_EXCLUSIVEADDRUSE
- if (option == @symbol(SO_EXCLUSIVEADDRUSE)) {
- /* Enables a socket to be bound for exclusive access.
- Does not require administrative privilege. */
- opt = SO_EXCLUSIVEADDRUSE;
- level = SOL_SOCKET;
- usize = sizeof(u.u_bool);
- if (arg1 == true) u.u_bool = TRUE;
- else if (arg1 == false) u.u_bool = FALSE;
- else goto argError;
- }
-# endif /* SO_OOBINLINE */
-
- if (usize == -1) goto argError;
-
- ok = ( setsockopt( sock, level, opt, &u, usize) >= 0) ? true : false;
- }
+}
argError: ;
%}.
@@ -2624,36 +1761,9 @@
ok ifFalse:[
'setsocketoption failed' infoPrintCR.
].
-! !
-
-!Socket methodsFor:'low level'!
-
-shutdown: howNum
- "shutDown the socket - inform it that no more I/O will be performed.
- 0 - read side (no further reads)
- 1 - write side (no further writes)
- 2 - both (no further I/O at all)
- shutDown:2
- discards any pending data
- (as opposed to close, which might wait until data is delivered as set by LINGER)"
+!
-%{
-#ifndef NO_SOCKET
-
- OBJ fp;
-
- fp = __INST(filePointer);
- if ((fp != nil) && __isSmallInteger(howNum)) {
- SOCKET sock;
- int ret;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-# ifdef DO_WRAP_CALLS
- do {
- __threadErrno = 0;
- DBGFPRINTF((stderr, "SOCKET: shutDown...\n"));
- ret = STX_WSA_CALL2("shutdown", shutdown, sock, __intVal(howNum));
- DBGFPRINTF((stderr, "SOCKET: shutDown -> %d (%d)\n", ret, __threadErrno));
+Errno));
} while ((ret < 0) && (__threadErrno == EINTR));
# else
__BEGIN_INTERRUPTABLE__
@@ -2663,26 +1773,16 @@
}
#endif
%}.
-!
-
-tryToBindTo:portNrOrNameOrNil
- (self bindTo:portNrOrNameOrNil address:nil) ifFalse:[
- ^ OpenError raiseWith:self errorString:('cannot bind socket to port: <1p>' expandMacrosWith:portNrOrNameOrNil).
- ].
- ^ self.
! !
!Socket methodsFor:'low level-accepting'!
-accept
- "create a new TCP socket from accepting on the receiver.
- This method will suspend the current process if no connection is waiting.
- For ST-80 compatibility"
+^ OpenError raiseWith:self errorString:('cannot bind socket to port: <1p>' expandMacrosWith:portNrOrNameOrNil).
+ ].
+ ^ self.
+!
- |newSock|
-
- newSock := self class new.
- (newSock acceptOn:self) ifFalse:[^ nil].
+newSock acceptOn:self) ifFalse:[^ nil].
^ newSock
"
@@ -2694,11 +1794,7 @@
"
!
-acceptOn:aSocket
- "accept a connection on a server port (created with:'Socket>>onIPPort:')
- usage is: (Socket basicNew acceptOn:(Socket onIPPort:9999)).
- This method will suspend the current process if no connection is waiting.
- Return the true if ok; false if not."
+alse if not."
aSocket readWait.
^ self primAcceptOn:aSocket blocking:false.
@@ -2707,9 +1803,7 @@
"Modified: / 1.8.1998 / 23:39:10 / cg"
!
-blockingAccept
- "create a new TCP socket from accepting on the receiver.
- This method will suspend the current process if no connection is waiting.
+ss if no connection is waiting.
For ST-80 compatibility"
|newSock|
@@ -2719,29 +1813,14 @@
^ newSock
!
-blockingAcceptOn:aSocket
- "accept a connection on a server port (created with:'Socket>>onIPPort:')
- usage is: (Socket basicNew acceptOn:(Socket onIPPort:9999)).
+:9999)).
This method will suspend the current process if no connection is waiting.
Return the true if ok; false if not."
^ self primAcceptOn:aSocket blocking:true.
!
-pollingWaitForNewConnectionOrDataOnAny:otherConnections timeout:timeoutSeconds
- <resource: #obsolete>
- "stupid MSDOS does not support select on sockets (sigh).
- Must poll here."
-
- |millis newConnection|
-
- millis := timeoutSeconds * 1000.
- [millis > 0] whileTrue:[
- otherConnections size > 0 ifTrue:[
- otherConnections do:[:aConnection |
- aConnection canReadWithoutBlocking ifTrue:[
- ^ aConnection
- ]
+]
].
].
newConnection := self blockingAccept.
@@ -2752,18 +1831,7 @@
^ nil.
!
-pollingWaitForNewConnectionWithTimeout:timeoutSeconds
- <resource: #obsolete>
- "stupid MSDOS does not support select on sockets (sigh).
- Must poll here."
-
- |millis newConnection|
-
- timeoutSeconds notNil ifTrue:[
- millis := timeoutSeconds * 1000.
- ].
- [millis isNil or:[millis > 0]] whileTrue:[
- newConnection := self blockingAccept.
+:= self blockingAccept.
newConnection notNil ifTrue:[^ newConnection].
Delay waitForMilliseconds:20.
millis notNil ifTrue:[
@@ -2773,180 +1841,7 @@
^ nil.
!
-primAcceptOn:aSocket blocking:blocking
- "accept a connection on a server port (created with:'Socket>>onIPPort:')
- usage is: (Socket basicNew acceptOn:(Socket onIPPort:9999)).
- Return the true if ok; false if not."
-
- |serverSocketFd addr addrLen domainClass|
-
- filePointer notNil ifTrue:[
- ^ self errorAlreadyOpen
- ].
-
- domain := aSocket domain.
- socketType := aSocket type.
- serverSocketFd := aSocket fileDescriptor.
- serverSocketFd isNil ifTrue:[
- ^ self error:'invalid server socket'
- ].
- (serverSocketFd isMemberOf:SmallInteger) ifFalse:[
- ^ self error:'invalid server socket'
- ].
-
- domainClass := self class socketAddressClassForDomain:domain.
- domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
- ].
- addrLen := domainClass socketAddressSize.
- addr := domainClass new.
-
-%{ /* STACK: 100000 */
-#ifndef NO_SOCKET
- FILE *fp;
- int flags;
- SOCKET sock, newSock;
- union sockaddr_u sa;
- unsigned int alen, alen0;
- struct hostent *he ;
- char dotted[20] ;
-
- if (!__isSmallInteger(addrLen)) {
- DBGPRINTF(("SOCKET: bad addrLen\n"));
- RETURN (false);
- }
- alen0 = __intVal(addrLen);
- sock = SOCKET_FROM_FD(__intVal(serverSocketFd));
-
- if (blocking == false) {
-# if defined(O_NONBLOCK) && defined(SET_NDELAY)
- flags = fcntl(sock, F_GETFL);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-# endif
- }
-
-# ifdef DO_WRAP_CALLS
- do {
- __threadErrno = 0;
- alen = alen0;
- newSock = STX_WSA_CALL3("accept", accept, sock, &sa, &alen);
- } while ((newSock < 0) && (__threadErrno == EINTR));
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- alen = alen0;
- newSock = accept(sock, (struct sockaddr *) &sa, &alen);
- } while ((newSock < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-# endif
- DBGFPRINTF((stderr, "SOCKET: accept newSock=%d\n", newSock));
-
- if (blocking == false) {
-# if defined(O_NDELAY) && defined(SET_NDELAY)
- fcntl(sock, F_SETFL, flags);
-# endif
- }
-
- if (newSock < 0) {
- DBGPRINTF(("SOCKET: accept call failed errno=%d\n", errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- RETURN (false);
- }
-
- if (__isNonNilObject(addr)) {
- OBJ oClass;
- int nInstVars, nInstBytes, objSize;
- char *cp;
-
- oClass = __qClass(addr);
- if (! __isBytes(addr) ) {
- DBGPRINTF(("SOCKET: bad addr\n"));
- closesocket(newSock);
- RETURN (false);
- }
-
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
- objSize = __qSize(addr) - nInstBytes;
- cp = (char *)__InstPtr(addr) + nInstBytes;
- if (objSize < alen) {
- DBGPRINTF(("SOCKET: bad addr\n"));
- closesocket(newSock);
- RETURN (false);
- }
-
- /*
- * extract the partners address
- */
- bcopy((char *)&sa, cp, alen);
- addrLen = __MKSMALLINT(alen);
- }
-
- /*
- * make it a FILE *
- */
-# ifdef WIN32
- {
- int _fd = _open_osfhandle(newSock, 0);
- fp = fdopen(_fd, "r+");
- DBGPRINTF(("SOCKET: sock=%d fd=%d fp=%x\n",newSock,_fd, fp));
- }
-# else
- fp = fdopen(newSock, "r+");
-# endif
-
- if (! fp) {
- DBGPRINTF(("SOCKET: fdopen call failed\n"));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
-# ifdef DO_WRAP_CALLS
- {
- int ret;
- do {
- __threadErrno = 0;
- ret = STX_WSA_CALL1("closesocket", closesocket, newSock);
- } while ((ret < 0) && (__threadErrno == EINTR));
- }
-# else
- closesocket(newSock);
-# endif
- DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock));
- RETURN (false);
- }
-
- if ((@global(FileOpenTrace) == true) || __debugging__) {
-# ifdef WIN32
- {
- HANDLE h;
- int _fd = fileno(fp);
- h = (HANDLE)_get_osfhandle(_fd);
- console_fprintf(stderr, "fdopen [Socket] -> %x (fd: %d) (H: %x)\n", fp, _fd, h);
- }
-# else
- console_fprintf(stderr, "fdopen [Socket] -> %x (fd: %d)\n", fp, newSock);
-# endif
- }
-
-# ifdef BUGGY_STDIO_LIB
- setbuf(fp, NULL);
- __INST(buffered) = false;
-# endif
-
-# if 0
- // The original code was:
- __INST(filePointer) = __MKOBJ((INT)fp); __STORESELF(filePointer);
- // but for that, gcc generates wrong code, which loads self (volatile) into
- // a register (bp), then calls __MKOBJ, then stores indirect bp.
- // That is wrong if a scavenge occurs in MKOBJ, as bp is now still pointing to the old
- // object.
-# endif
- {
- OBJ t;
-
- t = __MKOBJ(fp);
- __INST(filePointer) = t;
- __STORE(self, t);
- }
-#endif /* not NO_SOCKET */
+O_SOCKET */
%}.
mode := #readwrite.
Lobby register:self.
@@ -2960,60 +1855,7 @@
^ true
!
-waitForNewConnectionOrDataOnAny:otherConnections timeout:timeoutSeconds
- "suspend the current process, until either a new connection comes
- in at the receiver, or data arrives on any of the otherConnections.
- For a new connection, an accept is performed and the new socket is returned.
- For an old connection, that socket is returned.
- In any case, the caller gets a socket to operate on as return value,
- or nil, if a timeout occured.
- This method implements the inner wait-primitive of a multi-connection
- server application."
-
-
- |wasBlocked sema|
-
- "first, a quick check if data is already available"
- self canReadWithoutBlocking ifTrue:[
- ^ self accept.
- ].
- otherConnections do:[:aConnection |
- aConnection canReadWithoutBlocking ifTrue:[
- ^ aConnection
- ]
- ].
-
- [
- "check again - prevent incoming interrupts from disturbing our setup"
- wasBlocked := OperatingSystem blockInterrupts.
-
- self canReadWithoutBlocking ifTrue:[
- ^ self accept.
- ].
- otherConnections do:[:aConnection |
- aConnection canReadWithoutBlocking ifTrue:[
- ^ aConnection
- ]
- ].
-
- "nope - must wait"
- sema := Semaphore new name:'multiReadWait'.
- otherConnections do:[:aConnection |
- Processor signal:sema onInput:(aConnection fileDescriptor).
- ].
- Processor signal:sema onInput:(self fileDescriptor).
- timeoutSeconds notNil ifTrue:[
- Processor signal:sema afterSeconds:timeoutSeconds
- ].
- Processor activeProcess state:#ioWait.
- sema wait.
- ] ensure:[
- sema notNil ifTrue:[Processor disableSemaphore:sema].
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ].
-
- "see who it was ..."
- self canReadWithoutBlocking ifTrue:[
+[
^ self accept.
].
otherConnections do:[:aConnection |
@@ -3024,213 +1866,26 @@
"none - a timeout"
^ nil
-!
-
-waitForNewConnectionWithTimeout:timeoutSeconds
- "suspend the current process, until a new connection comes
- in at the receiver or a timeout occurs.
- For a new connection, an accept is performed and the new socket is returned.
- Returns nil, if a timeout occured.
- This method implements the inner wait-primitive of a single-connection
- server application."
-
- (self readWaitWithTimeout:timeoutSeconds) ifTrue:[
- "a timeout occurred - no connection within timeout"
- ^ nil
- ].
- ^ self accept.
! !
!Socket methodsFor:'low level-connecting'!
-connectTo:hostOrPathName port:portNrOrName
- "low level connect; connect to port, portNrOrNameOrNil on host, hostName.
- For backward compatibility, host may be also a string or a byteArray,
- but it is recommended to pass socketAddress instances.
+readWaitWithTimeout:timeoutSeconds) ifTrue:[
+ "a timeout occurred - no connection within timeout"
+ ^ nil
+ ].
+ ^ self accept.
+!
- Return true if ok, false otherwise.
- The current process will block (but not the whole Smalltalk) until the connection is established.
+the connection is established.
See also: #connectTo:port:withTimeout: for a somewhat nicer interface."
^ self connectTo:hostOrPathName port:portNrOrName withTimeout:nil
-!
-
-connectTo:hostOrPathNameOrSocketAddr port:portNrOrNameOrNil withTimeout:timeout
- "low level connect; connect to port, portNrOrNameOrNil on host, hostName.
- For backward compatibility, host may be also a string or a byteArray,
- but it is recommended to pass socketAddress instances.
-
- Return true if ok, false otherwise.
- The current process will block (but not the whole Smalltalk) until the connection is established,
- or timeout millliseconds have passed."
-
- |isAsync err domainClass addr addrName|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-
- domainClass := self class socketAddressClassForDomain:domain.
- domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
- ].
-
- "/ backward compatibility: support for byteArray and string arg
-
- hostOrPathNameOrSocketAddr isString ifTrue:[
- addr := domainClass hostName:hostOrPathNameOrSocketAddr port:portNrOrNameOrNil.
- addrName := hostOrPathNameOrSocketAddr.
- ] ifFalse:[
- hostOrPathNameOrSocketAddr isByteCollection ifFalse:[
- ^ self error:'bad host (socketAddress) argument'
- ].
- (hostOrPathNameOrSocketAddr isKindOf:SocketAddress) ifTrue:[
- addr := hostOrPathNameOrSocketAddr.
- portNrOrNameOrNil notNil ifTrue:[
- addr port:portNrOrNameOrNil.
- ].
- ] ifFalse:[
- addr := domainClass hostAddress:hostOrPathNameOrSocketAddr port:portNrOrNameOrNil.
- ].
- ].
-
-%{ /* STACK: 100000 */
-
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
- union sockaddr_u sa;
- SOCKET sock;
- int a;
- int ret, oldFlags;
- int on = 1;
- int sockaddr_size;
-
- if (!__isNonNilObject(addr) || !__isBytes(addr)) {
- DBGPRINTF(("SOCKET: invalid addrBytes\n"));
- RETURN (false);
- }
-
- {
- int sockAddrOffs, nIndex;
- OBJ cls;
-
- sockAddrOffs = 0;
- if ((cls = __qClass(addr)) != @global(ByteArray))
- sockAddrOffs += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
- nIndex = __qSize(addr) - OHDR_SIZE;
- sockaddr_size = nIndex - sockAddrOffs;
- if (sockaddr_size > sizeof(sa)) {
- console_fprintf(stderr, "Socket: bad socketAddr\n");
- RETURN (false);
- }
- bcopy((__byteArrayVal(addr) + sockAddrOffs), &sa, sockaddr_size);
- }
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-
-# if defined(O_NONBLOCK)
-# if !defined(WIN32)
- /*
- * set to non-blocking and wait later
- */
- oldFlags = fcntl(sock, F_GETFL, 0);
- /* on SUNOS4.x, would use fcntl(osfd, F_SETFL, flags | FNDELAY); */
- fcntl(sock, F_SETFL, oldFlags | O_NONBLOCK);
-# endif
-# endif
+! !
- /*
- * connect
- */
-# ifdef DO_WRAP_CALLS
- do {
- DBGFPRINTF((stderr, "SOCKET: connect...\n"));
- __threadErrno = 0;
- ret = STX_WSA_NOINT_CALL3("connect", connect, sock, &sa, sockaddr_size);
- DBGFPRINTF((stderr, "SOCKET: connect(%d) -> %d (%d)\n", sock, ret, __threadErrno));
- } while ((ret < 0) && (__threadErrno == EINTR));
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- ret = connect(sock, (struct sockaddr *)&sa, sockaddr_size);
- } while ((ret < 0)
- && ((errno == EINTR)
-# ifdef EAGAIN
- || (errno == EAGAIN)
-# endif
- ));
- __END_INTERRUPTABLE__
-#endif
+!Socket methodsFor:'printing & storing'!
- if (ret < 0) {
-# if defined(EINPROGRESS) || defined(EALREADY)
- if (0
-# ifdef EINPROGRESS
- || (errno == EINPROGRESS)
-# endif
-# ifdef EALREADY
- || (errno == EALREADY)
-# endif
- ) {
- /*
- * This was a nonblocking operation that will take some time.
- * Do a select on read to get informed when the operation is ready.
- */
- DBGFPRINTF((stderr, "SOCKET: isAsync is true\n"));
- isAsync = true;
- } else
-# endif /* EINPROGRESS or EALREADY */
- {
- DBGFPRINTF((stderr, "SOCKET: connect failed ret=%d errno=%d __threadErrno=%d\n",
- ret, errno, __threadErrno ));
-# ifdef DUMP_ADDRESS
- {
- char *cp = (char *)(&sa);
- int i;
-
- console_printf("address data:\n");
- for (i=0; i<sockaddr_size; i++) {
- console_printf(" %02x\n", *cp++);
- }
- }
-# endif
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- RETURN (false);
- }
- }
-
-# if defined(O_NONBLOCK)
-# if !defined(WIN32)
- fcntl(sock, F_SETFL, oldFlags);
-# endif
-# endif
-
-# else /* NO_SOCKET */
- RETURN (false);
-# endif /* NO_SOCKET */
-%}.
- isAsync == true ifTrue:[
- (self writeWaitWithTimeoutMs:timeout) ifTrue:[
- "/ a timeout occured
- "/ should cancel the connect?
- ^ false.
- ].
- err := self getSocketError.
- err ~~ 0 ifTrue:[
- lastErrorNumber := err.
- ^ false.
- ].
- ].
- port := portNrOrNameOrNil.
- peer := addr.
- peerName := addrName.
- ^ true
-
- "
- |sock|
- sock := Socket newTCP.
- sock connectTo:'localhost' port:21 withTimeout:1000.
- sock
+sock
|sock|
sock := Socket newTCP.
@@ -3239,106 +1894,18 @@
"
! !
-!Socket methodsFor:'printing & storing'!
+!Socket methodsFor:'queries'!
-printOn:aStream
- aStream nextPutAll:self className; nextPutAll:'(protocol='.
- protocol printOn:aStream.
- aStream nextPutAll:' port='.
+aStream nextPutAll:' port='.
port printOn:aStream.
aStream nextPutAll:' peer='.
peer printOn:aStream.
aStream nextPut:$).
-! !
-
-!Socket methodsFor:'queries'!
-
-domain
- "return the sockets addressing domain (i.e. #inet, #unix, #x25, #appletalk)"
-
- ^ domain
!
-getFullSocketAddress
- "implemented for swazoo project (primitive code cant be loaded as extension)
- Answer my own address (I am bound to this address).
- Note that this address may change after a connect or accept."
-
- |error domainClass addr addrLen|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-
- domainClass := self class socketAddressClassForDomain:domain.
- domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
- ].
- addrLen := domainClass socketAddressSize.
- addr := domainClass new.
-
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int ret;
- union sockaddr_u sa;
- unsigned int alen, alen0;
- char *addrP;
- int addrObjSize, nAddrInstBytes;
-
- if (!__isSmallInteger(addrLen)) {
- DBGPRINTF(("SOCKET: bad addrLen\n"));
- error = @symbol(badArgument);
- goto err;
- }
- alen = alen0 = __intVal(addrLen);
-
- if (!__isNonNilObject(addr) || !__isBytes(addr)) {
- DBGPRINTF(("SOCKET: bad addr\n"));
- error = @symbol(badArgument);
- goto err;
- }
-
- {
- OBJ addrClass;
- int nAddrInstVars;
-
- addrClass = __qClass(addr);
- nAddrInstVars = __intVal(__ClassInstPtr(addrClass)->c_ninstvars);
- nAddrInstBytes = OHDR_SIZE + (nAddrInstVars * sizeof(OBJ));
- addrObjSize = __qSize(addr) - nAddrInstBytes;
- if (addrObjSize < alen0) {
- DBGPRINTF(("SOCKET: bad addr/alen\n"));
- error = @symbol(badArgument);
- goto err;
- }
- }
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
-# ifdef WIN32
- __threadErrno = 0;
-# endif
- ret = getsockname(sock, (struct sockaddr *)&sa, &alen);
- if (ret < 0) {
-# ifdef WIN32
- errno = WSAGetLastError();
-# endif
- DBGPRINTF(("SOCKET: getsocketname failed ret=%d errno=%d\n", ret, errno));
- error = __MKSMALLINT(errno);
- goto err;
- }
-
- if (addrObjSize < alen) {
- DBGPRINTF(("SOCKET: bad addr\n"));
- error = @symbol(badArgument);
- goto err;
- }
-
- addrP = (char *)__InstPtr(addr) + nAddrInstBytes;
- bcopy((char *)&sa, addrP, alen);
-
- addrLen = __MKSMALLINT(alen);
+On:aStream.
+ aStream nextPut:$).
+!
err:;
#else /* NO_SOCKET */
@@ -3351,16 +1918,14 @@
^ addr
!
-getName
- "return the name; here, we return the ports name"
-
- ^ port printString
+}.
+ error notNil ifTrue:[
+ ^ self errorReporter reportOn:error
+ ].
+ ^ addr
!
-getPeer
- "ST-80 compatibility: return an IPSocketAddress instance representing
- my hostname/port combination.
- If you are interested in the hostname, use getPeerName directly."
+If you are interested in the hostname, use getPeerName directly."
peer isNil ifTrue:[
peer := self class peerFromDomain:domain name:peerName port:port.
@@ -3368,8 +1933,7 @@
^ peer
!
-getPeerName
- "return the peer name; thats the hostname (or dotted name) of the
+ame (or dotted name) of the
partners host after an accept."
peerName isNil ifTrue:[
@@ -3378,73 +1942,26 @@
^ peerName
!
-getSocketAddress
- "implemented for swazoo project primitive code cant load as extension
- answer my own address (I am bound to this address).
+to this address).
Note that this address may change after connect or accept."
^ self getFullSocketAddress hostAddress
"/ ^ self getFullSocketAddress copyFrom:5 to:8
!
-getSocketAdress
- "BAD SPELLING, of #getSocketAddress, kept for compatibility with swazoo"
+ddress copyFrom:5 to:8
+!
+
+compatibility with swazoo"
<resource: #obsolete>
^ self getSocketAddress
!
-isActive
- "return true, if the receiver has a connection"
-
- ^ filePointer notNil
-!
-
-isConnected
- "return true, if the receiver has a connection"
-
- ^ self isActive
- and:[port notNil
- and:[peerName notNil or:[peer notNil]]]
+ilePointer notNil
!
-old_getFullSocketAddress
- "implemented for swazoo project primitive code cant load as extension
- answer my own address (I am bound to this address).
- Note that this address may change after connect or accept."
-
- |socketAddress error|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
- socketAddress := ByteArray new:16.
-
-%{
-#ifndef NO_SOCKET
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- unsigned int sockaddr_size;
- int ret;
-
- if (!__isNonNilObject(socketAddress) ||
- (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
- error = @symbol(badArgument1);
- goto err;
- }
- sockaddr_size = __byteArraySize(socketAddress);
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
- ret = getsockname(sock, (struct sockaddr *)__byteArrayVal(socketAddress), &sockaddr_size);
- if (ret < 0) {
-# ifdef WIN32
- errno = WSAGetLastError();
-# endif
- DBGPRINTF(("SOCKET: getsocketname failed errno=%d\n", errno));
- error = __MKSMALLINT(errno);
- }
-err:;
#else /* NO_SOCKET */
error = @symbol(notImplemented);
#endif /* NO_SOCKET */
@@ -3455,10 +1972,7 @@
^ socketAddress
!
-port
- "return the port number (or name for unix-sockets) to which the socket is bound"
-
-"/ sometimes maybe we do am lazy fetch of the port
+e we do am lazy fetch of the port
"/ port == 0 ifTrue:[ |p|
"/ p := self getPort.
"/ p notNil ifTrue:[
@@ -3466,226 +1980,23 @@
"/ ]
"/ ].
^ port
-!
-
-type
- "return the sockets connection type (i.e. #datagram, #stream etc)"
-
- ^ socketType
! !
!Socket methodsFor:'socket setup'!
-domain:domainArg type:typeArg
- "set up socket with domain and type.
- This is a low level entry; no binding, listening or connect
- is done. Both arguments must be symbols from one of
+:= p
+"/ ]
+"/ ].
+ ^ port
+!
+
+uments must be symbols from one of
#inet,#unix, #appletalk, #x25 .. and #stream, #datagram, #raw resp."
^ self domain:domainArg type:typeArg protocol:0 reuseAddress:true
!
-domain:domainArg type:typeArg protocol:protocolNumber
- "set up socket with domain, type and protocol number.
- This is a low level entry; no binding, listening or connect
- is done. Both arguments must be symbols from one of
- #inet,#unix, #appletalk, #x25 .. and #stream, #datagram, #raw resp."
-
- ^ self domain:domainArg type:typeArg protocol:protocolNumber reuseAddress:true
-
- "
- Socket new domain:#inet type:#stream
- Socket new domain:#unix type:#stream
- "
-!
-
-domain:domainArg type:typeArg protocol:protocolNumber reuseAddress:reuse
- "set up socket with domain, type and protocol number.
- This is a low level entry; no binding, listening or connect
- is done. Both arguments must be symbols from one of
- #inet,#unix, #appletalk, #x25 .. and #stream, #datagram, #raw resp.
-
- The reuse boolean argument controls if the SO_REUSEADDR socket option
- is to be set (to avoid the 'bind: address in use' error)."
-
- |domainName domainCode typeCode error|
-
- filePointer notNil ifTrue:[
- ^ self errorAlreadyOpen
- ].
- domainName := SocketAddress domainCodeFromName:domainArg.
- domainCode := OperatingSystem domainCodeOf:domainName.
- typeCode := OperatingSystem socketTypeCodeOf:typeArg.
-%{
-
-#ifndef NO_SOCKET
- FILE *fp;
- int dom, typ, pf, proto = 0;
- int on = 1;
- SOCKET sock;
-
- if (! __isSmallInteger(domainCode)) {
- error = @symbol(badArgument1);
- goto out;
- }
- if (! __isSmallInteger(typeCode)) {
- error = @symbol(badArgument2);
- goto out;
- }
- if (protocolNumber != nil) {
- if (!__isSmallInteger(protocolNumber)) {
- error = @symbol(badArgument3);
- goto out;
- }
- proto = __intVal(protocolNumber);
- }
-
-
- /*
- * get address and protocol-family
- */
- dom = __intVal(domainCode);
- typ = __intVal(typeCode);
-
-# ifdef SOCKET_BLOCKS
-# ifdef DO_WRAP_CALLS
- do {
- __threadErrno = 0;
- sock = STX_WSA_CALL3("socket", socket, dom, typ, proto);
- } while ((sock < 0) && (__threadErrno == EINTR));
-# else
- __BEGIN_INTERRUPTABLE__
- do {
- DBGPRINTF(("SOCKET: opening socket domain=%d type=%d proto=%d\n", dom, typ, proto));
- sock = socket(dom, typ, proto);
-# if defined(EPROTONOSUPPORT) /* for SGI */
- if ((proto != 0) && (sock < 0) && (errno == EPROTONOSUPPORT)) {
- DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
- proto = 0;
- sock = socket(dom, typ, 0);
- }
-# endif
- } while ((sock < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-# endif
-# else
- sock = socket(dom, typ, proto);
-# if defined(EPROTONOSUPPORT) /* for SGI */
- if ((proto != 0) && (sock < 0) && (errno == EPROTONOSUPPORT)) {
- DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
- proto = 0;
- sock = socket(dom, typ, 0);
- }
-# endif
-# endif
-
- DBGFPRINTF((stderr, "SOCKET: create newSock=%d\n", sock));
-
-# ifdef WIN32
- if (sock == INVALID_SOCKET)
-# else
- if (sock < 0)
-# endif
- {
- DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=%d) call failed errno=%d\n", dom, typ, proto, errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- } else {
-# ifdef SO_REUSEADDR
- if (reuse == true) {
- DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR\n"));
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
- DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
- }
- }
-# endif /* SO_REUSEADDR */
-
-# ifdef SET_LINGER_WHEN_CREATING_SOCKET
-# ifdef SO_LINGER
- {
- struct linger l;
-
- l.l_onoff = 1;
- l.l_linger = 30;
- setsockopt( sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
- }
-# endif
-# endif
-# ifdef WIN32
- /*
- * make it blocking
- */
- {
- int zero = 0;
-
- ioctlsocket(sock, FIONBIO, &zero);
- }
-# endif
- /*
- * make it a FILE *
- */
-# ifdef WIN32
- {
- int _fd = _open_osfhandle(sock, 0);
- fp = fdopen(_fd, "r+");
- DBGPRINTF(("SOCKET: sock=%d fd=%d fp=%x\n",sock,_fd, fp));
- }
-# else
- fp = fdopen(sock, "r+");
-# endif
- if (! fp) {
- DBGPRINTF(("SOCKET: fdopen call failed\n"));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
-# ifdef DO_WRAP_CALLS
- { int ret;
-
- do {
- __threadErrno = 0;
- ret = STX_WSA_CALL1("closesocket", closesocket, sock);
- } while ((ret < 0) && (__threadErrno == EINTR));
- }
-# else
- __BEGIN_INTERRUPTABLE__
- closesocket(sock);
- DBGFPRINTF((stderr, "SOCKET: fdopen failed (%d)\n", sock));
- __END_INTERRUPTABLE__
-# endif
- } else {
- if ((@global(FileOpenTrace) == true) || __debugging__) {
- console_fprintf(stderr, "fdopen [Socket] -> %x\n", fp);
- }
-
-# if 0
- // The original code was:
- __INST(filePointer) = __MKOBJ((INT)fp); __STORESELF(filePointer);
- // but for that, gcc generates wrong code, which loads self (volatile) into
- // a register (bp), then calls __MKOBJ, then stores indirect bp.
- // That is wrong if a scavenge occurs in MKOBJ, as bp is now still pointing to the old
- // object.
-# endif
- {
- OBJ t;
-
- t = __MKOBJ(fp);
- __INST(filePointer) = t;
- __STORE(self, t);
- }
- }
- }
-#endif
-out:;
-%}.
-
- "all ok?"
- filePointer notNil ifTrue:[
- domain := domainArg.
- socketType := typeArg.
- Lobby register:self.
- ] ifFalse:[
- error notNil ifTrue:[
- ^ self primitiveFailed:error.
- ].
- ^ self openError
- ].
+^ self domain:domainArg type:typeArg protocol:protocolNumber reuseAddress:true
"
Socket new domain:#inet type:#stream
@@ -3695,23 +2006,18 @@
!Socket methodsFor:'specials'!
-receiveBufferSize
- "get the send buffer size - for special applications only.
- Not all operatingSystems offer this functionality
- (returns nil, if unsupported)"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
+ailed:error.
+ ].
+ ^ self openError
].
-%{
-#if defined(SO_RCVBUF) && defined(SOL_SOCKET)
- {
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int opt;
- unsigned int size;
- sock = SOCKET_FROM_FILE_OBJECT(fp);
+ "
+ Socket new domain:#inet type:#stream
+ Socket new domain:#unix type:#stream
+ "
+!
+
+sock = SOCKET_FROM_FILE_OBJECT(fp);
if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &size) >= 0) {
RETURN( __MKSMALLINT(opt) );
}
@@ -3721,22 +2027,7 @@
^ nil
!
-receiveBufferSize:size
- "set the receive buffer size - for special applications only.
- Not all operatingSystems offer this functionality
- (returns false, if unsupported)"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(SO_RCVBUF) && defined(SOL_SOCKET)
- if (__isSmallInteger(size)) {
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int opt;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
+OM_FILE_OBJECT(fp);
opt = __intVal(size);
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&opt, sizeof(int)) >= 0 ) {
RETURN(true);
@@ -3747,34 +2038,7 @@
^ false
!
-receiveTimeout
- "get the receive timeout in millis - for special applications only.
- Not all operatingSystems offer this functionality
- (returns nil, if unsupported)"
-
- |millis|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(SO_RCVTIMEO) && defined(SOL_SOCKET)
- {
- OBJ fp = __INST(filePointer);
- int sock;
- int len;
- int __millis;
- struct timeval tv = {0, 0};
-
- sock = fileno(__FILEVal(fp));
- len = sizeof(struct timeval);
- if (getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, &len) == 0) {
- __millis = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
- millis = __mkSmallInteger(__millis);
-# if 0
- console_fprintf(stderr, "getsockopt -> s:%d us:%d -> millis:%d\n", tv.tv_sec, tv.tv_usec, __millis);
-# endif
- } else {
+e {
console_fprintf(stderr, "Socket [warning]: getsockopt %d failed; errno=%d\n", sock, errno);
}
}
@@ -3784,32 +2048,7 @@
^ nil
!
-receiveTimeout:seconds
- "set the receive timeout - for special applications only.
- Not all operatingSystems offer this functionality
- (returns false, if unsupported)"
-
- |millis|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
- millis := (seconds * 1000) rounded.
-%{
-#if defined(SO_RCVTIMEO) && defined(SOL_SOCKET)
- if (__isSmallInteger(millis)) {
- OBJ fp = __INST(filePointer);
- int sock;
- int __millis = __intVal(millis);
- struct timeval tv = {0, 0};
-
- sock = fileno(__FILEVal(fp));
- tv.tv_sec = __millis / 1000;
- tv.tv_usec = (__millis % 1000) * 1000;
-# if 0
- console_fprintf(stderr, "setsockopt -> millis:%d -> s:%d us:%d \n", __millis, tv.tv_sec, tv.tv_usec);
-# endif
- if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(struct timeval)) == 0) {
+sizeof(struct timeval)) == 0) {
RETURN(true);
}
console_fprintf(stderr, "Socket [warning]: setsockopt %d failed; errno=%d\n", sock, errno);
@@ -3819,23 +2058,7 @@
^ false
!
-sendBufferSize
- "get the send buffer size - for special applications only.
- Not all operatingSystems offer this functionality
- (returns nil, if unsupported)"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(SO_SNDBUF) && defined(SOL_SOCKET)
- {
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int opt;
- unsigned int size;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
+sock = SOCKET_FROM_FILE_OBJECT(fp);
if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&opt, &size) >= 0) {
RETURN( __MKSMALLINT(opt) );
}
@@ -3845,22 +2068,7 @@
^ nil
!
-sendBufferSize:size
- "set the send buffer size - for special applications only.
- Not all operatingSystems offer this functionality
- (returns false, if unsupported)"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(SO_SNDBUF) && defined(SOL_SOCKET)
- if (__isSmallInteger(size)) {
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int opt;
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
+ROM_FILE_OBJECT(fp);
opt = __intVal(size);
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&opt, sizeof(int)) >= 0) {
RETURN(true);
@@ -3871,34 +2079,7 @@
^ false
!
-sendTimeout
- "get the send timeout in millis - for special applications only.
- Not all operatingSystems offer this functionality
- (returns nil, if unsupported)"
-
- |millis|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(SO_SNDTIMEO) && defined(SOL_SOCKET)
- {
- OBJ fp = __INST(filePointer);
- int sock;
- int len;
- int __millis;
- struct timeval tv = {0, 0};
-
- sock = fileno(__FILEVal(fp));
- len = sizeof(struct timeval);
- if (getsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, &len) == 0) {
- __millis = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
- millis = __mkSmallInteger(__millis);
-# if 0
- console_fprintf(stderr, "getsockopt -> s:%d us:%d -> millis:%d\n", tv.tv_sec, tv.tv_usec, __millis);
-# endif
- } else {
+e {
console_fprintf(stderr, "Socket [warning]: getsockopt %d failed; errno=%d\n", sock, errno);
}
}
@@ -3908,32 +2089,7 @@
^ nil
!
-sendTimeout:seconds
- "set the send timeout - for special applications only.
- Not all operatingSystems offer this functionality
- (returns false, if unsupported)"
-
- |millis|
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
- millis := (seconds * 1000) rounded.
-%{
-#if defined(SO_SNDTIMEO) && defined(SOL_SOCKET)
- if (__isSmallInteger(millis)) {
- OBJ fp = __INST(filePointer);
- int sock;
- int __millis = __intVal(millis);
- struct timeval tv = {0, 0};
-
- sock = fileno(__FILEVal(fp));
- tv.tv_sec = __millis / 1000;
- tv.tv_usec = (__millis % 1000) * 1000;
-# if 0
- console_fprintf(stderr, "setsockopt -> millis:%d -> s:%d us:%d \n", __millis, tv.tv_sec, tv.tv_usec);
-# endif
- if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, sizeof(struct timeval)) == 0) {
+zeof(struct timeval)) == 0) {
RETURN(true);
}
console_fprintf(stderr, "Socket [warning]: setsockopt %d failed; errno=%d\n", sock, errno);
@@ -3944,23 +2100,7 @@
!
-setTCPCork:aBoolean
- "enable/disable TCP_CORK (do-not-send-partial-frames)
- For special applications only.
- Not all OperatingSystems offer this functionality
- (returns false, if unsupported)"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(IPPROTO_TCP) && defined(TCP_CORK)
- int onOff = (aBoolean == true);
-
- if ((aBoolean == true) || (aBoolean == false)) {
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int onOff = (aBoolean == true);
+);
sock = SOCKET_FROM_FILE_OBJECT(fp);
if (setsockopt(sock, IPPROTO_TCP, TCP_CORK, (char *)&onOff, sizeof(int)) >= 0) {
@@ -3970,38 +2110,10 @@
#endif
%}.
^ false
-!
-
-setTCPNoDelay:aBoolean
- "enable/disable TCP_NODELAY (i.e. disable/enable the Nagle algorithm)
- For special applications only.
- Not all OperatingSystems offer this functionality
- (returns false, if unsupported)"
-
- filePointer isNil ifTrue:[
- ^ self errorNotOpen
- ].
-%{
-#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
- int onOff = (aBoolean == true);
-
- if ((aBoolean == true) || (aBoolean == false)) {
- OBJ fp = __INST(filePointer);
- SOCKET sock;
- int onOff = (aBoolean == true);
-
- sock = SOCKET_FROM_FILE_OBJECT(fp);
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&onOff, sizeof(int)) >= 0) {
- RETURN(true);
- }
- }
-#endif
-%}.
- ^ false
! !
!Socket class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.237 2007-05-31 15:57:38 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.238 2007-06-04 19:40:58 cg Exp $'
! !