When in list mode, the filenames in the archive are written to stdout.  
For pax, POSIX says that *only* the file listing output may be written 
there; all diagnostic output must go to stderr.  So don't use listf or 
listfd to write non-file-listing output.

There's a tricky bit that I'm not sure if I've made the correct choice on.  
Per POSIX, we write the filename when we read the header record for a file 
and only print the newline after it when we finish reading it.  So the 
code tracks whether a newline is needed in the 'vfpart' variable.  If we 
take a signal and that's set then we would print a newline to keep the 
output clear.  If the file listing and diagnostic output are now going to 
different fds (stdout vs stderr), should it still print that newline?  In 
this diff I say "no", and only print the newline if the file listing is 
going to stderr (as when doing "pax -rv" or "tar cvf -").

Opinions?

oks?


Philip Guenther

Index: ar_io.c
===================================================================
RCS file: /cvs/src/bin/pax/ar_io.c,v
retrieving revision 1.58
diff -u -p -r1.58 ar_io.c
--- ar_io.c     23 Aug 2016 06:00:28 -0000      1.58
+++ ar_io.c     25 Aug 2016 02:27:33 -0000
@@ -312,9 +312,9 @@ ar_close(int in_sig)
         * broken).
         */
        if (vflag && (artyp == ISTAPE)) {
-               (void)dprintf(listfd,
-                   "%s%s: Waiting for tape drive close to complete...",
-                   vfpart ? "\n" : "", argv0);
+               (void)dprintf(STDERR_FILENO,
+                   "%s: Waiting for tape drive close to complete...",
+                   (vfpart && listfd == STDERR_FILENO) ? "\n" : "", argv0);
        }
 
        /*
@@ -347,8 +347,9 @@ ar_close(int in_sig)
 
 
        if (vflag && (artyp == ISTAPE)) {
-               (void)write(listfd, "done.\n", sizeof("done.\n")-1);
-               vfpart = 0;
+               (void)write(STDERR_FILENO, "done.\n", sizeof("done.\n")-1);
+               if (listfd == STDERR_FILENO)
+                       vfpart = 0;
        }
        arfd = -1;
 
@@ -384,19 +385,19 @@ ar_close(int in_sig)
         * could have written anything yet.
         */
        if (frmt == NULL) {
-               (void)dprintf(listfd,
+               (void)dprintf(STDERR_FILENO,
                    "%s: unknown format, %llu bytes skipped.\n", argv0, rdcnt);
                flcnt = 0;
                return;
        }
 
        if (op_mode == OP_PAX)
-               (void)dprintf(listfd, "%s: %s vol %d, %lu files,"
+               (void)dprintf(STDERR_FILENO, "%s: %s vol %d, %lu files,"
                    " %llu bytes read, %llu bytes written.\n",
                    argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
 #ifndef NOCPIO
        else if (op_mode == OP_CPIO)
-               (void)dprintf(listfd, "%llu blocks\n",
+               (void)dprintf(STDERR_FILENO, "%llu blocks\n",
                    (rdcnt ? rdcnt : wrcnt) / 5120);
 #endif /* !NOCPIO */
        flcnt = 0;
Index: ar_subs.c
===================================================================
RCS file: /cvs/src/bin/pax/ar_subs.c,v
retrieving revision 1.46
diff -u -p -r1.46 ar_subs.c
--- ar_subs.c   25 Aug 2016 01:44:55 -0000      1.46
+++ ar_subs.c   25 Aug 2016 02:27:33 -0000
@@ -635,9 +635,10 @@ append(void)
         * reading the archive may take a long time. If verbose tell the user
         */
        if (vflag) {
-               (void)fprintf(listf,
+               (void)fprintf(stderr,
                        "%s: Reading archive to position at the end...", argv0);
-               vfpart = 1;
+               if (listf == stderr)
+                       vfpart = 1;
        }
 
        /*
@@ -696,9 +697,10 @@ append(void)
        /*
         * tell the user we are done reading.
         */
-       if (vflag && vfpart) {
-               (void)fputs("done.\n", listf);
-               vfpart = 0;
+       if (vflag) {
+               (void)fputs("done.\n", stderr);
+               if (listf == stderr)
+                       vfpart = 0;
        }
 
        /*

Reply via email to