Socket.st
branchjv
changeset 3619 ae55ba1cd11e
parent 3594 f2577133d3d2
parent 3617 2cb8727b8e0f
child 3623 8d9865be083a
--- a/Socket.st	Wed Sep 23 06:43:37 2015 +0200
+++ b/Socket.st	Wed Sep 30 07:05:19 2015 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 1992 by Claus Gittinger
 	      All Rights Reserved
@@ -136,78 +134,74 @@
 %{
 
 static int
-setupBufferParameters(aDataBuffer, startIndex, p_extPtr, p_offs, p_objSize)
-    OBJ aDataBuffer, startIndex;
-    char **p_extPtr;
-    int *p_offs;
-    int *p_objSize;
+setupBufferParameters(OBJ aDataBuffer, OBJ startIndex, char **p_extPtr, INT *p_offs, size_t *p_objSize)
 {
-	char *extPtr = 0;
-	int sIdx = 0, objSize = 0, offs = 0;
-
-	sIdx = 0;
-	if (__isSmallInteger(startIndex)) {
-	    sIdx = __intVal(startIndex) - 1;
-	}
-
-	if (__isExternalBytesLike(aDataBuffer)) {
-	    OBJ sz;
-
-	    extPtr = (char *)(__externalBytesAddress(aDataBuffer));
-	    sz = __externalBytesSize(aDataBuffer);
-	    if (__isSmallInteger(sz)) {
-		objSize = __intVal(sz);
-	    } else {
-		objSize = 0; /* unknown */
-	    }
-	    offs = sIdx;
-	} else {
-	    OBJ oClass;
-	    int nInstVars, nInstBytes;
-
-	    extPtr = (char *)0;
-	    oClass = __Class(aDataBuffer);
-	    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;
+        char *extPtr = 0;
+        int sIdx = 0, objSize = 0, offs = 0;
+
+        sIdx = 0;
+        if (__isSmallInteger(startIndex)) {
+            sIdx = __intVal(startIndex) - 1;
+        }
+
+        if (__isExternalBytesLike(aDataBuffer)) {
+            OBJ sz;
+
+            extPtr = (char *)(__externalBytesAddress(aDataBuffer));
+            sz = __externalBytesSize(aDataBuffer);
+            if (__isSmallInteger(sz)) {
+                objSize = __intVal(sz);
+            } else {
+                objSize = 0; /* unknown */
+            }
+            offs = sIdx;
+        } else {
+            OBJ oClass;
+            int nInstVars, nInstBytes;
+
+            extPtr = (char *)0;
+            oClass = __Class(aDataBuffer);
+            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:
-		    *p_objSize = -1;
-		    return 0;
-	    }
-	    nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
-	    nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
-	    offs = offs + nInstBytes;
-	    objSize = __Size(aDataBuffer) - offs;
-	}
-	*p_extPtr = extPtr;
-	*p_objSize = objSize;
-	*p_offs = offs;
-	return 1;
+                    break;
+                default:
+                    *p_objSize = -1;
+                    return 0;
+            }
+            nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+            nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
+            offs = offs + nInstBytes;
+            objSize = __Size(aDataBuffer) - offs;
+        }
+        *p_extPtr = extPtr;
+        *p_objSize = objSize;
+        *p_offs = offs;
+        return 1;
 }
 %}
 ! !
@@ -2319,69 +2313,67 @@
     OBJ fp = __INST(handle);
 
     if (fp != nil) {
-	SOCKET sock;
-	INT objSize, offs;
-	INT n;
-	char *extPtr;
-	unsigned char *buffer;
-	unsigned char *allocatedBuffer = NULL;
-	INT flags = 0;
-
-	sock = SOCKET_FROM_FILE_OBJECT(fp);
-
-	if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
-	if (__isSmallInteger(nBytes)) {
-	    if (__intVal(nBytes) < objSize) {
-		objSize = __intVal(nBytes);
-	    }
-	}
+        SOCKET sock;
+        INT objSize, offs;
+        INT n;
+        char *extPtr;
+        unsigned char *buffer;
+        unsigned char *allocatedBuffer = NULL;
+        INT flags = 0;
+
+        sock = SOCKET_FROM_FILE_OBJECT(fp);
+
+        if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
+        if (__isSmallInteger(nBytes)) {
+            if (__intVal(nBytes) < objSize) {
+                objSize = __intVal(nBytes);
+            }
+        }
 
 # ifdef DO_WRAP_CALLS
-	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) {
-		bcopy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, 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) {
+                bcopy(allocatedBuffer, (char *)__InstPtr(aDataBuffer) + offs, n);
+            }
+            free(allocatedBuffer);
+        }
 # else
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    if (extPtr) {
-		n = recv(sock, extPtr + offs, objSize, flags);
-	    } else {
-		n = recv(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, flags);
-	    }
-	} while ((n < 0) && (errno == EINTR));
-	__END_INTERRUPTABLE__
+        __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:[
-	^ ReadError
-	    raiseRequestWith:self
-	    errorString:(' : ' , OperatingSystem errorTextForNumber:error)
+        ^ self readError:error.
     ].
     "
      arrive here if you try to receive into an invalid buffer (i.e. not ByteArray-like)
@@ -2398,10 +2390,14 @@
      On error, the unix error code is left in the lastErrorNumber
      instance variable."
 
-    ^ self receiveFrom:anAddressBuffer buffer:aDataBuffer start:1 for:(aDataBuffer size)
+    ^ self receiveFrom:anAddressBuffer buffer:aDataBuffer start:1 for:(aDataBuffer size) flags:0
 !
 
 receiveFrom:anAddressBuffer buffer:aDataBuffer start:startIndex for:nBytes
+    ^ self receiveFrom:anAddressBuffer buffer:aDataBuffer start:startIndex for:nBytes flags:0
+!
+
+receiveFrom:anAddressBuffer buffer:aDataBuffer start:startIndex for:nBytes flags:flags
     "receive datagramm data
      - put address of originating host into anAddressBuffer, data into aBuffer.
      For backward compatibility, the addressBuffer may be a non-SocketAddress;
@@ -2417,17 +2413,17 @@
 
     domainClass := self class socketAddressClassForDomain:domain.
     domainClass isNil ifTrue:[
-	^ self error:'invalid (unsupported) domain'.
+        ^ self error:'invalid (unsupported) domain'.
     ].
     (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
-	anAddressBuffer class == domainClass ifFalse:[
-	    ^ self error:'addressBuffer class mismatch (domain)'.
-	].
-	addr := anAddressBuffer.
+        anAddressBuffer class == domainClass ifFalse:[
+            ^ self error:'addressBuffer class mismatch (domain)'.
+        ].
+        addr := anAddressBuffer.
     ] ifFalse:[
-	anAddressBuffer notNil ifTrue:[
-	    addr := domainClass new.
-	].
+        anAddressBuffer notNil ifTrue:[
+            addr := domainClass new.
+        ].
     ].
 
 %{
@@ -2435,106 +2431,103 @@
     OBJ fp = __INST(handle);
 
     if (fp != nil) {
-	SOCKET sock;
-	INT objSize;
-	union sockaddr_u sa;
-	unsigned INT alen = 0;
-	INT n, offs;
-	INT flags = 0;
-	char *extPtr;
-	unsigned char *allocatedBuffer = NULL;
-	unsigned char *buffer = NULL;
-
-	sock = SOCKET_FROM_FILE_OBJECT(fp);
-
-	if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
-	if (__isSmallInteger(nBytes)) {
-	    if (__intVal(nBytes) < objSize) {
-		objSize = __intVal(nBytes);
-	    }
-	}
+        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:[
-	^ ReadError
-	    raiseRequestWith:self
-	    errorString:(' : ' , OperatingSystem errorTextForNumber:error)
+        ^ self readError:error.
     ].
 
     nReceived notNil ifTrue:[
-	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
+        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
@@ -2562,73 +2555,68 @@
     if ((fp != nil)
      && __isSmallInteger(startIndex)
      && __isSmallInteger(nBytes)) {
-	SOCKET sock;
-	INT objSize;
-	INT n;
-	char *extPtr;
-	INT _flags = 0;
-	INT offs;
-	unsigned long norder;
-	unsigned char *buffer;
-	unsigned char *allocatedBuffer = NULL;
-
-	_flags = __longIntVal(flags);
-
-	sock = SOCKET_FROM_FILE_OBJECT(fp);
-
-	if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
-	if (__isSmallInteger(nBytes)) {
-	    if (__intVal(nBytes) < objSize) {
-		objSize = __intVal(nBytes);
-	    }
-	}
+        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);
-	    bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, 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);
+            bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, 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.
     ].
 
     "
@@ -2676,16 +2664,16 @@
     |domainClass addr error|
 
     (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
-	addr := anAddressBuffer.
+        addr := anAddressBuffer.
     ] ifFalse:[
-	anAddressBuffer isByteArray ifFalse:[
-	    ^ self error:'bad socketAddress argument'
-	].
-	domainClass := self class socketAddressClassForDomain:domain.
-	domainClass isNil ifTrue:[
-	    ^ self error:'invalid (unsupported) domain'.
-	].
-	addr := domainClass hostAddress:anAddressBuffer.
+        anAddressBuffer isByteArray ifFalse:[
+            ^ self error:'bad socketAddress argument'
+        ].
+        domainClass := self class socketAddressClassForDomain:domain.
+        domainClass isNil ifTrue:[
+            ^ self error:'invalid (unsupported) domain'.
+        ].
+        addr := domainClass hostAddress:anAddressBuffer.
     ].
 %{
 #ifndef NO_SOCKET
@@ -2694,92 +2682,90 @@
     if ((fp != nil)
      && __isSmallInteger(startIndex)
      && __isSmallInteger(nBytes)) {
-	SOCKET sock;
-	INT objSize;
-	struct sockaddr *sockaddr_ptr;
-	union sockaddr_u sa;
-	INT alen = 0;
-	INT sockAddrOffs, sockaddr_size;
-	INT n;
-	char *extPtr;
-	INT _flags = 0;
-	INT offs;
-	unsigned long norder;
-	unsigned char *buffer;
-	unsigned char *allocatedBuffer = NULL;
-
-	_flags = __longIntVal(flags);
-	sock = SOCKET_FROM_FILE_OBJECT(fp);
-
-	if (! __isBytes(addr)) {
-	    sockaddr_size = 0;
-	    sockaddr_ptr = (struct sockaddr *)0;
-	} else {
-	    int nIndex;
-	    OBJ cls;
-
-	    sockAddrOffs = 0;
-	    if ((cls = __qClass(addr)) != @global(ByteArray))
-		sockAddrOffs += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
-	    nIndex = __qSize(addr) - OHDR_SIZE;
-	    sockaddr_size = nIndex - sockAddrOffs;
-	    if (sockaddr_size > sizeof(sa)) {
-		console_fprintf(stderr, "Socket [warning]: bad socketAddr\n");
-		goto bad;
-	    }
-	    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);
-	    bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, 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);
+            bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, 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.
     ].
 
     "
@@ -3815,7 +3801,6 @@
     "
 ! !
 
-
 !Socket methodsFor:'specials'!
 
 linger:anIntegerOrNil
@@ -4091,7 +4076,6 @@
     ^ self setSocketOption:#'TCP_NODELAY' argument:aBoolean argument:nil.
 ! !
 
-
 !Socket methodsFor:'waiting'!
 
 waitForNewConnectionOrDataOnAny:otherConnections timeout:timeoutSeconds