From c2aaf8fbfbe1f979fc349d52211a0cebb0062f91 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 21 Feb 2010 10:24:27 -0500 Subject: [PATCH] Make sudo_debug do a single vfprintf() which will result in a single write call on most systems. Avoids problems with interleaved debug printf from different processes. Also remove an extraneous error case since recv() can't return a short read and add some more XXX. --- src/sudo.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sudo.c b/src/sudo.c index 2dfa5d275..67d639c04 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -796,7 +796,9 @@ run_command(struct command_details *details, char *argv[], char *envp[]) zero_bytes(fdsr, howmany(sv[0] + 1, NFDBITS) * sizeof(fd_mask)); FD_SET(sv[0], fdsr); for (;;) { + /* XXX - we may get SIGCILD before the wait status from the child */ if (sigchld) { + /* Note: this is the child, not the command we are waiting on */ sigchld = 0; do { pid = waitpid(child, &cstat.val, WNOHANG); @@ -818,11 +820,12 @@ run_command(struct command_details *details, char *argv[], char *envp[]) /* read child status */ nread = recv(sv[0], &cstat, sizeof(cstat), 0); if (nread == -1) { + /* XXX - could be interrupted by SIGCHLD */ if (errno == EINTR) continue; - } else if (nread != sizeof(cstat)) { - warningx("error reading command status"); + /* XXX - init cstat for failure case */ } + sudo_debug(9, "cmdtype %d, val %d", cstat.type, cstat.val); break; /* XXX */ } } @@ -862,14 +865,15 @@ void sudo_debug(int level, const char *fmt, ...) { va_list ap; + char *fmt2; if (level > debug_level) return; - fputs(getprogname(), stderr); - fputs(": ", stderr); + /* Backet fmt with program name and a newline to make it a single write */ + easprintf(&fmt2, "%s: %s\n", getprogname(), fmt); va_start(ap, fmt); - vfprintf(stderr, fmt, ap); + vfprintf(stderr, fmt2, ap); va_end(ap); - putc('\n', stderr); + efree(fmt2); } -- 2.50.1