diff -r 608e4912b5cf -r 11cbbbcbc87e Socket.st --- a/Socket.st Fri Jun 07 01:11:34 2019 +0200 +++ b/Socket.st Fri Jun 07 01:45:51 2019 +0200 @@ -71,7 +71,7 @@ #endif /* ! __win32__ */ #define SOCKET_FROM_FILE(f) (SOCKET_FROM_FD(fileno(f))) -#define SOCKET_FROM_FILE_OBJECT(f) (__INST(handleType) == @symbol(socketHandle) ? SOCKET_FROM_FD(__FILEVal(f)) : SOCKET_FROM_FILE(__FILEVal(f))) +#define SOCKET_FROM_FILE_OBJECT(f) (__INST(handleType) == @symbol(socketHandle) ? SOCKET_FROM_FD((INT)(__FILEVal(f))) : SOCKET_FROM_FILE(__FILEVal(f))) #ifndef __MINGW__ # include @@ -259,457 +259,457 @@ examples " example (get help info from an nntp server): - [exBegin] - |sock| - - sock := Socket newTCPclientToHost:'smtp.exept.de' port:'smtp'. - sock isNil ifTrue:[ - self warn:'no smtp daemon is running'. - ^ self - ]. - Transcript showCR:sock nextLine. - - sock nextPutAll:'HELO STX socket test'; cr. - Transcript showCR:sock nextLine. - sock close - [exEnd] + [exBegin] + |sock| + + sock := Socket newTCPclientToHost:'smtp.exept.de' port:'smtp'. + sock isNil ifTrue:[ + self warn:'no smtp daemon is running'. + ^ self + ]. + Transcript showCR:sock nextLine. + + sock nextPutAll:'HELO STX socket test'; cr. + Transcript showCR:sock nextLine. + sock close + [exEnd] example (connect to finger daemon, get users entry): - [exBegin] - |sock entry| - - sock := Socket newTCPclientToHost:'localhost' 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 entry| + + sock := Socket newTCPclientToHost:'localhost' 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| - - sock := Socket newTCPclientToHost:'www.exept.de' 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:'HELP'; cr. - [ - |line| - line := sock nextLine. - Transcript showCR:line. - (line at:4) = $- - ] whileTrue. - sock close. - - 'don't know enough of the ftp protocol to continue here ...' - [exEnd] + [exBegin] + |sock| + + sock := Socket newTCPclientToHost:'www.exept.de' 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:'HELP'; cr. + [ + |line| + line := sock nextLine. + Transcript showCR:line. + (line at:4) = $- + ] whileTrue. + sock close. + + 'don't know enough of the ftp protocol to continue here ...' + [exEnd] example (connect to an snmp server [UDP]): Note: this is not a real connection, only the destination address is - being fixed. - [exBegin] - |sock port| - - sock := Socket newUDP. - port := Socket portOfService:'snmp'. - sock connectTo:'224.1.2.3' port:port. - sock buffered:false. - Transcript showCR:'got it'. - sock close. - [exEnd] + being fixed. + [exBegin] + |sock port| + + sock := Socket newUDP. + port := Socket portOfService:'snmp'. + sock connectTo:'224.1.2.3' 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:'localhost' 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 '. - sock nextPutLine:'hello'. - sock close - ] - [exEnd] + [exBegin] + |sock| + + sock := Socket newTCPclientToHost:'localhost' 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 '. + 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 '. - 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 '. + 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 hostName:'127.0.0.1' port:9999) buffer:'hello world'. - sock close - ] - [exEnd] + [exBegin] + |sock| + + sock := Socket newUDP. + sock isNil ifTrue:[ + Transcript showCR:'nope' + ] ifFalse:[ + sock + sendTo:(IPSocketAddress hostName:'127.0.0.1' port:9999) buffer:'hello world'. + sock close + ] + [exEnd] example (UDP await packet from a client and read some multicast data): - [exBegin] - |udpSock sock addr n dataBuffer| - - udpSock := Socket newUDPserverAtPort:9999. - udpSock isNil ifTrue:[ - Transcript showCR:'socket setup failed.'. - ] ifFalse:[ - udpSock setSocketOption:#'IP_ADD_MEMBERSHIP' argument:#[224 1 2 3] argument:#[0 0 0 0]. - 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:[ + udpSock setSocketOption:#'IP_ADD_MEMBERSHIP' argument:#[224 1 2 3] argument:#[0 0 0 0]. + 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 multicast data): - [exBegin] - |sock| - - sock := Socket newUDP. - sock isNil ifTrue:[ - Transcript showCR:'nope' - ] ifFalse:[ - sock - setSocketOption:#'IP_MULTICAST_TTL' argument:3 argument:nil; - sendTo:(IPSocketAddress hostName:'224.1.2.3' port:9999) buffer:'hello world'. - sock close - ] - [exEnd] + [exBegin] + |sock| + + sock := Socket newUDP. + sock isNil ifTrue:[ + Transcript showCR:'nope' + ] ifFalse:[ + sock + setSocketOption:#'IP_MULTICAST_TTL' argument:3 argument:nil; + sendTo:(IPSocketAddress hostName:'224.1.2.3' port:9999) buffer:'hello world'. + sock close + ] + [exEnd] example: pingWalk (try to ping hosts on the local network) Note: it dosen't use ICMP ping, but tries to reache the echo service, - which is disabled on most OS. - [exBegin] - |myAddress list top hosts walkProcess port| - - myAddress := OperatingSystem getNetworkAddresses - keysAndValuesSelect:[:eachIFName :eachAddress| - eachAddress isLocal not - and:[eachIFName = 'wlan0'] - ]. - myAddress := myAddress first hostAddress. - - 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] + which is disabled on most OS. + [exBegin] + |myAddress list top hosts walkProcess port| + + myAddress := OperatingSystem getNetworkAddresses + keysAndValuesSelect:[:eachIFName :eachAddress| + eachAddress isLocal not + and:[eachIFName = 'wlan0'] + ]. + myAddress := myAddress first hostAddress. + + 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:'localhost' 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:'localhost' port:9999. + writingSocket nextPutLine:'Hello'. + writingSocket nextPutLine:'World'. + writingSocket close. + [exEnd] " ! ! @@ -782,14 +782,14 @@ newSock := self newIPv6. (newSock notNil and:[portNrOrServiceName notNil]) ifTrue:[ - [ - socketAddressClass := newSock socketAddressClass. - socketAddress := socketAddressClass hostName:nil serviceName:portNrOrServiceName type:#stream. - socketAddress hostAddress:socketAddressClass anyAddress. - newSock bindTo:socketAddress reuseAddress:true. - ] ifCurtailed:[ - newSock close. - ] + [ + socketAddressClass := newSock socketAddressClass. + socketAddress := socketAddressClass hostName:nil serviceName:portNrOrServiceName type:#stream. + socketAddress hostAddress:socketAddressClass anyAddress. + newSock bindTo:socketAddress reuseAddress:true. + ] ifCurtailed:[ + newSock close. + ] ]. ^ newSock @@ -798,13 +798,13 @@ (Socket newIPv6:9996). test (eval the code below, then open a browser on (replace by your own IPv6 address) - http://[2003:a:e4d:bb01:a17f:9312:54cb:fed7]:9997/ - - (Socket newIPv6:9997) - listenFor:1; - readWait; - accept. - + http://[2003:a:e4d:bb01:a17f:9312:54cb:fed7]:9997/ + + (Socket newIPv6:9997) + listenFor:1; + readWait; + accept. + " "Created: / 27-05-2019 / 14:06:49 / Claus Gittinger" @@ -829,21 +829,21 @@ newSock := self newTCP. (newSock notNil and:[portNrOrServiceName notNil]) ifTrue:[ - [ - socketAddressClass := newSock socketAddressClass. - socketAddress := socketAddressClass hostName:nil serviceName:portNrOrServiceName type:#stream. - socketAddress hostAddress:socketAddressClass anyAddress. - newSock bindTo:socketAddress reuseAddress:true. - ] ifCurtailed:[ - newSock close. - ] + [ + socketAddressClass := newSock socketAddressClass. + socketAddress := socketAddressClass hostName:nil serviceName:portNrOrServiceName type:#stream. + socketAddress hostAddress:socketAddressClass anyAddress. + newSock bindTo:socketAddress reuseAddress:true. + ] ifCurtailed:[ + newSock close. + ] ]. ^ newSock " - Socket newTCP:'http-alt'. - Socket newTCP:9996. + Socket newTCP:'http-alt'. + Socket newTCP:9996. " "Modified (comment): / 17-05-2019 / 13:10:18 / Claus Gittinger" @@ -868,18 +868,18 @@ |port socketAddress| aService isString ifTrue:[ - port := self portOfService:aService protocol:#tcp. + port := self portOfService:aService protocol:#tcp. ] ifFalse:[ - port := aService. + port := aService. ]. socketAddress := aSocketAddressOrByteArray isSocketAddress - ifTrue:[aSocketAddressOrByteArray] - ifFalse:[ - "Passing ByteArrays is obsolete and only supported for IPv4" - IPSocketAddress hostAddress:aSocketAddressOrByteArray - ]. + ifTrue:[aSocketAddressOrByteArray] + ifFalse:[ + "Passing ByteArrays is obsolete and only supported for IPv4" + IPSocketAddress hostAddress:aSocketAddressOrByteArray + ]. port notNil ifTrue:[ - socketAddress port:port. + socketAddress port:port. ]. ^ self newTCPclientToAddress:socketAddress withTimeout:milliSecondsOrTimeDuration @@ -896,14 +896,14 @@ socket := self domain:aSocketAddress domain type:#stream. ^ [ - (socket connectTo:aSocketAddress withTimeout:milliSecondsOrTimeDuration) - ifTrue:[socket] ifFalse:[socket close. nil] + (socket connectTo:aSocketAddress withTimeout:milliSecondsOrTimeDuration) + ifTrue:[socket] ifFalse:[socket close. nil] ] ifCurtailed:[ - socket close. + socket close. ]. " - self newTCPclientToAddress:(IPv6SocketAddress hostName:'www.exept.de' port:80) withTimeout:nil + self newTCPclientToAddress:(IPv6SocketAddress hostName:'www.exept.de' port:80) withTimeout:nil " "Modified (format): / 19-01-2018 / 18:22:30 / stefan" @@ -943,40 +943,40 @@ |socket addressList lastDomainSymbol lastNotification| hostNameOrAddress isString ifFalse:[ - ^ self newTCPclientToAddress:hostNameOrAddress port:aPortOrServiceName withTimeout:milliSecondsOrTimeDuration. + ^ self newTCPclientToAddress:hostNameOrAddress port:aPortOrServiceName withTimeout:milliSecondsOrTimeDuration. ]. addressList := SocketAddress - allForHostName:hostNameOrAddress - serviceName:aPortOrServiceName - domain:aDomainSymbolOrNil - type:#stream. + allForHostName:hostNameOrAddress + serviceName:aPortOrServiceName + domain:aDomainSymbolOrNil + type:#stream. addressList do:[:eachAddress| - |domainSymbol| - - domainSymbol := eachAddress domain. - domainSymbol ~~ lastDomainSymbol ifTrue:[ - socket notNil ifTrue:[ - socket close. - ]. - socket := self new domain:domainSymbol type:#stream. - lastDomainSymbol := domainSymbol. - ]. - [ - (socket connectTo:eachAddress withTimeout:milliSecondsOrTimeDuration) ifTrue:[ - ^ socket. - ]. - ] on:SocketErrorNotification do:[:ex| - lastNotification := ex. - ]. + |domainSymbol| + + domainSymbol := eachAddress domain. + domainSymbol ~~ lastDomainSymbol ifTrue:[ + socket notNil ifTrue:[ + socket close. + ]. + socket := self new domain:domainSymbol type:#stream. + lastDomainSymbol := domainSymbol. + ]. + [ + (socket connectTo:eachAddress withTimeout:milliSecondsOrTimeDuration) ifTrue:[ + ^ socket. + ]. + ] on:SocketErrorNotification do:[:ex| + lastNotification := ex. + ]. ]. socket notNil ifTrue:[ - socket close. + socket close. ]. lastNotification notNil ifTrue:[ - "if someone is interested in the notification - raise the last one" - lastNotification raiseRequest. + "if someone is interested in the notification - raise the last one" + lastNotification raiseRequest. ]. ^ nil. @@ -986,10 +986,10 @@ Socket newTCPclientToHost:'www.exept.de' port:80 domain:nil withTimeout:1000. [ - "if nobody is listening (Connection refused") the timeout does not apply" - Socket newTCPclientToHost:'localhost' port:'nntp' withTimeout:10s + "if nobody is listening (Connection refused") the timeout does not apply" + Socket newTCPclientToHost:'localhost' port:'nntp' withTimeout:10s ] on:SocketErrorNotification do:[:ex| - ex halt. + ex halt. ]. EOC" @@ -1006,10 +1006,10 @@ and return nil." ^ self - newTCPclientToHost:hostNameOrAddress - port:aPortOrServiceName - domain:self defaultIpDomainForConnect - withTimeout:milliSecondsOrTimeDuration + newTCPclientToHost:hostNameOrAddress + port:aPortOrServiceName + domain:self defaultIpDomainForConnect + withTimeout:milliSecondsOrTimeDuration "Modified (format): / 19-01-2018 / 18:24:57 / stefan" ! @@ -1108,23 +1108,23 @@ socket := self newUNIX. socket isNil ifTrue:[ - ^ nil. + ^ nil. ]. ^ [ - (socket connectTo:(UDSocketAddress name:pathName) withTimeout:milliSecondsOrTimeDuration) - ifTrue:[socket] ifFalse:[socket close. nil] + (socket connectTo:(UDSocketAddress name:pathName) withTimeout:milliSecondsOrTimeDuration) + ifTrue:[socket] ifFalse:[socket close. nil] ] ifCurtailed:[ - socket close. + socket close. ]. " - Socket newUNIXclientTo:'/tmp/foo' - - [ - Socket newUNIXclientTo:'/tmp/foo' - ] on:SocketErrorNotification do:[:ex| - ex halt. - ] + Socket newUNIXclientTo:'/tmp/foo' + + [ + Socket newUNIXclientTo:'/tmp/foo' + ] on:SocketErrorNotification do:[:ex| + ex halt. + ] " "Modified (format): / 19-01-2018 / 18:23:24 / stefan" @@ -1755,7 +1755,7 @@ noTimeout "disable timeouts - dummy for now" - ^ self + ^ self ! peerName @@ -1806,8 +1806,8 @@ newSock := self class new. (newSock primAcceptOn:self blocking:true) ifFalse:[ - "should raise an error here - primitive code raises a notification" - ^ nil + "should raise an error here - primitive code raises a notification" + ^ nil ]. ^ newSock @@ -1859,15 +1859,15 @@ Notify with a SocketErrorNotification on error. The interpretation of hostOrPathNameOrSocketAddrOrNil portNrOrName depends on the domain: - Best use a SocketAddress - For backward compatibility: - AF_INET domain can also use (4byte) byteArray like internet numbers, - AF_UNIX domain cab use pathname strings." + Best use a SocketAddress + For backward compatibility: + AF_INET domain can also use (4byte) byteArray like internet numbers, + AF_UNIX domain cab use pathname strings." ^ self - bindTo:portNrOrNameString - address:addressString - reuseAddress:true + bindTo:portNrOrNameString + address:addressString + reuseAddress:true "Modified (comment): / 19-01-2018 / 13:36:54 / stefan" ! @@ -1878,10 +1878,10 @@ - returns true if ok, false otherwise. The interpretation of hostOrPathNameOrSocketAddrOrNil portNrOrName depends on the domain: - Best use a SocketAddress - For backward compatibility: - AF_INET domain can also use (4byte) byteArray like internet numbers, - AF_UNIX domain can use pathname strings. + Best use a SocketAddress + For backward compatibility: + AF_INET domain can also use (4byte) byteArray like internet numbers, + AF_UNIX domain can use pathname strings. The reuse boolean argument controls if the SO_REUSEADDR socket option is to be set (to avoid the 'bind: address in use' error). @@ -1890,35 +1890,35 @@ |socketAddress| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. hostOrPathNameOrSocketAddrOrNil isNil ifTrue:[ - socketAddress := self socketAddressClass anyHost. + socketAddress := self socketAddressClass anyHost. ] ifFalse:[ - (hostOrPathNameOrSocketAddrOrNil isSocketAddress) ifTrue:[ - socketAddress := hostOrPathNameOrSocketAddrOrNil. - ] ifFalse:[ - "backward compatibility: support for byteArray and string arg" - hostOrPathNameOrSocketAddrOrNil isString ifTrue:[ - socketAddress := self socketAddressClass hostName:hostOrPathNameOrSocketAddrOrNil. - ] ifFalse:[ - hostOrPathNameOrSocketAddrOrNil isByteCollection ifFalse:[ - ^ self error:'bindTo: bad host (socketAddress) argument' - ]. - socketAddress := self socketAddressClass hostAddress:hostOrPathNameOrSocketAddrOrNil. - ]. - ]. + (hostOrPathNameOrSocketAddrOrNil isSocketAddress) ifTrue:[ + socketAddress := hostOrPathNameOrSocketAddrOrNil. + ] ifFalse:[ + "backward compatibility: support for byteArray and string arg" + hostOrPathNameOrSocketAddrOrNil isString ifTrue:[ + socketAddress := self socketAddressClass hostName:hostOrPathNameOrSocketAddrOrNil. + ] ifFalse:[ + hostOrPathNameOrSocketAddrOrNil isByteCollection ifFalse:[ + ^ self error:'bindTo: bad host (socketAddress) argument' + ]. + socketAddress := self socketAddressClass hostAddress:hostOrPathNameOrSocketAddrOrNil. + ]. + ]. ]. portNrOrNameOrNil notNil ifTrue:[ - socketAddress port:portNrOrNameOrNil. + socketAddress port:portNrOrNameOrNil. ]. ^ self bindTo:socketAddress reuseAddress:reuse. " (Socket domain:#'AF_INET' type:#stream) - bindTo:2144 address:nil; yourself + bindTo:2144 address:nil; yourself " "Modified (comment): / 19-01-2018 / 13:37:13 / stefan" @@ -1936,17 +1936,17 @@ |ok error socketAddress| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. socketAddress := aSocketAddress. socketAddress isNil ifTrue:[ - "ok, get an all zero socket address, so it is for anyHost - and the port will be assigned" - socketAddress := self socketAddressClass new. + "ok, get an all zero socket address, so it is for anyHost + and the port will be assigned" + socketAddress := self socketAddressClass new. ]. domain == #'AF_INET6' ifTrue:[ - "accept also IPv4 connections on IPv6 sockets (this is off by default for windows" - self setSocketOption:#'IPV6_V6ONLY' argument:false argument:nil. + "accept also IPv4 connections on IPv6 sockets (this is off by default for windows" + self setSocketOption:#'IPV6_V6ONLY' argument:false argument:nil. ]. ok := false. @@ -1960,52 +1960,52 @@ int sockAddrOffs; if (fp == nil) { - goto getOutOfHere; + goto getOutOfHere; } if (! __isBytes(socketAddress)) { - error = __mkSmallInteger(-1); - goto getOutOfHere; + error = __mkSmallInteger(-1); + goto getOutOfHere; } /* get the socket-address */ if (__isNonNilObject(socketAddress)){ - int nIndex; - OBJ cls = __qClass(socketAddress); - - sockAddrOffs = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); - nIndex = __qSize(socketAddress) - OHDR_SIZE; - sockaddr_size = nIndex - sockAddrOffs; - if (sockaddr_size > sizeof(sa)) { - error=__mkSmallInteger(-2); - goto getOutOfHere; - } - memcpy(&sa, __byteArrayVal(socketAddress) + sockAddrOffs, sockaddr_size); + int nIndex; + OBJ cls = __qClass(socketAddress); + + sockAddrOffs = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); + nIndex = __qSize(socketAddress) - OHDR_SIZE; + sockaddr_size = nIndex - sockAddrOffs; + if (sockaddr_size > sizeof(sa)) { + error=__mkSmallInteger(-2); + goto getOutOfHere; + } + memcpy(&sa, __byteArrayVal(socketAddress) + sockAddrOffs, sockaddr_size); } sock = SOCKET_FROM_FILE_OBJECT(fp); # ifdef SO_REUSEADDR if (reuse == true) { - int on = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) { - DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n")); - } + int on = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) { + DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n")); + } } # endif /* SO_REUSEADDR */ # ifdef BIND_BLOCKS # ifdef DO_WRAP_CALLS do { - __threadErrno = 0; - ret = STX_WSA_NOINT_CALL3("bind", bind, sock, &sa, sockaddr_size); + __threadErrno = 0; + ret = STX_WSA_NOINT_CALL3("bind", bind, sock, &sa, sockaddr_size); } while ((ret < 0) && (__threadErrno == EINTR)); if (ret < 0) { - errno = __threadErrno; + errno = __threadErrno; } # else __BEGIN_INTERRUPTABLE__ do { - ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size); + ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size); } while ((ret < 0) && (errno == EINTR)); __END_INTERRUPTABLE__ # endif @@ -2015,68 +2015,68 @@ # endif if (ret < 0) { # ifdef __win32__ - if (errno == 0) { - errno = WSAGetLastError(); - } + if (errno == 0) { + errno = WSAGetLastError(); + } # endif - DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno)); - error = __INST(lastErrorNumber) = __MKSMALLINT(errno); - goto getOutOfHere; + DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno)); + error = __INST(lastErrorNumber) = __MKSMALLINT(errno); + goto getOutOfHere; } else { - ok = true; + ok = true; } #endif /* NO_SOCKET */ getOutOfHere: ; %}. ok ifFalse:[ - |errorHolder errorString| - - error isInteger ifTrue:[ - errorHolder := OperatingSystem errorHolderForNumber:error. - errorString := errorHolder errorString. - ] ifFalse:[ - errorString := error. - ]. - OpenError newException - errorString:('cannot bind socket to address: %1 (%2)' - bindWith:socketAddress - with:errorString); - errorCode:error; - osErrorHolder:errorHolder; - parameter:self; - raiseRequest. - "maybe someone catches the error and binds to some other port..." - ^ true. + |errorHolder errorString| + + error isInteger ifTrue:[ + errorHolder := OperatingSystem errorHolderForNumber:error. + errorString := errorHolder errorString. + ] ifFalse:[ + errorString := error. + ]. + OpenError newException + errorString:('cannot bind socket to address: %1 (%2)' + bindWith:socketAddress + with:errorString); + errorCode:error; + osErrorHolder:errorHolder; + parameter:self; + raiseRequest. + "maybe someone catches the error and binds to some other port..." + ^ true. ]. port := socketAddress port. port == 0 ifTrue:[ - "this is a bind to a random port, now we can get the real port" - port := self getFullSocketAddress port. + "this is a bind to a random port, now we can get the real port" + port := self getFullSocketAddress port. ]. ^ true " (Socket domain:#'AF_INET' type:#stream) - bindTo:(IPSocketAddress anyHost port:445) reuseAddress:false; - yourself. + bindTo:(IPSocketAddress anyHost port:445) reuseAddress:false; + yourself. (Socket domain:#'AF_INET' type:#stream) - bindTo:139 reuseAddress:false; - yourself. + bindTo:139 reuseAddress:false; + yourself. (Socket domain:#'AF_INET6' type:#stream) - bindTo:nil reuseAddress:false; - yourself. + bindTo:nil reuseAddress:false; + yourself. (Socket domain:#'AF_INET' type:#stream) - bindTo:(IPSocketAddress localHost port:2122) reuseAddress:false; - yourself. + bindTo:(IPSocketAddress localHost port:2122) reuseAddress:false; + yourself. (Socket domain:#'AF_UNIX' type:#stream) - bindTo:nil reuseAddress:false; - yourself. + bindTo:nil reuseAddress:false; + yourself. " "Modified: / 19-01-2018 / 13:37:21 / stefan" @@ -2091,7 +2091,7 @@ |err| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. %{ #ifndef NO_SOCKET @@ -2100,9 +2100,9 @@ int ret; if (! __isSmallInteger(aNumber)) { - DBGPRINTF(("SOCKET: invalid arg\n")); - err = @symbol(badArgument); - goto out; + DBGPRINTF(("SOCKET: invalid arg\n")); + err = @symbol(badArgument); + goto out; } sock = SOCKET_FROM_FILE_OBJECT(fp); @@ -2110,16 +2110,16 @@ #ifdef LISTEN_BLOCKS # ifdef DO_WRAP_CALLS do { - __threadErrno = 0; - ret = STX_WSA_NOINT_CALL2("listen", listen, sock, __intVal(aNumber)); + __threadErrno = 0; + ret = STX_WSA_NOINT_CALL2("listen", listen, sock, __intVal(aNumber)); } while ((ret < 0) && (__threadErrno == EINTR)); if (ret < 0) { - errno = __threadErrno; + errno = __threadErrno; } # else __BEGIN_INTERRUPTABLE__ do { - ret = listen(sock, __intVal(aNumber)); + ret = listen(sock, __intVal(aNumber)); } while ((ret < 0) && (errno == EINTR)); __END_INTERRUPTABLE__ # endif @@ -2130,13 +2130,13 @@ if (ret < 0) { # ifdef __win32__ - if (errno == 0) { - errno = WSAGetLastError(); - } + if (errno == 0) { + errno = WSAGetLastError(); + } # endif - err = __MKSMALLINT(errno); - DBGPRINTF(("SOCKET: listen call failed errno=%d\n", errno)); - goto out; + err = __MKSMALLINT(errno); + DBGPRINTF(("SOCKET: listen call failed errno=%d\n", errno)); + goto out; } #else RETURN (false); @@ -2144,10 +2144,10 @@ out:; %}. err notNil ifTrue:[ - err isSymbol ifTrue:[ - self error:err. - ]. - ^ self reportError:err. + err isSymbol ifTrue:[ + self error:err. + ]. + ^ self reportError:err. ]. listening := aNumber. @@ -2155,12 +2155,12 @@ " [ - |sock| - sock := Socket newTCP. - sock listenFor:1. - sock + |sock| + sock := Socket newTCP. + sock listenFor:1. + sock ] on:SocketErrorNotification do:[:ex| - ex halt. + ex halt. ]. " @@ -2242,26 +2242,26 @@ |domainClass socketAddress| (hostOrPathNameOrSocketAddr isSocketAddress) ifTrue:[ - socketAddress := hostOrPathNameOrSocketAddr. - portNrOrNameOrNil notNil ifTrue:[ - socketAddress port:portNrOrNameOrNil. - ]. + socketAddress := hostOrPathNameOrSocketAddr. + portNrOrNameOrNil notNil ifTrue:[ + socketAddress port:portNrOrNameOrNil. + ]. ] ifFalse:[ - "backward compatibility: support for byteArray and string arg" - domainClass := self class socketAddressClassForDomain:domain. - domainClass isNil ifTrue:[ - ^ self error:'invalid (unsupported) domain'. - ]. - - hostOrPathNameOrSocketAddr isString ifTrue:[ - socketAddress := domainClass hostName:hostOrPathNameOrSocketAddr serviceName:portNrOrNameOrNil type:#SOCK_STREAM. - peerName := hostOrPathNameOrSocketAddr. - ] ifFalse:[ - hostOrPathNameOrSocketAddr isByteCollection ifFalse:[ - ^ self error:'connectTo: bad host (socketAddress) argument' - ]. - socketAddress := domainClass hostAddress:hostOrPathNameOrSocketAddr port:portNrOrNameOrNil. - ]. + "backward compatibility: support for byteArray and string arg" + domainClass := self class socketAddressClassForDomain:domain. + domainClass isNil ifTrue:[ + ^ self error:'invalid (unsupported) domain'. + ]. + + hostOrPathNameOrSocketAddr isString ifTrue:[ + socketAddress := domainClass hostName:hostOrPathNameOrSocketAddr serviceName:portNrOrNameOrNil type:#SOCK_STREAM. + peerName := hostOrPathNameOrSocketAddr. + ] ifFalse:[ + hostOrPathNameOrSocketAddr isByteCollection ifFalse:[ + ^ self error:'connectTo: bad host (socketAddress) argument' + ]. + socketAddress := domainClass hostAddress:hostOrPathNameOrSocketAddr port:portNrOrNameOrNil. + ]. ]. ^ self connectTo:socketAddress withTimeout:milliSecondsOrTimeDuration. @@ -2293,7 +2293,7 @@ |isAsync err timeoutMs milliSeconds| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. isAsync := false. @@ -2314,25 +2314,25 @@ int sockaddr_size; if (!__isNonNilObject(aSocketAddress) || !__isBytes(aSocketAddress)) { - DBGPRINTF(("SOCKET: invalid socketAddress\n")); - err = @symbol(argumentError); - goto out; + DBGPRINTF(("SOCKET: invalid socketAddress\n")); + err = @symbol(argumentError); + goto out; } { - int sockAddrOffs = 0; - int nIndex =__byteArraySize(aSocketAddress); - OBJ cls = __qClass(aSocketAddress); - - //if (cls != @global(ByteArray)) - // sockAddrOffs = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); - sockaddr_size = nIndex - sockAddrOffs; - if (sockaddr_size > sizeof(sa)) { - DBGPRINTF(("SOCKET: invalid (short) socketAddress\n")); - err = @symbol(argumentError); - goto out; - } - memcpy(&sa, __byteArrayVal(aSocketAddress) + sockAddrOffs, sockaddr_size); + int sockAddrOffs = 0; + int nIndex =__byteArraySize(aSocketAddress); + OBJ cls = __qClass(aSocketAddress); + + //if (cls != @global(ByteArray)) + // sockAddrOffs = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); + sockaddr_size = nIndex - sockAddrOffs; + if (sockaddr_size > sizeof(sa)) { + DBGPRINTF(("SOCKET: invalid (short) socketAddress\n")); + err = @symbol(argumentError); + goto out; + } + memcpy(&sa, __byteArrayVal(aSocketAddress) + sockAddrOffs, sockaddr_size); } sock = SOCKET_FROM_FILE_OBJECT(fp); @@ -2359,18 +2359,18 @@ do { - DBGFPRINTF((stderr, "SOCKET: (sock=%d) connect...\n", sock)); - ret = STX_WSA_NOINT_CALL3("connect", connect, sock, &sa, (INT)sockaddr_size); - DBGFPRINTF((stderr, "SOCKET: connect(%d) -> %"_ld_" (%d)\n", sock, (INT)ret, __threadErrno)); + DBGFPRINTF((stderr, "SOCKET: (sock=%d) connect...\n", sock)); + ret = STX_WSA_NOINT_CALL3("connect", connect, sock, &sa, (INT)sockaddr_size); + DBGFPRINTF((stderr, "SOCKET: connect(%d) -> %"_ld_" (%d)\n", sock, (INT)ret, __threadErrno)); } while ((ret < 0) && (__threadErrno == EINTR)); if (ret < 0) { - int optLen = sizeof(errno); - errno = __threadErrno; + int optLen = sizeof(errno); + errno = __threadErrno; #if 0 - if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &errno, &optLen) == SOCKET_ERROR) { - DBGFPRINTF((stderr, "SOCKET: getsockopt(SO_ERROR) failed: %d\n", WSAGetLastError())); - } + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &errno, &optLen) == SOCKET_ERROR) { + DBGFPRINTF((stderr, "SOCKET: getsockopt(SO_ERROR) failed: %d\n", WSAGetLastError())); + } #endif // 0 } @@ -2381,16 +2381,16 @@ __BEGIN_INTERRUPTABLE__ # endif do { - ret = connect(sock, (struct sockaddr *)&sa, sockaddr_size); + ret = connect(sock, (struct sockaddr *)&sa, sockaddr_size); } while ((ret < 0) # ifdef __win32__ - && (errno = WSAGetLastError()) + && (errno = WSAGetLastError()) # endif - && ((errno == EINTR) + && ((errno == EINTR) # ifdef EAGAIN - || (errno == EAGAIN) + || (errno == EAGAIN) # endif - )); + )); # if !defined(__win32__) && !defined(O_NONBLOCK) __END_INTERRUPTABLE__ # endif @@ -2403,47 +2403,47 @@ if (ret < 0) { # if defined(EINPROGRESS) || defined(EALREADY) - if (0 + if (0 # ifdef __win32__ - || (errno == WSAEWOULDBLOCK) + || (errno == WSAEWOULDBLOCK) # endif # ifdef EINPROGRESS - || (errno == EINPROGRESS) + || (errno == EINPROGRESS) # endif # ifdef EALREADY - || (errno == 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 + ) { + /* + * 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=%"_ld_" errno=%d __threadErrno=%d\n", - (INT)ret, errno, __threadErrno )); + { + DBGFPRINTF((stderr, "SOCKET: connect failed ret=%"_ld_" errno=%d __threadErrno=%d\n", + (INT)ret, errno, __threadErrno )); # ifdef DUMP_ADDRESS - { - unsigned char *cp = (unsigned char *)(&sa); - int i; - - console_printf("address data:\n"); - for (i=0; i 0) { - memcpy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, n); - } - free(allocatedBuffer); - } + if (extPtr) { + buffer = extPtr + offs; + } else { + allocatedBuffer = buffer = (char *)malloc(objSize); + } + + do { + __threadErrno = 0; + n = (INT)STX_WSA_NOINT_CALL4("recv", recv, sock, buffer, objSize, flags); + } while ((n < 0) && (__threadErrno == EINTR)); + if (n < 0) { + errno = __threadErrno; + } + + if (allocatedBuffer) { + if (n > 0) { + memcpy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, 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__ + __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) { - error = __INST(lastErrorNumber) = __MKSMALLINT(errno); - } else { - RETURN(__MKSMALLINT(n)); - } + if (n < 0) { + error = __INST(lastErrorNumber) = __MKSMALLINT(errno); + } else { + RETURN(__MKSMALLINT(n)); + } } #endif bad: ; %}. error notNil ifTrue:[ - ^ self readError:error. + ^ self readError:error. ]. " arrive here if you try to receive into an invalid buffer (i.e. not ByteArray-like) @@ -2632,17 +2632,17 @@ domainClass := self class socketAddressClassForDomain:domain. domainClass isNil ifTrue:[ - ^ self error:'invalid (unsupported) domain'. + ^ self error:'invalid (unsupported) domain'. ]. aSocketAddress isSocketAddress ifTrue:[ - aSocketAddress class == domainClass ifFalse:[ - ^ self error:'addressBuffer class mismatch (domain)'. - ]. - addr := aSocketAddress. + aSocketAddress class == domainClass ifFalse:[ + ^ self error:'addressBuffer class mismatch (domain)'. + ]. + addr := aSocketAddress. ] ifFalse:[ - aSocketAddress notNil ifTrue:[ - addr := domainClass new. - ]. + aSocketAddress notNil ifTrue:[ + addr := domainClass new. + ]. ]. %{ @@ -2650,103 +2650,103 @@ OBJ fp = __INST(handle); if (fp != nil) { - SOCKET sock; - size_t objSize; - union sockaddr_u sa; - socklen_t alen = 0; - INT n, offs; - int _flags = __longIntVal(flags); - char *extPtr; - unsigned char *allocatedBuffer = NULL, *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); - } - } + SOCKET sock; + size_t objSize; + union sockaddr_u sa; + socklen_t alen = 0; + INT n, offs; + int _flags = __longIntVal(flags); + char *extPtr; + unsigned char *allocatedBuffer = NULL, *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 = (INT)STX_WSA_NOINT_CALL6("recvfrom", recvfrom, sock, buffer, objSize, _flags, (struct sockaddr *)&sa, &alen); - } while ((n < 0) && (__threadErrno == EINTR)); - if (n < 0) { - errno = __threadErrno; - } - - if (allocatedBuffer) { - if (n > 0) { - memcpy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, n); - } - free(allocatedBuffer); - } + if (extPtr) { + buffer = extPtr + offs; + } else { + allocatedBuffer = buffer = (char *)malloc(objSize); + } + + do { + __threadErrno = 0; + alen = sizeof(sa); + n = (INT)STX_WSA_NOINT_CALL6("recvfrom", recvfrom, sock, buffer, objSize, _flags, (struct sockaddr *)&sa, &alen); + } while ((n < 0) && (__threadErrno == EINTR)); + if (n < 0) { + errno = __threadErrno; + } + + if (allocatedBuffer) { + if (n > 0) { + memcpy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, 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__ + __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 - */ - memcpy(addrPtr, (char *)&sa, alen); - addrLen = __MKSMALLINT(alen); - } - } - if (n < 0) { - error = __INST(lastErrorNumber) = __MKSMALLINT(errno); - } - nReceived = __MKSMALLINT(n); + 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 + */ + memcpy(addrPtr, (char *)&sa, alen); + addrLen = __MKSMALLINT(alen); + } + } + if (n < 0) { + error = __INST(lastErrorNumber) = __MKSMALLINT(errno); + } + nReceived = __MKSMALLINT(n); } #endif bad: ; %}. error notNil ifTrue:[ - ^ self readError:error. + ^ self readError:error. ]. nReceived notNil ifTrue:[ - addrLen notNil ifTrue:[ - (addr == aSocketAddress) ifFalse:[ - self obsoleteFeatureWarning:'please use a socketAddress argument'. - - "can be a ByteArray for backward compatibility" - aSocketAddress replaceFrom:1 to:addrLen with:(addr hostAddress). - ]. - ]. - ^ nReceived + addrLen notNil ifTrue:[ + (addr == aSocketAddress) ifFalse:[ + self obsoleteFeatureWarning:'please use a socketAddress argument'. + + "can be a ByteArray for backward compatibility" + aSocketAddress replaceFrom:1 to:addrLen with:(addr hostAddress). + ]. + ]. + ^ nReceived ]. " arrive here if you try to receive into an invalid buffer @@ -2772,68 +2772,68 @@ if ((fp != nil) && __isSmallInteger(startIndex) && __isSmallInteger(nBytes)) { - SOCKET sock; - INT objSize, n, offs; - char *extPtr; - int _flags = __longIntVal(flags); - unsigned long norder; - unsigned char *buffer, *allocatedBuffer = 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); - } - } + SOCKET sock; + INT objSize, n, offs; + char *extPtr; + int _flags = __longIntVal(flags); + unsigned long norder; + unsigned char *buffer, *allocatedBuffer = 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 DGRAM_DEBUG - console_printf("sending %d bytes ...\n", nBytes); + console_printf("sending %d bytes ...\n", nBytes); # endif #ifdef DO_WRAP_CALLS - if (extPtr) { - buffer = extPtr + offs; - } else { - allocatedBuffer = buffer = (char *)malloc(objSize); - memcpy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, objSize); - } - - do { - __threadErrno = 0; - n = (INT)STX_WSA_NOINT_CALL4("send", send, sock, buffer, objSize, _flags); - } while ((n < 0) && (__threadErrno == EINTR)); - if (n < 0) { - errno = __threadErrno; - } - - if (allocatedBuffer) { - free(allocatedBuffer); - } + if (extPtr) { + buffer = extPtr + offs; + } else { + allocatedBuffer = buffer = (char *)malloc(objSize); + memcpy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, objSize); + } + + do { + __threadErrno = 0; + n = (INT)STX_WSA_NOINT_CALL4("send", send, sock, buffer, objSize, _flags); + } while ((n < 0) && (__threadErrno == EINTR)); + if (n < 0) { + errno = __threadErrno; + } + + 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__ + __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) { - error = __INST(lastErrorNumber) = __MKSMALLINT(errno); - } else { - RETURN (__MKSMALLINT(n)); - } + if (n < 0) { + error = __INST(lastErrorNumber) = __MKSMALLINT(errno); + } else { + RETURN (__MKSMALLINT(n)); + } } #endif bad: ; %}. error notNil ifTrue:[ - self writeError:error. + self writeError:error. ]. " @@ -2847,8 +2847,8 @@ sendTo:aSocketAddress buffer:buffer "send datagramm data - fetch address of destination host from aSocketAddress, data from aDataBuffer. - aDataBuffer must be ByteArray-like. - aSocketAddress must be a valid SocketAddress for my domain + aDataBuffer must be ByteArray-like. + aSocketAddress must be a valid SocketAddress for my domain (i.e. for IPv4, an IPSocketAddress). For backward compatibility, a ByteArray is still supported in aSocketAddress (i.e. for IPv4, a 4-byte byteArray). @@ -2862,8 +2862,8 @@ sendTo:aSocketAddress buffer:buffer start:startIndex for:count "send datagramm data - fetch address of destination host from aSocketAddress, data from aDataBuffer. - aDataBuffer must be ByteArray-like. - aSocketAddress must be a valid SocketAddress for my domain + aDataBuffer must be ByteArray-like. + aSocketAddress must be a valid SocketAddress for my domain (i.e. for IPv4, an IPSocketAddress). For backward compatibility, a ByteArray is still supported in aSocketAddress (i.e. for IPv4, a 4-byte byteArray). @@ -2878,8 +2878,8 @@ "send datagramm data - fetch address of destination host from aSocketAddress, data from aDataBuffer starting at startIndex, sending count bytes. - aDataBuffer must be ByteArray-like. - aSocketAddress must be a valid SocketAddress for my domain + aDataBuffer must be ByteArray-like. + aSocketAddress must be a valid SocketAddress for my domain (i.e. for IPv4, an IPSocketAddress). For backward compatibility, a ByteArray is still supported in aSocketAddress (i.e. for IPv4, a 4-byte byteArray). @@ -2888,16 +2888,16 @@ |domainClass addr error| aSocketAddress isSocketAddress ifTrue:[ - addr := aSocketAddress. + addr := aSocketAddress. ] ifFalse:[ - aSocketAddress isByteArray ifFalse:[ - ^ self error:'bad socketAddress argument' - ]. - domainClass := self class socketAddressClassForDomain:domain. - domainClass isNil ifTrue:[ - ^ self error:'invalid (unsupported) domain'. - ]. - addr := domainClass hostAddress:aSocketAddress. + aSocketAddress isByteArray ifFalse:[ + ^ self error:'bad socketAddress argument' + ]. + domainClass := self class socketAddressClassForDomain:domain. + domainClass isNil ifTrue:[ + ^ self error:'invalid (unsupported) domain'. + ]. + addr := domainClass hostAddress:aSocketAddress. ]. %{ #ifndef NO_SOCKET @@ -2906,90 +2906,90 @@ if ((fp != nil) && __isSmallInteger(startIndex) && __isSmallInteger(nBytes)) { - SOCKET sock; - INT objSize; - struct sockaddr *sockaddr_ptr; - union sockaddr_u sa; - socklen_t sockaddr_size, alen = 0; - INT sockAddrOffs; - INT n, offs; - char *extPtr; - int _flags = __longIntVal(flags); - unsigned long norder; - unsigned char *buffer; - unsigned char *allocatedBuffer = NULL; - - 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; - } - memcpy(&sa, (__byteArrayVal(addr) + sockAddrOffs), 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); - } - } + SOCKET sock; + INT objSize; + struct sockaddr *sockaddr_ptr; + union sockaddr_u sa; + socklen_t sockaddr_size, alen = 0; + INT sockAddrOffs; + INT n, offs; + char *extPtr; + int _flags = __longIntVal(flags); + unsigned long norder; + unsigned char *buffer; + unsigned char *allocatedBuffer = NULL; + + 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; + } + memcpy(&sa, (__byteArrayVal(addr) + sockAddrOffs), 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); - memcpy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, objSize); - } - - do { - __threadErrno = 0; - n = (INT)STX_WSA_NOINT_CALL6("sendto", sendto, sock, buffer, objSize, _flags, sockaddr_ptr, sockaddr_size); - } while ((n < 0) && (__threadErrno == EINTR)); - if (n < 0) { - errno = __threadErrno; - } - - if (allocatedBuffer) { - free(allocatedBuffer); - } + if (extPtr) { + buffer = extPtr + offs; + } else { + allocatedBuffer = buffer = (char *)malloc(objSize); + memcpy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, objSize); + } + + do { + __threadErrno = 0; + n = (INT)STX_WSA_NOINT_CALL6("sendto", sendto, sock, buffer, objSize, _flags, sockaddr_ptr, sockaddr_size); + } while ((n < 0) && (__threadErrno == EINTR)); + if (n < 0) { + errno = __threadErrno; + } + + 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__ + __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) { - error = __INST(lastErrorNumber) = __MKSMALLINT(errno); - } else { - RETURN (__MKSMALLINT(n)); - } + if (n < 0) { + error = __INST(lastErrorNumber) = __MKSMALLINT(errno); + } else { + RETURN (__MKSMALLINT(n)); + } } #endif bad: ; %}. error notNil ifTrue:[ - self writeError:error. + self writeError:error. ]. " @@ -3098,12 +3098,12 @@ |serverSocketHandle addr domainClass newHandle err| handle notNil ifTrue:[ - ^ self errorAlreadyOpen. + ^ self errorAlreadyOpen. ]. serverSocketHandle := aServerSocket fileHandle. serverSocketHandle isNil ifTrue:[ - "socket is not open" - ^ self errorNotOpen + "socket is not open" + ^ self errorNotOpen ]. domain := aServerSocket domain. @@ -3112,7 +3112,7 @@ "unix domain sockets do not return a valid peer name on accept" domainClass := self class socketAddressClassForDomain:domain. domainClass isNil ifTrue:[ - ^ self error:'invalid (unsupported) domain'. + ^ self error:'invalid (unsupported) domain'. ]. addr := domainClass new. newHandle := OperatingSystem socketAccessor new. @@ -3134,70 +3134,70 @@ # if defined(O_NONBLOCK) && defined(SET_NDELAY) if (blocking == false) { - flags = fcntl(serverSocket, F_GETFL); - fcntl(serverSocket, F_SETFL, flags | O_NONBLOCK); + flags = fcntl(serverSocket, F_GETFL); + fcntl(serverSocket, F_SETFL, flags | O_NONBLOCK); } # endif # ifdef DO_WRAP_CALLS do { - __threadErrno = 0; - alen = sizeof(sa); - newSock = (SOCKET)STX_WSA_CALL3("accept", accept, serverSocket, &sa, &alen); + __threadErrno = 0; + alen = sizeof(sa); + newSock = (SOCKET)STX_WSA_CALL3("accept", accept, serverSocket, &sa, &alen); } while ((newSock < 0) && (__threadErrno == EINTR)); if (newSock == -1) { - err = __MKSMALLINT(__threadErrno); + err = __MKSMALLINT(__threadErrno); } # else __BEGIN_INTERRUPTABLE__ do { - alen = sizeof(sa); - newSock = accept(serverSocket, (struct sockaddr *) &sa, &alen); + alen = sizeof(sa); + newSock = accept(serverSocket, (struct sockaddr *) &sa, &alen); } while ((newSock < 0) && (errno == EINTR)); __END_INTERRUPTABLE__ if (newSock == -1) { - err = __MKSMALLINT(errno); + err = __MKSMALLINT(errno); } # endif DBGFPRINTF((stderr, "SOCKET: accept newSock=%d\n", newSock)); # if defined(O_NDELAY) && defined(SET_NDELAY) if (blocking == false) { - fcntl(serverSocket, F_SETFL, flags); + fcntl(serverSocket, F_SETFL, flags); } # endif if (newSock == -1) { - DBGPRINTF(("SOCKET: accept call failed errno=%d\n", err)); - goto out; + DBGPRINTF(("SOCKET: accept call failed errno=%d\n", (int)(__intVal(err)))); + goto out; } if (__isNonNilObject(addr)) { - OBJ oClass = __qClass(addr); - int nInstVars, nInstBytes, objSize; - char *addrP; - - if (! __isBytes(addr)) { - DBGPRINTF(("SOCKET: bad addr\n")); - closesocket(newSock); - err = @symbol(badAddressArg); - goto out; - } - - nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); - nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ)); - objSize = __qSize(addr) - nInstBytes; - addrP = (char *)__InstPtr(addr) + nInstBytes; - if (objSize < alen) { - DBGPRINTF(("SOCKET: bad addr\n")); - closesocket(newSock); - err = @symbol(badAddressArgLen); - goto out; - } - - /* - * extract the partners address - */ - memcpy(addrP, (char *)&sa, alen); + OBJ oClass = __qClass(addr); + int nInstVars, nInstBytes, objSize; + char *addrP; + + if (! __isBytes(addr)) { + DBGPRINTF(("SOCKET: bad addr\n")); + closesocket(newSock); + err = @symbol(badAddressArg); + goto out; + } + + nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); + nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ)); + objSize = __qSize(addr) - nInstBytes; + addrP = (char *)__InstPtr(addr) + nInstBytes; + if (objSize < alen) { + DBGPRINTF(("SOCKET: bad addr\n")); + closesocket(newSock); + err = @symbol(badAddressArgLen); + goto out; + } + + /* + * extract the partners address + */ + memcpy(addrP, (char *)&sa, alen); } /* @@ -3215,19 +3215,19 @@ # else // ! __win32__ fp = fdopen(newSock, "r+"); if (! fp) { - DBGPRINTF(("SOCKET: fdopen call failed\n")); - err = __MKSMALLINT(errno); - closesocket(newSock); - DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock)); - goto out; + DBGPRINTF(("SOCKET: fdopen call failed\n")); + err = __MKSMALLINT(errno); + closesocket(newSock); + DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock)); + goto out; } # endif // ! __win32__ if ((@global(FileOpenTrace) == true) || __debugging__) { # ifdef __win32__ - console_fprintf(stderr, "fdopen [Socket accept] -> fd: %d (H: %"_lx_")\n", _fd, (INT)newSock); + console_fprintf(stderr, "fdopen [Socket accept] -> fd: %d (H: %"_lx_")\n", _fd, (INT)newSock); # else - console_fprintf(stderr, "fdopen [Socket accept] -> %"_lx_" (fd: %d)\n", (INT)fp, newSock); + console_fprintf(stderr, "fdopen [Socket accept] -> %"_lx_" (fd: %d)\n", (INT)fp, newSock); # endif } @@ -3243,10 +3243,10 @@ %}. err notNil ifTrue:[ - err isSymbol ifTrue:[ - self error:err. - ]. - ^ self reportError:err. + err isSymbol ifTrue:[ + self error:err. + ]. + ^ self reportError:err. ]. handle := newHandle. @@ -3266,7 +3266,7 @@ |ok error| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. %{ /* STACK: 32000 */ @@ -3274,255 +3274,255 @@ OBJ fp = __INST(handle); if (fp != nil) { - SOCKET sock = SOCKET_FROM_FILE_OBJECT(fp); - int opt = -1; - int level = -1; - int usize = -1; - int ret; - union u { - BOOL u_bool; - int u_int; - struct linger u_linger; + SOCKET sock = SOCKET_FROM_FILE_OBJECT(fp); + int opt = -1; + int level = -1; + int usize = -1; + int ret; + union u { + BOOL u_bool; + int u_int; + struct linger u_linger; # ifdef IP_ADD_MEMBERSHIP - struct ip_mreq u_ip_mreq; + struct ip_mreq u_ip_mreq; # endif # if defined(SO_RCVTIMEO) || defined(SO_SNDTIMEO) - struct timeval u_tv; + struct timeval u_tv; # endif - } u; + } u; # ifdef IP_ADD_MEMBERSHIP - if (option == @symbol(IP_DROP_MEMBERSHIP)) { - opt = IP_DROP_MEMBERSHIP; - goto dropOrAdd; - } - if (option == @symbol(IP_ADD_MEMBERSHIP)) { - /* add membership to a multicast group */ - opt = IP_ADD_MEMBERSHIP; + if (option == @symbol(IP_DROP_MEMBERSHIP)) { + opt = IP_DROP_MEMBERSHIP; + goto dropOrAdd; + } + if (option == @symbol(IP_ADD_MEMBERSHIP)) { + /* add membership to a multicast group */ + opt = IP_ADD_MEMBERSHIP; dropOrAdd: - level = IPPROTO_IP; - usize = sizeof(u.u_ip_mreq); - if (__isByteArrayLike(arg1) && __isByteArrayLike(arg2)) { - memcpy(&u.u_ip_mreq.imr_multiaddr, __byteArrayVal(arg1), sizeof(u.u_ip_mreq.imr_multiaddr)); - memcpy(&u.u_ip_mreq.imr_interface, __byteArrayVal(arg2), sizeof(u.u_ip_mreq.imr_interface)); - // once we use the struct ip_mreqn: - // u.u_ip_mreqn.imr_ifindex = 0; - } - else - goto argError; - } + level = IPPROTO_IP; + usize = sizeof(u.u_ip_mreq); + if (__isByteArrayLike(arg1) && __isByteArrayLike(arg2)) { + memcpy(&u.u_ip_mreq.imr_multiaddr, __byteArrayVal(arg1), sizeof(u.u_ip_mreq.imr_multiaddr)); + memcpy(&u.u_ip_mreq.imr_interface, __byteArrayVal(arg2), sizeof(u.u_ip_mreq.imr_interface)); + // once we use the struct ip_mreqn: + // u.u_ip_mreqn.imr_ifindex = 0; + } + else + goto argError; + } # endif /* IP_ADD_MEMBERSHIP */ # ifdef IP_TTL - if (option == @symbol(IP_TTL)) { - opt = IP_TTL; - level = IPPROTO_IP; - usize = sizeof(u.u_int); - if (__isSmallInteger(arg1))u.u_int = __intVal(arg1); - else goto argError; - } + if (option == @symbol(IP_TTL)) { + opt = IP_TTL; + level = IPPROTO_IP; + usize = sizeof(u.u_int); + if (__isSmallInteger(arg1))u.u_int = __intVal(arg1); + else goto argError; + } # endif /* IP_TTL */ # ifdef IP_MULTICAST_TTL - if (option == @symbol(IP_MULTICAST_TTL)) { - opt = IP_MULTICAST_TTL; - level = IPPROTO_IP; - usize = sizeof(u.u_int); - if (__isSmallInteger(arg1))u.u_int = __intVal(arg1); - else goto argError; - } + if (option == @symbol(IP_MULTICAST_TTL)) { + opt = IP_MULTICAST_TTL; + level = IPPROTO_IP; + usize = sizeof(u.u_int); + if (__isSmallInteger(arg1))u.u_int = __intVal(arg1); + else goto argError; + } # endif /* IP_TTL */ # 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; - } + 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; - } + 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; - } + 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; - } + 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; - } + 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 */ #if defined(IPPROTO_TCP) && defined(TCP_NODELAY) - if (option == @symbol(TCP_NODELAY)) { - /* enable/disable TCP_NODELAY (i.e. disable/enable the Nagle algorithm) */ - opt = TCP_NODELAY; - level = IPPROTO_TCP; - usize = sizeof(u.u_bool); - if (arg1 == true) u.u_bool = TRUE; - else if (arg1 == false) u.u_bool = FALSE; - else goto argError; - } + if (option == @symbol(TCP_NODELAY)) { + /* enable/disable TCP_NODELAY (i.e. disable/enable the Nagle algorithm) */ + opt = TCP_NODELAY; + level = IPPROTO_TCP; + usize = sizeof(u.u_bool); + if (arg1 == true) u.u_bool = TRUE; + else if (arg1 == false) u.u_bool = FALSE; + else goto argError; + } # endif /* TCP_NODELAY */ # 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; - } + 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)); - } + 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; - } + 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; - } + 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; - } + 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; - } + 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; - } + 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 */ # ifdef SO_RCVTIMEO - if ((option == @symbol(SO_RCVTIMEO)) - && __isSmallInteger(arg1) - && __isSmallInteger(arg2)) { - opt = SO_RCVTIMEO; - level = SOL_SOCKET; - u.u_tv.tv_sec = __intVal(arg1); - u.u_tv.tv_usec = __intVal(arg2); - usize = sizeof(u.u_tv); - } + if ((option == @symbol(SO_RCVTIMEO)) + && __isSmallInteger(arg1) + && __isSmallInteger(arg2)) { + opt = SO_RCVTIMEO; + level = SOL_SOCKET; + u.u_tv.tv_sec = __intVal(arg1); + u.u_tv.tv_usec = __intVal(arg2); + usize = sizeof(u.u_tv); + } # endif /* SO_RCVTIMEO */ # ifdef SO_SNDTIMEO - if ((option == @symbol(SO_SNDTIMEO)) - && __isSmallInteger(arg1) - && __isSmallInteger(arg2)) { - opt = SO_SNDTIMEO; - level = SOL_SOCKET; - u.u_tv.tv_sec = __intVal(arg1); - u.u_tv.tv_usec = __intVal(arg2); - usize = sizeof(u.u_tv); - } + if ((option == @symbol(SO_SNDTIMEO)) + && __isSmallInteger(arg1) + && __isSmallInteger(arg2)) { + opt = SO_SNDTIMEO; + level = SOL_SOCKET; + u.u_tv.tv_sec = __intVal(arg1); + u.u_tv.tv_usec = __intVal(arg2); + usize = sizeof(u.u_tv); + } # endif /* SO_SNDTIMEO */ # if !defined(IPV6_V6ONLY) && defined(__win32__) @@ -3531,39 +3531,39 @@ # endif # if defined(IPV6_V6ONLY) - if (option == @symbol(IPV6_V6ONLY)) { - opt = IPV6_V6ONLY; - level = IPPROTO_IPV6; - usize = sizeof(u.u_bool); - if (arg1 == true) u.u_bool = TRUE; - else if (arg1 == false) u.u_bool = FALSE; - else goto argError; + if (option == @symbol(IPV6_V6ONLY)) { + opt = IPV6_V6ONLY; + level = IPPROTO_IPV6; + usize = sizeof(u.u_bool); + if (arg1 == true) u.u_bool = TRUE; + else if (arg1 == false) u.u_bool = FALSE; + else goto argError; # ifdef __win32__ - console_fprintf(stderr, "%d %d %d %d\n", level, opt, usize, u.u_int); + console_fprintf(stderr, "%d %d %d %d\n", level, opt, usize, u.u_int); # endif - } + } # endif /* IPV6_V6ONLY */ - if (usize == -1) goto argError; - - ok = (setsockopt(sock, level, opt, (char *)&u, usize) >= 0) ? true : false; - if (ok == false) { + if (usize == -1) goto argError; + + ok = (setsockopt(sock, level, opt, (char *)&u, usize) >= 0) ? true : false; + if (ok == false) { # ifdef __win32__ - error = __mkSmallInteger(WSAGetLastError()); + error = __mkSmallInteger(WSAGetLastError()); # else - error = __mkSmallInteger(errno); + error = __mkSmallInteger(errno); # endif - } + } } argError: ; #endif /* NO_SOCKET */ %}. ok isNil ifTrue:[ - self primitiveFailed + self primitiveFailed ]. ok ifFalse:[ - '++++ Info: Socket>>#setSocketOption:... failed. error: ' infoPrint. error infoPrintCR. + '++++ Info: Socket>>#setSocketOption:... failed. error: ' infoPrint. error infoPrintCR. ]. ! @@ -3615,13 +3615,13 @@ aStream nextPutAll:' port='. self port printOn:aStream. peer notNil ifTrue:[ - aStream nextPutAll:' peer='. - peer printOn:aStream. + aStream nextPutAll:' peer='. + peer printOn:aStream. ]. listening notNil ifTrue:[ - aStream nextPutAll:' *listening('. - listening printOn:aStream. - aStream nextPutAll:')*'. + aStream nextPutAll:' *listening('. + listening printOn:aStream. + aStream nextPutAll:')*'. ]. aStream nextPut:$). @@ -4041,17 +4041,17 @@ linger:anIntegerOrNil "set the linger behavior on close: anIntegerOrNil == nil: close returns immediately, socket tries - to send buffered data in background. + to send buffered data in background. anIntegerOrNil == 0: close returns immediately, bufferd data is discarded. anIntegerOrNil > 0: close waits this many seconds for buffered data - to be delivered, after this time buffered data is - discarded and close returns with an error. + to be delivered, after this time buffered data is + discarded and close returns with an error. (returns false, if unsupported)" ^ self - setSocketOption:#'SO_LINGER' - argument:anIntegerOrNil notNil - argument:anIntegerOrNil. + setSocketOption:#'SO_LINGER' + argument:anIntegerOrNil notNil + argument:anIntegerOrNil. "Modified (comment): / 08-02-2019 / 22:33:14 / Claus Gittinger" ! @@ -4116,7 +4116,7 @@ |millis| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. %{ #if defined(SO_RCVTIMEO) && defined(SOL_SOCKET) @@ -4128,20 +4128,20 @@ 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); + __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); + console_fprintf(stderr, "getsockopt -> s:%d us:%d -> millis:%d\n", tv.tv_sec, tv.tv_usec, __millis); # endif } else { - console_fprintf(stderr, "Socket [warning]: getsockopt %d failed; errno=%d\n", sock, errno); + console_fprintf(stderr, "Socket [warning]: getsockopt %d failed; errno=%d\n", sock, errno); } #endif %}. ^ millis " - Socket newTCP receiveTimeout + Socket newTCP receiveTimeout " "Modified: / 19-01-2018 / 19:15:17 / stefan" @@ -4153,54 +4153,54 @@ (returns false, if unsupported). From linux manpage: - SO_RCVTIMEO and SO_SNDTIMEO - Specify the receiving or sending timeouts until reporting an error. The argument is a - struct timeval. If an input or output function blocks for this period of time, and data has - been sent or received, the return value of that function will be the amount of data trans- - ferred; if no data has been transferred and the timeout has been reached, then -1 is - returned with errno set to EAGAIN or EWOULDBLOCK, or EINPROGRESS (for connect(2)) just as if - the socket was specified to be nonblocking. If the timeout is set to zero (the default), - then the operation will never timeout. Timeouts only have effect for system calls that per- - form socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect - for select(2), poll(2), epoll_wait(2), and so on." + SO_RCVTIMEO and SO_SNDTIMEO + Specify the receiving or sending timeouts until reporting an error. The argument is a + struct timeval. If an input or output function blocks for this period of time, and data has + been sent or received, the return value of that function will be the amount of data trans- + ferred; if no data has been transferred and the timeout has been reached, then -1 is + returned with errno set to EAGAIN or EWOULDBLOCK, or EINPROGRESS (for connect(2)) just as if + the socket was specified to be nonblocking. If the timeout is set to zero (the default), + then the operation will never timeout. Timeouts only have effect for system calls that per- + form socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect + for select(2), poll(2), epoll_wait(2), and so on." |millis| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. secondsOrTimeDuration isTimeDuration ifTrue:[ - millis := secondsOrTimeDuration getMilliseconds. + millis := secondsOrTimeDuration getMilliseconds. ] ifFalse:[ - millis := (secondsOrTimeDuration * 1000) rounded. + millis := (secondsOrTimeDuration * 1000) rounded. ]. %{ #if defined(SO_RCVTIMEO) && defined(SOL_SOCKET) if (__isSmallInteger(millis)) { - OBJ fp = __INST(handle); - SOCKET sock = SOCKET_FROM_FILE_OBJECT(fp); - int __millis = __intVal(millis); - struct timeval tv = {0, 0}; - - tv.tv_sec = __millis / 1000; - tv.tv_usec = (__millis % 1000) * 1000; + OBJ fp = __INST(handle); + SOCKET sock = SOCKET_FROM_FILE_OBJECT(fp); + int __millis = __intVal(millis); + struct timeval tv = {0, 0}; + + 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); + 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) { - RETURN(true); - } - console_fprintf(stderr, "Socket [warning]: setsockopt %d failed; errno=%d\n", sock, errno); + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(struct timeval)) == 0) { + RETURN(true); + } + console_fprintf(stderr, "Socket [warning]: setsockopt %d failed; errno=%d\n", sock, errno); } #endif %}. ^ false " - Socket newTCP - receiveTimeout:5s; - receiveTimeout + Socket newTCP + receiveTimeout:5s; + receiveTimeout " "Modified (comment): / 19-01-2018 / 19:14:49 / stefan" @@ -4266,7 +4266,7 @@ |millis| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. %{ #if defined(SO_SNDTIMEO) && defined(SOL_SOCKET) @@ -4278,20 +4278,20 @@ 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); + __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); + console_fprintf(stderr, "getsockopt -> s:%d us:%d -> millis:%d\n", tv.tv_sec, tv.tv_usec, __millis); # endif } else { - console_fprintf(stderr, "Socket [warning]: getsockopt %d failed; errno=%d\n", sock, errno); + console_fprintf(stderr, "Socket [warning]: getsockopt %d failed; errno=%d\n", sock, errno); } #endif %}. ^ millis " - Socket newTCP sendTimeout + Socket newTCP sendTimeout " "Modified (comment): / 19-01-2018 / 19:16:23 / stefan" @@ -4302,53 +4302,53 @@ Not all operatingSystems offer this functionality (returns false, if unsupported). From linux manpage: - SO_RCVTIMEO and SO_SNDTIMEO - Specify the receiving or sending timeouts until reporting an error. The argument is a - struct timeval. If an input or output function blocks for this period of time, and data has - been sent or received, the return value of that function will be the amount of data trans- - ferred; if no data has been transferred and the timeout has been reached, then -1 is - returned with errno set to EAGAIN or EWOULDBLOCK, or EINPROGRESS (for connect(2)) just as if - the socket was specified to be nonblocking. If the timeout is set to zero (the default), - then the operation will never timeout. Timeouts only have effect for system calls that per- - form socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect - for select(2), poll(2), epoll_wait(2), and so on." + SO_RCVTIMEO and SO_SNDTIMEO + Specify the receiving or sending timeouts until reporting an error. The argument is a + struct timeval. If an input or output function blocks for this period of time, and data has + been sent or received, the return value of that function will be the amount of data trans- + ferred; if no data has been transferred and the timeout has been reached, then -1 is + returned with errno set to EAGAIN or EWOULDBLOCK, or EINPROGRESS (for connect(2)) just as if + the socket was specified to be nonblocking. If the timeout is set to zero (the default), + then the operation will never timeout. Timeouts only have effect for system calls that per- + form socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect + for select(2), poll(2), epoll_wait(2), and so on." |millis| handle isNil ifTrue:[ - ^ self errorNotOpen + ^ self errorNotOpen ]. secondsOrTimeDuration isTimeDuration ifTrue:[ - millis := secondsOrTimeDuration getMilliseconds. + millis := secondsOrTimeDuration getMilliseconds. ] ifFalse:[ - millis := (secondsOrTimeDuration * 1000) rounded. + millis := (secondsOrTimeDuration * 1000) rounded. ]. %{ #if defined(SO_SNDTIMEO) && defined(SOL_SOCKET) if (__isSmallInteger(millis)) { - OBJ fp = __INST(handle); - SOCKET sock = SOCKET_FROM_FILE_OBJECT(fp); - int __millis = __intVal(millis); - struct timeval tv = {0, 0}; - - tv.tv_sec = __millis / 1000; - tv.tv_usec = (__millis % 1000) * 1000; + OBJ fp = __INST(handle); + SOCKET sock = SOCKET_FROM_FILE_OBJECT(fp); + int __millis = __intVal(millis); + struct timeval tv = {0, 0}; + + 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); + 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) { - RETURN(true); - } - console_fprintf(stderr, "Socket [warning]: setsockopt %d failed; errno=%d\n", sock, errno); + if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, sizeof(struct timeval)) == 0) { + RETURN(true); + } + console_fprintf(stderr, "Socket [warning]: setsockopt %d failed; errno=%d\n", sock, errno); } #endif %}. ^ false " - Socket newTCP - sendTimeout:5s; - sendTimeout + Socket newTCP + sendTimeout:5s; + sendTimeout " "Modified (comment): / 19-01-2018 / 19:12:51 / stefan" @@ -4390,50 +4390,50 @@ "first, a quick check if data is already available" self canReadWithoutBlocking ifTrue:[ - ^ self accept. + ^ self accept. ]. otherConnections do:[:aConnection | - aConnection canReadWithoutBlocking ifTrue:[ - ^ aConnection - ] + aConnection canReadWithoutBlocking ifTrue:[ + ^ aConnection + ] ]. "check again - prevent incoming interrupts from disturbing our setup" secondsOrTimeDurationOrNil notNil ifTrue:[ - secondsOrTimeDurationOrNil isTimeDuration ifTrue:[ - timeoutMs := secondsOrTimeDurationOrNil getMilliseconds. - ] ifFalse:[ - timeoutMs := secondsOrTimeDurationOrNil * 1000. - ] + secondsOrTimeDurationOrNil isTimeDuration ifTrue:[ + timeoutMs := secondsOrTimeDurationOrNil getMilliseconds. + ] ifFalse:[ + timeoutMs := secondsOrTimeDurationOrNil * 1000. + ] ]. wasBlocked := OperatingSystem blockInterrupts. [ - sema := Semaphore name:'multiReadWait'. - otherConnections do:[:aConnection | - Processor signal:sema onInput:(aConnection fileDescriptor). - ]. - Processor signal:sema onInput:(self fileDescriptor). - timeoutMs notNil ifTrue:[ - Processor signal:sema afterMilliseconds:timeoutMs - ]. - Processor activeProcess state:#ioWait. - sema wait. + sema := Semaphore name:'multiReadWait'. + otherConnections do:[:aConnection | + Processor signal:sema onInput:(aConnection fileDescriptor). + ]. + Processor signal:sema onInput:(self fileDescriptor). + timeoutMs notNil ifTrue:[ + Processor signal:sema afterMilliseconds:timeoutMs + ]. + Processor activeProcess state:#ioWait. + sema wait. ] ifCurtailed:[ - sema notNil ifTrue:[Processor disableSemaphore:sema]. - wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. + sema notNil ifTrue:[Processor disableSemaphore:sema]. + wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. ]. wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. "see who it was ..." self canReadWithoutBlocking ifTrue:[ - ^ self accept. + ^ self accept. ]. otherConnections do:[:aConnection | - aConnection canReadWithoutBlocking ifTrue:[ - ^ aConnection - ] + aConnection canReadWithoutBlocking ifTrue:[ + ^ aConnection + ] ]. "none - a timeout" @@ -4454,20 +4454,20 @@ |newSock| (self readWaitWithTimeout:secondsOrTimeDurationOrNil) ifTrue:[ - "a timeout occurred - no connection within timeout" - self reportError:(OperatingSystem errorNumberFor:#ETIMEDOUT). - ^ nil. + "a timeout occurred - no connection within timeout" + self reportError:(OperatingSystem errorNumberFor:#ETIMEDOUT). + ^ nil. ]. self isOpen ifFalse:[ - "I have been closed while waiting" - ^ self errorNotOpen. + "I have been closed while waiting" + ^ self errorNotOpen. ]. "ok, a connection is present - accept it" newSock := self class new. (newSock primAcceptOn:self blocking:false) ifFalse:[ - "should raise an error here - primitive code raises a notification" - ^ nil + "should raise an error here - primitive code raises a notification" + ^ nil ]. ^ newSock @@ -4483,4 +4483,3 @@ version_CVS ^ '$Header$' ! ! -