summaryrefslogtreecommitdiffstats
path: root/hw4
diff options
context:
space:
mode:
Diffstat (limited to 'hw4')
-rw-r--r--hw4/chttpd/chttpd-server.c40
-rw-r--r--hw4/chttpd/chttpd-socket.c11
-rw-r--r--hw4/chttpd/chttpd-socket.h1
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);