]> granicus.if.org Git - sudo/commitdiff
Make sudo_debug do a single vfprintf() which will result in a single
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 21 Feb 2010 15:24:27 +0000 (10:24 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 21 Feb 2010 15:24:27 +0000 (10:24 -0500)
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

index 2dfa5d2752a34b3daee558ad6434c358097ed813..67d639c04636aa2ff21f10df437609a28ca8759d 100644 (file)
@@ -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);
 }