aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodale <goodale@9697cf00-7f2a-4e1b-af3c-314b8e4b499e>2000-05-25 12:51:03 +0000
committergoodale <goodale@9697cf00-7f2a-4e1b-af3c-314b8e4b499e>2000-05-25 12:51:03 +0000
commit952da7887f4feaba5c1ec1e81fc5531a9947c52a (patch)
treed07dc502bc95af220d4adf8e578c630659e2b891
parentf3310ca1a7c38ffd2cf1464e7b0313411fb68455 (diff)
Socket thorn based on John Shalf's code
git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/Socket/trunk@2 9697cf00-7f2a-4e1b-af3c-314b8e4b499e
-rw-r--r--README10
-rw-r--r--interface.ccl4
-rw-r--r--param.ccl2
-rw-r--r--schedule.ccl2
-rw-r--r--src/SocketUtils.h110
-rw-r--r--src/Utils.c411
-rw-r--r--src/make.code.defn9
7 files changed, 548 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..8f6c09a
--- /dev/null
+++ b/README
@@ -0,0 +1,10 @@
+Cactus Code Thorn Socket
+Authors : Tom Goodale, John Shalf
+CVS info : $Header$
+--------------------------------------------------------------------------
+
+Purpose of the thorn:
+
+This thorn provides platform-independent socket calls.
+
+
diff --git a/interface.ccl b/interface.ccl
new file mode 100644
index 0000000..e18d2d6
--- /dev/null
+++ b/interface.ccl
@@ -0,0 +1,4 @@
+# Interface definition for thorn Socket
+# $Header$
+
+implements: Socket \ No newline at end of file
diff --git a/param.ccl b/param.ccl
new file mode 100644
index 0000000..9f7d2d1
--- /dev/null
+++ b/param.ccl
@@ -0,0 +1,2 @@
+# Parameter definitions for thorn Socket
+# $Header$
diff --git a/schedule.ccl b/schedule.ccl
new file mode 100644
index 0000000..d706530
--- /dev/null
+++ b/schedule.ccl
@@ -0,0 +1,2 @@
+# Schedule definitions for thorn Socket
+# $Header$
diff --git a/src/SocketUtils.h b/src/SocketUtils.h
new file mode 100644
index 0000000..aa9fe82
--- /dev/null
+++ b/src/SocketUtils.h
@@ -0,0 +1,110 @@
+ /*@@
+ @header SocketUtils.h
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @version $Header$
+ @@*/
+
+#ifndef _SOCKETUTILS_H_
+#define _SOCKETUTILS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* #if defined(ANSI) || defined(__STDC__) */
+#ifdef __STDC__
+/*
+ TCP utilities library (1991)
+ Last modification Dec 1995
+*/
+/*==================================================================
+** name: OpenClientSockTCP
+** purpose: Given the hostname of the server and the portnumber of the
+** service to connect to, it opens a TCP socket to the host and returns
+** the file descriptor of the socket.
+** parameters:
+** hostname: the name of the server host as a character string (not ip number)
+** port: The port number for the server.
+** returns:
+** integer file descriptor for low level io. Can convert to FILE *
+** using the fdopen() system call.
+**=================================================================*/
+int Socket_TCPOpenClientSock(const char *hostname, int port);
+int Socket_UDPOpenClientSock(const char *hostname, int port);
+
+/*==================================================================
+** name: OpenServerSockTCP
+** purpose: Opens a passive TCP connection on "port". After opening
+** the socket, the server is automatically set to listen on that socket.
+** The programmer need only call accept() to allow connections by clients.
+** parameters:
+** port: The port number for the server.
+** returns:
+** integer file descriptor for low level io. Needs to remain a file
+** descriptor to accept() client connections. Can convert the client
+** connection file descriptor to a FILE * using fdopen();
+**=================================================================*/
+int Socket_TCPOpenServerSock(int port);
+int Socket_UDPOpenServerSock(int port);
+
+/*==================================================================
+** name: TCPBlockingWrite
+** purpose: Handles error conditions when writing to a file descriptor.
+** If a buffer is too large to write in one block, this routine will
+** divide the buffer into two segments and recursively call itself to
+** send each of the halves.
+** parameters:
+** fd: file descriptor to write the buffer data to.
+** buffer: an array of bytes write to the file stream.
+** buflen: number of bytes in the buffer
+** returns:
+** either the number of characters written or constant describing
+** why the write failed.
+** notes: If you want the routine to print identifiable errors
+** to stderr, define PERRORS.
+**=================================================================*/
+int Socket_TCPBlockingWrite(int fd, char *buffer, int buflen);
+
+/*==================================================================
+** name: TCPBlockingRead
+** purpose: Handles error conditions when reading from a file descriptor.
+** With TCP stream connections, the record size of the recieved stream
+** may not coincide with the record written. This routine assembles
+** a fragmented record into a single array by blocking until buflen
+** characters are recieved, or write returns a premature EOF.
+** parameters:
+** fd: file descriptor to read the buffer data from.
+** buffer: an array of bytes read from the file stream.
+** buflen: number of bytes in the buffer
+** returns:
+** either the number of characters read into the buffer or constant describing
+** why the read failed.
+** notes: If you want the routine to print out identifiable errors
+** to stderr, define PERRORS.
+**=================================================================*/
+int Socket_TCPBlockingRead(int fd,char *buffer,int buflen);
+#else
+int Socket_TCPOpenClientSock();
+int Socket_TCPOpenServerSock();
+int Socket_TCPBlockingWrite();
+int Socket_TCPBlockingRead();
+#endif
+
+#define PERRORS
+#ifndef __IN_HEADER
+#include <sys/types.h>
+#include <netinet/in.h>
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SOCKETUTILS_H */
+
diff --git a/src/Utils.c b/src/Utils.c
new file mode 100644
index 0000000..ceb4d0f
--- /dev/null
+++ b/src/Utils.c
@@ -0,0 +1,411 @@
+/*@@
+ @file Utils.c
+ @date 1991
+ @author John Shalf
+ @desc
+ Socket stuff provided by John Shalf
+ @enddesc
+ @history
+ @hdate Thu May 25 13:45:29 2000 @hauthor Tom Goodale
+ @hdesc Moved this file into Cactus
+ @endhistory
+ @version $Header$
+ @@*/
+
+#include "cctk.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/errno.h>
+#include <arpa/inet.h>
+
+#include "SocketUtils.h"
+
+/* #if defined(ANSI) || defined(__STDC__) */
+#ifdef __STDC__
+/*
+u_long htonl(u_long hostlong);
+u_short htons(u_short hostshort);
+u_long ntohl(u_long netlong);
+u_short ntohs(u_short netshort);
+
+int inet_aton(const char *cp, struct in_addr *pin);
+unsigned long inet_addr(const char *cp);
+unsigned long inet_network(const char *cp);
+char *inet_ntoa(struct in_addr in);
+struct in_addr inet_makeaddr(int net, int lna);
+unsigned long inet_lnaof(struct in_addr in);
+unsigned long inet_netof(struct in_addr in);
+*/
+#else
+u_short htons();
+u_short ntohs();
+u_long inet_addr();
+#endif
+
+static char *rcsid = "$Header$";
+
+
+extern int errno;
+
+ /*@@
+ @routine Socket_TCPOpenClientSock
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int Socket_TCPOpenClientSock(const char *hostname,int port)
+{
+ struct hostent *phe;
+ /* struct servent *pse; */
+ struct protoent *ppe;
+ struct sockaddr_in sin;
+ int s /*,type*/;
+
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr=INADDR_ANY;
+ sin.sin_port = htons((u_short)port);
+
+ if(phe=gethostbyname(hostname))
+ {
+ bcopy(phe->h_addr, (char *)&sin.sin_addr, phe->h_length);
+ }
+ else if((sin.sin_addr.s_addr = inet_addr(hostname)) == INADDR_NONE)
+ {
+ fprintf(stderr,"can\'t find host %s \n",hostname);
+ }
+ if((ppe=getprotobyname("tcp")) == 0)
+ {
+ perror("can\'t find tcp protocol\n");
+ return -1;
+ }
+ s=socket(PF_INET,SOCK_STREAM,ppe->p_proto);
+ if(s<0)
+ {
+ perror("");
+ fprintf(stderr,"couldn\'t allocate socket on host %s: port %u\n",hostname,port);
+ return s;
+ }
+ if(connect(s,(struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {
+ perror("");
+ fprintf(stderr,"couldn\'t connect to host %s: port %u\n",hostname,port);
+ return -1;
+ }
+ return s;
+}
+
+/*@@
+ @routine Socket_UDPOpenClientSock
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int Socket_UDPOpenClientSock(const char *hostname,int port)
+{
+ struct hostent *phe;
+ /* struct servent *pse; */
+ struct protoent *ppe;
+ struct sockaddr_in sin;
+ int sock/*,type*/;
+
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr=INADDR_ANY;
+ sin.sin_port = htons((u_short)port);
+
+ if(phe=gethostbyname(hostname))
+ {
+ bcopy(phe->h_addr, (char *)&sin.sin_addr, phe->h_length);
+ }
+ else if((sin.sin_addr.s_addr = inet_addr(hostname)) == INADDR_NONE)
+ {
+ fprintf(stderr,"can\'t find host %s \n",hostname);
+ }
+ if((ppe=getprotobyname("udp")) == 0)
+ {
+ perror("can\'t find udp protocol\n");
+ return -1;
+ }
+ sock=socket(PF_INET,SOCK_DGRAM,ppe->p_proto);
+ if(sock<0)
+ {
+ perror("");
+ fprintf(stderr,"couldn\'t allocate socket on host %s: port %u\n",hostname,port);
+ return sock;
+ }
+ if(bind(sock,&sin,sizeof(sin)) <0)
+ {
+ close(sock);
+ perror("client: bind failed");
+ return -1;
+ }
+
+
+ /* if(connect(s,(struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {`
+ perror("");
+ fprintf(stderr,"couldn\'t connect to host %s: port %u\n",hostname,port);
+ return -1;
+ }
+ */
+ return sock;
+}
+
+/*@@
+ @routine Socket_TCPOpenServerSock
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int Socket_TCPOpenServerSock(int port)
+{
+ /* struct servent *pse; */
+ struct protoent *ppe;
+ struct sockaddr_in sin;
+ int s/*,type*/;
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = htons((u_short)port);
+
+ if((ppe=getprotobyname("tcp")) == 0)
+ {
+ perror("can\'t find tcp protocol\n");
+ return -1;
+ }
+ s=socket(PF_INET,SOCK_STREAM,ppe->p_proto);
+ if(s<0)
+ {
+ fprintf(stderr,"couldn\'t create socket on port %u\n",port);
+ return s;
+ }
+ if(bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {
+ fprintf(stderr,"couldn\'t bind to port %u\n",port);
+ return s;
+ }
+ if(listen(s,5) < 0) /* note, server connection qlen fixed to 5 */
+ {
+ fprintf(stderr,"couldn\'t listen on port %u\n",port);
+ }
+ return s;
+}
+
+/*@@
+ @routine Socket_UDPOpenServerSock
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int Socket_UDPOpenServerSock(int port)
+{
+ /* struct servent *pse; */
+ struct protoent *ppe;
+ struct sockaddr_in sin;
+ int s/*,type*/;
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = htons((u_short)port);
+
+ if((ppe=getprotobyname("udp")) == 0)
+ {
+ perror("can\'t find udp protocol\n");
+ return -1;
+ }
+ s=socket(PF_INET,SOCK_DGRAM,ppe->p_proto);
+ if(s<0)
+ {
+ fprintf(stderr,"couldn\'t create socket on port %u\n",port);
+ return s;
+ }
+ if(bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {
+ fprintf(stderr,"couldn\'t bind to port %u\n",port);
+ return s;
+ }
+ return s;
+}
+
+/*@@
+ @routine Socket_TCPBlockingWrite
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int Socket_TCPBlockingWrite(int fd,char *buffer, int buflen)
+{
+ register int n;
+ int nstore;
+ n=write(fd,buffer,buflen);
+
+ if(n>=0)
+ {
+ return n;
+ }
+ else
+ {
+ switch(errno) /* note use of global variable errno */
+ {
+ case EBADF:
+#ifdef PERRORS
+ perror("invalid file descriptor");
+#endif
+ break;
+ case EPIPE:
+#ifdef PERRORS
+ perror("attemped to write to an unconnected socket");
+#endif
+ break;
+ case EFBIG:
+#ifdef PERRORS
+ perror("datasize too large to write.");
+ perror("will attempt recovery by sending in smaller pieces");
+#endif
+ /* subdivide buffer and call TCPBlockingWrite() recursively */
+ nstore=n; /* preserve register variable */
+ TCPBlockingWrite(fd,buffer,buflen>>1);
+ TCPBlockingWrite(fd,buffer+(buflen>>1),buflen-(buflen>>1));
+ n=nstore; /* restore register variable */
+ break;
+ case EFAULT:
+#ifdef PERRORS
+ perror("invalid buffer address");
+#endif
+ break;
+ case EINVAL:
+#ifdef PERRORS
+ perror("file descriptor points to unusable device.");
+#endif
+ break;
+ case EIO:
+#ifdef PERRORS
+ perror("an io error occured");
+#endif
+ break;
+ case EWOULDBLOCK:
+#ifdef PERRORS
+ perror("Non-blocking I/O is specified by ioctl");
+ perror("but socket has no data (would have blocked).");
+#endif
+ break;
+ }
+ }
+ return n; /* default, don't know what happened */
+}
+
+/*@@
+ @routine Socket_TCPBlockingRead
+ @date 1991
+ @author John Shalf
+ @desc
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int Socket_TCPBlockingRead(int fd,char *buffer, int buflen)
+{
+ /* do errno only if types.h has been included */
+ /* how can I tell if this has been included ? */
+ register int n,accum=0;
+ while((n=read(fd,buffer,buflen)) > 0)
+ {
+ if(n>=0)
+ {
+ buffer = buffer + n;
+ buflen -= n;
+ accum+=n;
+ }
+ }
+#ifdef PERRORS
+ if(n<0)
+ {
+ switch(errno) /* note use of global variable errno */
+ {
+ case EBADF:
+#ifdef PERRORS
+ perror("invalid file descriptor");
+#endif
+ break;
+ case EFAULT:
+#ifdef PERRORS
+ perror("invalid buffer address");
+#endif
+ break;
+ case EINTR:
+#ifdef PERRORS
+ perror("operation interrupted by a signal");
+ perror("disable signals and try again");
+#endif
+ break;
+ case EWOULDBLOCK:
+#ifdef PERRORS
+ perror("Non-blocking I/O is specified by ioctl");
+ perror("but socket has no data (would have blocked).");
+#endif
+ break;
+ }
+ }
+#endif
+
+ if(n<0)
+ {
+ return n;
+ }
+ else
+ {
+ return accum;
+ }
+}
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100644
index 0000000..b8eac84
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,9 @@
+# Main make.code.defn file for thorn Socket
+# $Header$
+
+# Source files in this directory
+SRCS = Utils.c
+
+# Subdirectories containing source files
+SUBDIRS =
+