--- 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