aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2020-08-19 14:45:31 -0700
committerRob Landley <rob@landley.net>2020-08-21 05:17:13 -0500
commitfa1af3b085ccbf9aacf423e12f69e04a41dcd1a7 (patch)
tree42223a073ca263e44890d934c1553cbd849d577e
parentc88d3b8bfa339a00a42187529a87085ca68b5a1f (diff)
downloadtoybox-fa1af3b085ccbf9aacf423e12f69e04a41dcd1a7.tar.gz
cpio: fixes for Android kernel build.
Allow -pd to work by changing -p from an option that takes an argument to an option that implies there will be an argument (that is, `-pd x` is `-p -d x` with x being the directory for -p, rather than `-p d x` with d being the directory, as we previously interpreted it). Fix -d (aka --make-directories) to not be a no-op. Previously we acted as if this was always on. Accept --quiet and effectively just ignore it, since toybox cpio doesn't seem to produce any output that --quiet would suppress.
-rwxr-xr-xtests/cpio.test6
-rw-r--r--toys/posix/cpio.c19
2 files changed, 19 insertions, 6 deletions
diff --git a/tests/cpio.test b/tests/cpio.test
index 7231ba0f..11b3a5bf 100755
--- a/tests/cpio.test
+++ b/tests/cpio.test
@@ -29,6 +29,12 @@ testing "archive length" "cpio -o -H newc|dd ibs=2 skip=291 count=5 2>/dev/null"
testing "archive magic" "cpio -o -H newc|dd ibs=2 count=3 2>/dev/null" "070701" "" "a\n"
# check name length (8 bytes before the empty "crc")
testing "name length" "cpio -o -H newc|dd ibs=2 skip=47 count=4 2>/dev/null" "00000002" "" "a\n"
+testing "-t" "cpio -o -H newc|cpio -it" "a\nbb\n" "" "a\nbb"
+testing "-t --quiet" "cpio -o -H newc|cpio -it --quiet" "a\nbb\n" "" "a\nbb"
+mkdir out
+testing "-p" "cpio -p out && find out | sort" "out\nout/a\nout/bb\n" "" "a\nbb"
+rm -rf out
+testing "-pd" "cpio -pd out && find out | sort" "out\nout/a\nout/bb\n" "" "a\nbb"
rm a bb ccc dddd
# archive dangling symlinks and empty files even if we cannot open them
diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c
index 64725c13..69accbe3 100644
--- a/toys/posix/cpio.c
+++ b/toys/posix/cpio.c
@@ -16,7 +16,7 @@
* rdevmajor rdevminor namesize check
* This is the equiavlent of mode -H newc when using GNU CPIO.
-USE_CPIO(NEWTOY(cpio, "(no-preserve-owner)mduH:p:|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
config CPIO
bool "cpio"
@@ -32,6 +32,7 @@ config CPIO
-i Extract from archive into file system (stdin=archive)
-o Create archive (stdin=list of files, stdout=archive)
-t Test files (list only, stdin=archive, stdout=list of files)
+ -d Create directories if needed
-v Verbose
--no-preserve-owner (don't set ownership during extract)
*/
@@ -40,7 +41,7 @@ config CPIO
#include "toys.h"
GLOBALS(
- char *F, *p, *H;
+ char *F, *H;
)
// Read strings, tail padded to 4 byte alignment. Argument "align" is amount
@@ -84,7 +85,12 @@ void cpio_main(void)
// In passthrough mode, parent stays in original dir and generates archive
// to pipe, child does chdir to new dir and reads archive from stdin (pipe).
- if (TT.p) {
+ if (FLAG(p)) {
+ if (FLAG(d)) {
+ if (!*toys.optargs) error_exit("need directory for -p");
+ if (mkdir(*toys.optargs, 0700) == -1 && errno != EEXIST)
+ perror_exit("mkdir %s", *toys.optargs);
+ }
if (toys.stacktop) {
// xpopen() doesn't return from child due to vfork(), instead restarts
// with !toys.stacktop
@@ -93,7 +99,7 @@ void cpio_main(void)
} else {
// child
toys.optflags |= FLAG_i;
- xchdir(TT.p);
+ xchdir(*toys.optargs);
}
}
@@ -129,9 +135,10 @@ void cpio_main(void)
gid = x8u(toybuf+30);
timestamp = x8u(toybuf+46); // unsigned 32 bit, so year 2100 problem
+ // (This output is unaffected by --quiet.)
if (FLAG(t) || FLAG(v)) puts(name);
- if (!test && strrchr(name, '/') && mkpath(name)) {
+ if (!test && FLAG(d) && strrchr(name, '/') && mkpath(name)) {
perror_msg("mkpath '%s'", name);
test++;
}
@@ -279,5 +286,5 @@ void cpio_main(void)
}
if (TT.F) xclose(afd);
- if (TT.p) toys.exitval |= xpclose(pid, pipe);
+ if (FLAG(p) && pid) toys.exitval |= xpclose(pid, pipe);
}