X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fcf.c;h=41352090e96c42e9f1faf11c5f30f9595bab3071;hb=7a092cefb32b7dceae2a5140bf9d83f00a991572;hp=1f7be797c1688cefb9bb11945b3abf3965a952cd;hpb=6f761f0ad9ab8ab78de873612668bea4c7c86045;p=ashd.git diff --git a/lib/cf.c b/lib/cf.c index 1f7be79..4135209 100644 --- a/lib/cf.c +++ b/lib/cf.c @@ -43,6 +43,7 @@ struct stdchild { char **argv; char **envp; int fd; + int agains; }; static int parsefile(struct cfstate *s, FILE *in); @@ -354,26 +355,35 @@ static char **expandargs(struct stdchild *sd) return(ret); } -static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *idata) +struct sidata { + struct stdchild *sd; + void (*sinit)(void *); + void *sdata; +}; + +static void stdinit(void *data) +{ + struct sidata *d = data; + int i; + + for(i = 0; d->sd->envp[i]; i += 2) + putenv(sprintf2("%s=%s", d->sd->envp[i], d->sd->envp[i + 1])); + if(d->sinit != NULL) + d->sinit(d->sdata); +} + +static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *sdata) { struct stdchild *sd = ch->pdata; int serr; char **args; - - void stdinit(void *data) - { - int i; - - for(i = 0; sd->envp[i]; i += 2) - putenv(sprintf2("%s=%s", sd->envp[i], sd->envp[i + 1])); - if(chinit != NULL) - chinit(data); - } + struct sidata idat; if(sd->type == CH_SOCKET) { + idat = (struct sidata) {.sd = sd, .sinit = chinit, .sdata = sdata}; if(sd->fd < 0) { args = expandargs(sd); - sd->fd = stdmkchild(args, stdinit, idata); + sd->fd = stdmkchild(args, stdinit, &idat); freeca(args); } if(sendreq2(sd->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) { @@ -382,22 +392,30 @@ static int stdhandle(struct child *ch, struct hthead *req, int fd, void (*chinit /* Assume that the child has crashed and restart it. */ close(sd->fd); args = expandargs(sd); - sd->fd = stdmkchild(args, stdinit, idata); + sd->fd = stdmkchild(args, stdinit, &idat); freeca(args); if(!sendreq2(sd->fd, req, fd, MSG_NOSIGNAL | MSG_DONTWAIT)) - return(0); + goto ok; serr = errno; } - flog(LOG_ERR, "could not pass on request to child %s: %s", ch->name, strerror(serr)); - if(serr != EAGAIN) { + if(serr == EAGAIN) { + if(sd->agains++ == 0) + flog(LOG_WARNING, "request to child %s denied due to buffer overload", ch->name); + } else { + flog(LOG_ERR, "could not pass on request to child %s: %s", ch->name, strerror(serr)); close(sd->fd); sd->fd = -1; } return(-1); } + ok: + if(sd->agains > 0) { + flog(LOG_WARNING, "%i requests to child %s were denied due to buffer overload", sd->agains, ch->name); + sd->agains = 0; + } } else if(sd->type == CH_FORK) { args = expandargs(sd); - if(stdforkserve(args, req, fd, chinit, idata) < 0) { + if(stdforkserve(args, req, fd, chinit, sdata) < 0) { freeca(args); return(-1); }