These are kinda weird corner cases that I found while checking on other
things.
First, not a bug but a cleanup: when support for TAPE=- was added we ended
up with duplicate code recognizing '-' as meaning stdin/stdout. By
delaying the handling of that to after the "no -f option? use $TAPE, else
_PATH_DEFTAPE" code, the duplication can be eliminated. That also
eliminates the need for the fstdin variable as the -f option can no longer
leave arcname == NULL.
Next: tar writes "list-like" output to stdout unless it's writing an
archive there...except the 'append' case (-r) was missed. Sure enough,
tar rvf - 1<>whatever.tar filenames...
corrupts whatever.tar instead of writing the list of appended filenames to
stderr. Insane corner case, but it's easy to fix the test to catch the
correct cases.
Finally, cpio's -t option is treated as a mode flag when it's really a
modifier on -i. This is a problem because it means
cpio -i -t -v -F archive
lists the archive verbosely while
cpio -t -i -F archive
*extracts* it...and writes the extraction list to stdout instead of
stderr! The last few chunks of this diff treat -t as a flag to apply once
we know -i is in effect. Possible downside: -t without -i becomes an
error...though that matches the usage and manpage...
ok?
(For clarity, I should probably make these three separate commits)
Philip
Index: options.c
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/options.c,v
retrieving revision 1.95
diff -u -p -r1.95 options.c
--- options.c 23 Aug 2016 06:00:28 -0000 1.95
+++ options.c 24 Aug 2016 04:16:53 -0000
@@ -641,7 +641,6 @@ static void
tar_options(int argc, char **argv)
{
int c;
- int fstdin = 0;
int Oflag = 0;
int nincfiles = 0;
int incfiles_max = 0;
@@ -688,15 +687,6 @@ tar_options(int argc, char **argv)
/*
* filename where the archive is stored
*/
- if ((optarg[0] == '-') && (optarg[1]== '\0')) {
- /*
- * treat a - as stdin
- */
- fstdin = 1;
- arcname = NULL;
- break;
- }
- fstdin = 0;
arcname = optarg;
break;
case 'h':
@@ -872,20 +862,19 @@ tar_options(int argc, char **argv)
argc -= optind;
argv += optind;
- if (!fstdin && ((arcname == NULL) || (*arcname == '\0'))) {
+ if ((arcname == NULL) || (*arcname == '\0')) {
arcname = getenv("TAPE");
if ((arcname == NULL) || (*arcname == '\0'))
arcname = _PATH_DEFTAPE;
- else if ((arcname[0] == '-') && (arcname[1]== '\0')) {
- arcname = NULL;
- fstdin = 1;
- }
}
+ if ((arcname[0] == '-') && (arcname[1]== '\0'))
+ arcname = NULL;
- /* Traditional tar behaviour (pax uses stderr unless in list mode) */
- if (fstdin == 1 && act == ARCHIVE)
- listf = stderr;
- else
+ /*
+ * Traditional tar behaviour: list-like output goes to stdout unless
+ * writing the archive there. (pax uses stderr unless in list mode)
+ */
+ if (act == LIST || act == EXTRACT || arcname != NULL)
listf = stdout;
/* Traditional tar behaviour (pax wants to read file list from stdin) */
@@ -1090,7 +1079,7 @@ static void
cpio_options(int argc, char **argv)
{
const char *errstr;
- int c;
+ int c, list_only = 0;
unsigned i;
char *str;
FILE *fp;
@@ -1188,8 +1177,7 @@ cpio_options(int argc, char **argv)
/*
* list contents of archive
*/
- act = LIST;
- listf = stdout;
+ list_only = 1;
break;
case 'u':
/*
@@ -1322,8 +1310,16 @@ cpio_options(int argc, char **argv)
* process the args as they are interpreted by the operation mode
*/
switch (act) {
- case LIST:
case EXTRACT:
+ if (list_only) {
+ act = LIST;
+
+ /*
+ * cpio is like pax: list to stderr
+ * unless in list mode
+ */
+ listf = stdout;
+ }
while (*argv != NULL)
if (pat_add(*argv++, NULL) < 0)
cpio_usage();