From cac13158ac4fdd8b7682f16f879796e9c4e339ff Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Fri, 28 Dec 2012 07:00:27 +0100 Subject: [PATCH] htparser: More well-defined shutdown behavior. --- src/htparser.c | 41 +++++++++++++++++++++++++++++++++++------ src/htparser.h | 7 +++++++ src/plaintcp.c | 7 ++++--- src/ssl-gnutls.c | 7 ++++--- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/htparser.c b/src/htparser.c index e6f545a..8eb3873 100644 --- a/src/htparser.c +++ b/src/htparser.c @@ -41,6 +41,7 @@ static int plex; static char *pidfile = NULL; static int daemonize, usesyslog; +struct mtbuf listeners; static void trimx(struct hthead *req) { @@ -290,7 +291,7 @@ void serve(FILE *in, struct conn *conn) out = NULL; req = resp = NULL; - while(1) { + while(plex >= 0) { if((req = parsereq(in)) == NULL) break; if(!canonreq(req)) @@ -299,7 +300,7 @@ void serve(FILE *in, struct conn *conn) if((conn->initreq != NULL) && conn->initreq(conn, req)) break; - if(block(plex, EV_WRITE, 60) <= 0) + if((plex < 0) || block(plex, EV_WRITE, 60) <= 0) break; if(socketpair(PF_UNIX, SOCK_STREAM, 0, pfds)) break; @@ -407,7 +408,8 @@ static void plexwatch(struct muth *muth, va_list args) int ret; while(1) { - block(fd, EV_READ, 0); + if(block(fd, EV_READ, 0) == 0) + break; buf = smalloc(65536); ret = recv(fd, buf, 65536, 0); if(ret < 0) { @@ -420,6 +422,8 @@ static void plexwatch(struct muth *muth, va_list args) * some day... */ free(buf); } + close(plex); + plex = -1; } static void initroot(void *uu) @@ -494,9 +498,14 @@ static void addport(char *spec) buffree(vals); } +static void sighandler(int sig) +{ + exitioloop(1); +} + int main(int argc, char **argv) { - int c; + int c, d; int i, s1; char *root; FILE *pidout; @@ -548,7 +557,7 @@ int main(int argc, char **argv) flog(LOG_ERR, "could not spawn root multiplexer: %s", strerror(errno)); return(1); } - mustart(plexwatch, plex); + bufadd(listeners, mustart(plexwatch, plex)); pidout = NULL; if(pidfile != NULL) { if((pidout = fopen(pidfile, "w")) == NULL) { @@ -575,6 +584,9 @@ int main(int argc, char **argv) } } signal(SIGPIPE, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); if(daemonize) { daemon(0, 0); } @@ -582,6 +594,23 @@ int main(int argc, char **argv) fprintf(pidout, "%i\n", getpid()); fclose(pidout); } - ioloop(); + d = 0; + while(!d) { + switch(ioloop()) { + case 0: + d = 1; + break; + case 1: + if(listeners.d > 0) { + for(i = 0; i < listeners.d; i++) + resume(listeners.b[i], 0); + listeners.d = 0; + flog(LOG_INFO, "no longer listening"); + } else { + d = 1; + } + break; + } + } return(0); } diff --git a/src/htparser.h b/src/htparser.h index 88bfb6e..7bd60a0 100644 --- a/src/htparser.h +++ b/src/htparser.h @@ -6,6 +6,11 @@ struct conn { void *pdata; }; +struct mtbuf { + struct muth **b; + size_t s, d; +}; + void serve(FILE *in, struct conn *conn); int listensock4(int port); @@ -16,4 +21,6 @@ void handleplain(int argc, char **argp, char **argv); void handlegnussl(int argc, char **argp, char **argv); #endif +extern struct mtbuf listeners; + #endif diff --git a/src/plaintcp.c b/src/plaintcp.c index b898e37..fb4c6ce 100644 --- a/src/plaintcp.c +++ b/src/plaintcp.c @@ -174,7 +174,8 @@ static void listenloop(struct muth *muth, va_list args) while(1) { namelen = sizeof(name); - block(tcp->fd, EV_READ, 0); + if(block(tcp->fd, EV_READ, 0) == 0) + goto out; ns = accept(tcp->fd, (struct sockaddr *)&name, &namelen); if(ns < 0) { flog(LOG_ERR, "accept: %s", strerror(errno)); @@ -215,7 +216,7 @@ void handleplain(int argc, char **argp, char **argv) omalloc(tcp); tcp->fd = fd; tcp->sport = port; - mustart(listenloop, tcp); + bufadd(listeners, mustart(listenloop, tcp)); if((fd = listensock4(port)) < 0) { if(errno != EADDRINUSE) { flog(LOG_ERR, "could not listen on IPv4 (port %i): %s", port, strerror(errno)); @@ -225,6 +226,6 @@ void handleplain(int argc, char **argp, char **argv) omalloc(tcp); tcp->fd = fd; tcp->sport = port; - mustart(listenloop, tcp); + bufadd(listeners, mustart(listenloop, tcp)); } } diff --git a/src/ssl-gnutls.c b/src/ssl-gnutls.c index d4862d4..baa1334 100644 --- a/src/ssl-gnutls.c +++ b/src/ssl-gnutls.c @@ -365,7 +365,8 @@ static void listenloop(struct muth *muth, va_list args) while(1) { namelen = sizeof(name); - block(pd->fd, EV_READ, 0); + if(block(pd->fd, EV_READ, 0) == 0) + goto out; ns = accept(pd->fd, (struct sockaddr *)&name, &namelen); if(ns < 0) { flog(LOG_ERR, "accept: %s", strerror(errno)); @@ -606,7 +607,7 @@ void handlegnussl(int argc, char **argp, char **argv) pd->sport = port; pd->creds = creds; pd->ncreds = ncreds.b; - mustart(listenloop, pd); + bufadd(listeners, mustart(listenloop, pd)); if((fd = listensock4(port)) < 0) { if(errno != EADDRINUSE) { flog(LOG_ERR, "could not listen on IPv4 port (port %i): %s", port, strerror(errno)); @@ -617,7 +618,7 @@ void handlegnussl(int argc, char **argp, char **argv) pd->fd = fd; pd->sport = port; pd->creds = creds; - mustart(listenloop, pd); + bufadd(listeners, mustart(listenloop, pd)); } } -- 2.11.0