--- a/Socket.st Sun Aug 05 11:44:04 2012 +0200
+++ b/Socket.st Sun Aug 05 18:19:07 2012 +0200
@@ -45,8 +45,11 @@
# define xxCLOSESOCKET_BEFORE_FCLOSE
# endif
+# ifdef __BORLANDC__
# define SOCKET_FROM_FD(fd) (_get_osfhandle(fd))
-
+# else
+# define SOCKET_FROM_FD(fd) (fd)
+# endif
#else /* not WIN32 */
# define SOCKET_FROM_FD(fd) (fd)
@@ -263,411 +266,411 @@
examples
"
example (get help info from an nntp server):
- [exBegin]
- |sock host|
-
- host := OperatingSystem getEnvironment:'NNTPSERVER'.
-
- sock := Socket newTCPclientToHost:host port:'nntp'.
- sock isNil ifTrue:[
- self warn:'no nntp daemon is running'.
- ^ self
- ].
- Transcript showCR:sock nextLine.
- sock buffered:false.
-
- sock nextPutAll:'HELP'; cr.
- [:exit |
- |line|
-
- line := sock nextLine.
- line = '.' ifTrue:[exit value:nil].
- Transcript showCR:line.
- ] loopWithExit.
- sock close
- [exEnd]
+ [exBegin]
+ |sock host|
+
+ host := OperatingSystem getEnvironment:'NNTPSERVER'.
+
+ sock := Socket newTCPclientToHost:host port:'nntp'.
+ sock isNil ifTrue:[
+ self warn:'no nntp daemon is running'.
+ ^ self
+ ].
+ Transcript showCR:sock nextLine.
+ sock buffered:false.
+
+ sock nextPutAll:'HELP'; cr.
+ [:exit |
+ |line|
+
+ line := sock nextLine.
+ line = '.' ifTrue:[exit value:nil].
+ Transcript showCR:line.
+ ] loopWithExit.
+ sock close
+ [exEnd]
example (connect to finger daemon, get users entry):
- [exBegin]
- |sock host entry|
-
- host := OperatingSystem getHostName.
-
- sock := Socket newTCPclientToHost:host port:'finger'.
- sock isNil ifTrue:[
- self warn:'no finger daemon is running'.
- ^ self
- ].
- sock useCRLF:true.
- sock buffered:false.
- sock isNil ifTrue:[
- Transcript showCR:'cannot connect to local finger daemon'
- ] ifFalse:[
- sock nextPutAll:(OperatingSystem getLoginName).
- sock cr.
-
- entry := sock nextLine.
- Transcript showCR:entry.
-
- sock close
- ]
- [exEnd]
+ [exBegin]
+ |sock host entry|
+
+ host := OperatingSystem getHostName.
+
+ sock := Socket newTCPclientToHost:host port:'finger'.
+ sock isNil ifTrue:[
+ self warn:'no finger daemon is running'.
+ ^ self
+ ].
+ sock useCRLF:true.
+ sock buffered:false.
+ sock isNil ifTrue:[
+ Transcript showCR:'cannot connect to local finger daemon'
+ ] ifFalse:[
+ sock nextPutAll:(OperatingSystem getLoginName).
+ sock cr.
+
+ entry := sock nextLine.
+ Transcript showCR:entry.
+
+ sock close
+ ]
+ [exEnd]
example (connect to an ftp server):
- [exBegin]
- |sock host|
-
- host := OperatingSystem getHostName.
- sock := Socket newTCPclientToHost:host port:'ftp'.
-
- sock buffered:false.
- Transcript showCR:sock nextLine.
- sock nextPutAll:('USER ' , 'anonymous'); cr.
- Transcript showCR:sock nextLine.
- sock nextPutAll:('PASS ' , 'fooBar'); cr.
- Transcript showCR:sock nextLine.
- sock nextPutAll:'LIST'; cr.
- Transcript showCR:sock nextLine.
- sock close.
-
- 'dont know enough of the ftp protocol to continue here ...'
- [exEnd]
+ [exBegin]
+ |sock host|
+
+ host := OperatingSystem getHostName.
+ sock := Socket newTCPclientToHost:host port:'ftp'.
+
+ sock buffered:false.
+ Transcript showCR:sock nextLine.
+ sock nextPutAll:('USER ' , 'anonymous'); cr.
+ Transcript showCR:sock nextLine.
+ sock nextPutAll:('PASS ' , 'fooBar'); cr.
+ Transcript showCR:sock nextLine.
+ sock nextPutAll:'LIST'; cr.
+ Transcript showCR:sock nextLine.
+ sock close.
+
+ 'dont know enough of the ftp protocol to continue here ...'
+ [exEnd]
example (connect to an snmp server [UDP]):
- [exBegin]
- |sock port|
-
- sock := Socket newUDP.
- port := Socket portOfService:'snmp'.
- sock connectTo:(OperatingSystem getHostName) port:port.
- sock buffered:false.
- Transcript showCR:'got it'.
- sock close.
- [exEnd]
+ [exBegin]
+ |sock port|
+
+ sock := Socket newUDP.
+ port := Socket portOfService:'snmp'.
+ sock connectTo:(OperatingSystem getHostName) port:port.
+ sock buffered:false.
+ Transcript showCR:'got it'.
+ sock close.
+ [exEnd]
example (await connection from a client and read some data):
- [exBegin]
- |connectSock sock|
-
- connectSock := Socket newTCPserverAtPort:9998.
- connectSock isNil ifTrue:[
- Transcript showCR:'socket setup failed.'.
- ] ifFalse:[
- Transcript showCR:'listen ..'.
- (connectSock listenFor:5) ifFalse:[
- Transcript showCR:'listen failed.'.
- ] ifTrue:[
- Transcript showCR:'wait'.
- connectSock readWait.
- Transcript showCR:'accept'.
- sock := connectSock accept.
- sock isNil ifTrue:[
- Transcript showCR:'accept failed.'.
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'server: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'read'.
- Transcript showCR:('got: ' , sock nextLine).
-
- Transcript showCR:'close'.
- sock close
- ].
- connectSock close.
- ]
- ]
- [exEnd]
+ [exBegin]
+ |connectSock sock|
+
+ connectSock := Socket newTCPserverAtPort:9998.
+ connectSock isNil ifTrue:[
+ Transcript showCR:'socket setup failed.'.
+ ] ifFalse:[
+ Transcript showCR:'listen ..'.
+ (connectSock listenFor:5) ifFalse:[
+ Transcript showCR:'listen failed.'.
+ ] ifTrue:[
+ Transcript showCR:'wait'.
+ connectSock readWait.
+ Transcript showCR:'accept'.
+ sock := connectSock accept.
+ sock isNil ifTrue:[
+ Transcript showCR:'accept failed.'.
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'server: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'read'.
+ Transcript showCR:('got: ' , sock nextLine).
+
+ Transcript showCR:'close'.
+ sock close
+ ].
+ connectSock close.
+ ]
+ ]
+ [exEnd]
example (connect to above server and send some data):
- [exBegin]
- |sock|
-
- sock := Socket newTCPclientToHost:(OperatingSystem getHostName) port:9998.
- sock isNil ifTrue:[
- Transcript showCR:'nope'
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'client: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'sending <hello>'.
- sock nextPutLine:'hello'.
- sock close
- ]
- [exEnd]
+ [exBegin]
+ |sock|
+
+ sock := Socket newTCPclientToHost:(OperatingSystem getHostName) port:9998.
+ sock isNil ifTrue:[
+ Transcript showCR:'nope'
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'client: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'sending <hello>'.
+ sock nextPutLine:'hello'.
+ sock close
+ ]
+ [exEnd]
example: UNIX domain socket (await connection from a client and read some data):
- |connectSock sock|
-
- '/tmp/ud_socket' asFilename remove.
- connectSock := Socket newUNIXserverAt:'/tmp/ud_socket'.
- connectSock isNil ifTrue:[
- Transcript showCR:'socket setup failed.'.
- ] ifFalse:[
- Transcript showCR:'listen ..'.
- (connectSock listenFor:5) ifFalse:[
- Transcript showCR:'listen failed.'.
- ] ifTrue:[
- Transcript showCR:'wait'.
- connectSock buffered:false.
- connectSock readWait.
- Transcript showCR:'accept'.
- sock := connectSock accept.
- sock isNil ifTrue:[
- Transcript showCR:'accept failed.'.
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'server: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'read'.
- Transcript showCR:('got: ' , sock nextLine).
-
- Transcript showCR:'close'.
- sock close
- ].
- connectSock close.
- ]
- ]
+ |connectSock sock|
+
+ '/tmp/ud_socket' asFilename remove.
+ connectSock := Socket newUNIXserverAt:'/tmp/ud_socket'.
+ connectSock isNil ifTrue:[
+ Transcript showCR:'socket setup failed.'.
+ ] ifFalse:[
+ Transcript showCR:'listen ..'.
+ (connectSock listenFor:5) ifFalse:[
+ Transcript showCR:'listen failed.'.
+ ] ifTrue:[
+ Transcript showCR:'wait'.
+ connectSock buffered:false.
+ connectSock readWait.
+ Transcript showCR:'accept'.
+ sock := connectSock accept.
+ sock isNil ifTrue:[
+ Transcript showCR:'accept failed.'.
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'server: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'read'.
+ Transcript showCR:('got: ' , sock nextLine).
+
+ Transcript showCR:'close'.
+ sock close
+ ].
+ connectSock close.
+ ]
+ ]
example (connect to above server and send some data;
- Notice, this fails, if above server code is executed in the same ST/X image
- (at least on LINUX), since the OS does not correctly handle
- a connect from within an interrupted accept system call
- On SGI's SVR4, this works ok
- [exBegin]
- |sock|
-
- sock := Socket newUNIXclientTo:'/tmp/ud_socket'.
- sock isNil ifTrue:[
- Transcript showCR:'nope'
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'client: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'sending <hello>'.
- sock nextPutLine:'hello'.
- sock close
- ]
- [exEnd]
+ Notice, this fails, if above server code is executed in the same ST/X image
+ (at least on LINUX), since the OS does not correctly handle
+ a connect from within an interrupted accept system call
+ On SGI's SVR4, this works ok
+ [exBegin]
+ |sock|
+
+ sock := Socket newUNIXclientTo:'/tmp/ud_socket'.
+ sock isNil ifTrue:[
+ Transcript showCR:'nope'
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'client: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'sending <hello>'.
+ sock nextPutLine:'hello'.
+ sock close
+ ]
+ [exEnd]
example (UDP await packet from a client and read some data):
- [exBegin]
- |udpSock sock addr n dataBuffer|
-
- udpSock := Socket newUDPserverAtPort:9999.
- udpSock isNil ifTrue:[
- Transcript showCR:'socket setup failed.'.
- ] ifFalse:[
- Transcript showCR:'wait'.
- udpSock readWait.
-
- addr := IPSocketAddress new.
- dataBuffer := ByteArray new:1000.
- n := udpSock receiveFrom:addr buffer:dataBuffer start:1 for:dataBuffer size.
- n > 0 ifTrue:[
- Transcript showCR:('got: ' , n printString , 'bytes from ' , addr printString).
- Transcript showCR:('data: ' , (dataBuffer copyTo:n) printString).
- ] ifFalse:[
- Transcript showCR:'read failed'.
- ].
-
- Transcript showCR:'close'.
- udpSock close
- ]
- [exEnd]
+ [exBegin]
+ |udpSock sock addr n dataBuffer|
+
+ udpSock := Socket newUDPserverAtPort:9999.
+ udpSock isNil ifTrue:[
+ Transcript showCR:'socket setup failed.'.
+ ] ifFalse:[
+ Transcript showCR:'wait'.
+ udpSock readWait.
+
+ addr := IPSocketAddress new.
+ dataBuffer := ByteArray new:1000.
+ n := udpSock receiveFrom:addr buffer:dataBuffer start:1 for:dataBuffer size.
+ n > 0 ifTrue:[
+ Transcript showCR:('got: ' , n printString , 'bytes from ' , addr printString).
+ Transcript showCR:('data: ' , (dataBuffer copyTo:n) printString).
+ ] ifFalse:[
+ Transcript showCR:'read failed'.
+ ].
+
+ Transcript showCR:'close'.
+ udpSock close
+ ]
+ [exEnd]
example (connect to above UDP server and send some data;
- [exBegin]
- |sock|
-
- sock := Socket newUDP.
- sock isNil ifTrue:[
- Transcript showCR:'nope'
- ] ifFalse:[
- sock sendTo:(IPSocketAddress new hostName:'localhost' port:9999) buffer:'hello world'.
- sock close
- ]
- [exEnd]
+ [exBegin]
+ |sock|
+
+ sock := Socket newUDP.
+ sock isNil ifTrue:[
+ Transcript showCR:'nope'
+ ] ifFalse:[
+ sock sendTo:(IPSocketAddress new hostName:'localhost' port:9999) buffer:'hello world'.
+ sock close
+ ]
+ [exEnd]
example: pingWalk (try to ping hosts on the local network)
- [exBegin]
- |myName myAddress list top hosts walkProcess port|
-
- myName := OperatingSystem getHostName.
- myAddress := Socket ipAddressOfHost:myName.
-
- port := Socket portOfService:'echo'.
- port isNil ifTrue:[
- self error:'dont know echo port'.
- ^ self
- ].
-
- top := StandardSystemView new.
- top label:'PING net walk'.
-
- list := ScrollableView for:ListView in:top.
- list origin:0.0@0.0 corner:1.0@1.0.
-
- top openAndWait.
-
- walkProcess := [
- |l low hi direction tryHostID dottedName hostName conn addr|
-
- l := SortedCollection new.
-
- ' only works with type C-net
- the code below could simply do 1 to:254 do:[:hostID }
- but, to probe likely hosts earlier, the probing is done
- ping-pong like around my ip-address (assuming, that other machines
- have numbers around my own)'.
-
- low := hi := (myAddress at:4).
- direction := 1.
-
- [low > 0 or:[hi < 255]] whileTrue:[
- direction > 0 ifTrue:[
- hi := hi + 1.
- tryHostID := hi.
- direction := -1.
- ] ifFalse:[
- low := low - 1.
- tryHostID := low.
- direction := 1.
- ].
- (tryHostID between:1 and:254) ifTrue:[
- dottedName := (myAddress at:1) printString
- , '.' , (myAddress at:2) printString
- , '.' , (myAddress at:3) printString
- , '.' , tryHostID printString.
-
- top label:'PING net walk - trying ' , dottedName.
-
- top windowGroup withCursor:Cursor wait do:[
- conn := Socket newTCPclientToHost:dottedName port:port withTimeout:1000.
- conn notNil ifTrue:[
- addr := Socket ipAddressOfHost:dottedName.
- hostName := Socket hostWithIpAddress:addr.
- hostName isNil ifTrue:[
- hostName :='?'
- ].
- l add:(dottedName paddedTo:15 with:Character space)
- , ' '
- , (hostName paddedTo:15 with:Character space)
- , ' up & reachable'.
- list list:l.
- conn close.
- ]
- ].
- ].
- ].
- top label:'PING reachable hosts'.
- ] forkAt:(Processor userBackgroundPriority).
- walkProcess name:'ping net walker'.
- [exEnd]
-
-
- This example creates a simple UDP server that accepts
- single packets from anybody and broadcasts them to all
- clients that have connected so far.
-
- [exBegin]
- | socket address buffer msgSize clients |
- clients := Set new.
- address := IPSocketAddress new.
- buffer := String new: 1024.
-
- socket := self newUDPserverAtPort: 6666.
-
- Transcript showCR: 'server starting'.
-
- [
- [true] whileTrue: [
- (socket readWaitWithTimeoutMs: 200) ifFalse: [
- msgSize := socket
- receiveFrom: address
- buffer: buffer
- start: 1
- for: buffer size.
-
- clients add: address copy.
- clients do: [ :clientAddress |
- socket
- sendTo: clientAddress
- buffer: buffer
- start: 1
- for: msgSize]]
- ]
- ] ensure:[
- Transcript showCR: 'server shutting down'.
- socket close
- ]
- [exEnd]
+ [exBegin]
+ |myName myAddress list top hosts walkProcess port|
+
+ myName := OperatingSystem getHostName.
+ myAddress := Socket ipAddressOfHost:myName.
+
+ port := Socket portOfService:'echo'.
+ port isNil ifTrue:[
+ self error:'dont know echo port'.
+ ^ self
+ ].
+
+ top := StandardSystemView new.
+ top label:'PING net walk'.
+
+ list := ScrollableView for:ListView in:top.
+ list origin:0.0@0.0 corner:1.0@1.0.
+
+ top openAndWait.
+
+ walkProcess := [
+ |l low hi direction tryHostID dottedName hostName conn addr|
+
+ l := SortedCollection new.
+
+ ' only works with type C-net
+ the code below could simply do 1 to:254 do:[:hostID }
+ but, to probe likely hosts earlier, the probing is done
+ ping-pong like around my ip-address (assuming, that other machines
+ have numbers around my own)'.
+
+ low := hi := (myAddress at:4).
+ direction := 1.
+
+ [low > 0 or:[hi < 255]] whileTrue:[
+ direction > 0 ifTrue:[
+ hi := hi + 1.
+ tryHostID := hi.
+ direction := -1.
+ ] ifFalse:[
+ low := low - 1.
+ tryHostID := low.
+ direction := 1.
+ ].
+ (tryHostID between:1 and:254) ifTrue:[
+ dottedName := (myAddress at:1) printString
+ , '.' , (myAddress at:2) printString
+ , '.' , (myAddress at:3) printString
+ , '.' , tryHostID printString.
+
+ top label:'PING net walk - trying ' , dottedName.
+
+ top windowGroup withCursor:Cursor wait do:[
+ conn := Socket newTCPclientToHost:dottedName port:port withTimeout:1000.
+ conn notNil ifTrue:[
+ addr := Socket ipAddressOfHost:dottedName.
+ hostName := Socket hostWithIpAddress:addr.
+ hostName isNil ifTrue:[
+ hostName :='?'
+ ].
+ l add:(dottedName paddedTo:15 with:Character space)
+ , ' '
+ , (hostName paddedTo:15 with:Character space)
+ , ' up & reachable'.
+ list list:l.
+ conn close.
+ ]
+ ].
+ ].
+ ].
+ top label:'PING reachable hosts'.
+ ] forkAt:(Processor userBackgroundPriority).
+ walkProcess name:'ping net walker'.
+ [exEnd]
+
+
+ This example creates a simple UDP server that accepts
+ single packets from anybody and broadcasts them to all
+ clients that have connected so far.
+
+ [exBegin]
+ | socket address buffer msgSize clients |
+ clients := Set new.
+ address := IPSocketAddress new.
+ buffer := String new: 1024.
+
+ socket := self newUDPserverAtPort: 6666.
+
+ Transcript showCR: 'server starting'.
+
+ [
+ [true] whileTrue: [
+ (socket readWaitWithTimeoutMs: 200) ifFalse: [
+ msgSize := socket
+ receiveFrom: address
+ buffer: buffer
+ start: 1
+ for: buffer size.
+
+ clients add: address copy.
+ clients do: [ :clientAddress |
+ socket
+ sendTo: clientAddress
+ buffer: buffer
+ start: 1
+ for: msgSize]]
+ ]
+ ] ensure:[
+ Transcript showCR: 'server shutting down'.
+ socket close
+ ]
+ [exEnd]
send a datagram to above server:
- [exBegin]
-
- | socket address buffer host msg |
-
- host := Dialog
- request: 'What is the name of the server''s host?'
- initialAnswer: 'localhost'.
-
- socket := self newUDP.
-
- address := IPSocketAddress hostName: host port: 6666.
-
- buffer := ByteArray new: 1000.
- [
- [(msg := Dialog request: 'Say something') isEmpty] whileFalse:[
- | replySize stream |
-
- socket writeWait.
- stream := buffer writeStream.
- stream nextPutAll: msg.
- socket sendTo:address buffer:buffer start:1 for:stream position.
- socket readWait.
-
- replySize := socket receiveFrom:address buffer:buffer.
- replySize > 0 ifTrue: [
- Transcript cr; nextPutAll: 'Server acknowledged: '.
- Transcript show: ((buffer copyFrom: 1 to: replySize) asString)
- ]
- ]
- ] ensure: [socket close].
- Transcript cr
- [exEnd]
+ [exBegin]
+
+ | socket address buffer host msg |
+
+ host := Dialog
+ request: 'What is the name of the server''s host?'
+ initialAnswer: 'localhost'.
+
+ socket := self newUDP.
+
+ address := IPSocketAddress hostName: host port: 6666.
+
+ buffer := ByteArray new: 1000.
+ [
+ [(msg := Dialog request: 'Say something') isEmpty] whileFalse:[
+ | replySize stream |
+
+ socket writeWait.
+ stream := buffer writeStream.
+ stream nextPutAll: msg.
+ socket sendTo:address buffer:buffer start:1 for:stream position.
+ socket readWait.
+
+ replySize := socket receiveFrom:address buffer:buffer.
+ replySize > 0 ifTrue: [
+ Transcript cr; nextPutAll: 'Server acknowledged: '.
+ Transcript show: ((buffer copyFrom: 1 to: replySize) asString)
+ ]
+ ]
+ ] ensure: [socket close].
+ Transcript cr
+ [exEnd]
loopBack:
- [exBegin]
-
- |readerTask readingSocket writingSocket|
-
- readingSocket := self newTCPserverAtPort:9999.
- readerTask :=
- [
- |connection|
-
- readingSocket listenFor:1.
- connection := readingSocket accept.
- readingSocket close.
- [connection atEnd] whileFalse:[
- Transcript showCR:(connection nextLine).
- ].
- connection close.
- ] fork.
-
- Delay waitForSeconds:1.
- writingSocket := self newTCPclientToHost:(OperatingSystem getHostName) port:9999.
- writingSocket nextPutLine:'Hello'.
- writingSocket nextPutLine:'World'.
- writingSocket close.
- [exEnd]
+ [exBegin]
+
+ |readerTask readingSocket writingSocket|
+
+ readingSocket := self newTCPserverAtPort:9999.
+ readerTask :=
+ [
+ |connection|
+
+ readingSocket listenFor:1.
+ connection := readingSocket accept.
+ readingSocket close.
+ [connection atEnd] whileFalse:[
+ Transcript showCR:(connection nextLine).
+ ].
+ connection close.
+ ] fork.
+
+ Delay waitForSeconds:1.
+ writingSocket := self newTCPclientToHost:(OperatingSystem getHostName) port:9999.
+ writingSocket nextPutLine:'Hello'.
+ writingSocket nextPutLine:'World'.
+ writingSocket close.
+ [exEnd]
"
! !
@@ -2643,50 +2646,50 @@
t = __INST(handle);
if (t != nil) {
- FILE *fp;
- SOCKET sock;
- int fd;
-
- __INST(handle) = nil;
- fp = __FILEVal(t);
- fd = fileno(fp);
- sock = SOCKET_FROM_FD(fd);
+ FILE *fp;
+ SOCKET sock;
+ int fd;
+
+ __INST(handle) = nil;
+ fp = __FILEVal(t);
+ fd = fileno(fp);
+ sock = SOCKET_FROM_FD(fd);
# ifdef DO_WRAP_CALLS
- {
- int ret;
- /*__setWrapCallDebugging(1,1); */
-
- do {
- __threadErrno = 0;
- ret = STX_C_NOINT_CALL1("fclose", fclose, fp);
- } while ((ret < 0) && (__threadErrno == EINTR));
+ {
+ int ret;
+ /*__setWrapCallDebugging(1,1); */
+
+ do {
+ __threadErrno = 0;
+ ret = STX_C_NOINT_CALL1("fclose", fclose, fp);
+ } while ((ret < 0) && (__threadErrno == EINTR));
# if defined(WIN32) && defined(CLOSESOCKET_AFTER_FCLOSE)
- do {
- __threadErrno = 0;
- ret = STX_WSA_NOINT_CALL1("closesocket", closesocket, sock);
- } while ((ret < 0) && (__threadErrno == EINTR));
+ do {
+ __threadErrno = 0;
+ ret = STX_WSA_NOINT_CALL1("closesocket", closesocket, sock);
+ } while ((ret < 0) && (__threadErrno == EINTR));
# endif
- /*__setWrapCallDebugging(1,0);*/
- }
+ /*__setWrapCallDebugging(1,0);*/
+ }
# else /* !DO_WRAP_CALLS */
- DBGFPRINTF((stderr, "SOCKET: fflush %x (%d %d)\n", fp, fileno(fp), sock));
- fflush(fp);
+ 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));
- closesocket(sock);
+ DBGFPRINTF((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 ((@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);
+ DBGFPRINTF((stderr, "SOCKET: closesocket (%d)\n", sock));
+ closesocket(sock);
# endif
# endif /* !DO_WRAP_CALLS */
@@ -2797,22 +2800,22 @@
|serverSocketFd addr addrLen domainClass|
handle notNil ifTrue:[
- ^ self errorAlreadyOpen
+ ^ self errorAlreadyOpen
].
domain := aSocket domain.
socketType := aSocket type.
serverSocketFd := aSocket fileDescriptor.
serverSocketFd isNil ifTrue:[
- ^ self error:'invalid server socket'
+ ^ self error:'invalid server socket'
].
(serverSocketFd isMemberOf:SmallInteger) ifFalse:[
- ^ self error:'invalid server socket'
+ ^ self error:'invalid server socket'
].
domainClass := self class socketAddressClassForDomain:domain.
domainClass isNil ifTrue:[
- ^ self error:'invalid (unsupported) domain'.
+ ^ self error:'invalid (unsupported) domain'.
].
addrLen := domainClass socketAddressSize.
addr := domainClass new.
@@ -2828,30 +2831,30 @@
char dotted[20] ;
if (!__isSmallInteger(addrLen)) {
- DBGPRINTF(("SOCKET: bad addrLen\n"));
- RETURN (false);
+ 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);
+ 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);
+ __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);
+ alen = alen0;
+ newSock = accept(sock, (struct sockaddr *) &sa, &alen);
} while ((newSock < 0) && (errno == EINTR));
__END_INTERRUPTABLE__
# endif
@@ -2859,43 +2862,43 @@
if (blocking == false) {
# if defined(O_NDELAY) && defined(SET_NDELAY)
- fcntl(sock, F_SETFL, flags);
+ fcntl(sock, F_SETFL, flags);
# endif
}
if (newSock < 0) {
- DBGPRINTF(("SOCKET: accept call failed errno=%d\n", errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- RETURN (false);
+ 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);
+ 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);
}
/*
@@ -2903,46 +2906,50 @@
*/
# ifdef WIN32
{
- int _fd;
- __stxWrapApiEnterCritical();
- _fd = _open_osfhandle((long)newSock, 0);
- fp = fdopen(_fd, "r+");
- __stxWrapApiLeaveCritical();
- DBGPRINTF(("SOCKET: sock=%d fd=%d fp=%x\n",newSock,_fd, fp));
+ int _fd;
+ __stxWrapApiEnterCritical();
+# ifdef __BORLANDC__
+ _fd = _open_osfhandle((long)newSock, 0);
+# else
+ _fd = (int)newSock;
+# endif
+ fp = fdopen(_fd, "r+");
+ __stxWrapApiLeaveCritical();
+ 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);
+ 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));
- }
+ {
+ int ret;
+ do {
+ __threadErrno = 0;
+ ret = STX_WSA_CALL1("closesocket", closesocket, newSock);
+ } while ((ret < 0) && (__threadErrno == EINTR));
+ }
# else
- closesocket(newSock);
+ closesocket(newSock);
# endif
- DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock));
- RETURN (false);
+ DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock));
+ RETURN (false);
}
__INST(handleType) = @symbol(socketFilePointer);
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);
- }
+ {
+ 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);
+ console_fprintf(stderr, "fdopen [Socket] -> %x (fd: %d)\n", fp, newSock);
# endif
}
@@ -2960,11 +2967,11 @@
// object.
# endif
{
- OBJ t;
-
- t = __MKEXTERNALADDRESS(fp);
- __INST(handle) = t;
- __STORE(self, t);
+ OBJ t;
+
+ t = __MKEXTERNALADDRESS(fp);
+ __INST(handle) = t;
+ __STORE(self, t);
}
#endif /* not NO_SOCKET */
%}.
@@ -2974,7 +2981,7 @@
port := aSocket port.
addr notNil ifTrue:[
- peer := addr.
+ peer := addr.
].
^ true
@@ -3457,7 +3464,7 @@
|domainName domainCode typeCode error|
handle notNil ifTrue:[
- ^ self errorAlreadyOpen
+ ^ self errorAlreadyOpen
].
domainName := SocketAddress domainCodeFromName:domainArg.
domainCode := OperatingSystem domainCodeOf:domainName.
@@ -3471,19 +3478,19 @@
SOCKET sock;
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);
}
@@ -3496,20 +3503,20 @@
# ifdef SOCKET_BLOCKS
# ifdef DO_WRAP_CALLS
do {
- __threadErrno = 0;
- sock = STX_WSA_NOINT_CALL3("socket", socket, dom, typ, proto);
+ __threadErrno = 0;
+ sock = STX_WSA_NOINT_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);
+ 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);
- }
+ 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__
@@ -3518,9 +3525,9 @@
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);
+ DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
+ proto = 0;
+ sock = socket(dom, typ, 0);
}
# endif
# endif
@@ -3533,94 +3540,98 @@
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);
+ 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"));
- }
- }
+ 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));
- }
+ {
+ 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;
- __stxWrapApiEnterCritical();
- _fd = _open_osfhandle((long)sock, 0);
- fp = fdopen(_fd, "r+");
- __stxWrapApiLeaveCritical();
- DBGPRINTF(("SOCKET: sock=%d fd=%d fp=%x\n",sock,_fd, fp));
- }
-# else
- fp = fdopen(sock, "r+");
+ /*
+ * make it blocking
+ */
+ {
+ int zero = 0;
+
+ ioctlsocket(sock, FIONBIO, &zero);
+ }
# 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_NOINT_CALL1("closesocket", closesocket, sock);
- } while ((ret < 0) && (__threadErrno == EINTR));
- }
+ /*
+ * make it a FILE *
+ */
+# ifdef WIN32
+ {
+ int _fd;
+ __stxWrapApiEnterCritical();
+# ifdef __BORLANDC__
+ _fd = _open_osfhandle((long)sock, 0);
+# else
+ _fd = (int)sock;
+# endif
+ fp = fdopen(_fd, "r+");
+ __stxWrapApiLeaveCritical();
+ DBGPRINTF(("SOCKET: sock=%d fd=%d fp=%x\n",sock,_fd, fp));
+ }
# else
- __BEGIN_INTERRUPTABLE__
- closesocket(sock);
- DBGFPRINTF((stderr, "SOCKET: fdopen failed (%d)\n", sock));
- __END_INTERRUPTABLE__
+ fp = fdopen(sock, "r+");
# endif
- } else {
- __INST(handleType) = @symbol(socketFilePointer);
-
- if ((@global(FileOpenTrace) == true) || __debugging__) {
- console_fprintf(stderr, "fdopen [Socket] -> %x\n", fp);
- }
+ if (! fp) {
+ DBGPRINTF(("SOCKET: fdopen call failed\n"));
+ __INST(lastErrorNumber) = __MKSMALLINT(errno);
+# ifdef DO_WRAP_CALLS
+ { int ret;
+
+ do {
+ __threadErrno = 0;
+ ret = STX_WSA_NOINT_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 {
+ __INST(handleType) = @symbol(socketFilePointer);
+
+ if ((@global(FileOpenTrace) == true) || __debugging__) {
+ console_fprintf(stderr, "fdopen [Socket] -> %x\n", fp);
+ }
# if 0
- // The original code was:
- __INST(handle) = __MKEXTERNALADDRESS(fp); __STORESELF(handle);
- // but for that, gcc generates wrong code, which loads self (volatile) into
- // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp.
- // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old
- // object.
+ // The original code was:
+ __INST(handle) = __MKEXTERNALADDRESS(fp); __STORESELF(handle);
+ // but for that, gcc generates wrong code, which loads self (volatile) into
+ // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp.
+ // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old
+ // object.
# endif
- {
- OBJ t;
-
- t = __MKEXTERNALADDRESS(fp);
- __INST(handle) = t;
- __STORE(self, t);
- }
- }
+ {
+ OBJ t;
+
+ t = __MKEXTERNALADDRESS(fp);
+ __INST(handle) = t;
+ __STORE(self, t);
+ }
+ }
}
#endif
out:;
@@ -3628,14 +3639,14 @@
"all ok?"
handle notNil ifTrue:[
- domain := domainArg.
- socketType := typeArg.
- Lobby register:self.
+ domain := domainArg.
+ socketType := typeArg.
+ Lobby register:self.
] ifFalse:[
- error notNil ifTrue:[
- ^ self primitiveFailed:error.
- ].
- ^ self openError
+ error notNil ifTrue:[
+ ^ self primitiveFailed:error.
+ ].
+ ^ self openError
].
"
@@ -3999,9 +4010,9 @@
!Socket class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.267 2012-05-21 08:11:04 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.268 2012-08-05 16:19:07 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.267 2012-05-21 08:11:04 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.268 2012-08-05 16:19:07 cg Exp $'
! !