diff options
author | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2000-09-21 14:00:38 +0000 |
---|---|---|
committer | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2000-09-21 14:00:38 +0000 |
commit | d459e03bae0f4757a19986c5559641f1c51831a1 (patch) | |
tree | 8704a3ad6434d3a91efd4c08756a203bd6029aab /src/Sockets.c | |
parent | 6da8c26dc91515af7f192bb44e868f202dcb4a3a (diff) |
Added hunting for a port if the specified port is in use - this can be
switched off by setting the parameter httpd::hunt to false.
Added printing of URL to stdout.
Fixed up error stuff in Sockets.c so it compiles under NT.
Tom
git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPD/trunk@75 1faa4e14-9dd3-4be0-9f0e-ffe519881164
Diffstat (limited to 'src/Sockets.c')
-rw-r--r-- | src/Sockets.c | 119 |
1 files changed, 104 insertions, 15 deletions
diff --git a/src/Sockets.c b/src/Sockets.c index 688996a..9ed6a7a 100644 --- a/src/Sockets.c +++ b/src/Sockets.c @@ -66,6 +66,10 @@ CCTK_FILEVERSION(DevThorns_httpd_Socket_c) #define CLOSESOCKET(a) close(a) #endif +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + typedef enum {closed, open} httpSocketState; typedef struct HTTPSocket @@ -80,7 +84,7 @@ typedef struct HTTPSocket ********************* Local Routine Prototypes ********************* ********************************************************************/ -SOCKET HTTP_MakeSocket (unsigned long port); +SOCKET HTTP_MakeSocket (unsigned long port, int *hunt); static httpSocket *SocketCreate(unsigned long int filedes); static void SocketDestroy(httpSocket *this); @@ -125,19 +129,27 @@ static httpSocket *socklist = NULL; @endhistory @@*/ -int HTTP_SetupServer(int port, int queue_size) +int HTTP_SetupServer(int port, int queue_size, int hunt) { + char hostname[1025]; + int realport; + /* Some systems need special logic for starting up TCP. */ InitialiseTCP(); /* Create the socket and set it up to accept connections. */ - sock = HTTP_MakeSocket (port); + sock = HTTP_MakeSocket (port, hunt ? &realport : NULL); + if (ERROR_CHECK(listen (sock, queue_size))) { perror ("listen"); exit (EXIT_FAILURE); } + gethostname(hostname, 1024); + + printf("Server started on http://%s:%d/\n", hostname, hunt ? port : realport); + minsock = sock; maxsock = sock; @@ -316,10 +328,11 @@ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) MSG_NOSIGNAL); /* Check for errors */ - if(retval == -1) + if(ERROR_CHECK(retval)) { switch(errno) { +#ifdef EMSGSIZE case EMSGSIZE : /* The socket requires that message be sent atomically, * and the size of the message to be sent made this * impossible. @@ -340,7 +353,9 @@ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) retval = tmp; } break; - +#endif + +#ifdef ENOBUFS case ENOBUFS : /* The output queue for a network interface was full. This generally indicates that the interface has * stopped sending, but may be caused by transient congestion. (This cannot occur in Linux, packets are @@ -348,10 +363,11 @@ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) */ retval = 0; break; - +#endif case EBADF : /* An invalid descriptor was specified. */ - +#ifdef ENOTSOCK case ENOTSOCK : /* The filedescriptor is not a socket. */ +#endif case EPIPE : /* The local end has been shut down on a connection oriented socket. In this case the process will also * receive a SIGPIPE unless MSG_NOSIGNAL is set. */ @@ -381,7 +397,7 @@ int HTTP_Write(httpRequest *request, const char *buffer, size_t count) bytes_sent += retval; } - if(retval > -1 && bytes_sent < count) + if(!(ERROR_CHECK(retval)) && bytes_sent < count) { /* Wait until can write */ FD_SET (connection->filedes, &this_set); @@ -466,11 +482,14 @@ int HTTP_Read(httpRequest *request, char *buffer, size_t count) @endhistory @@*/ -int HTTP_MakeSocket (unsigned long port) +int HTTP_MakeSocket (unsigned long port, int *hunt) { int sock; struct sockaddr_in name; int opt; + int done; + int realport; + int error; /* Create the socket. */ sock = socket (PF_INET, SOCK_STREAM, 0); @@ -486,19 +505,61 @@ int HTTP_MakeSocket (unsigned long port) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); #endif - /* Give the socket a name. */ - name.sin_family = AF_INET; - name.sin_port = htons (port); - name.sin_addr.s_addr = htonl (INADDR_ANY); - if (ERROR_CHECK(bind (sock, (struct sockaddr *) &name, sizeof (name)))) + done = 0; + realport = port; + + while(!done) + { + /* Give the socket a name. */ + name.sin_family = AF_INET; + name.sin_port = htons (realport); + name.sin_addr.s_addr = htonl (INADDR_ANY); + if (ERROR_CHECK(error = bind (sock, (struct sockaddr *) &name, sizeof (name)))) + { + if(hunt) + { + /* Hunt for a new port */ + fprintf(stderr, "Port %lu taken, trying %lu\n", realport, realport+1); + realport++; + } + else + { + done = 1; + } + } + else + { + done = 1; + } + } + + if(ERROR_CHECK(error)) { perror ("bind"); CCTK_Abort(NULL,EXIT_FAILURE); } + else if(hunt) + { + *hunt = realport; + } return sock; } + /*@@ + @routine SocketCreate + @date Thu Sep 21 15:03:32 2000 + @author Tom Goodale + @desc + Creates an httpSocket structure and links it to the list. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ static httpSocket *SocketCreate(unsigned long int filedes) { httpSocket *this; @@ -525,6 +586,20 @@ static httpSocket *SocketCreate(unsigned long int filedes) return this; } + /*@@ + @routine SocketDestroy + @date Thu Sep 21 15:04:03 2000 + @author Tom Goodale + @desc + Destroys an httpSocket structure and removes it from the list. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ static void SocketDestroy(httpSocket *this) { if(this) @@ -552,6 +627,20 @@ static void SocketDestroy(httpSocket *this) } } + /*@@ + @routine SocketClose + @date Thu Sep 21 15:04:27 2000 + @author Tom Goodale + @desc + Closes the socket associated with an httpSocket structure. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ static void SocketClose(httpSocket *this) { if(this) @@ -596,7 +685,7 @@ static int InitialiseTCP(void) } else { - printf("Windows socket layer initialized."); + printf("Windows socket layer initialized.\n"); } return errnumber; |