Socket.st
changeset 430 12d736316f69
parent 429 197dee9342a3
child 444 9ba31a1fba38
--- a/Socket.st	Fri Aug 30 00:41:19 1996 +0200
+++ b/Socket.st	Thu Sep 05 15:04:48 1996 +0200
@@ -1747,16 +1747,18 @@
      is established. 
      See also: #connectTo:port:withTimeout: for a somewhat nicer interface."
 
+    |isAsync|
+
     filePointer isNil ifTrue:[
-	^ self error:'not a valid socket'
+        ^ self error:'not a valid socket'
     ].
 %{
 #ifndef NO_SOCKET
     OBJ t = __INST(filePointer);
     OBJ myDomain;
     union {
-	struct sockaddr_in in ;
-	struct sockaddr_un un;
+        struct sockaddr_in in ;
+        struct sockaddr_un un;
     } sa;
     struct hostent *hp ;
     int a, sock ;
@@ -1768,8 +1770,8 @@
     int sockaddr_size;
 
     if (!__isString(__INST(domain)) && !__isSymbol(__INST(domain))) {
-	DBGPRINTF(("SOCKET: invalid domain arg\n"));
-	RETURN (false);
+        DBGPRINTF(("SOCKET: invalid domain arg\n"));
+        RETURN (false);
     }
 
     ok = 0;
@@ -1777,62 +1779,62 @@
     bzero((char *) &sa, sizeof(sa)) ;
 #ifdef AF_INET
     if (myDomain == @symbol(inet)) {
-	char *hostName;
+        char *hostName;
 
-	if (! __isString(hostOrPathName)) {
-	    DBGPRINTF(("SOCKET: invalid hostname arg\n"));
-	    RETURN (false);
-	}
-	hostName = (char *) _stringVal(hostOrPathName);
+        if (! __isString(hostOrPathName)) {
+            DBGPRINTF(("SOCKET: invalid hostname arg\n"));
+            RETURN (false);
+        }
+        hostName = (char *) _stringVal(hostOrPathName);
 
-	if (! __isSmallInteger(portNrOrName)) {
-	    DBGPRINTF(("SOCKET: invalid port arg\n"));
-	    RETURN (false);
-	}
+        if (! __isSmallInteger(portNrOrName)) {
+            DBGPRINTF(("SOCKET: invalid port arg\n"));
+            RETURN (false);
+        }
 
-	sa.in.sin_family = AF_INET;
-	sa.in.sin_port = htons((u_short) _intVal(portNrOrName)) ;
+        sa.in.sin_family = AF_INET;
+        sa.in.sin_port = htons((u_short) _intVal(portNrOrName)) ;
 
-	if ((addr = inet_addr(hostName)) != -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? 
-	     */
-	    if ((hp = gethostbyname(hostName)) == NULL) {
-		DBGPRINTF(("SOCKET: unknown host:%s\n", hostName));
-		RETURN (false);
-	    }
-	    bcopy(hp->h_addr, (char *) &sa.in.sin_addr, hp->h_length) ;
-	    sa.in.sin_family = hp->h_addrtype;
-	}
-	sockaddr_size = sizeof(struct sockaddr_in);
-	ok = 1;
+        if ((addr = inet_addr(hostName)) != -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? 
+             */
+            if ((hp = gethostbyname(hostName)) == NULL) {
+                DBGPRINTF(("SOCKET: unknown host:%s\n", hostName));
+                RETURN (false);
+            }
+            bcopy(hp->h_addr, (char *) &sa.in.sin_addr, hp->h_length) ;
+            sa.in.sin_family = hp->h_addrtype;
+        }
+        sockaddr_size = sizeof(struct sockaddr_in);
+        ok = 1;
     }
 #endif
 #ifdef AF_UNIX
     if (myDomain == @symbol(unix)) {
-	char *pathName;
-	int l;
+        char *pathName;
+        int l;
 
-	if (! __isString(hostOrPathName)) {
-	    DBGPRINTF(("SOCKET: invalid port (pathname) arg\n"));
-	    RETURN (false);
-	}
-	pathName = (char *) __stringVal(hostOrPathName);
-	l = strlen(pathName);
-	if ((l + sizeof ( sa.un.sun_family )) > sizeof(struct sockaddr_un)) {
-	    DBGPRINTF(("SOCKET: pathname too long\n"));
-	    RETURN (false);
-	}
+        if (! __isString(hostOrPathName)) {
+            DBGPRINTF(("SOCKET: invalid port (pathname) arg\n"));
+            RETURN (false);
+        }
+        pathName = (char *) __stringVal(hostOrPathName);
+        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;
+        strcpy(sa.un.sun_path, pathName);
+        sa.un.sun_family = AF_UNIX;
+        sockaddr_size = l + sizeof ( sa.un.sun_family );
+        ok = 1;
     }
 #endif
     /*
@@ -1864,8 +1866,8 @@
 #endif
 
     if (! ok) {
-	DBGPRINTF(("SOCKET: unsupported domain\n"));
-	RETURN (false);
+        DBGPRINTF(("SOCKET: unsupported domain\n"));
+        RETURN (false);
     }
 
     sock = fileno(__FILEVal(t));
@@ -1876,38 +1878,51 @@
     __BEGIN_INTERRUPTABLE__
 
     do {
-	ret = connect(sock, (struct sockaddr *)&sa, sockaddr_size);
+        ret = connect(sock, (struct sockaddr *)&sa, sockaddr_size);
     } while ((ret < 0) 
-	     && ((errno == EINTR)
+             && ((errno == EINTR)
 #ifdef EAGAIN
-		 || (errno == EAGAIN)
+                 || (errno == EAGAIN)
 #endif
-#ifdef EINPROGRESS
-		 || (errno == EINPROGRESS)
-#endif
-		));
+                ));
     __END_INTERRUPTABLE__
 
     if (ret < 0) { 
-	DBGPRINTF(("SOCKET: connect failed errno=%d\n", errno));
+#ifdef EINPROGRESS
+        if (errno == EINPROGRESS || errno == EALREADY) {
+            /*
+             * We were interrupted. Do not call connect again
+             * (we will get an EALREADY.
+             * Do a select on write instead.
+             */
+
+            isAsync = true;
+        } else
+#endif
+        {
+            DBGPRINTF(("SOCKET: connect failed errno=%d\n", errno));
 #ifdef DUMP_ADDRESS
-	{
-	    char *cp = (char *)(&sa);
-	    int i;
+            {
+                char *cp = (char *)(&sa);
+                int i;
 
-	    printf("address data:\n");
-	    for (i=0; i<sockaddr_size; i++) {
-		printf(" %02x\n", *cp++);
-	    }
-	}
+                printf("address data:\n");
+                for (i=0; i<sockaddr_size; i++) {
+                    printf(" %02x\n", *cp++);
+                }
+            }
 #endif
-	__INST(lastErrorNumber) = __MKSMALLINT(errno);
-	RETURN (false);
+            __INST(lastErrorNumber) = __MKSMALLINT(errno);
+            RETURN (false);
+        }
     }
-#else
+#else /* NO_SOCKET */
     RETURN (false);
-#endif
+#endif /* NO_SOCKET */
 %}.
+    isAsync == true ifTrue:[
+        self writeWait.
+    ].
     port := portNrOrName.
     peerName := hostOrPathName.
     ^ true
@@ -2558,5 +2573,5 @@
 !Socket  class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.68 1996-08-29 22:41:19 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.69 1996-09-05 13:04:48 stefan Exp $'
 ! !