worker.c (nagios-4.4.3) | : | worker.c (nagios-4.4.4) | ||
---|---|---|---|---|
skipping to change at line 218 | skipping to change at line 218 | |||
kvvec_addkv_wlen(kvv, key, sizeof(key) - 1, buf, strlen(buf)); \ | kvvec_addkv_wlen(kvv, key, sizeof(key) - 1, buf, strlen(buf)); \ | |||
} while (0) | } while (0) | |||
#define kvvec_add_tv(kvv, key, value) \ | #define kvvec_add_tv(kvv, key, value) \ | |||
do { \ | do { \ | |||
const char *buf = mkstr("%ld.%06ld", value.tv_sec, value.tv_usec) ; \ | const char *buf = mkstr("%ld.%06ld", value.tv_sec, value.tv_usec) ; \ | |||
kvvec_addkv_wlen(kvv, key, sizeof(key) - 1, buf, strlen(buf)); \ | kvvec_addkv_wlen(kvv, key, sizeof(key) - 1, buf, strlen(buf)); \ | |||
} while (0) | } while (0) | |||
/* forward declaration */ | /* forward declaration */ | |||
static void gather_output(child_process *cp, iobuf *io, int final); | static int gather_output(child_process *cp, iobuf *io, int final); | |||
static void destroy_job(child_process *cp) | static void destroy_job(child_process *cp) | |||
{ | { | |||
/* | /* | |||
* we must remove the job's timeout ticker, | * we must remove the job's timeout ticker, | |||
* or we'll end up accessing an already free()'d | * or we'll end up accessing an already free()'d | |||
* pointer, or the pointer to a different child. | * pointer, or the pointer to a different child. | |||
*/ | */ | |||
squeue_remove(sq, cp->ei->sq_event); | squeue_remove(sq, cp->ei->sq_event); | |||
running_jobs--; | running_jobs--; | |||
skipping to change at line 261 | skipping to change at line 261 | |||
if (!io.buf || !*io.buf) \ | if (!io.buf || !*io.buf) \ | |||
io.len = 0; \ | io.len = 0; \ | |||
else if ((nul = memchr(io.buf, 0, io.len))) { \ | else if ((nul = memchr(io.buf, 0, io.len))) { \ | |||
io.len = (unsigned long)nul - (unsigned long)io.buf; \ | io.len = (unsigned long)nul - (unsigned long)io.buf; \ | |||
} \ | } \ | |||
} while (0) | } while (0) | |||
int finish_job(child_process *cp, int reason) | int finish_job(child_process *cp, int reason) | |||
{ | { | |||
static struct kvvec resp = KVVEC_INITIALIZER; | static struct kvvec resp = KVVEC_INITIALIZER; | |||
int i, ret; | int i, ret, rd; | |||
/* get rid of still open filedescriptors */ | /* get rid of still open filedescriptors */ | |||
if (cp->outstd.fd != -1) { | if (cp->outstd.fd != -1) { | |||
gather_output(cp, &cp->outstd, 1); | ||||
rd = 1; | ||||
while(rd > 0) { | ||||
rd = gather_output(cp, &cp->outstd, 0); | ||||
} | ||||
iobroker_close(iobs, cp->outstd.fd); | iobroker_close(iobs, cp->outstd.fd); | |||
} | } | |||
if (cp->outerr.fd != -1) { | if (cp->outerr.fd != -1) { | |||
gather_output(cp, &cp->outerr, 1); | ||||
rd = 1; | ||||
while(rd > 0) { | ||||
rd = gather_output(cp, &cp->outerr, 0); | ||||
} | ||||
iobroker_close(iobs, cp->outerr.fd); | iobroker_close(iobs, cp->outerr.fd); | |||
} | } | |||
/* Make sure network-supplied data doesn't contain nul bytes */ | /* Make sure network-supplied data doesn't contain nul bytes */ | |||
strip_nul_bytes(cp->outstd); | strip_nul_bytes(cp->outstd); | |||
strip_nul_bytes(cp->outerr); | strip_nul_bytes(cp->outerr); | |||
/* how many key/value pairs do we need? */ | /* how many key/value pairs do we need? */ | |||
if (kvvec_init(&resp, 12 + cp->request->kv_pairs) == NULL) { | if (kvvec_init(&resp, 12 + cp->request->kv_pairs) == NULL) { | |||
/* what the hell do we do now? */ | /* what the hell do we do now? */ | |||
skipping to change at line 445 | skipping to change at line 453 | |||
} | } | |||
} while (!reaped); | } while (!reaped); | |||
if (cp->ei->state != ESTALE) | if (cp->ei->state != ESTALE) | |||
finish_job(cp, reason); | finish_job(cp, reason); | |||
else | else | |||
wlog("job %d (pid=%ld): Dormant child reaped", cp->id, (long)cp-> ei->pid); | wlog("job %d (pid=%ld): Dormant child reaped", cp->id, (long)cp-> ei->pid); | |||
destroy_job(cp); | destroy_job(cp); | |||
} | } | |||
static void gather_output(child_process *cp, iobuf *io, int final) | static int gather_output(child_process *cp, iobuf *io, int final) | |||
{ | { | |||
int retry = 5; | int retry = 5; | |||
int rd; | ||||
for (;;) { | for (;;) { | |||
char buf[4096]; | char buf[4096]; | |||
int rd; | ||||
rd = read(io->fd, buf, sizeof(buf)); | rd = read(io->fd, buf, sizeof(buf)); | |||
if (rd < 0) { | if (rd < 0) { | |||
if (errno == EAGAIN && !final) | if (errno == EAGAIN && !final) | |||
break; | break; | |||
if (errno == EINTR || errno == EAGAIN) { | if (errno == EINTR || errno == EAGAIN) { | |||
char buf[1024]; | char buf[1024]; | |||
if (--retry == 0) { | if (--retry == 0) { | |||
sprintf(buf, "job %d (pid=%ld): Failed to read(): %s", cp->id, (long)cp->ei->pid, strerror(errno)); | sprintf(buf, "job %d (pid=%ld): Failed to read(): %s", cp->id, (long)cp->ei->pid, strerror(errno)); | |||
break; | break; | |||
skipping to change at line 487 | skipping to change at line 495 | |||
io->buf[io->len] = '\0'; | io->buf[io->len] = '\0'; | |||
} | } | |||
/* | /* | |||
* Close down on bad, zero and final reads (we don't get | * Close down on bad, zero and final reads (we don't get | |||
* EAGAIN, so all errors are really unfixable) | * EAGAIN, so all errors are really unfixable) | |||
*/ | */ | |||
if (rd <= 0 || final) { | if (rd <= 0 || final) { | |||
iobroker_close(iobs, io->fd); | iobroker_close(iobs, io->fd); | |||
io->fd = -1; | io->fd = -1; | |||
if (!final) | ||||
check_completion(cp, WNOHANG); | ||||
break; | break; | |||
} | } | |||
break; | break; | |||
} | } | |||
return rd; | ||||
} | } | |||
static int stderr_handler(int fd, int events, void *cp_) | static int stderr_handler(int fd, int events, void *cp_) | |||
{ | { | |||
child_process *cp = (child_process *)cp_; | child_process *cp = (child_process *)cp_; | |||
gather_output(cp, &cp->outerr, 0); | gather_output(cp, &cp->outerr, 0); | |||
return 0; | return 0; | |||
} | } | |||
static int stdout_handler(int fd, int events, void *cp_) | static int stdout_handler(int fd, int events, void *cp_) | |||
End of changes. 9 change blocks. | ||||
8 lines changed or deleted | 16 lines changed or added |