.
authorClaus Gittinger <cg@exept.de>
Fri, 27 Oct 1995 14:24:03 +0100
changeset 93 8d1a86bd642c
parent 92 13061190c6e7
child 94 06daded50597
.
Socket.st
--- a/Socket.st	Tue Oct 24 17:39:22 1995 +0100
+++ b/Socket.st	Fri Oct 27 14:24:03 1995 +0100
@@ -22,7 +22,7 @@
 COPYRIGHT (c) 1992 by Claus Gittinger
 	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.29 1995-10-24 16:39:22 cg Exp $
+$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.30 1995-10-27 13:24:03 cg Exp $
 '!
 
 !Socket class methodsFor:'documentation'!
@@ -43,7 +43,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.29 1995-10-24 16:39:22 cg Exp $
+$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.30 1995-10-27 13:24:03 cg Exp $
 "
 !
 
@@ -74,12 +74,11 @@
 "
     example (get help info from an nntp server):
 
-	|sock|
+	|sock host|
 
-	sock := Socket 
-		    newTCPclientToHost:(OperatingSystem 
-					    getEnvironment:'NNTPSERVER') 
-				  port:'nntp'.
+	host := OperatingSystem getEnvironment:'NNTPSERVER'.
+
+	sock := Socket newTCPclientToHost:host port:'nntp'.
 	Transcript showCr:sock nextLine.
 	sock buffered:false.
 
@@ -96,25 +95,25 @@
 
     example (connect to an ftp server):
 
-	|sock|
+	|sock host|
 
-	sock := Socket 
-		    newTCPclientToHost:(OperatingSystem getHostName) 
-				  port:'ftp'.
+	host := OperatingSystem getHostName.
+	sock := Socket newTCPclientToHost:host port:'ftp'.
 
 	sock buffered:false.
 	Transcript showCr:sock nextLine.
-	sock nextPutAll:('USER ' , OperatingSystem getLoginName); cr.
+	sock nextPutAll:('USER ' , 'anonymous'); cr.
 	Transcript showCr:sock nextLine.
-	sock nextPutAll:('PASS ' , 'your password here'); cr.
+	sock nextPutAll:('PASS ' , 'fooBar'); cr.
 	Transcript showCr:sock nextLine.
 	sock nextPutAll:'LIST'; cr.
 	Transcript showCr:sock nextLine.
+	sock close.
 
 	'dont know enough of the ftp protocol to continue here ...'
 
 
-    example (connect to an snmp server):
+    example (connect to an snmp server [UDP]):
 
 	|sock port|
 
@@ -123,32 +122,46 @@
 	sock connectTo:(OperatingSystem getHostName) port:port.
 	sock buffered:false.
 	Transcript showCr:'got it'.
+	sock close.
+
 
     example (await connection from a client and read some data):
 
 	|connectSock sock|
 
-	connectSock := Socket provide:9996.  
-	Transcript showCr:'listen ..'.
-	connectSock listenFor:5.
-	Transcript showCr:'wait'.
-	connectSock readWait.  
-	Transcript showCr:'accept'.
-	sock := Socket new acceptOn:self.
-	Transcript showCr:'close'.
-	connectSock close.
-	sock buffered:false.
-	Transcript showCr:'server: got it'.
-	'can now do transfer via sock'.
-	Transcript showCr:'read'.
-	Transcript showCr:('got: ' , sock nextLine).
-	sock close
+	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.
+	    ]
+	]
 
     example (connect to above server and send some data):
 
 	|sock|
 
-	sock := Socket connectTo:9996 on:'porty'.
+	sock := Socket newTCPclientToHost:(OperatingSystem getHostName) port:9997.
 	sock buffered:false.
 	Transcript showCr:'client: got it'.
 	'can now do transfer via sock'.
@@ -161,6 +174,8 @@
 !Socket primitiveDefinitions!
 
 %{
+/* #define NO_BUFFER */
+
 #include <stdio.h>
 #include <errno.h>
 
@@ -174,7 +189,7 @@
 # include <fcntl.h>
 # include <sys/types.h>
 
-# ifdef IRIS
+# if defined(IRIS) && !defined(IRIX5)
    /* no socket.h on 4.0.5h ?!?!? */
 #  define AF_UNIX 1
 #  define AF_INET 2
@@ -197,6 +212,50 @@
 #endif
 
 /*
+ * just in case those PF_xxx's are undefined
+ */
+#ifdef AF_UNIX
+# ifndef PF_UNIX
+#  define PF_UNIX AF_UNIX
+# endif
+#endif
+#ifdef AF_INET
+# ifndef PF_INET
+#  define PF_INET AF_INET
+# endif
+#endif
+#ifdef AF_DECnet
+# ifndef PF_DECnet
+#  define PF_DECnet AF_DECnet
+# endif
+#endif
+#ifdef AF_APPLETALK
+# ifndef PF_APPLETALK
+#  define PF_APPLETALK AF_APPLETALK
+# endif
+#endif
+#ifdef AF_X25
+# ifndef PF_X25
+#  define PF_X25 AF_X25
+# endif
+#endif
+#ifdef AF_NS
+# ifndef PF_NS
+#  define PF_NS AF_NS
+# endif
+#endif
+#ifdef AF_SNA
+# ifndef PF_SNA
+#  define PF_SNA AF_SNA
+# endif
+#endif
+#ifdef AF_RAW
+# ifndef PF_RAW
+#  define PF_RAW AF_RAW
+# endif
+#endif
+
+/*
  * on some systems errno is a macro ... check for it here
  */
 #ifndef errno
@@ -236,6 +295,10 @@
 
     __debugging__ = (aBoolean == true);
 %}
+    "
+     Socket debug:true
+     Socket debug:false
+    "
 ! !
 
 !Socket class methodsFor:'queries'!
@@ -361,37 +424,37 @@
     int tryBoth = 0;
 
     if (__isString(aProtocol)) {
-        protocol = __stringVal(aProtocol);
+	protocol = __stringVal(aProtocol);
     } else {
-        protocol = "tcp";
-        tryBoth = 1;
+	protocol = "tcp";
+	tryBoth = 1;
     }
 
     if (__isSmallInteger(aNameOrNumber)) {
-        servent = getservbyport(htons(_intVal(aNameOrNumber)), protocol);
-        if (servent != NULL) {
-            RETURN ( aNameOrNumber );
-        }
-        if (tryBoth) {
-            servent = getservbyport(htons(_intVal(aNameOrNumber)), "udp");
-            if (servent != NULL) {
-                RETURN ( aNameOrNumber );
-            }
-        }
-        RETURN ( aNameOrNumber );
+	servent = getservbyport(htons(_intVal(aNameOrNumber)), protocol);
+	if (servent != NULL) {
+	    RETURN ( aNameOrNumber );
+	}
+	if (tryBoth) {
+	    servent = getservbyport(htons(_intVal(aNameOrNumber)), "udp");
+	    if (servent != NULL) {
+		RETURN ( aNameOrNumber );
+	    }
+	}
+	RETURN ( aNameOrNumber );
     }
     if (__isString(aNameOrNumber)) {
-        servent = getservbyname((char *) _stringVal(aNameOrNumber), protocol);
-        if (servent != NULL) {
-            RETURN ( _MKSMALLINT(ntohs(servent->s_port)) );
-        }
-        if (tryBoth) {
-            servent = getservbyname((char *) _stringVal(aNameOrNumber), "udp");
-            if (servent != NULL) {
-                RETURN ( _MKSMALLINT(ntohs(servent->s_port)) );
-            }
-        }
-        RETURN ( nil );
+	servent = getservbyname((char *) _stringVal(aNameOrNumber), protocol);
+	if (servent != NULL) {
+	    RETURN ( _MKSMALLINT(ntohs(servent->s_port)) );
+	}
+	if (tryBoth) {
+	    servent = getservbyname((char *) _stringVal(aNameOrNumber), "udp");
+	    if (servent != NULL) {
+		RETURN ( _MKSMALLINT(ntohs(servent->s_port)) );
+	    }
+	}
+	RETURN ( nil );
     }
     RETURN ( nil );
 %}
@@ -704,6 +767,15 @@
      is done. Both arguments must be symbols from one of
      #inet,#unix, #appletalk, #x25 .. and #stream, #datagram, #raw resp."
 
+    ^ self domain:domainArg type:typeArg protocol:0
+!
+
+domain:domainArg type:typeArg protocol:protocolNumber
+    "set up socket with domain, type and protocol number.
+     This is a low level entry; no binding, listening or connect
+     is done. Both arguments must be symbols from one of
+     #inet,#unix, #appletalk, #x25 .. and #stream, #datagram, #raw resp."
+
     |errorNr|
 
     filePointer notNil ifTrue:[
@@ -711,7 +783,7 @@
     ].
 %{
     FILE *fp;
-    int dom, typ, proto, sock;
+    int dom, typ, pf, proto = 0, sock;
 
     if (! __isSymbol(domainArg)) { 
 	DBGPRINTF(("bad domain\n"));
@@ -721,39 +793,57 @@
 	DBGPRINTF(("bad type\n"));
 	RETURN ( nil );
     }
+    if (protocolNumber != nil) {
+        if (!__isSmallInteger(protocolNumber)) {
+	    DBGPRINTF(("bad protocol\n"));
+	    RETURN ( nil );
+	}
+	proto = __intVal(protocolNumber);
+    }
+	
 
     /*
-     * get address-family
+     * get address and protocol-family
      */
 #ifdef AF_UNIX
-    if (domainArg == @symbol(unix))
+    if (domainArg == @symbol(unix)) {
 	dom = AF_UNIX;
-    else
+    } else
 #endif
 #ifdef AF_INET
-    if (domainArg == @symbol(inet))
+    if (domainArg == @symbol(inet)) {
 	dom = AF_INET;
-    else
+    } else
+#endif
+#ifdef AF_DECnet
+    if (domainArg == @symbol(DECnet)) {
+	dom = AF_DECnet;
+    } else
+#endif
+#ifdef AF_APPLETALK
+    if (domainArg == @symbol(appletalk)) {
+	dom = AF_APPLETALK;
+    } else
+#endif
+#ifdef AF_X25
+    if (domainArg == @symbol(x25)) {
+	dom = AF_X25;
+    } else
 #endif
 #ifdef AF_NS
-    if (domainArg == @symbol(ns))
+    if (domainArg == @symbol(xns)) {
 	dom = AF_NS;
-    else
-#endif
-#ifdef AF_DECnet
-    if (domainArg == @symbol(DECnet))
-	dom = AF_DECnet;
-    else
+    } else
 #endif
-#ifdef AF_APPLETALK
-    if (domainArg == @symbol(appletalk))
-	dom = AF_APPLETALK;
-    else
+#ifdef AF_SNA
+    if (domainArg == @symbol(sna)) {
+	dom = AF_SNA;
+    } else
 #endif
-#ifdef AF_X25
-    if (domainArg == @symbol(x25))
-	dom = AF_X25;
-    else
+#ifdef AF_RAW
+    if (domainArg == @symbol(raw)) {
+	dom = AF_RAW;
+    } else
 #endif
     {
 	DBGPRINTF(("unknown domain <%s>\n", _stringVal(domainArg)));
@@ -761,14 +851,14 @@
     }
 
 #ifdef SOCK_STREAM
-    if (typeArg == @symbol(stream))
+    if (typeArg == @symbol(stream)) {
 	typ = SOCK_STREAM;
-    else
+    } else
 #endif
 #ifdef SOCK_DGRAM
-    if (typeArg == @symbol(datagram))
+    if (typeArg == @symbol(datagram)) {
 	typ = SOCK_DGRAM;
-    else 
+    } else 
 #endif
 #ifdef SOCK_RAW
     if (typeArg == @symbol(raw))
@@ -787,13 +877,20 @@
 
     __BEGIN_INTERRUPTABLE__
     do {
-printf("opening socket type=%d\n", typ);
-	sock = socket(dom, typ, 0);
+	DBGPRINTF(("opening socket domain=%d type=%d proto=%d\n", dom, typ, proto));
+	sock = socket(dom, typ, proto);
+#if defined(EPROTONOSUPPORT) /* for SGI */
+	if ((proto != 0) && (sock < 0) && (errno == EPROTONOSUPPORT)) {
+	    DBGPRINTF(("retry with UNSPEC protocol\n"));
+	    proto = 0;
+	    sock = socket(dom, typ, 0);
+	}
+#endif
     } while ((sock < 0) && (errno == EINTR));
     __END_INTERRUPTABLE__
 
     if (sock < 0) {
-	DBGPRINTF(("socket call failed\n"));
+	DBGPRINTF(("socket call failed errno=%d\n", errno));
 	_INST(lastErrorNumber) = _MKSMALLINT(errno);
     } else {
 	/* 
@@ -810,8 +907,8 @@
 	    _INST(filePointer) = MKOBJ(fp);
 	}
     }
-%}
-.
+%}.
+
     "all ok?"
     filePointer notNil ifTrue:[
 	domain := domainArg.
@@ -923,9 +1020,10 @@
 		close(sock);
 		__END_INTERRUPTABLE__
 	    } else {
-/*
+#ifdef NO_BUFFER 
 		setbuf(fp, NULL);
- */
+		_INST(buffered) = false;
+#endif
 		_INST(filePointer) = MKOBJ(fp);
 	    }
 	}
@@ -935,9 +1033,6 @@
 	^ nil
     ].
 
-"
-    buffered := false.
-"
     mode := #readwrite.
     binary := false.
 
@@ -1010,7 +1105,7 @@
     __END_INTERRUPTABLE__
 
     if (sock < 0) {
-	DBGPRINTF(("socket call failed\n"));
+	DBGPRINTF(("socket call failed errno=%d\n", errno));
 	_INST(lastErrorNumber) = _MKSMALLINT(errno);
     } else {
 	/* 
@@ -1040,7 +1135,7 @@
 	__END_INTERRUPTABLE__
 
 	if (ret < 0) { 
-	    DBGPRINTF(("bind/connect call failed\n"));
+	    DBGPRINTF(("bind/connect call failed errno=%d\n", errno));
 	    _INST(lastErrorNumber) = _MKSMALLINT(errno);
 	    __BEGIN_INTERRUPTABLE__
 	    close(sock) ;
@@ -1057,9 +1152,10 @@
 		close(sock);
 		__END_INTERRUPTABLE__
 	    } else {
-/*
+#ifdef NO_BUFFER 
 		setbuf(fp, NULL);
-*/
+		_INST(buffered) = false;
+#endif
 		_INST(filePointer) = MKOBJ(fp);
 	    }
 	}
@@ -1068,9 +1164,6 @@
     filePointer isNil ifTrue:[
 	^ nil
     ].
-"
-    buffered := false.
-"
     mode := #readwrite.
     binary := false.
 
@@ -1080,6 +1173,9 @@
 
     "
      Socket new for:'clam' port:(Socket portOfService:'echo')
+
+     Socket new for:nil port:9999
+     Socket new for:(OperatingSystem getHostName) port:9999
     "
 ! !
 
@@ -1189,6 +1285,18 @@
     if (myDomain == @symbol(appletalk)) {
     }
 #endif
+#ifdef AF_SNA
+    if (myDomain == @symbol(sna)) {
+    }
+#endif
+#ifdef AF_NS
+    if (myDomain == @symbol(xns)) {
+    }
+#endif
+#ifdef AF_RAW
+    if (myDomain == @symbol(raw)) {
+    }
+#endif
 
     if (! ok) {
 	DBGPRINTF(("unsupported domain\n"));
@@ -1208,7 +1316,7 @@
     } while ((ret < 0) && (errno == EINTR));
 
     if (ret < 0) {
-	DBGPRINTF(("bind failed\n"));
+	DBGPRINTF(("bind failed errno=%d\n", errno));
 	_INST(lastErrorNumber) = _MKSMALLINT(errno);
 	RETURN (false);
     }
@@ -1305,6 +1413,18 @@
     if (myDomain == @symbol(appletalk)) {
     }
 #endif
+#ifdef AF_NS 
+    if (myDomain == @symbol(xns)) {
+    }
+#endif
+#ifdef AF_SNA
+    if (myDomain == @symbol(sna)) {
+    }
+#endif
+#ifdef AF_RAW 
+    if (myDomain == @symbol(raw)) {
+    }
+#endif
 
     if (! ok) {
 	DBGPRINTF(("unsupported domain\n"));
@@ -1324,7 +1444,7 @@
     __END_INTERRUPTABLE__
 
     if (ret < 0) { 
-	DBGPRINTF(("connect failed\n"));
+	DBGPRINTF(("connect failed errno=%d\n", errno));
 	_INST(lastErrorNumber) = _MKSMALLINT(errno);
 	RETURN (false);
     }
@@ -1358,7 +1478,7 @@
     __END_INTERRUPTABLE__
 
     if (ret < 0) {
-	DBGPRINTF(("listen call failed\n"));
+	DBGPRINTF(("listen call failed errno=%d\n", errno));
 	_INST(lastErrorNumber) = _MKSMALLINT(errno);
 	RETURN (false);
     }
@@ -1416,7 +1536,7 @@
     __END_INTERRUPTABLE__
 
     if (newSock < 0) {
-	DBGPRINTF(("accept call failed\n"));
+	DBGPRINTF(("accept call failed errno=%d\n", errno));
 	_INST(lastErrorNumber) = _MKSMALLINT(errno);
 	RETURN (false);
     }
@@ -1452,15 +1572,13 @@
 	close(newSock);
 	RETURN (false);
     } else {
-/*
+#ifdef NO_BUFFER 
 	setbuf(fp, NULL);
-*/
+	_INST(buffered) = false;
+#endif
 	_INST(filePointer) = MKOBJ(fp);
     }
 %}.
-"
-    buffered := false.
-"
     mode := #readwrite.
     binary := false.
     port := aSocket port.
@@ -1474,7 +1592,7 @@
 
     |newSock|
 
-    self readWait.  
+"/    self readWait.  
     newSock := self class new.
     (newSock acceptOn:self) ifFalse:[^ nil].
     ^ newSock