diff options
author | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2000-09-14 19:09:58 +0000 |
---|---|---|
committer | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2000-09-14 19:09:58 +0000 |
commit | 37a1b7289e02a794269bf1ab248da152d4c80648 (patch) | |
tree | cc7d14cc7c672fabb580671608355064ac526213 /src/Sockets.c | |
parent | 68d3b18fee8e7331fd47f85b396a0fe25634e0d6 (diff) |
Initial version of C http thorn. There are still a fair number of things on
my to-do list, but it is fairly usable now as far as functionality is
concerned.
Tom
git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPD/trunk@2 1faa4e14-9dd3-4be0-9f0e-ffe519881164
Diffstat (limited to 'src/Sockets.c')
-rw-r--r-- | src/Sockets.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/Sockets.c b/src/Sockets.c new file mode 100644 index 0000000..6643ffd --- /dev/null +++ b/src/Sockets.c @@ -0,0 +1,241 @@ + /*@@ + @file Sockets.c + @date Wed Sep 13 20:39:15 2000 + @author Tom Goodale + @desc + Routines which deal with sockets. + These should probably move into thorn Socket at some point if + they aren't already there. + @enddesc + @version $Header$ + @@*/ + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <sys/time.h> +#include <sys/types.h> + +#include "cctk.h" + +#include "httpd.h" + +static char *rcsid = "$Header$"; + +CCTK_FILEVERSION(DevThorns_httpd_Socket_c) + +/******************************************************************** + ********************* Local Data Types *********************** + ********************************************************************/ + +/******************************************************************** + ********************* Local Routine Prototypes ********************* + ********************************************************************/ + +int HTTP_MakeSocket (uint16_t port); + +/******************************************************************** + ********************* Other Routine Prototypes ********************* + ********************************************************************/ + +/******************************************************************** + ********************* Local Data ***************************** + ********************************************************************/ + +/* Active file descriptors */ +static fd_set active_fd_set; + +/* Main server socket */ +static int sock; + +/******************************************************************** + ********************* External Routines ********************** + ********************************************************************/ + + + /*@@ + @routine HTTP_SetupServer + @date Wed Sep 13 20:39:15 2000 + @author Tom Goodale + @desc + Creates a socket to listen on. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int HTTP_SetupServer(int port, int queue_size) +{ + /* Create the socket and set it up to accept connections. */ + sock = HTTP_MakeSocket (port); + if (listen (sock, queue_size) < 0) + { + perror ("listen"); + exit (EXIT_FAILURE); + } + + /* Initialize the set of active sockets. */ + FD_ZERO (&active_fd_set); + FD_SET (sock, &active_fd_set); + + return 0; +} + + /*@@ + @routine HTTP_ShutdownServer + @date Wed Sep 13 20:39:15 2000 + @author Tom Goodale + @desc + Closes all sockets we are interested in. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int HTTP_ShutdownServer(void) +{ + int i; + + /* Close all sockets in our active set */ + for(i = FD_SETSIZE-1; i >=0; i--) + { + if(FD_ISSET(i, &active_fd_set)) + { + close(i); + } + } + + return 0; +} + + /*@@ + @routine HTTP_Poll + @date Wed Sep 13 20:39:15 2000 + @author Tom Goodale + @desc + Main workhorse routine. + Looks for activity on any of the sockets which are open + and dispatches work. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int HTTP_Poll(cGH *cctkGH, long sec, long usec) +{ + int i; + size_t size; + fd_set read_fd_set; + + struct sockaddr_in clientname; + struct timeval timeout; + + timeout.tv_sec = sec; + timeout.tv_usec = usec; + + /* Block until input arrives on one or more active sockets. */ + read_fd_set = active_fd_set; + + if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, &timeout) < 0) + { + perror ("select"); + exit (EXIT_FAILURE); + } + + /* Service all the sockets with input pending. */ + for (i = 0; i < FD_SETSIZE; ++i) + { + if (FD_ISSET (i, &read_fd_set)) + { + if (i == sock) + { + /* Connection request on original socket. */ + int new; + size = sizeof (clientname); + new = accept (sock, + (struct sockaddr *) &clientname, + &size); + if (new < 0) + { + perror ("accept"); + exit (EXIT_FAILURE); + } + fprintf (stderr, + "Server: connect from host %s, port %hd.\n", + inet_ntoa (clientname.sin_addr), + ntohs (clientname.sin_port)); + FD_SET (new, &active_fd_set); + } + else + { + /* Data arriving on an already-connected socket. */ + if (HTTP_ReadFromClient (cctkGH, i) < 0) + { + close (i); + FD_CLR (i, &active_fd_set); + } + } + } + } + + return 0; +} + +/******************************************************************** + ********************* Local Routines ************************* + ********************************************************************/ + + /*@@ + @routine HTTP_MakeSocket + @date Wed Sep 13 20:39:15 2000 + @author Tom Goodale + @desc + Creates a socket. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int HTTP_MakeSocket (uint16_t port) +{ + int sock; + struct sockaddr_in name; + + /* Create the socket. */ + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + perror ("socket"); + exit (EXIT_FAILURE); + } + + /* Give the socket a name. */ + name.sin_family = AF_INET; + name.sin_port = htons (port); + name.sin_addr.s_addr = htonl (INADDR_ANY); + if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) + { + perror ("bind"); + exit (EXIT_FAILURE); + } + + return sock; +} |