From fab1a0ed405c112518f6f6247ec479c2518a5f72 Mon Sep 17 00:00:00 2001 From: tradke Date: Tue, 14 May 2002 19:14:12 +0000 Subject: Final changes before moving this thorn over to CactusConnect. git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/Socket/trunk@20 9697cf00-7f2a-4e1b-af3c-314b8e4b499e --- README | 2 - interface.ccl | 4 +- src/SocketUtils.h | 118 +++-------- src/Utils.c | 581 +++++++++++++++++++++++++++++++++-------------------- src/make.code.defn | 4 - 5 files changed, 399 insertions(+), 310 deletions(-) diff --git a/README b/README index 8f6c09a..4c28002 100644 --- a/README +++ b/README @@ -6,5 +6,3 @@ CVS info : $Header$ Purpose of the thorn: This thorn provides platform-independent socket calls. - - diff --git a/interface.ccl b/interface.ccl index e18d2d6..b61b5b3 100644 --- a/interface.ccl +++ b/interface.ccl @@ -1,4 +1,6 @@ # Interface definition for thorn Socket # $Header$ -implements: Socket \ No newline at end of file +implements: Socket + +INCLUDE HEADER: SocketUtils.h in SocketUtils.h diff --git a/src/SocketUtils.h b/src/SocketUtils.h index 7f5ddb4..9783351 100644 --- a/src/SocketUtils.h +++ b/src/SocketUtils.h @@ -2,9 +2,10 @@ @header SocketUtils.h @date 1991 @author John Shalf - @desc - - @enddesc + @desc + Header file for thorn Socket which defines routines + to deal with sockets. + @enddesc @version $Header$ @@*/ @@ -16,96 +17,39 @@ 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); +#include "cctk.h" /* HAVE_WINSOCK2_H */ -/*================================================================== -** 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); - - -int Socket_SetNonBlocking(int sock); +/* check what sockets type we have (Unix or Windows sockets) + Note that only MS compilers require to use Windows sockets + but gcc under Windows does not. */ +#if ! defined(HAVE_WINSOCK2_H) || defined(__GNUC__) +#define SOCKET_HAVE_UNIX_SOCKETS 1 +#endif +/* define the socket data type and constants denoting an invalid socket + and an error code returned from a socket call */ +#ifdef SOCKET_HAVE_UNIX_SOCKETS +#define SOCKET int +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 #else -int Socket_TCPOpenClientSock(); -int Socket_TCPOpenServerSock(); -int Socket_TCPBlockingWrite(); -int Socket_TCPBlockingRead(); -int Socket_SetNonBlocking(); +/* the SOCKET type and the constants are defined in this header */ +#include #endif -#define PERRORS -#ifndef __IN_HEADER -#include -#include -#endif +int Socket_InitializeSocketLayer (void); +SOCKET Socket_TCPOpenServerSocket (unsigned int port, unsigned int *hunt, + int backlog); +SOCKET Socket_TCPOpenClientSocket (const char *hostname, unsigned int port); +SOCKET Socket_UDPOpenServerSocket (unsigned int port); +SOCKET Socket_UDPOpenClientSocket (const char *hostname, unsigned int port); +void Socket_CloseSocket (SOCKET s); + +int Socket_TCPBlockingWrite (SOCKET s, const char *buffer, int buflen); +int Socket_TCPBlockingRead (SOCKET s, char *buffer, int buflen); + +int Socket_SetNonBlocking (SOCKET s); #ifdef __cplusplus } diff --git a/src/Utils.c b/src/Utils.c index e89b482..afd8981 100644 --- a/src/Utils.c +++ b/src/Utils.c @@ -2,268 +2,327 @@ @file Utils.c @date 1991 @author John Shalf - @desc + @desc Routines which deal with sockets. @enddesc @history - @hdate Thu May 25 13:45:29 2000 + @hdate Thu May 25 13:45:29 2000 @hauthor Tom Goodale @hdesc Moved this file into Cactus - @endhistory + @hdate Thu 14 May 2002 + @hauthor Thomas Radke + @hdesc Merged with HTTPD socket code + @endhistory @version $Id$ @@*/ -#include "cctk.h" +#include "SocketUtils.h" #include #include #include +#include +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_WINSOCK2_H +#include +#include +#endif +#ifdef HAVE_SYS_TYPES_H #include +#endif +#ifdef HAVE_SYS_SOCKET_H #include +#endif +#ifdef HAVE_NETINET_IN_H #include -#include -#include -#include +#endif +#ifdef HAVE_ARPA_INET_H #include -#include -#ifdef HAVE_UNISTD_H -#include #endif -#include "SocketUtils.h" - static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusConnect_Socket_Utils_c) - +/******************************************************************** + ********************* Macro Definitions ********************** + ********************************************************************/ /* SunOS doesn't know INADDR_NONE */ #ifndef INADDR_NONE #define INADDR_NONE (-1) #endif +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +#ifdef SOCKET_HAVE_UNIX_SOCKETS +#include +#define IOCTL_SOCKET(a, b, c) ioctl(a, b, c) +#else +#define errno WSAGetLastError() +#define IOCTL_SOCKET(a, b, c) ioctlsocket (a, b, (u_long *) (c)) +#endif + +#define GET_INADDR(hostname, sin_addr) \ + { \ + struct hostent *host_entry; \ + \ + \ + host_entry = gethostbyname (hostname); \ + if (host_entry) \ + { \ + memcpy (&sin_addr, host_entry->h_addr, host_entry->h_length); \ + } \ + else \ + { \ + sin_addr.s_addr = inet_addr (hostname); \ + if (sin_addr.s_addr == INADDR_NONE) \ + { \ + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, \ + "Can't find network address for host '%s'", \ + hostname); \ + return (INVALID_SOCKET); \ + } \ + } \ + } + + +/******************************************************************** + ********************* Internal Functions ********************* + ********************************************************************/ +static SOCKET TCPOpenSocket (void); +static SOCKET UDPOpenSocket (struct in_addr sin_addr, unsigned int port); + /*@@ - @routine Socket_TCPOpenClientSock - @date 1991 - @author John Shalf - @desc - - @enddesc + @routine Socket_InitializeSocketLayer + @date Wed Sep 13 20:39:15 2000 + @author Tom Goodale + @desc + Special code for starting up the socket layer. + This is only neccessary for Windows. + @enddesc + + @returntype int + @returndesc + 0 for success, negative otherwise + @endreturndesc @@*/ -int Socket_TCPOpenClientSock(const char *hostname,int port) +int Socket_InitializeSocketLayer (void) { - struct hostent *phe; - /* struct servent *pse; */ - struct protoent *ppe; - struct sockaddr_in s_in; - int s /*,type*/; - - memset(&s_in, 0, sizeof(s_in)); - s_in.sin_family = AF_INET; - s_in.sin_addr.s_addr=INADDR_ANY; - s_in.sin_port = htons((u_short)port); - - if((phe=gethostbyname(hostname)) != NULL) - { - memcpy(&s_in.sin_addr, phe->h_addr, phe->h_length); - } - else if((s_in.sin_addr.s_addr = inet_addr(hostname)) == INADDR_NONE) - { - fprintf(stderr,"can\'t find host %s \n",hostname); - } - if((ppe=getprotobyname("tcp")) == NULL) - { - 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 *)&s_in, sizeof(s_in)) < 0) - { - perror(""); - fprintf(stderr,"couldn\'t connect to host %s: port %u\n",hostname,port); - close (s); - return -1; - } - return s; + int retval; +#ifdef HAVE_WINSOCK2_H + WSADATA wsaData; + + + retval = WSAStartup (MAKEWORD (2, 0), &wsaData); +#else + retval = 0; +#endif /* HAVE_WINSOCK2_H */ + + return (retval == 0 ? 0 : -1); } -/*@@ - @routine Socket_UDPOpenClientSock + + /*@@ + @routine Socket_TCPOpenClientSocket @date 1991 @author John Shalf - @desc - - @enddesc + @desc + Opens a TCP client socket by connecting to a server host with + given port number. + @enddesc + + @var hostname + @vdesc hostname of the server to connect to + @vtype const char * + @vio in + @endvar + @var port + @vdesc port number on the server to connect to + @vtype unsigned int + @vio in + @endvar + + @returntype SOCKET + @returndesc + a valid socket descriptor, or INVALID_SOCKET for failure + @endreturndesc @@*/ -int Socket_UDPOpenClientSock(const char *hostname,int port) +SOCKET Socket_TCPOpenClientSocket (const char *hostname, unsigned int port) { - struct hostent *phe; - /* struct servent *pse; */ - struct protoent *ppe; - struct sockaddr_in s_in; - int sock/*,type*/; - - memset(&s_in, 0, sizeof(s_in)); - s_in.sin_family = AF_INET; - s_in.sin_addr.s_addr=INADDR_ANY; - s_in.sin_port = htons((u_short)port); - - if((phe=gethostbyname(hostname)) != NULL) - { - memcpy(&s_in.sin_addr, phe->h_addr, phe->h_length); - } - else if((s_in.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,(struct sockaddr *)&s_in,sizeof(s_in)) <0) + SOCKET s; + struct sockaddr_in server; + + + memset (&server, 0, sizeof (server)); + server.sin_family = AF_INET; + server.sin_port = htons (port); + GET_INADDR (hostname, server.sin_addr); + + s = TCPOpenSocket (); + if (s != INVALID_SOCKET && + connect (s, (struct sockaddr *) &server, sizeof (server)) == SOCKET_ERROR) { - close(sock); - perror("client: bind failed"); - return -1; + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't connect to host '%s' port %u: %s", + hostname, port, strerror (errno)); + Socket_CloseSocket (s); + s = INVALID_SOCKET; } - - /* if(connect(s,(struct sockaddr *)&s_in, sizeof(s_in)) < 0) - {` - perror(""); - fprintf(stderr,"couldn\'t connect to host %s: port %u\n",hostname,port); - return -1; - } - */ - return sock; + return (s); } + /*@@ - @routine Socket_TCPOpenServerSock + @routine Socket_TCPOpenServerSocket @date 1991 @author John Shalf - @desc - - @enddesc + @desc + Opens a TCP server socket on the given port. + If the port is already taken, it will hunt for the next + available port. The port is set up to be listened on. + @enddesc + + @var port + @vdesc port number to bind server socket + @vtype unsigned int + @vio in + @endvar + + @returntype SOCKET + @returndesc + a valid socket descriptor, or INVALID_SOCKET for failure + @endreturndesc @@*/ -int Socket_TCPOpenServerSock(int port) +SOCKET Socket_TCPOpenServerSocket (unsigned int port, unsigned int *hunt, + int backlog) { - /* struct servent *pse; */ - struct protoent *ppe; - struct sockaddr_in s_in; - int s/*,type*/; + SOCKET s; + int is_bound; const int on = 1; - memset(&s_in, 0, sizeof(s_in)); - s_in.sin_family = AF_INET; - s_in.sin_addr.s_addr = INADDR_ANY; - s_in.sin_port = htons((u_short)port); + struct sockaddr_in addr; - if((ppe=getprotobyname("tcp")) == NULL) - { - fprintf (stderr, "can\'t find tcp protocol: %s\n", strerror (errno)); - return -1; - } - s=socket(PF_INET,SOCK_STREAM,ppe->p_proto); - if(s<0) - { - fprintf (stderr, "couldn\'t create socket on port %u: %s\n", - port, strerror (errno)); - return s; - } - if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0) - { - fprintf (stderr, "couldn\'t set SO_REUSEADDR to port %u: %s\n", - port, strerror (errno)); - close(s); - return -1; - } - if(bind(s,(struct sockaddr *)&s_in, sizeof(s_in)) < 0) + + s = TCPOpenSocket (); + +#ifdef SO_REUSEADDR + /* try to reuse the port if possible */ + if (s != INVALID_SOCKET) { - fprintf (stderr, "couldn\'t bind to port %u: %s\n", port, strerror (errno)); - close(s); - return -1; + if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) == + SOCKET_ERROR) + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't set SO_REUSEADDR to port %u: %s", + port, strerror (errno)); + Socket_CloseSocket (s); + s = INVALID_SOCKET; + } } - if(listen(s,5) < 0) /* note, server connection qlen fixed to 5 */ +#endif + + if (s != INVALID_SOCKET) { - fprintf (stderr, "couldn\'t listen on port %u: %s\n", port, strerror (errno)); + do + { + /* give the socket a name */ + addr.sin_family = AF_INET; + addr.sin_port = htons (port); + addr.sin_addr.s_addr = htonl (INADDR_ANY); + is_bound = bind (s, (struct sockaddr *) &addr, sizeof (addr)) != + SOCKET_ERROR; + if (! is_bound && hunt) + { + /* hunt for a new port */ + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Port %u taken, trying next port", port++); + } + } while (! is_bound && hunt); + + if (is_bound) + { + if (listen (s, backlog) == SOCKET_ERROR) + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't listen on port %u: %s", port, strerror (errno)); + Socket_CloseSocket (s); + s = INVALID_SOCKET; + } + else if (hunt) + { + *hunt = port; + } + } + else + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't bind socket on port %u: %s", port, strerror(errno)); + Socket_CloseSocket (s); + s = INVALID_SOCKET; + } } - return s; + + return (s); } + /*@@ - @routine Socket_UDPOpenServerSock - @date 1991 - @author John Shalf - @desc - - @enddesc + @routine Socket_CloseSocket + @date Tue 15 May 2002 + @author Thomas Radke + @desc + Closes the given socket descriptor. + @enddesc + + @var s + @vdesc socket to close + @vtype SOCKET + @vio in + @endvar @@*/ -int Socket_UDPOpenServerSock(int port) +void Socket_CloseSocket (SOCKET s) { - /* struct servent *pse; */ - struct protoent *ppe; - struct sockaddr_in s_in; - int s/*,type*/; - memset(&s_in, 0, sizeof(s_in)); - s_in.sin_family = AF_INET; - s_in.sin_addr.s_addr = INADDR_ANY; - s_in.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 *)&s_in, sizeof(s_in)) < 0) - { - fprintf(stderr,"couldn\'t bind to port %u\n",port); - close(s); - return -1; - } - return s; +#ifdef SOCKET_HAVE_UNIX_SOCKETS + close (s); +#else + closesocket (s); +#endif } + /*@@ @routine Socket_TCPBlockingWrite @date 1991 @author John Shalf - @desc - - @enddesc + @desc +** 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. + @enddesc @@*/ -int Socket_TCPBlockingWrite(int fd,char *buffer, int buflen) +int Socket_TCPBlockingWrite (SOCKET s, const char *buffer, int buflen) { int n; int nstore; - n=write(fd,buffer,buflen); - if(n>=0) + + n = send (s, buffer, buflen, MSG_NOSIGNAL); + + if(n != SOCKET_ERROR) { return n; } else - { + { switch(errno) /* note use of global variable errno */ { case EBADF: @@ -283,8 +342,8 @@ int Socket_TCPBlockingWrite(int fd,char *buffer, int buflen) #endif /* subdivide buffer and call TCPBlockingWrite() recursively */ nstore=n; /* preserve variable */ - Socket_TCPBlockingWrite(fd,buffer,buflen>>1); - Socket_TCPBlockingWrite(fd,buffer+(buflen>>1),buflen-(buflen>>1)); + Socket_TCPBlockingWrite(s,buffer,buflen>>1); + Socket_TCPBlockingWrite(s,buffer+(buflen>>1),buflen-(buflen>>1)); n=nstore; /* restore variable */ break; case EFAULT: @@ -317,26 +376,26 @@ int Socket_TCPBlockingWrite(int fd,char *buffer, int buflen) @routine Socket_TCPBlockingRead @date 1991 @author John Shalf - @desc - - @enddesc + @desc +** 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. + @enddesc @@*/ -int Socket_TCPBlockingRead(int fd,char *buffer, int buflen) +int Socket_TCPBlockingRead(SOCKET s,char *buffer, int buflen) { - /* do errno only if types.h has been included */ - /* how can I tell if this has been included ? */ int n,accum=0; - while((n=read(fd,buffer,buflen)) > 0) + + + while ((n = recv (s, buffer, buflen, MSG_NOSIGNAL)) != SOCKET_ERROR) { - if(n>=0) - { - buffer = buffer + n; - buflen -= n; - accum+=n; - } + buffer = buffer + n; + buflen -= n; + accum+=n; } -#ifdef PERRORS - if(n<0) + if (n == SOCKET_ERROR) { switch(errno) /* note use of global variable errno */ { @@ -364,10 +423,9 @@ int Socket_TCPBlockingRead(int fd,char *buffer, int buflen) break; } } -#endif if(n<0) - { + { return n; } else @@ -376,15 +434,106 @@ int Socket_TCPBlockingRead(int fd,char *buffer, int buflen) } } -int Socket_SetNonBlocking(int sock) +int Socket_SetNonBlocking (SOCKET s) { - int retval,ierr; - ierr = fcntl (sock, F_SETFL, O_NONBLOCK); - - if (ierr<0) - retval = -1; - else - retval = 0; + int retval; + unsigned long int on = 1; + + + retval = IOCTL_SOCKET (s, FIONBIO, &on) != SOCKET_ERROR ? 0 : -1; return(retval); } + + +SOCKET Socket_UDPOpenClientSocket (const char *hostname, unsigned int port) +{ + SOCKET s; + struct in_addr sin_addr; + + + GET_INADDR (hostname, sin_addr); + + s = UDPOpenSocket (sin_addr, port); + + return (s); +} + + +SOCKET Socket_UDPOpenServerSocket (unsigned int port) +{ + SOCKET s; + struct in_addr sin_addr; + + + sin_addr.s_addr = INADDR_ANY; + + s = UDPOpenSocket (sin_addr, port); + + return (s); +} + + +/******************************************************************** + ********************* Internal Routines ********************** + ********************************************************************/ +static SOCKET TCPOpenSocket (void) +{ + SOCKET s; + struct protoent *protocol; + + + protocol = getprotobyname ("tcp"); + if (! protocol) + { + CCTK_WARN (3, "Can't find TCP protocol"); + return (INVALID_SOCKET); + } + + s = socket (PF_INET, SOCK_STREAM, protocol->p_proto); + if (s == INVALID_SOCKET) + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't create socket: %s", strerror (errno)); + } + + return (s); +} + + +static SOCKET UDPOpenSocket (struct in_addr sin_addr, unsigned int port) +{ + SOCKET s; + struct protoent *protocol; + struct sockaddr_in addr; + + + memset (&addr, 0, sizeof (addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons (port); + addr.sin_addr = sin_addr; + + protocol = getprotobyname ("udp"); + if (! protocol) + { + CCTK_WARN (3, "Can't find UDP protocol"); + return (INVALID_SOCKET); + } + + s = socket (PF_INET, SOCK_DGRAM, protocol->p_proto); + if (s == INVALID_SOCKET) + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't create socket on port %u: %s", + port, strerror (errno)); + } + else if (bind (s, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR) + { + CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING, + "Couldn't bind to port %u: %s", port, strerror (errno)); + Socket_CloseSocket (s); + s = INVALID_SOCKET; + } + + return (s); +} diff --git a/src/make.code.defn b/src/make.code.defn index b8eac84..6398257 100644 --- a/src/make.code.defn +++ b/src/make.code.defn @@ -3,7 +3,3 @@ # Source files in this directory SRCS = Utils.c - -# Subdirectories containing source files -SUBDIRS = - -- cgit v1.2.3