X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=blobdiff_plain;f=src%2Fhtparser.c;h=de5bbc2a61f32f93fa1ebe1db51c197fcd857840;hp=c1903b44a349157e87d1db806fea7e11fc7a9485;hb=ecd4208b888be7f60bc2ae013b799861959b7cb9;hpb=8d19a9ecff0be0cd79c161096ead60f60d6b50e2 diff --git a/src/htparser.c b/src/htparser.c index c1903b4..de5bbc2 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; @@ -319,7 +320,8 @@ void serve(FILE *in, struct conn *conn) if(recvchunks(in, out)) break; } else { - break; + /* Ignore rather than abort, to be kinder to broken clients. */ + headrmheader(req, "content-type"); } } if(fflush(out)) @@ -403,30 +405,40 @@ static void plexwatch(struct muth *muth, va_list args) { vavar(int, fd); char *buf; - int ret; + int i, 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) { flog(LOG_WARNING, "received error on rootplex read channel: %s", strerror(errno)); exit(1); } else if(ret == 0) { - exit(0); + free(buf); + break; } /* Maybe I'd like to implement some protocol in this direction * some day... */ free(buf); } + shutdown(plex, SHUT_RDWR); + for(i = 0; i < listeners.d; i++) { + if(listeners.b[i] == muth) + bufdel(listeners, i); + } + flog(LOG_INFO, "root handler exited, so shutting down listening..."); + while(listeners.d > 0) + resume(listeners.b[0], 0); } static void initroot(void *uu) { int fd; + setsid(); if(daemonize) { - setsid(); chdir("/"); if((fd = open("/dev/null", O_RDWR)) >= 0) { dup2(fd, 0); @@ -493,9 +505,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; @@ -547,7 +564,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) { @@ -574,6 +591,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); } @@ -581,6 +601,22 @@ 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) { + while(listeners.d > 0) + resume(listeners.b[0], 0); + flog(LOG_INFO, "no longer listening"); + } else { + d = 1; + } + break; + } + } return(0); }