--- 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 $'
! !