--- a/Socket.st Wed Jul 16 18:44:37 2003 +0200
+++ b/Socket.st Thu Jul 17 15:24:40 2003 +0200
@@ -1268,15 +1268,11 @@
newSock := self newTCP.
newSock notNil ifTrue:[
- (newSock bindTo:(self portOfService:aService) address:nil) ifFalse:[
- ^ nil
- ]
+ (newSock bindTo:(self portOfService:aService) address:nil) ifFalse:[
+ ^ nil
+ ]
].
^ newSock
-"
-same as:
- ^ (self new) for:nil port:aPort
-"
!
newUDP
@@ -1552,14 +1548,9 @@
"standard & easy client setup:
create new client tcp socket, bind and connect;
return the socket.
- The thread block (interruptable), until the connection is
- established."
-
- <resource:#obsolete>
-
- self obsoleteMethodWarning:'use newTCP: / connect'.
-
- ^ (self new) for:host port:(self portOfService:service).
+ The thread block (interruptable), until the connection is established."
+
+ ^ self newTCPclientToHost:host port:(self portOfService:service).
"
Socket connectTo:9995 on:'clam'
@@ -1570,7 +1561,7 @@
"
!
-provide:service
+provide:aService
"standard & easy server setup:
create a new TCP server socket providing a service."
@@ -1578,9 +1569,9 @@
|newSock|
- self obsoleteMethodWarning:'use newTCP: / listen'.
-
- newSock := (self new) for:nil port:(self portOfService:service).
+ self obsoleteMethodWarning:'use newTCPserverAtPort: / listen'.
+
+ newSock := self newTCPserverAtPort:(self portOfService:aService).
newSock notNil ifTrue:[
newSock listenFor:5.
].
@@ -1946,62 +1937,59 @@
int flags = 0;
if (fp != nil) {
- sock = fileno(__FILEVal(fp));
-
- oClass = __Class(aDataBuffer);
- switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
- case BYTEARRAY:
- case WORDARRAY:
- case SWORDARRAY:
- case LONGARRAY:
- case SLONGARRAY:
- case FLOATARRAY:
- case DOUBLEARRAY:
- break;
- default:
- goto bad;
- }
-
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
- objSize = _Size(aDataBuffer) - nInstBytes;
- cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
- if (__isSmallInteger(startIndex)) {
- cp += __intVal(startIndex);
- objSize -= __intVal(startIndex);
- }
- if (__isSmallInteger(nBytes)) {
- if (__intVal(nBytes) < objSize) {
- objSize = __intVal(nBytes);
- }
- }
-
- __BEGIN_INTERRUPTABLE__
- do {
- n = recv(sock, cp, objSize, flags);
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- nReceived = __MKSMALLINT(n);
+ sock = fileno(__FILEVal(fp));
+
+ oClass = __Class(aDataBuffer);
+ switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ case WORDARRAY:
+ case SWORDARRAY:
+ case LONGARRAY:
+ case SLONGARRAY:
+ case FLOATARRAY:
+ case DOUBLEARRAY:
+ break;
+ default:
+ goto bad;
+ }
+
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+ objSize = _Size(aDataBuffer) - nInstBytes;
+ cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
+ if (__isSmallInteger(startIndex)) {
+ cp += __intVal(startIndex);
+ objSize -= __intVal(startIndex);
+ }
+ if (__isSmallInteger(nBytes)) {
+ if (__intVal(nBytes) < objSize) {
+ objSize = __intVal(nBytes);
+ }
+ }
+
+ __BEGIN_INTERRUPTABLE__
+ do {
+ n = recv(sock, cp, objSize, flags);
+ } while ((n < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+
+ if (n < 0) {
+ __INST(lastErrorNumber) = __MKSMALLINT(errno);
+ }
+ nReceived = __MKSMALLINT(n);
}
#endif
bad: ;
%}.
nReceived notNil ifTrue:[
- nReceived < 0 ifTrue:[
- 'Socket [warning]: ' infoPrint.
- (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
- ].
- ^ nReceived
+ nReceived < 0 ifTrue:[
+ 'Socket [warning]: ' infoPrint.
+ (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
+ ].
+ ^ nReceived
].
"
- arrive here if you try to receive into an invalid buffer
- (i.e. not ByteArray-like),
- or if the addressBuffer is nonNil AND not a ByteArray/String
- or if the addressBuffer is nonNil AND too small.
+ arrive here if you try to receive into an invalid buffer (i.e. not ByteArray-like)
"
self primitiveFailed
!
@@ -2019,19 +2007,34 @@
!
receiveFrom:anAddressBuffer buffer:aDataBuffer start:startIndex for:nBytes
- "receive datagramm data - put address of originating host into
- anAddressBuffer, data into aBuffer. For ST-80 compatibility,
- the addressBuffer may be a non-ByteArray; then, it must understand
- the addressBytes-message (i.e. be a SocketAddress instance).
+ "receive datagramm data
+ - put address of originating host into anAddressBuffer, data into aBuffer.
+ For backward compatibility, the addressBuffer may be a non-SocketAddress;
+ then, it must be a byteArray with appropriate size for the addressBytes.
+
Return the number of bytes received, or a negative number on error.
On error, the unix error code is left in the lastErrorNumber
instance variable.
The thread blocks until data arrives - you may want to wait before
receiving, using #readWait or #readWaitWithTimeout:."
- |addrBytes addrLen nReceived addrPort|
-
- addrBytes := ByteArray new:100.
+ |domainClass addr addrLen nReceived|
+
+ domainClass := self class socketAddressClassForDomain:domain.
+ domainClass isNil ifTrue:[
+ ^ self error:'invalid (unsupported) domain'.
+ ].
+ (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
+ anAddressBuffer class == domainClass ifFalse:[
+ ^ self error:'addressBuffer class mismatch (domain)'.
+ ].
+ addr := anAddressBuffer.
+ ] ifFalse:[
+ anAddressBuffer notNil ifTrue:[
+ addr := domainClass new.
+ ].
+ ].
+
%{
#ifndef NO_SOCKET
OBJ oClass, myDomain;
@@ -2045,242 +2048,110 @@
int flags = 0;
if (fp != nil) {
- sock = fileno(__FILEVal(fp));
-
- oClass = __Class(aDataBuffer);
- offs = 0;
- sIdx = 0;
- if (__isSmallInteger(startIndex)) {
- sIdx = __intVal(startIndex) - 1;
- }
- switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
- case BYTEARRAY:
- offs = sIdx;
- break;
- case WORDARRAY:
- case SWORDARRAY:
- offs = sIdx * 2;
- break;
- case LONGARRAY:
- case SLONGARRAY:
- offs = sIdx * 4;
- break;
- case LONGLONGARRAY:
- case SLONGLONGARRAY:
- offs = sIdx * 8;
+ sock = fileno(__FILEVal(fp));
+
+ oClass = __Class(aDataBuffer);
+ offs = 0;
+ sIdx = 0;
+ if (__isSmallInteger(startIndex)) {
+ sIdx = __intVal(startIndex) - 1;
+ }
+ switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ offs = sIdx;
+ break;
+ case WORDARRAY:
+ case SWORDARRAY:
+ offs = sIdx * 2;
+ break;
+ case LONGARRAY:
+ case SLONGARRAY:
+ offs = sIdx * 4;
+ break;
+ case LONGLONGARRAY:
+ case SLONGLONGARRAY:
+ offs = sIdx * 8;
# ifdef __NEED_LONGLONG_ALIGN
- offs += 4;
+ offs += 4;
# endif
- break;
- case FLOATARRAY:
- offs = sIdx * sizeof(float);
- break;
- case DOUBLEARRAY:
- offs = sIdx * sizeof(double);
+ break;
+ case FLOATARRAY:
+ offs = sIdx * sizeof(float);
+ break;
+ case DOUBLEARRAY:
+ offs = sIdx * sizeof(double);
# ifdef __NEED_DOUBLE_ALIGN
- offs += 4;
+ offs += 4;
# endif
- break;
- default:
- goto bad;
- }
-
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
- objSize = _Size(aDataBuffer) - nInstBytes;
- objSize -= offs;
- if (__isSmallInteger(nBytes)) {
- if (__intVal(nBytes) < objSize) {
- objSize = __intVal(nBytes);
- }
- }
-
- __BEGIN_INTERRUPTABLE__
- do {
- cp = (char *)__InstPtr(aDataBuffer) + nInstBytes + offs;
- alen = sizeof(sa);
- n = recvfrom(sock, cp, objSize, flags, (struct sockaddr *) &sa, &alen);
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-
- if (n >= 0) {
- if (__isNonNilObject(addrBytes)) {
- oClass = __qClass(addrBytes);
- if ((__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) != BYTEARRAY)
- goto bad;
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
- objSize = __qSize(addrBytes) - nInstBytes;
- cp = (char *)__InstPtr(addrBytes) + nInstBytes;
- if (objSize < alen)
- goto bad;
-
- myDomain = __INST(domain);
-
- /*
- * extract the datagrams address
- */
- if (0) {
- /* for else below */
- }
-# ifdef AF_INET
- else if (myDomain == @symbol(inet)) {
- if (objSize < 4)
- goto bad;
-# ifdef DGRAM_DEBUG
- printf("alen: %d s_addr:%x\n", alen, sa.in.sin_addr.s_addr);
-# endif /* DGRAM_DEBUG */
- addrPort = __MKSMALLINT( ntohs(sa.in.sin_port) );
- sa.in.sin_addr.s_addr = ntohl(sa.in.sin_addr.s_addr);
- cp[0] = (sa.in.sin_addr.s_addr >> 24) & 0xFF;
- cp[1] = (sa.in.sin_addr.s_addr >> 16) & 0xFF;
- cp[2] = (sa.in.sin_addr.s_addr >> 8) & 0xFF;
- cp[3] = (sa.in.sin_addr.s_addr >> 0) & 0xFF;
- alen = 4;
-# ifdef DGRAM_DEBUG
- printf("addr:%d.%d.%d.%d\n", cp[0], cp[1], cp[2], cp[3]);
-# endif /* DGRAM_DEBUG */
- }
-# endif /* AF_INET */
-
-# ifdef AF_INET6
- else if (myDomain == @symbol(inet6)) {
- if (objSize < sizeof(sa.in6.sin6_addr.s6_addr))
- goto bad;
- bcopy(sa.in6.sin6_addr.s6_addr, cp, sizeof(sa.in6.sin6_addr.s6_addr));
- alen = sizeof(sa.in6.sin6_addr.s6_addr);
- }
-# endif /* AF_INET6 */
-
-# ifdef AF_APPLETALK
- else if (myDomain == @symbol(appletalk)) {
- if (objSize < 3)
- goto bad;
- cp[0] = (sa.at.sat_addr.s_net >> 8) & 0xFF;
- cp[1] = (sa.at.sat_addr.s_net) & 0xFF;
- cp[2] = (sa.at.sat_addr.s_node) & 0xFF;
- alen = 3;
- }
-# endif /* AF_APPLETALK */
-
- /*
- * XXXX add addressing stuff for other domains here ...
- */
-# ifdef AF_X25
- else if (myDomain == @symbol(x25)) {
- }
-# endif
-
-# ifdef AF_AX25
- else if (myDomain == @symbol(ax25)) {
- }
-# endif
-
-# ifdef AF_NS
- else if ((myDomain == @symbol(ns))
- || (myDomain == @symbol(xns))) {
- }
-# endif
-
-# ifdef AF_SNA
- else if (myDomain == @symbol(sna)) {
- }
-# endif
-
-# ifdef AF_RAW
- else if (myDomain == @symbol(raw)) {
- }
-# endif
-
-# ifdef AF_ISO
- else if (myDomain == @symbol(iso)) {
- }
-# endif
-
-# ifdef AF_DECnet
- else if (myDomain == @symbol(decnet)) {
- }
-# endif
-
-# ifdef AF_NETBIOS
- else if (myDomain == @symbol(netbios)) {
- }
-# endif
-
-# ifdef AF_IPX
- else if (myDomain == @symbol(ipx)) {
- }
-# endif
-
-# ifdef AF_BRIDGE
- else if (myDomain == @symbol(bridge)) {
- }
-# endif
-
-# ifdef AF_BSC
- else if (myDomain == @symbol(bsc)) {
- }
-# endif
-
-# ifdef AF_ROSE
- else if (myDomain == @symbol(rose)) {
- }
-# endif
-
-# ifdef AF_IRDA
- else if (myDomain == @symbol(irda)) {
- }
-# endif
-
-# if defined(AF_CCITT) && (AF_CCITT != AF_X25)
- else if (myDomain == @symbol(ccitt)) {
- }
-# endif
-
- addrLen = __MKSMALLINT(alen);
- }
- }
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- nReceived = __MKSMALLINT(n);
+ break;
+ default:
+ goto bad;
+ }
+
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+ objSize = _Size(aDataBuffer) - nInstBytes;
+ objSize -= offs;
+ if (__isSmallInteger(nBytes)) {
+ if (__intVal(nBytes) < objSize) {
+ objSize = __intVal(nBytes);
+ }
+ }
+
+ __BEGIN_INTERRUPTABLE__
+ do {
+ cp = (char *)__InstPtr(aDataBuffer) + nInstBytes + offs;
+ alen = sizeof(sa);
+ n = recvfrom(sock, cp, objSize, flags, (struct sockaddr *) &sa, &alen);
+ } while ((n < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+
+ if (n >= 0) {
+ if (__isNonNilObject(addr)) {
+ oClass = __qClass(addr);
+ if (! __isBytes(addr) )
+ goto bad;
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
+ objSize = __qSize(addr) - nInstBytes;
+ cp = (char *)__InstPtr(addr) + nInstBytes;
+ if (objSize < alen)
+ goto bad;
+
+ /*
+ * extract the datagrams address
+ */
+ bcopy((char *)&sa, cp, alen);
+ addrLen = __MKSMALLINT(alen);
+ }
+ }
+ if (n < 0) {
+ __INST(lastErrorNumber) = __MKSMALLINT(errno);
+ }
+ nReceived = __MKSMALLINT(n);
}
#endif
bad: ;
%}.
nReceived notNil ifTrue:[
- nReceived < 0 ifTrue:[
- 'Socket [warning]: ' infoPrint.
- (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
- ].
- addrLen notNil ifTrue:[
- (anAddressBuffer isKindOf:SocketAddress) ifFalse:[
- "/ can be a ByteArray for ST/X compatibility
- anAddressBuffer replaceFrom:1 to:addrLen with:addrBytes
- domain == #inet ifTrue:[
- addrBytes := anAddressBuffer copyFrom:1 to:4.
- anAddressBuffer at:5 put:(addrPort digitByteAt:2).
- anAddressBuffer at:6 put:(addrPort digitByteAt:1).
- ] ifFalse:[
- domain == #appletalk ifTrue:[
- addrBytes := anAddressBuffer copyFrom:1 to:3.
- anAddressBuffer at:4 put:(addrPort digitByteAt:2).
- anAddressBuffer at:5 put:(addrPort digitByteAt:1).
- ] ifFalse:[
- self error:'please use a SocketAddress'
- ]
- ]
- ] ifTrue:[
- "/ can be a SocketAddress for ST-80 compatibility
- anAddressBuffer hostAddress:(addrBytes copyTo:addrLen) port:addrPort.
- ].
- ].
- ^ nReceived
+ nReceived < 0 ifTrue:[
+ 'Socket [warning]: ' infoPrint.
+ (OperatingSystem errorTextForNumber:lastErrorNumber) infoPrintCR.
+ ].
+ addrLen notNil ifTrue:[
+ (addr == anAddressBuffer) ifFalse:[
+ self obsoleteFeatureWarning:'please use a socketAddress argument'.
+
+ "/ can be a ByteArray for backward compatibility
+ anAddressBuffer replaceFrom:1 to:addrLen with:(addr hostAddress).
+ ].
+ ].
+ ^ nReceived
].
"
arrive here if you try to receive into an invalid buffer
(i.e. not ByteArray-like),
- or if the addressBuffer is nonNil AND not a ByteArray/String
+ or if the addressBuffer is nonNil AND not a SocketAddress/ByteArray
or if the addressBuffer is nonNil AND too small.
"
self primitiveFailed
@@ -2313,78 +2184,75 @@
if ((fp != nil)
&& __isSmallInteger(startIndex)
&& __isSmallInteger(count)) {
- sock = fileno(__FILEVal(fp));
-
- oClass = __Class(aDataBuffer);
- sIdx = __intVal(startIndex) - 1;
- switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
- case BYTEARRAY:
- offs = sIdx;
- break;
- case WORDARRAY:
- case SWORDARRAY:
- offs = sIdx * 2;
- break;
- case LONGARRAY:
- case SLONGARRAY:
- offs = sIdx * 4;
- break;
- case LONGLONGARRAY:
- case SLONGLONGARRAY:
- offs = sIdx * 8;
+ sock = fileno(__FILEVal(fp));
+
+ oClass = __Class(aDataBuffer);
+ sIdx = __intVal(startIndex) - 1;
+ switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ offs = sIdx;
+ break;
+ case WORDARRAY:
+ case SWORDARRAY:
+ offs = sIdx * 2;
+ break;
+ case LONGARRAY:
+ case SLONGARRAY:
+ offs = sIdx * 4;
+ break;
+ case LONGLONGARRAY:
+ case SLONGLONGARRAY:
+ offs = sIdx * 8;
# ifdef __NEED_LONGLONG_ALIGN
- offs += 4;
+ offs += 4;
# endif
- break;
- case FLOATARRAY:
- offs = sIdx * sizeof(float);
- break;
- case DOUBLEARRAY:
- offs = sIdx * sizeof(double);
+ break;
+ case FLOATARRAY:
+ offs = sIdx * sizeof(float);
+ break;
+ case DOUBLEARRAY:
+ offs = sIdx * sizeof(double);
# ifdef __NEED_DOUBLE_ALIGN
- offs += 4;
+ offs += 4;
# endif
- break;
- default:
- goto bad;
- }
- nBytes = __intVal(count);
-
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
- objSize = __qSize(aDataBuffer) - nInstBytes;
- cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
- cp += offs;
- if ((offs + nBytes) > objSize) {
+ break;
+ default:
+ goto bad;
+ }
+ nBytes = __intVal(count);
+
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+ objSize = __qSize(aDataBuffer) - nInstBytes;
+ cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
+ cp += offs;
+ if ((offs + nBytes) > objSize) {
# ifdef DGRAM_DEBUG
- printf("cut off ...\n");
+ printf("cut off ...\n");
# endif
- nBytes = objSize - offs;
- }
+ nBytes = objSize - offs;
+ }
# ifdef DGRAM_DEBUG
- printf("sending %d bytes ...\n", nBytes);
+ printf("sending %d bytes ...\n", nBytes);
# endif
- __BEGIN_INTERRUPTABLE__
- do {
- n = send(sock, cp, nBytes, _flags);
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- RETURN (__MKSMALLINT(n));
+ __BEGIN_INTERRUPTABLE__
+ do {
+ n = send(sock, cp, nBytes, _flags);
+ } while ((n < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+
+ if (n < 0) {
+ __INST(lastErrorNumber) = __MKSMALLINT(errno);
+ }
+ RETURN (__MKSMALLINT(n));
}
#endif
bad: ;
%}.
"
- arrive here if you try to send from an invalid buffer
- (i.e. not ByteArray-like),
- or if the addressBuffer is nonNil AND not a ByteArray/String
- or if the addressBuffer is nonNil AND too small.
+ arrive here if you try to send from an invalid buffer (i.e. not ByteArray-like),
"
self primitiveFailed
!
@@ -2425,38 +2293,29 @@
On error, the unix error code is left in the lastErrorNumber
instance variable."
- |addrBytes addrLen nReceived portNo|
-
- "/ addressBuffer can be a byteArray (last 2 bytes are portNo, msb-first)
- "/ or (better) an instance of SocketAddress
- "/
- (anAddressBuffer isKindOf:SocketAddress) ifFalse:[
- domain == #inet ifTrue:[
- addrBytes := anAddressBuffer copyFrom:1 to:4.
- portNo := ((anAddressBuffer at:5) bitShift:8)
- + (anAddressBuffer at:6).
- ] ifFalse:[
- domain == #appletalk ifTrue:[
- addrBytes := anAddressBuffer copyFrom:1 to:3.
- portNo := ((anAddressBuffer at:5) bitShift:8)
- + (anAddressBuffer at:6).
- ] ifFalse:[
- self error:'please use a SocketAddress'
- ]
- ].
- ] ifTrue:[
- addrBytes := anAddressBuffer hostAddress.
- portNo := anAddressBuffer port.
+ |domainClass addr|
+
+ domainClass := self class socketAddressClassForDomain:domain.
+ domainClass isNil ifTrue:[
+ ^ self error:'invalid (unsupported) domain'.
+ ].
+
+ (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
+ addr := anAddressBuffer.
+ ] ifFalse:[
+ anAddressBuffer isByteArray ifFalse:[
+ ^ self error:'bad socketAddress argument'
+ ].
+ addr := domainClass hostAddress:anAddressBuffer.
].
%{
#ifndef NO_SOCKET
OBJ oClass;
OBJ fp = __INST(filePointer);
int nInstVars, nInstBytes, objSize;
+ struct sockaddr *sockaddr_ptr;
+ int sockAddrOffs, sockaddr_size;
int sock;
- union sockaddr_u sa;
- struct sockaddr *saPtr = (struct sockaddr *)&sa;
- int alen = sizeof(sa);
int n;
char *cp;
int _flags = 0;
@@ -2468,114 +2327,79 @@
if ((fp != nil)
&& __isSmallInteger(startIndex)
&& __isSmallInteger(count)) {
- sock = fileno(__FILEVal(fp));
-
- if (addrBytes == nil) {
- alen = 0;
- saPtr = (struct sockaddr *)0;
- } else {
- if (! __isByteArray(addrBytes)) goto bad;
-
- cp = (char *)__ByteArrayInstPtr(addrBytes)->ba_element;
- n = __byteArraySize(addrBytes);
- if (alen < n) n = alen;
-# ifdef DGRAM_DEBUG
- printf("address is %d bytes ... %d.%d.%d.%d\n", n, cp[0], cp[1], cp[2], cp[3]);
-# endif
- bcopy(cp, &sa.in.sin_addr.s_addr, n);
-
- if (0) {
- /* for else below */
- }
-# ifdef AF_INET
- else if (__INST(domain) == @symbol(inet)) {
- sa.in.sin_family = AF_INET;
- sa.in.sin_port = htons((u_short) __intVal(portNo));
- }
-# endif
-# ifdef AF_INET6
- else if (__INST(domain) == @symbol(inet6)) {
- sa.in6.sin6_family = AF_INET6;
- sa.in6.sin6_port = htons((u_short) __intVal(portNo));
- }
-# endif
-# ifdef AF_APPLETALK
- else if (__INST(domain) == @symbol(appletalk)) {
- sa.at.sat_family = AF_APPLETALK;
- sa.at.sat_port = __intVal(portNo);
- }
-# endif
-# ifdef AF_IRDA
- else if (__INST(domain) == @symbol(irda)) {
- }
+ sock = fileno(__FILEVal(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;
+ sockaddr_ptr = (struct sockaddr *)(__byteArrayVal(addr) + sockAddrOffs);
+ }
+
+ oClass = __Class(aDataBuffer);
+ switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+ case BYTEARRAY:
+ offs = __intVal(startIndex) - 1;
+ break;
+ case WORDARRAY:
+ case SWORDARRAY:
+ offs = (__intVal(startIndex) - 1) * 2;
+ break;
+ case LONGARRAY:
+ case SLONGARRAY:
+ offs = (__intVal(startIndex) - 1) * 4;
+ break;
+ case LONGLONGARRAY:
+ case SLONGLONGARRAY:
+ offs = (__intVal(startIndex) - 1) * 8;
+# ifdef __NEED_LONGLONG_ALIGN
+ offs += 4;
# endif
- }
-
- oClass = __Class(aDataBuffer);
- switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
- case BYTEARRAY:
- offs = __intVal(startIndex) - 1;
- break;
- case WORDARRAY:
- case SWORDARRAY:
- offs = (__intVal(startIndex) - 1) * 2;
- break;
- case LONGARRAY:
- case SLONGARRAY:
- offs = (__intVal(startIndex) - 1) * 4;
- break;
- case LONGLONGARRAY:
- case SLONGLONGARRAY:
- offs = (__intVal(startIndex) - 1) * 8;
-# ifdef __NEED_LONGLONG_ALIGN
- offs += 4;
-# endif
- break;
- case FLOATARRAY:
- offs = (__intVal(startIndex) - 1) * sizeof(float);
- break;
- case DOUBLEARRAY:
- offs = (__intVal(startIndex) - 1) * sizeof(double);
+ break;
+ case FLOATARRAY:
+ offs = (__intVal(startIndex) - 1) * sizeof(float);
+ break;
+ case DOUBLEARRAY:
+ offs = (__intVal(startIndex) - 1) * sizeof(double);
# ifdef __NEED_DOUBLE_ALIGN
- offs += 4;
+ offs += 4;
# endif
- break;
- default:
- goto bad;
- }
- nBytes = __intVal(count);
-
- nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
- nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
- objSize = __qSize(aDataBuffer) - nInstBytes;
- if ((offs + nBytes) > objSize) {
-# ifdef DGRAM_DEBUG
- printf("cut off ...\n");
-# endif
- nBytes = objSize - offs;
- }
-
- norder = htonl(sa.in.sin_addr.s_addr);
+ break;
+ default:
+ goto bad;
+ }
+ nBytes = __intVal(count);
+
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+ objSize = __qSize(aDataBuffer) - nInstBytes;
+ if ((offs + nBytes) > objSize) {
# ifdef DGRAM_DEBUG
- printf("sending %d bytes ... to ", nBytes);
- printf("%d.%d.%d.%d\n",
- (norder >> 24) & 0xFF,
- (norder >> 16) & 0xFF,
- (norder >> 8) & 0xFF,
- norder & 0xFF);
+ printf("cut off ...\n");
# endif
-
- __BEGIN_INTERRUPTABLE__
- do {
- cp = (char *)__InstPtr(aDataBuffer) + nInstBytes + offs;
- n = sendto(sock, cp, nBytes, _flags, saPtr, alen);
- } while ((n < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
-
- if (n < 0) {
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- }
- RETURN (__MKSMALLINT(n));
+ nBytes = objSize - offs;
+ }
+
+ __BEGIN_INTERRUPTABLE__
+ do {
+ sockaddr_ptr = (struct sockaddr *)(__byteArrayVal(addr) + sockAddrOffs);
+ cp = (char *)__InstPtr(aDataBuffer) + nInstBytes + offs;
+ n = sendto(sock, cp, nBytes, _flags, sockaddr_ptr, sockaddr_size);
+ } while ((n < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+
+ if (n < 0) {
+ __INST(lastErrorNumber) = __MKSMALLINT(errno);
+ }
+ RETURN (__MKSMALLINT(n));
}
#endif
bad: ;
@@ -2632,453 +2456,129 @@
reuseAddress:true
!
-bindTo:portNrOrName address:address reuseAddress:reuse
+bindTo:portNrOrNameOrNil address:hostOrPathNameOrSocketAddrOrNil reuseAddress:reuse
"low level bind - returns true if ok, false otherwise.
Currently only non-address binding is supported;
i.e. address must always be nil.
The interpretation of portNrOrName depends on the domain:
- inet domain uses (4byte) byteArray like internet numbers,
- unix domain uses pathname strings,
- others use whatever will come up in the future
+ inet domain uses (4byte) byteArray like internet numbers,
+ unix domain uses pathname strings,
+ others use whatever will come up in the future
The reuse boolean argument controls if the SO_REUSEADDR socket option
is to be set (to avoid the 'bind: address in use' error).
"
+ |ok addr addrName domainClass|
+
filePointer isNil ifTrue:[
- ^ self errorNotOpen
+ ^ self errorNotOpen
+ ].
+
+ domainClass := self class socketAddressClassForDomain:domain.
+ domainClass isNil ifTrue:[
+ ^ self error:'invalid (unsupported) domain'.
].
+
+ "/ backward compatibility: support for byteArray and string arg
+
+ hostOrPathNameOrSocketAddrOrNil isNil ifTrue:[
+ addr := domainClass anyHost.
+ ] ifFalse:[
+ hostOrPathNameOrSocketAddrOrNil isString ifTrue:[
+ addr := domainClass hostName:hostOrPathNameOrSocketAddrOrNil.
+ addrName := hostOrPathNameOrSocketAddrOrNil.
+ ] ifFalse:[
+ (hostOrPathNameOrSocketAddrOrNil isKindOf:SocketAddress) ifTrue:[
+ addr := hostOrPathNameOrSocketAddrOrNil.
+ portNrOrNameOrNil notNil ifTrue:[
+ addr port:portNrOrNameOrNil.
+ ].
+ ] ifFalse:[
+ hostOrPathNameOrSocketAddrOrNil isByteArray ifFalse:[
+ ^ self error:'bad host (socketAddress) argument'
+ ].
+ addr := domainClass hostAddress:hostOrPathNameOrSocketAddrOrNil.
+ ].
+ ].
+ ].
+ portNrOrNameOrNil notNil ifTrue:[
+ addr port:portNrOrNameOrNil.
+ ].
+
%{ /* STACK: 100000 */
#ifndef NO_SOCKET
OBJ t = __INST(filePointer);
OBJ myDomain;
int sock;
union sockaddr_u sa;
- int sockaddr_size;
+ struct sockaddr *sockaddr_ptr;
+ int sockaddr_size;
int ret;
int on = 1;
- int ok;
-
- if (!__isString(__INST(domain)) && !__isSymbol(__INST(domain))) {
- DBGPRINTF(("SOCKET: invalid domain arg\n"));
- RETURN (false);
- }
-
- ok = 0;
- myDomain = __INST(domain);
-
- if (0) {
- /* for else below */
- }
-
-# ifdef AF_INET
- else if (myDomain == @symbol(inet)) {
- /*
- * INET addresses - port must be a smallinteger or nil
- */
- sa.in.sin_family = AF_INET;
-
- if (portNrOrName == nil) {
- sa.in.sin_port = 0;
- } else {
- if (! __isSmallInteger(portNrOrName)) {
- DBGPRINTF(("SOCKET: invalid port arg\n"));
- RETURN (false);
- }
- sa.in.sin_port = htons((u_short) __intVal(portNrOrName));
- }
-
- /*
- * INET addresses - addr must be nil, integer or byteArray
- */
- if (address == nil) {
- sa.in.sin_addr.s_addr = htonl(INADDR_ANY);
- } else {
- if (__isInteger(address)) {
- sa.in.sin_addr.s_addr = htonl(__longIntVal(address));
- } else {
- if (__isByteArray(address)) {
- unsigned char *cp;
- int n;
-
- cp = __ByteArrayInstPtr(address)->ba_element;
- n = __byteArraySize(address);
- if (n > 4) n = 4;
- bcopy(cp, &sa.in.sin_addr.s_addr, n);
- } else {
- unsigned addr;
- struct hostent *hp ;
-
- if (! __isString(address)) {
- DBGPRINTF(("SOCKET: invalid address arg in bind\n"));
- RETURN (false);
- }
-
- if ((addr = inet_addr(__stringVal(address))) != -1) {
- /*
- * is Internet addr in octet notation
- */
- bcopy(&addr, (char *) &sa.in.sin_addr, sizeof(addr)) ; /* set address */
- } else {
- /*
- * do we know the host's address?
- */
- GETHOSTBYNAME(hp, __stringVal(address))
- if (hp == NULL) {
- DBGPRINTF(("SOCKET: unknown host:%s\n", __stringVal(address)));
- RETURN (false);
- }
- if (hp->h_addrtype != AF_INET) {
- DBGPRINTF(("SOCKET: host:%s is not an inet host\n", __stringVal(address)));
- RETURN (false);
- }
- bcopy(hp->h_addr, (char *) &sa.in.sin_addr, hp->h_length) ;
- sa.in.sin_family = hp->h_addrtype;
- }
- }
- }
- }
- DBGPRINTF(("SOCKET: bind addr: %x port: %x\n", sa.in.sin_addr.s_addr, sa.in.sin_port));
- sockaddr_size = sizeof(struct sockaddr_in);
- ok = 1;
- }
-# endif /* AF_INET */
-
-# ifdef AF_INET6
- else if (myDomain == @symbol(inet6)) {
- /*
- * INET6 addresses - port must be a smallinteger or nil
- */
- sa.in6.sin6_family = AF_INET6;
-
- if (portNrOrName == nil) {
- sa.in6.sin6_port = 0;
- } else {
- if (! __isSmallInteger(portNrOrName)) {
- DBGPRINTF(("SOCKET: invalid port arg\n"));
- RETURN (false);
- }
- sa.in6.sin6_port = htons((u_short) __intVal(portNrOrName));
- }
-
- /*
- * INET6 addresses - addr must be nil or byteArray or string
- */
- if (address == nil) {
- bzero(sa.in6.sin6_addr.s6_addr, sizeof(sa.in6.sin6_addr.s6_addr));
- } else {
- if (__isByteArray(address)) {
- unsigned char *cp;
- int n;
-
- cp = __ByteArrayInstPtr(address)->ba_element;
- n = __byteArraySize(address);
- if (n > sizeof(sa.in6.sin6_addr.s6_addr)) n = sizeof(sa.in6.sin6_addr.s6_addr);
- bcopy(cp, sa.in6.sin6_addr.s6_addr, n);
- } else {
- unsigned addr;
- struct hostent *hp ;
-
- if (! __isString(address)) {
- DBGPRINTF(("SOCKET: invalid address arg in bind\n"));
- RETURN (false);
- }
-
- /*
- * do we know the host's address?
- */
- GETHOSTBYNAME(hp, __stringVal(address))
- if (hp == NULL) {
- DBGPRINTF(("SOCKET: unknown host:%s\n", __stringVal(address)));
- RETURN (false);
- }
- if (hp->h_addrtype != AF_INET6) {
- DBGPRINTF(("SOCKET: host:%s is not an ipv6 host\n", __stringVal(address)));
- RETURN (false);
- }
- bcopy(hp->h_addr, (char *) &sa.in6.sin6_addr, hp->h_length) ;
- sa.in.sin_family = hp->h_addrtype;
- }
- }
-
- DBGPRINTF(("SOCKET: bind addr: %x.%x.%x.%x.%x.%x... port: %x\n",
- sa.in6.sin6_addr.s6_addr[0],
- sa.in6.sin6_addr.s6_addr[1],
- sa.in6.sin6_addr.s6_addr[2],
- sa.in6.sin6_addr.s6_addr[3],
- sa.in6.sin6_addr.s6_addr[4],
- sa.in6.sin6_addr.s6_addr[5],
- sa.in6.sin6_port));
- sockaddr_size = sizeof(struct sockaddr_in6);
- ok = 1;
+ int sockAddrOffs;
+
+ if (! __isBytes(addr)) {
+ addr = nil;
+ goto getOutOfHere;
}
-# endif /* AF_INET6 */
-
-# ifdef AF_UNIX
- /*
- * UNIX domain - port is ignored; address must be a string (path)
- */
- else if (myDomain == @symbol(unix)) {
- char *pathName;
- int l;
-
- if (! __isString(portNrOrName)) {
- DBGPRINTF(("SOCKET: invalid port (pathname) arg\n"));
- RETURN (false);
- }
- pathName = (char *)__stringVal(portNrOrName);
- l = strlen(pathName);
- if ((l + sizeof ( sa.un.sun_family )) > sizeof(struct sockaddr_un)) {
- DBGPRINTF(("SOCKET: pathname too long\n"));
- RETURN (false);
- }
-
- strcpy(sa.un.sun_path, pathName);
- sa.un.sun_family = AF_UNIX;
- sockaddr_size = l + sizeof ( sa.un.sun_family );
- ok = 1;
- }
-# endif /* AF_UNIX */
-
-# ifdef AF_APPLETALK
- /*
- * this has never been tested ....
- */
- else if (myDomain == @symbol(appletalk)) {
- /*
- * APPLETALK addresses - port must be a smallinteger or nil
- */
- sa.at.sat_family = AF_APPLETALK;
-
- if (portNrOrName == nil) {
- sa.at.sat_port = 0;
- } else {
- if (! __isSmallInteger(portNrOrName)) {
- DBGPRINTF(("SOCKET: invalid port arg\n"));
- RETURN (false);
- }
- sa.at.sat_port = __intVal(portNrOrName);
- }
-
- /*
- * APPLETALK addresses - addr must be nil, integer or byteArray
- * if integer, the first byte are the hi net bits, next byte are low net bits,
- * last byte is node.
- */
- if (address == nil) {
- sa.at.sat_addr.s_net = ATADDR_ANYNET;
- sa.at.sat_addr.s_node = ATADDR_ANYNODE;
- } else {
- if (__isInteger(address)) {
- unsigned a = __longIntVal(address);
- sa.at.sat_addr.s_net = htons((a >> 8) & 0xFFFF);
- sa.at.sat_addr.s_node = htons(a & 0xFF);
- } else {
- if (__isByteArray(address)) {
- unsigned char *cp;
- int n;
-
- cp = __ByteArrayInstPtr(address)->ba_element;
- n = __byteArraySize(address);
- if (n > 3) n = 3;
- bcopy(cp, &sa.at.sat_addr, n);
- } else {
- unsigned addr;
- struct hostent *hp ;
-
- if (! __isString(address)) {
- DBGPRINTF(("SOCKET: invalid address arg in bind\n"));
- RETURN (false);
- }
-
- /*
- * do we know the host's address?
- */
- GETHOSTBYNAME(hp, __stringVal(address))
- if (hp == NULL) {
- DBGPRINTF(("SOCKET: unknown host: %s\n", __stringVal(address)));
- RETURN (false);
- }
- if (hp->h_addrtype != AF_APPLETALK) {
- DBGPRINTF(("SOCKET: host:%s is not an appletalk host\n", __stringVal(address)));
- RETURN (false);
- }
- bcopy(hp->h_addr, (char *) &sa.at.sat_addr, hp->h_length) ;
- sa.at.sat_family = hp->h_addrtype;
- }
- }
- }
- DBGPRINTF(("SOCKET: bind addr: %x port: %x\n", sa.in.sin_addr.s_addr, sa.in.sin_port));
- sockaddr_size = sizeof(struct sockaddr_at);
- ok = 1;
- }
-# endif /* AF_APPLETALK */
-
- /*
- * XXXX add addressing stuff for other domains here ...
- */
-# ifdef AF_X25
- else if (myDomain == @symbol(x25)) {
- }
-# endif
-# ifdef AF_AX25
- else if (myDomain == @symbol(ax25)) {
- }
-# endif
-# ifdef AF_NS
- else if ((myDomain == @symbol(ns))
- || (myDomain == @symbol(xns))) {
- }
-# endif
-# ifdef AF_DECnet
- else if (myDomain == @symbol(decnet)) {
- }
-# endif
-# ifdef AF_SNA
- else if (myDomain == @symbol(sna)) {
- }
-# endif
-# ifdef AF_RAW
- else if (myDomain == @symbol(raw)) {
- }
-# endif
-# ifdef AF_ISO
- else if (myDomain == @symbol(iso)) {
- }
-# endif
-# ifdef AF_NETBIOS
- else if (myDomain == @symbol(netbios)) {
- }
-# endif
-# ifdef AF_IPX
- else if (myDomain == @symbol(ipx)) {
- }
-# endif
-# ifdef AF_BRIDGE
- else if (myDomain == @symbol(bridge)) {
- }
-# endif
-# ifdef AF_BSC
- else if (myDomain == @symbol(bsc)) {
- }
-# endif
-# ifdef AF_ROSE
- else if (myDomain == @symbol(rose)) {
- }
-# endif
-# ifdef AF_IRDA
- else if (myDomain == @symbol(irda)) {
- }
-# endif
-# if defined(AF_CCITT) && (AF_CCITT != AF_X25)
- else if (myDomain == @symbol(ccitt)) {
- }
-# endif
-
- if (! ok) {
- DBGPRINTF(("SOCKET: unsupported domain\n"));
- RETURN (false);
+
+ {
+ 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;
+ sockaddr_ptr = (struct sockaddr *)(__byteArrayVal(addr) + sockAddrOffs);
}
sock = fileno(__FILEVal(t));
# ifdef SO_REUSEADDR
if (reuse == true) {
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
- DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
- }
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
+ DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
+ }
}
# endif /* SO_REUSEADDR */
__BEGIN_INTERRUPTABLE__
do {
- ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
+ sockaddr_ptr = (struct sockaddr *)(__byteArrayVal(addr) + sockAddrOffs);
+ ret = bind(sock, sockaddr_ptr, sockaddr_size);
} while ((ret < 0) && (errno == EINTR));
__END_INTERRUPTABLE__
if (ret < 0) {
- DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- RETURN (false);
- }
-
- __INST(port) = portNrOrName; __STORE(self, portNrOrName);
-
- if (0) {
- /* for else below */
- }
-
-# ifdef AF_INET
- else if (myDomain == @symbol(inet)) {
- if (! __isSmallInteger(portNrOrName)
- || (portNrOrName == __MKSMALLINT(0))) {
- int p;
-
- /*
- * INET anonymous port - get the actual portNr
- */
- if (getsockname(sock, (struct sockaddr *)&sa, &sockaddr_size) < 0) {
- DBGPRINTF(("SOCKET: cannot get peername\n"));
- } else {
- DBGPRINTF(("SOCKET: anon port=%x\n", sa.in.sin_port));
- p = ntohs(sa.in.sin_port);
- __INST(port) = __MKSMALLINT(p);
- }
- }
+ DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
+ __INST(lastErrorNumber) = __MKSMALLINT(errno);
+ RETURN (false);
+ } else {
+ ok = true;
}
-# endif
-
-# ifdef AF_INET6
- else if (myDomain == @symbol(inet6)) {
- if (! __isSmallInteger(portNrOrName)
- || (portNrOrName == __MKSMALLINT(0))) {
- int p;
-
- /*
- * INET6 anonymous port - get the actual portNr
- */
- if (getsockname(sock, (struct sockaddr *)&sa, &sockaddr_size) < 0) {
- DBGPRINTF(("SOCKET: cannot get peername\n"));
- } else {
- DBGPRINTF(("SOCKET: anon port=%x\n", sa.in.sin_port));
- p = ntohs(sa.in6.sin6_port);
- __INST(port) = __MKSMALLINT(p);
- }
- }
- }
-# endif
-
-# ifdef AF_APPLETALK
- else if (myDomain == @symbol(appletalk)) {
- if (! __isSmallInteger(portNrOrName)
- || (portNrOrName == __MKSMALLINT(0))) {
- int p;
-
- /*
- * APPLETALK anonymous port - get the actual portNr
- */
- if (getsockname(sock, (struct sockaddr *)&sa, &sockaddr_size) < 0) {
- DBGPRINTF(("SOCKET: cannot get peername\n"));
- } else {
- DBGPRINTF(("SOCKET: anon port=%x\n", sa.in.sin_port));
- p = sa.at.sat_port;
- __INST(port) = __MKSMALLINT(p);
- }
- }
- }
-# endif
-
-#else /* NO_SOCKET */
- RETURN (false);
+
#endif /* NO_SOCKET */
+
+getOutOfHere: ;
%}.
+ ok ~~ true ifTrue:[
+ ^ false
+ ].
+
+ peer := addr.
+ port := addr port.
+ peerName := addrName.
+
^ true
"
(Socket domain:#inet type:#stream)
- bindTo:9999
- address:nil
+ bindTo:9999
+ address:nil
"
!
@@ -3113,25 +2613,25 @@
result of an asynchronous operation"
%{
+#ifndef NO_SOCKET
OBJ t;
int err;
t = __INST(filePointer);
if (t == nil)
- err = EBADF;
+ err = EBADF;
else {
- int sz, fd;
-
- fd = fileno(__FILEVal(t));
- sz = sizeof(err);
- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &sz) < 0)
- err = errno;
+ int sz, fd;
+
+ fd = fileno(__FILEVal(t));
+ sz = sizeof(err);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &sz) < 0)
+ err = errno;
}
RETURN(__MKSMALLINT(err));
+#endif
%}
-
-
!
listenFor:aNumber
@@ -3250,7 +2750,7 @@
usage is: (Socket basicNew acceptOn:(Socket onIPPort:9999)).
Return the true if ok; false if not."
- |serverSocketFd addrBytes|
+ |serverSocketFd addr addrLen domainClass|
filePointer notNil ifTrue:[
^ self errorAlreadyOpen
@@ -3265,6 +2765,14 @@
(serverSocketFd isMemberOf:SmallInteger) ifFalse:[
^ self error:'invalid server socket'
].
+
+ domainClass := self class socketAddressClassForDomain:domain.
+ domainClass isNil ifTrue:[
+ ^ self error:'invalid (unsupported) domain'.
+ ].
+ addrLen := domainClass socketAddressSize.
+ addr := domainClass new.
+
%{ /* STACK: 100000 */
#ifndef NO_SOCKET
FILE *fp;
@@ -3275,96 +2783,11 @@
struct hostent *he ;
char dotted[20] ;
- if (0) {
- /* for else below */
- }
-# ifdef AF_INET
- else if (__INST(domain) == @symbol(inet)) {
- alen0 = sizeof(sa.in);
- }
-# endif
-# ifdef AF_INET6
- else if (__INST(domain) == @symbol(inet6)) {
- alen0 = sizeof(sa.in6);
- }
-# endif
-# ifdef AF_UNIX
- else if (__INST(domain) == @symbol(unix)) {
- alen0 = sizeof(sa.un);
- }
-# endif
-# ifdef AF_APPLETALK
- else if (__INST(domain) == @symbol(appletalk)) {
- alen0 = sizeof(sa.at);
- }
-# endif
-
- /*
- * XXXX add addressing stuff for other domains here ...
- */
-# ifdef AF_X25
- else if (__INST(domain) == @symbol(x25)) {
- alen0 = sizeof(sa.x25);
- }
-# endif
-# ifdef AF_AX25
- else if (__INST(domain) == @symbol(ax25)) {
- alen0 = sizeof(sa.ax25);
- }
-# endif
-# ifdef AF_NS
- else if ((__INST(domain) == @symbol(ns))
- || (__INST(domain) == @symbol(xns))) {
+ if (!__isSmallInteger(addrLen)) {
+ DBGPRINTF(("SOCKET: bad addrLen\n"));
+ RETURN (false);
}
-# endif
-# ifdef AF_DECnet
- else if (__INST(domain) == @symbol(decnet)) {
- alen0 = sizeof(sa.dn);
- }
-# endif
-# ifdef AF_SNA
- else if (__INST(domain) == @symbol(sna)) {
- alen0 = sizeof(sa.sna);
- }
-# endif
-# ifdef AF_RAW
- else if (__INST(domain) == @symbol(raw)) {
- }
-# endif
-# ifdef AF_ISO
- else if (__INST(domain) == @symbol(iso)) {
- }
-# endif
-# ifdef AF_NETBIOS
- else if (__INST(domain) == @symbol(netbios)) {
- }
-# endif
-# ifdef AF_IPX
- else if (__INST(domain) == @symbol(ipx)) {
- alen0 = sizeof(sa.ipx);
- }
-# endif
-# ifdef AF_BRIDGE
- else if (__INST(domain) == @symbol(bridge)) {
- }
-# endif
-# ifdef AF_BSC
- else if (__INST(domain) == @symbol(bsc)) {
- }
-# endif
-# ifdef AF_ROSE
- else if (__INST(domain) == @symbol(rose)) {
- }
-# endif
-# ifdef AF_IRDA
- else if (__INST(domain) == @symbol(irda)) {
- }
-# endif
-# if defined(AF_CCITT) && (AF_CCITT != AF_X25)
- else if (__INST(domain) == @symbol(ccitt)) {
- }
-# endif
-
+ alen0 = __intVal(addrLen);
sock = __intVal(serverSocketFd);
@@ -3391,155 +2814,34 @@
RETURN (false);
}
- /*
- * extract the partners address
- */
- if (0) {
- /* for else below */
- }
-
-# ifdef AF_INET
- else if (__INST(domain) == @symbol(inet)) {
-# ifdef RESOLVE_NAME_NOW
- GETHOSTBYADDR(he, (char *) &sa.in.sin_addr, sizeof(sa.in.sin_addr), AF_INET);
- if (! he) {
- unsigned long norder;
-
- norder = htonl(sa.in.sin_addr.s_addr) ;
- sprintf(dotted, "%d.%d.%d.%d",
- (norder >> 24) & 0xFF,
- (norder >> 16) & 0xFF,
- (norder >> 8) & 0xFF,
- norder & 0xFF);
+ if (__isNonNilObject(addr)) {
+ OBJ oClass;
+ int nInstVars, nInstBytes, objSize;
+ char *cp;
+
+ oClass = __qClass(addr);
+ if (! __isBytes(addr) ) {
+ DBGPRINTF(("SOCKET: bad addr\n"));
+ close(newSock);
+ RETURN (false);
}
- DBGPRINTF(("SOCKET: accepted connection from host %s\n", (he ? he->h_name : dotted))) ;
- __INST(peerName) = __MKSTRING((he ? he->h_name : dotted));
- __STORESELF(peerName);
-# else
- addrBytes = __MKBYTEARRAY(&sa.in, sizeof(sa.in));
-# endif
- }
-# endif
-
-# ifdef AF_INET6
- else if (__INST(domain) == @symbol(inet6)) {
-# ifdef RESOLVE_NAME_NOW
- GETHOSTBYADDR(he, (char *) &sa.in6.sin6_addr, sizeof(sa.in6.sin6_addr), AF_INET6);
- if (! he) {
- unsigned long norder;
-
- /*
- * XXX: what is inet6's naming convention ?
- */
- norder = htonl(sa.in.sin_addr.s_addr) ;
- sprintf(dotted, "%d.%d.%d.%d.%d.%d...",
- sa.in6.sin6_addr.s6_addr[0],
- sa.in6.sin6_addr.s6_addr[1],
- sa.in6.sin6_addr.s6_addr[2],
- sa.in6.sin6_addr.s6_addr[3],
- sa.in6.sin6_addr.s6_addr[4],
- sa.in6.sin6_addr.s6_addr[5]);
+
+ nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+ nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
+ objSize = __qSize(addr) - nInstBytes;
+ cp = (char *)__InstPtr(addr) + nInstBytes;
+ if (objSize < alen) {
+ DBGPRINTF(("SOCKET: bad addr\n"));
+ close(newSock);
+ RETURN (false);
}
- DBGPRINTF(("SOCKET: accepted connection from host %s\n", (he ? he->h_name : dotted))) ;
- __INST(peerName) = __MKSTRING((he ? he->h_name : dotted));
- __STORESELF(peerName);
-# else
- addrBytes = __MKBYTEARRAY(&sa.in6, sizeof(sa.in6));
-# endif
- }
-# endif
-
-# ifdef AF_UNIX
- else if (__INST(domain) == @symbol(unix)) {
- DBGPRINTF(("SOCKET: accepted connection on unix socket\n")) ;
- /* nothing to be done here */
+
+ /*
+ * extract the partners address
+ */
+ bcopy((char *)&sa, cp, alen);
+ addrLen = __MKSMALLINT(alen);
}
-# endif
-
-# ifdef AF_APPLETALK
- else if (__INST(domain) == @symbol(appletalk)) {
-# ifdef RESOLVE_NAME_NOW
- GETHOSTBYADDR(he, (char *) &sa.at.sat_addr, sizeof(sa.at.sat_addr), AF_APPLETALK);
- if (! he) {
- unsigned net;
-
- /*
- * XXX: what is apples naming convention ?
- */
- net = htons(sa.at.sat_addr.s_net) ;
- sprintf(dotted, "%d.%d",
- net,
- sa.at.sat_addr.s_node);
- }
- DBGPRINTF(("SOCKET: accepted connection from host %s\n", (he ? he->h_name : dotted))) ;
- __INST(peerName) = __MKSTRING((he ? he->h_name : dotted));
- __STORESELF(peerName);
-# else
- addrBytes = __MKBYTEARRAY(&sa.at, sizeof(sa.at));
-# endif
- }
-# endif
-
- /*
- * XXXX add addressing stuff for other domains here ...
- */
-# ifdef AF_X25
- else if (__INST(domain) == @symbol(x25)) {
- }
-# endif
-# ifdef AF_AX25
- else if (__INST(domain) == @symbol(ax25)) {
- }
-# endif
-# ifdef AF_NS
- else if ((__INST(domain) == @symbol(ns))
- || (__INST(domain) == @symbol(xns))) {
- }
-# endif
-# ifdef AF_DECnet
- else if (__INST(domain) == @symbol(decnet)) {
- }
-# endif
-# ifdef AF_SNA
- else if (__INST(domain) == @symbol(sna)) {
- }
-# endif
-# ifdef AF_RAW
- else if (__INST(domain) == @symbol(raw)) {
- }
-# endif
-# ifdef AF_ISO
- else if (__INST(domain) == @symbol(iso)) {
- }
-# endif
-# ifdef AF_NETBIOS
- else if (__INST(domain) == @symbol(netbios)) {
- }
-# endif
-# ifdef AF_IPX
- else if (__INST(domain) == @symbol(ipx)) {
- }
-# endif
-# ifdef AF_BRIDGE
- else if (__INST(domain) == @symbol(bridge)) {
- }
-# endif
-# ifdef AF_BSC
- else if (__INST(domain) == @symbol(bsc)) {
- }
-# endif
-# ifdef AF_ROSE
- else if (__INST(domain) == @symbol(rose)) {
- }
-# endif
-# ifdef AF_IRDA
- else if (__INST(domain) == @symbol(irda)) {
- }
-# endif
-# if defined(AF_CCITT) && (AF_CCITT != AF_X25)
- else if (__INST(domain) == @symbol(ccitt)) {
- }
-# endif
/*
* make it a FILE *
@@ -3570,9 +2872,8 @@
binary := false.
port := aSocket port.
- addrBytes notNil ifTrue:[
- addrBytes changeClassTo:(self class socketAddressClassForDomain:domain).
- peer := addrBytes.
+ addr notNil ifTrue:[
+ peer := addr.
].
^ true
@@ -4100,289 +3401,6 @@
Socket new domain:#inet type:#stream
Socket new domain:#unix type:#stream
"
-!
-
-for:hostName port:portNr
- "setup for a TCP socket (i.e. inet domain, stream type)
- If hostname is nil, a server port is opened,
- otherwise a client port to the server on host.
-
- HISTORIC LEFTOVER:
- This method will vanish, as soon as the low level
- connect/bind works,"
-
- self obsoleteMethodWarning.
-
- filePointer notNil ifTrue:[
- ^ self errorAlreadyOpen
- ].
- (portNr isMemberOf:SmallInteger) ifFalse:[
- self error:'invalid portNr'
- ].
-%{ /* STACK: 100000 */
-#ifndef NO_SOCKET
- struct sockaddr_in sa ;
- struct hostent *hp ;
- int a, sock ;
- long addr;
- FILE *fp;
- int ret;
- int on = 1;
-
- bzero((char *) &sa, sizeof(sa)) ;
- sa.sin_family = AF_INET;
- sa.sin_addr.s_addr = htonl(INADDR_ANY);
-
- if ((hostName != nil) && __isString(hostName)){
- bzero(&sa, sizeof(sa)) ;
- if ((addr = inet_addr((char *) __stringVal(hostName))) != -1) {
- /*
- * is Internet addr in octet notation
- */
- bcopy(&addr, (char *) &sa.sin_addr, sizeof(addr)) ; /* set address */
- } else {
- /*
- * do we know the host's address?
- */
- GETHOSTBYNAME(hp, __stringVal(hostName))
- if (hp == NULL) {
- DBGPRINTF(("SOCKET: unknown host: %s\n", __stringVal(hostName)));
- RETURN ( nil );
- }
- bcopy(hp->h_addr, (char *) &sa.sin_addr, hp->h_length) ;
- sa.sin_family = hp->h_addrtype;
- }
- }
-
- /*
- * create the socket
- */
- __BEGIN_INTERRUPTABLE__
- do {
- sock = socket(sa.sin_family, SOCK_STREAM, 0);
- } while ((sock < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- DBGFPRINTF((stderr, "socket create newSock=%d\n", sock));
-
- if (sock < 0) {
- DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=0) call failed errno=%d\n", sa.sin_family, SOCK_STREAM, errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- } else {
- /*
- * connect/bind
- */
- sa.sin_port = htons((u_short) __intVal(portNr)) ;
-
- __BEGIN_INTERRUPTABLE__
- if (hostName != nil) {
- do {
- ret = connect(sock, (struct sockaddr *)&sa, sizeof(sa));
- } while ((ret < 0) && (errno == EINTR));
- } else {
-#ifdef SO_REUSEADDR
- /*
- * should I also do this for DGRAM sockets ?
- */
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
- DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
- }
-#endif /* SO_REUSEADDR */
- sa.sin_addr.s_addr = htonl(INADDR_ANY);
- do {
- ret = bind(sock, (struct sockaddr *)&sa, sizeof(sa));
- } while ((ret < 0) && (errno == EINTR));
- }
- __END_INTERRUPTABLE__
-
- if (ret < 0) {
- DBGPRINTF(("SOCKET: bind/connect call failed errno=%d\n", errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- __BEGIN_INTERRUPTABLE__
- close(sock) ;
- DBGFPRINTF((stderr, "socket close (fdopen failed) (%d)\n", sock));
- __END_INTERRUPTABLE__
- } else {
- /*
- * make it a FILE *
- */
- fp = fdopen(sock, "r+");
- if (! fp) {
- DBGPRINTF(("SOCKET: fdopen failed\n"));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- __BEGIN_INTERRUPTABLE__
- close(sock);
- DBGFPRINTF((stderr, "socket close (fdopen failed) (%d)\n", sock));
- __END_INTERRUPTABLE__
- } else {
- if (@global(FileOpenTrace) == true) {
- fprintf(stderr, "fdopen [Socket] -> %x\n", fp);
- }
-
-#ifdef BUGGY_STDIO_LIB
- setbuf(fp, NULL);
- __INST(buffered) = false;
-#endif
- __INST(filePointer) = __MKOBJ(fp);
- __STORESELF(filePointer);
- }
- }
- }
-#endif
-%}.
- filePointer isNil ifTrue:[
- ^ nil
- ].
- mode := #readwrite.
- Lobby register:self.
- binary := false.
-
- domain := #inet.
- socketType := #stream.
- protocol := portNr.
- peerName := hostName.
-
- "
- Socket new for:'clam' port:(Socket portOfService:'echo')
-
- Socket new for:nil port:9999
- Socket new for:(OperatingSystem getHostName) port:9999
- "
-!
-
-for:hostName udpPort:portNr
- "setup for a UDP socket (i.e. inet domain, datagram type)
- if hostname is nil, a server port is opened;
- otherwise a client port to the server on host.
-
- HISTORIC LEFTOVER:
- This method will vanish, as soon as the low level
- connect/bind works,"
-
- self obsoleteMethodWarning.
-
- filePointer notNil ifTrue:[
- ^ self errorAlreadyOpen
- ].
- (portNr isMemberOf:SmallInteger) ifFalse:[
- self error:'invalid portNr'
- ].
-%{ /* STACK: 100000 */
-#ifndef NO_SOCKET
- struct sockaddr_in sa ;
- struct hostent *hp ;
- int a, sock ;
- long addr;
- FILE *fp;
- int ret;
-
- if (hostName != nil) {
- bzero(&sa, sizeof(sa)) ;
- if ((addr = inet_addr((char *) __stringVal(hostName))) != -1) {
- /*
- * is Internet addr in octet notation
- */
- bcopy(&addr, (char *) &sa.sin_addr, sizeof(addr)) ; /* set address */
- sa.sin_family = AF_INET ;
- } else {
- /*
- * is hostname -
- * do we know the host's address?
- */
- GETHOSTBYNAME(hp, __stringVal(hostName))
- if (hp == NULL) {
- DBGPRINTF(("SOCKET: unknown host: %s\n", __stringVal(hostName)));
- RETURN ( nil );
- }
- bcopy(hp->h_addr, (char *) &sa.sin_addr, hp->h_length) ;
- sa.sin_family = hp->h_addrtype ;
- }
- } else {
- sa.sin_family = AF_INET;
- }
-
- /*
- * create the socket
- */
- __BEGIN_INTERRUPTABLE__
- do {
- sock = socket(sa.sin_family, SOCK_DGRAM, 0);
- } while ((sock < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- DBGFPRINTF((stderr, "socket create newSock=%d\n", sock));
-
- if (sock < 0) {
- DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=0) call failed errno=%d\n", sa.sin_family, SOCK_DGRAM, errno));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- } else {
- /*
- * ok,
- * connect/bind
- */
- __BEGIN_INTERRUPTABLE__
- if (hostName == nil) {
- sa.sin_addr.s_addr = htonl(INADDR_ANY);
- do {
- ret = bind(sock, (struct sockaddr *)&sa, sizeof(sa));
- } while ((ret < 0) && (errno == EINTR));
- } else {
- sa.sin_port = htons((u_short) __intVal(portNr)) ;
- do {
- ret = connect(sock, (struct sockaddr *)&sa, sizeof(sa));
- } while ((ret < 0) && (errno == EINTR));
- }
- __END_INTERRUPTABLE__
-
- if (ret < 0) {
- DBGPRINTF(("SOCKET: bind/connect call failed\n"));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- __BEGIN_INTERRUPTABLE__
- close(sock) ;
- DBGFPRINTF((stderr, "socket close (fdopen failed) (%d)\n", sock));
- __END_INTERRUPTABLE__
- } else {
- /*
- * make it a FILE *
- */
- fp = fdopen(sock, "r+");
- if (! fp) {
- DBGPRINTF(("SOCKET: fdopen call failed\n"));
- __INST(lastErrorNumber) = __MKSMALLINT(errno);
- __BEGIN_INTERRUPTABLE__
- close(sock);
- DBGFPRINTF((stderr, "socket close (fdopen failed) (%d)\n", sock));
- __END_INTERRUPTABLE__
- } else {
- if (@global(ExternalStream:FileOpenTrace) == true) {
- fprintf(stderr, "fdopen [Socket] -> %x\n", fp);
- }
-
-#ifdef BUGGY_STDIO_LIB
- setbuf(fp, NULL);
- __INST(buffered) = false;
-#endif
- __INST(filePointer) = __MKOBJ(fp);
- __STORESELF(filePointer);
- }
- }
- }
-#endif
-%}.
- filePointer isNil ifTrue:[
- ^ nil
- ].
-
- mode := #readwrite.
- Lobby register:self.
- binary := false.
-
- domain := #inet.
- socketType := #datagram.
- protocol := portNr.
- peerName := hostName.
-
- "
- Socket new for:'clam' udpPort:(Socket portOfService:'echo')
- "
! !
!Socket methodsFor:'specials'!
@@ -4446,5 +3464,5 @@
!Socket class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.183 2003-07-15 12:20:11 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.184 2003-07-17 13:24:40 cg Exp $'
! !