From: Fredrik Tolf Date: Sun, 3 Feb 2013 02:29:45 +0000 (+0100) Subject: Merge branches 'block' and 'py-reserve' X-Git-Tag: 0.12~6 X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=commitdiff_plain;h=27ca317cc6d19aa6080eae9a446212e928696bf5;hp=62705f8e38c65b1eddca7e88d57cf9f3ee3a71c5 Merge branches 'block' and 'py-reserve' --- diff --git a/examples/python/dynhosts/dynhosts b/examples/python/dynhosts/dynhosts index 9a69a70..0e10b73 100755 --- a/examples/python/dynhosts/dynhosts +++ b/examples/python/dynhosts/dynhosts @@ -20,6 +20,6 @@ def serve(req): children[dname] = util.pchild(["dirplex", path], autorespawn = True) children[dname].passreq(req) return - util.respond(req, "No such host in configured.\n", status = "404 Not Found", ctype = "text/plain") + util.respond(req, "No such host is configured.\n", status = "404 Not Found", ctype = "text/plain") util.serveloop(serve) diff --git a/examples/python/dynhosts/run b/examples/python/dynhosts/run index d4203ea..07f6673 100755 --- a/examples/python/dynhosts/run +++ b/examples/python/dynhosts/run @@ -4,9 +4,5 @@ set -e cd "$(dirname "$0")" -# Start htparser running this dynhosts script. The setsid command -# ensures that SIGINT is only received by htparser and not by -# dynhosts; it is not of grave importance, but makes shutdown slightly -# more clean, and hides the KeyboardInterrupt otherwise raised by -# Python. -htparser plain:port=8080 -- setsid ./dynhosts . +# Start htparser running this dynhosts script. +htparser plain:port=8080 -- ./dynhosts . diff --git a/examples/python/wsgidir/run b/examples/python/wsgidir/run index 5dbe5d2..8931d4c 100755 --- a/examples/python/wsgidir/run +++ b/examples/python/wsgidir/run @@ -7,9 +7,4 @@ cd "$(dirname "$0")" # Invoke dirplex running in this directory, loading the wsgidir.rc # configuration file. The same configuration can be put in # e.g. /etc/ashd/dirplex.d or in any .htrc file. - -# The setsid command ensures that SIGINT is only received by htparser -# and not by dirplex or its children; it is not of any importance, but -# makes shutdown slightly cleaner, and hides the KeyboardInterrupt -# otherwise raised by Python. -htparser plain:port=8080 -- setsid dirplex -c ./wsgidir.rc . +htparser plain:port=8080 -- dirplex -c ./wsgidir.rc . diff --git a/lib/cf.c b/lib/cf.c index 38d9808..ba63999 100644 --- a/lib/cf.c +++ b/lib/cf.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #ifdef HAVE_CONFIG_H @@ -305,21 +306,25 @@ static struct chandler stdhandler = { static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *idata) { struct stdchild *i = ch->pdata; + int serr; if(i->type == CH_SOCKET) { if(i->fd < 0) i->fd = stdmkchild(i->argv, chinit, idata); - if(sendreq(i->fd, req, fd)) { - if((errno == EPIPE) || (errno == ECONNRESET)) { + if(sendreq2(i->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) { + serr = errno; + if((serr == EPIPE) || (serr == ECONNRESET)) { /* Assume that the child has crashed and restart it. */ close(i->fd); i->fd = stdmkchild(i->argv, chinit, idata); - if(!sendreq(i->fd, req, fd)) + if(!sendreq2(i->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) return(0); } - flog(LOG_ERR, "could not pass on request to child %s: %s", ch->name, strerror(errno)); - close(i->fd); - i->fd = -1; + flog(LOG_ERR, "could not pass on request to child %s: %s", ch->name, strerror(serr)); + if(serr != EAGAIN) { + close(i->fd); + i->fd = -1; + } return(-1); } } else if(i->type == CH_FORK) { diff --git a/lib/proc.c b/lib/proc.c index a1dc336..ac777d4 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -83,7 +83,7 @@ int sendfd2(int sock, int fd, char *data, size_t datalen, int flags) int sendfd(int sock, int fd, char *data, size_t datalen) { - return(sendfd2(sock, fd, data, datalen, MSG_NOSIGNAL | MSG_DONTWAIT)); + return(sendfd2(sock, fd, data, datalen, MSG_NOSIGNAL)); } int recvfd(int sock, char **data, size_t *datalen) diff --git a/lib/req.c b/lib/req.c index 8ff26e0..ed5aeba 100644 --- a/lib/req.c +++ b/lib/req.c @@ -315,7 +315,7 @@ int sendreq2(int sock, struct hthead *req, int fd, int flags) int sendreq(int sock, struct hthead *req, int fd) { - return(sendreq2(sock, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)); + return(sendreq2(sock, req, fd, MSG_NOSIGNAL)); } int recvreq(int sock, struct hthead **reqp) diff --git a/src/htparser.c b/src/htparser.c index 8d0b515..1dbb8ee 100644 --- a/src/htparser.c +++ b/src/htparser.c @@ -405,8 +405,9 @@ static void plexwatch(struct muth *muth, va_list args) { vavar(int, fd); char *buf; - int i, ret; + int i, s, ret; + s = 0; while(1) { if(block(fd, EV_READ, 0) == 0) break; @@ -416,6 +417,7 @@ static void plexwatch(struct muth *muth, va_list args) flog(LOG_WARNING, "received error on rootplex read channel: %s", strerror(errno)); exit(1); } else if(ret == 0) { + s = 1; free(buf); break; } @@ -423,15 +425,16 @@ static void plexwatch(struct muth *muth, va_list args) * some day... */ free(buf); } - close(plex); - plex = -1; + 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); + if(s) { + flog(LOG_INFO, "root handler exited, so shutting down listening..."); + while(listeners.d > 0) + resume(listeners.b[0], 0); + } } static void initroot(void *uu) diff --git a/src/userplex.c b/src/userplex.c index c50a15c..48a8ed3 100644 --- a/src/userplex.c +++ b/src/userplex.c @@ -158,19 +158,24 @@ static int forkchild(char *usrnm, struct hthead *forreq, int reqfd) static void serve2(struct user *usr, struct hthead *req, int fd) { + int serr; + if(usr->fd < 0) usr->fd = forkchild(usr->name, req, fd); - if(sendreq(usr->fd, req, fd)) { - if((errno == EPIPE) || (errno == ECONNRESET)) { + if(sendreq2(usr->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) { + serr = errno; + if((serr == EPIPE) || (serr == ECONNRESET)) { /* Assume that the child has crashed and restart it. */ close(usr->fd); usr->fd = forkchild(usr->name, req, fd); - if(!sendreq(usr->fd, req, fd)) + if(!sendreq2(usr->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) return; } - flog(LOG_ERR, "could not pass on request to user `%s': %s", usr->name, strerror(errno)); - close(usr->fd); - usr->fd = -1; + flog(LOG_ERR, "could not pass on request to user `%s': %s", usr->name, strerror(serr)); + if(serr != EAGAIN) { + close(usr->fd); + usr->fd = -1; + } } }