X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fcf.c;h=aae8485054912592177c2018d2665e61eaaa5292;hb=35737971905d2247746bc81e0da851744cc49902;hp=5a6388e1432ebdc09ac3d0fe796df93321f45026;hpb=8240565929c54d87883659f41ceef717bcdfa4b7;p=ashd.git diff --git a/lib/cf.c b/lib/cf.c index 5a6388e..aae8485 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; } - 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); }