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; } /*