diff options
Diffstat (limited to 'hw4')
-rw-r--r-- | hw4/chttpd/chttpd-server.c | 40 | ||||
-rw-r--r-- | hw4/chttpd/chttpd-socket.c | 11 | ||||
-rw-r--r-- | hw4/chttpd/chttpd-socket.h | 1 |
3 files changed, 46 insertions, 6 deletions
diff --git a/hw4/chttpd/chttpd-server.c b/hw4/chttpd/chttpd-server.c index 611a7a6..f9c6f33 100644 --- a/hw4/chttpd/chttpd-server.c +++ b/hw4/chttpd/chttpd-server.c @@ -17,6 +17,7 @@ #include <inttypes.h> #include <locale.h> #include <netdb.h> +#include <poll.h> #include <signal.h> #include <stdbool.h> #include <stdio.h> @@ -43,9 +44,12 @@ static inline void report_unix_error (int rval) { case CHTTPD_SOCKET_NEW_ERROR_BIND: fputs ("bind: ", stdout); break; + case CHTTPD_SOCKET_NEW_ERROR_LISTEN: + fputs ("listen: ", stdout); + break; } puts (strerror (errno_backup)); - errno_backup = errno; + errno = errno_backup; } static inline bool init_runtime_dir (ChttpdServer* server, @@ -98,11 +102,15 @@ static inline void report_inet_error (int rval, int gai_error) { fputs ("bind: ", stdout); puts (strerror (errno_backup)); break; + case CHTTPD_SOCKET_NEW_ERROR_LISTEN: + fputs ("listen: ", stdout); + puts (strerror (errno_backup)); + break; case CHTTPD_SOCKET_NEW_ERROR_UNEXPECTED: puts ("Unexpected error! Is your system broken?"); break; } - errno_backup = errno; + errno = errno_backup; } static LbsListMeta* chttpd_main_init (ChttpdLog* hlog, const char* service) { @@ -247,6 +255,8 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { sigaddset (&crit_mask, SIGHUP); sigaddset (&crit_mask, SIGUSR2); + struct pollfd* pfds = NULL; + while (lbs_list_meta_get_len (slist) > 0) { pthread_sigmask (SIG_BLOCK, &crit_mask, NULL); @@ -278,7 +288,7 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { /* Remove unused servers */ LbsList* iter = slist->first; - LbsList* next = iter; + LbsList* next; for (; iter != NULL; iter = next) { ChttpdServer* server = iter->data; next = iter->next; @@ -292,7 +302,23 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { } } - /* Rebuild poll list */ + /* Rebuild poll fd list */ + if (slist->len > 0) { + pfds = xrealloc (pfds, sizeof (struct pollfd) * slist->len); + unsigned c = 0; + for (iter = slist->first; iter != NULL; iter = iter->next, c++) { + ChttpdServer* server = iter->data; + pfds[c] = (struct pollfd) { + .fd = server->sockfd, + .events = POLLIN | POLLPRI, + .revents = 0 + }; + } + } else { + free (pfds); + pfds = NULL; + } + /* Log current server info */ chttpd_log_write_str (hlog, "[Server status change notification]"); @@ -347,7 +373,7 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { break; } } - + chttpd_log_write (hlog, "%u servers are active", slist->len); } else { pthread_mutex_unlock (&chttpd_server_notify_mutex); } @@ -355,6 +381,8 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { pthread_sigmask (SIG_UNBLOCK, &crit_mask, NULL); /* */ } + + free (pfds); } void chttpd_server_ctor (void* server_generic, ChttpdLog* hlog, bool is_admin) { @@ -420,6 +448,8 @@ int main (int argc, char* argv[]) { sigaddset (&main_mask, SIGUSR1); pthread_sigmask (SIG_BLOCK, &main_mask, NULL); + puts ("Starting " PACKAGE_NAME " version " PACKAGE_VERSION " ..."); + LbsListMeta* slist = chttpd_main_init (hlog, argv[1]); if (lbs_list_meta_get_len (slist) > 0) { chttpd_main_loop (hlog, slist); diff --git a/hw4/chttpd/chttpd-socket.c b/hw4/chttpd/chttpd-socket.c index cd1ff2e..7fd0efc 100644 --- a/hw4/chttpd/chttpd-socket.c +++ b/hw4/chttpd/chttpd-socket.c @@ -36,6 +36,10 @@ int chttpd_socket_new_unix (const char* path, close (sockfd); return CHTTPD_SOCKET_NEW_ERROR_BIND; } + if (listen (sockfd, SOMAXCONN) < 0) { + close (sockfd); + return CHTTPD_SOCKET_NEW_ERROR_LISTEN; + } if (saddr != NULL) { *saddr = addr; @@ -87,6 +91,8 @@ int chttpd_socket_new_inet (const char* host, const char* service, int domain, bindrv = bind (sockfd, iter->ai_addr, iter->ai_addrlen); if (bindrv < 0) { close (sockfd); + } else if (listen (sockfd, SOMAXCONN) < 0) { + close (sockfd); } else { if (saddr != NULL) { switch (iter->ai_family) { @@ -115,6 +121,9 @@ int chttpd_socket_new_inet (const char* host, const char* service, int domain, if (sockfd < 0) { return CHTTPD_SOCKET_NEW_ERROR_SOCKET; } + if (bindrv < 0) { + return CHTTPD_SOCKET_NEW_ERROR_BIND; + } - return CHTTPD_SOCKET_NEW_ERROR_BIND; + return CHTTPD_SOCKET_NEW_ERROR_LISTEN; } diff --git a/hw4/chttpd/chttpd-socket.h b/hw4/chttpd/chttpd-socket.h index 2ac05b6..7bafcad 100644 --- a/hw4/chttpd/chttpd-socket.h +++ b/hw4/chttpd/chttpd-socket.h @@ -9,6 +9,7 @@ #define CHTTPD_SOCKET_NEW_ERROR_GETADDRINFO -1 #define CHTTPD_SOCKET_NEW_ERROR_SOCKET -2 #define CHTTPD_SOCKET_NEW_ERROR_BIND -3 +#define CHTTPD_SOCKET_NEW_ERROR_LISTEN -4 #define CHTTPD_SOCKET_NEW_ERROR_UNEXPECTED -100 int chttpd_socket_new_unix (const char* path, struct sockaddr_un* saddr, socklen_t* saddrlen); |