aboutsummaryrefslogtreecommitdiff
path: root/src/Sockets.c
diff options
context:
space:
mode:
authorgoodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164>2000-09-21 14:00:38 +0000
committergoodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164>2000-09-21 14:00:38 +0000
commitd459e03bae0f4757a19986c5559641f1c51831a1 (patch)
tree8704a3ad6434d3a91efd4c08756a203bd6029aab /src/Sockets.c
parent6da8c26dc91515af7f192bb44e868f202dcb4a3a (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.c119
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;