Merge changes I8bf8a347,Ifd81d7f8,I5f6555d8,Ia7fdbaae,I05e5b66a, ...
* changes:
Merge remote-tracking branch 'toybox/master' into HEAD
Bash Compatibility Patch
modinfo: various small fixes.
split.test: don't rely on bash process substitution.
file, stat: various small improvements.
touch.test: add missing `TZ=utc`s.
diff --git a/generated/globals.h b/generated/globals.h
index ddec5f6..9f54f13 100644
--- a/generated/globals.h
+++ b/generated/globals.h
@@ -344,6 +344,7 @@
char *F, *k, *b;
long mod;
+ int count;
};
// toys/other/nsenter.c
diff --git a/generated/help.h b/generated/help.h
index 9ad97af..7466a97 100644
--- a/generated/help.h
+++ b/generated/help.h
@@ -212,7 +212,7 @@
#define HELP_mountpoint "usage: mountpoint [-qd] DIR\n mountpoint [-qx] DEVICE\n\nCheck whether the directory or device is a mountpoint.\n\n-q Be quiet, return zero if directory is a mountpoint\n-d Print major/minor device number of the directory\n-x Print major/minor device number of the block device"
-#define HELP_modinfo "usage: modinfo [-0] [-b basedir] [-k kernrelease] [-F field] [modulename...]\n\nDisplay module fields for all specified modules, looking in\n<basedir>/lib/modules/<kernrelease>/ (kernrelease defaults to uname -r)."
+#define HELP_modinfo "usage: modinfo [-0] [-b basedir] [-k kernel] [-F field] [module|file...]\n\nDisplay module fields for modules specified by name or .ko path.\n\n-F Only show the given field\n-0 Separate fields with NUL rather than newline\n-b Use <basedir> as root for /lib/modules/\n-k Look in given directory under /lib/modules/"
#define HELP_mkswap "usage: mkswap [-L LABEL] DEVICE\n\nSet up a Linux swap area on a device or file."
diff --git a/scripts/make.sh b/scripts/make.sh
index 6649999..2a78844 100755
--- a/scripts/make.sh
+++ b/scripts/make.sh
@@ -152,7 +152,7 @@
$KCONFIG_CONFIG > generated/config.h || exit 1
fi
-if [ generated/mkflags -ot scripts/mkflags.c ]
+if [ ! -f generated/mkflags ] || [ generated/mkflags -ot scripts/mkflags.c ]
then
do_loudly $HOSTCC scripts/mkflags.c -o generated/mkflags || exit 1
fi
@@ -236,7 +236,7 @@
) > generated/globals.h
fi
-if [ generated/mktags -ot scripts/mktags.c ]
+if [ ! -f generated/mktags ] || [ generated/mktags -ot scripts/mktags.c ]
then
do_loudly $HOSTCC scripts/mktags.c -o generated/mktags || exit 1
fi
@@ -249,7 +249,7 @@
toys/*/*.c lib/*.c | generated/mktags > generated/tags.h
fi
-if [ generated/config2help -ot scripts/config2help.c ]
+if [ ! -f generated/config2help ] || [ generated/config2help -ot scripts/config2help.c ]
then
do_loudly $HOSTCC scripts/config2help.c -o generated/config2help || exit 1
fi
diff --git a/scripts/portability.sh b/scripts/portability.sh
index abeb31f..618022c 100644
--- a/scripts/portability.sh
+++ b/scripts/portability.sh
@@ -10,5 +10,5 @@
if [ -z "$SED" ]
then
- [ ! -z "$(which gsed 2>/dev/null)" ] && SED=gsed || SED=sed
+ [ ! -z "$(command -v gsed 2>/dev/null)" ] && SED=gsed || SED=sed
fi
diff --git a/tests/file.test b/tests/file.test
index fa8ea45..57204e6 100755
--- a/tests/file.test
+++ b/tests/file.test
@@ -11,6 +11,9 @@
echo "Hello, world!" > ascii
echo "6465780a3033350038ca8f6ce910f94e" | xxd -r -p > android.dex
ln -s $FILES/java.class symlink
+LINK=$(readlink symlink)
+ln -s $FILES/java.klass dangler
+BROKEN=$(readlink dangler)
testing "directory" "file ." ".: directory\n" "" ""
testing "empty" "file empty" "empty: empty\n" "" ""
@@ -43,14 +46,15 @@
"file $FILES/elf/ndk-elf-note-short | sed 's/^.*: //'" \
"ELF shared object, 32-bit LSB arm, dynamic (/system/bin/linker), for Android 28, BuildID=da6a5f4ca8da163b9339326e626d8a3c, stripped\n" "" ""
-testing "symlink" "file symlink" "symlink: symbolic link\n" "" ""
-testing "symlink -h" "file -h symlink" "symlink: symbolic link\n" "" ""
+testing "broken symlink" "file dangler" "dangler: broken symbolic link to $BROKEN\n" "" ""
+testing "symlink" "file symlink" "symlink: symbolic link to $LINK\n" "" ""
+testing "symlink -h" "file -h symlink" "symlink: symbolic link to $LINK\n" "" ""
testing "symlink -L" "file -L symlink" "symlink: Java class file, version 53.0 (Java 1.9)\n" "" ""
testing "- pipe" "cat $FILES/java.class | file -" "-: Java class file, version 53.0 (Java 1.9)\n" "" ""
testing "- redirect" "file - <$FILES/java.class" "-: Java class file, version 53.0 (Java 1.9)\n" "" ""
-testing "/dev/zero" "file /dev/zero" "/dev/zero: character special\n" "" ""
+testing "/dev/zero" "file /dev/zero" "/dev/zero: character special (1/5)\n" "" ""
testing "- </dev/zero" "file - </dev/zero" "-: data\n" "" ""
rm empty bash.script bash.script2 env.python.script ascii android.dex
diff --git a/tests/modinfo.test b/tests/modinfo.test
index 0a8c2be..f39dc6f 100644
--- a/tests/modinfo.test
+++ b/tests/modinfo.test
@@ -4,7 +4,23 @@
#testing "name" "command" "result" "infile" "stdin"
-[ -e /proc/modules ] || { echo "Skipping test because modules are not supported"; exit 1; }
+testcmd "missing" "missing 2>&1" "modinfo: missing: not found\n" "" ""
+
+[ -e /proc/modules ] || { echo "Skipping: no /proc/modules"; exit 1; }
+
+# Android keeps its modules on the vendor partition.
+MODULE_ROOT=""
+[ -d /vendor/lib/modules ] && MODULE_ROOT="/vendor"
+
+# Find some modules to work with.
+MODULE_PATH1=$(find $MODULE_ROOT/lib/modules -name *.ko | head -1 2>/dev/null)
+MODULE1=$(basename -s .ko $MODULE_PATH1)
+MODULE_PATH2=$(find $MODULE_ROOT/lib/modules -name *.ko | tail -1 2>/dev/null)
+MODULE2=$(basename -s .ko $MODULE_PATH2)
+DASH_MODULE=$(basename -s .ko \
+ $(find $MODULE_ROOT/lib/modules -name *-*.ko | tail -1 2>/dev/null))
+BAR_MODULE=$(basename -s .ko \
+ $(find $MODULE_ROOT/lib/modules -name *_*.ko | tail -1 2>/dev/null))
# modinfo does not need to output fields in a specified order.
# Instead, there are labelled fields. We can use sort to make up for this.
@@ -12,19 +28,19 @@
# which change from kernel to kernel and can be disabled.
# We grep to remove these.
-#We expect they have ne2k-pci as a module.
-
-testing "gets right number of fields" "modinfo ne2k-pci |cut -d: -f1 |grep -v ver|sort" "alias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nauthor\ndepends\ndescription\nfilename\nlicense\nparm\nparm\nparm\n" "" ""
-testing "treats - and _ as equivalent" "modinfo ne2k_pci |cut -d: -f1 |grep -v ver|sort" "alias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nalias\nauthor\ndepends\ndescription\nfilename\nlicense\nparm\nparm\nparm\n" "" ""
+skipnot [ -n "$DASH_MODULE" ]
+testing "treats - and _ as equivalent" "modinfo $DASH_MODULE > dash-dash &&
+ modinfo ${DASH_MODULE/-/_} > dash-bar && diff -u dash-dash dash-bar" "" "" ""
+skipnot [ -n "$BAR_MODULE" ]
+testing "treats _ and - as equivalent" "modinfo $BAR_MODULE > bar-bar &&
+ modinfo ${BAR_MODULE/_/-} > bar-dash && diff -u bar-bar bar-dash" "" "" ""
# Output of -F filename should be an absolute path to the module.
# Otherwise, initrd generating scripts will break.
-testing "-F filename gets absolute path" "[ -e `modinfo -F filename ne2k-pci` ] && echo ne2k-pci " "ne2k-pci\n" "" ""
+testing "-F filename gets absolute path" "modinfo -F filename $MODULE1" \
+ "$MODULE_PATH1\n" "" ""
-testing "supports multiple modules" "modinfo -F filename ne2k-pci 8390 | wc -l" "2\n" "" ""
-
-testing "does not output filename for bad module" "modinfo -F filename zxcvbnm__9753" "" "" ""
-
-
-
+skipnot [ "$MODULE1" != "$MODULE2" ]
+testing "supports multiple modules" "modinfo -F filename $MODULE1 $MODULE2" \
+ "$MODULE_PATH1\n$MODULE_PATH2\n" "" ""
diff --git a/tests/split.test b/tests/split.test
index 533cd4f..4a52243 100755
--- a/tests/split.test
+++ b/tests/split.test
@@ -25,7 +25,7 @@
"seq 1 20000 | split -b 100 -a 3 - whang && ls whang* | wc -l && wc -c whangbpw" "1089\n94 whangbpw\n" "" ""
testing "reassembly" \
- 'diff -u <(ls whang* | sort | xargs cat) <(seq 1 20000) && echo yes' \
+ 'ls whang* | sort | xargs cat > reassembled && seq 1 20000 | diff -u reassembled - && echo yes' \
"yes\n" "" ""
-rm file whang*
+rm file whang* reassembled
diff --git a/tests/touch.test b/tests/touch.test
index b010f7d..8be231b 100644
--- a/tests/touch.test
+++ b/tests/touch.test
@@ -64,10 +64,10 @@
"touch -t 2101231234 input && date +%Y-%m-%d:%H-%M-%S -r input" \
"$(date +%C)21-01-23:12-34-00\n" "" ""
-testing "-a" "touch -t 197101020304 walrus &&
- touch -t 197203040506 -a walrus && stat -c '%X %Y' walrus" \
- "68555160 31655040\n" "" ""
-testing "-m" "TZ=utc touch -t 197101020304 walrus &&
+testing "-a" "TZ=utc touch -t 197101020304 walrus &&
+ TZ=utc touch -t 197203040506 -a walrus && TZ=utc stat -c '%X %Y' walrus" \
+ "68533560 31633440\n" "" ""
+testing "-m" "TZ=utc touch -t 197101020304 walrus &&
TZ=utc touch -t 197203040506 -m walrus && TZ=utc stat -c '%X %Y' walrus" \
"31633440 68533560\n" "" ""
testing "-am" "TZ=utc touch -t 197101020304 walrus &&
diff --git a/toys/other/modinfo.c b/toys/other/modinfo.c
index eaf6cb9..286570f 100644
--- a/toys/other/modinfo.c
+++ b/toys/other/modinfo.c
@@ -10,10 +10,14 @@
bool "modinfo"
default y
help
- usage: modinfo [-0] [-b basedir] [-k kernrelease] [-F field] [modulename...]
+ usage: modinfo [-0] [-b basedir] [-k kernel] [-F field] [module|file...]
- Display module fields for all specified modules, looking in
- <basedir>/lib/modules/<kernrelease>/ (kernrelease defaults to uname -r).
+ Display module fields for modules specified by name or .ko path.
+
+ -F Only show the given field
+ -0 Separate fields with NUL rather than newline
+ -b Use <basedir> as root for /lib/modules/
+ -k Look in given directory under /lib/modules/
*/
#define FOR_modinfo
@@ -23,6 +27,7 @@
char *F, *k, *b;
long mod;
+ int count;
)
static void output_field(char *field, char *value)
@@ -30,7 +35,7 @@
if (!TT.F) xprintf("%s:%*c", field, 15-(int)strlen(field), ' ');
else if (strcmp(TT.F, field)) return;
xprintf("%s", value);
- xputc((toys.optflags & FLAG_0) ? 0 : '\n');
+ xputc(FLAG(0) ? 0 : '\n');
}
static void modinfo_file(char *full_name)
@@ -53,6 +58,7 @@
return;
}
+ TT.count++;
output_field("filename", full_name);
for (pos = buf; pos < buf+len; pos++) {
@@ -100,19 +106,30 @@
void modinfo_main(void)
{
- for(TT.mod = 0; TT.mod<toys.optc; TT.mod++) {
+ struct utsname uts;
+
+ // Android (as shipped by Google) currently only has modules on /vendor.
+ // Android does not support multiple sets of modules for different kernels.
+ if (CFG_TOYBOX_ON_ANDROID) {
+ if (!TT.b) TT.b = "/vendor";
+ if (!TT.k) TT.k = "";
+ } else {
+ uname(&uts);
+ if (!TT.b) TT.b = "";
+ if (!TT.k) TT.k = uts.release;
+ }
+
+ for (TT.mod = 0; TT.mod<toys.optc; TT.mod++) {
char *s = strstr(toys.optargs[TT.mod], ".ko");
if (s && !s[3]) modinfo_file(toys.optargs[TT.mod]);
else {
- struct utsname uts;
+ char *path = xmprintf("%s/lib/modules/%s", TT.b, TT.k);
- if (uname(&uts) < 0) perror_exit("bad uname");
- if (snprintf(toybuf, sizeof(toybuf), "%s/lib/modules/%s",
- (toys.optflags & FLAG_b) ? TT.b : "",
- (toys.optflags & FLAG_k) ? TT.k : uts.release) >= sizeof(toybuf))
- perror_exit("basedir/kernrelease too long");
- dirtree_read(toybuf, check_module);
+ TT.count = 0;
+ dirtree_read(path, check_module);
+ if (!TT.count) error_msg("%s: not found", toys.optargs[TT.mod]);
+ free(path);
}
}
}
diff --git a/toys/other/stat.c b/toys/other/stat.c
index c4c1bf4..66c5dc3 100644
--- a/toys/other/stat.c
+++ b/toys/other/stat.c
@@ -191,8 +191,8 @@
"Block Size: %s Fundamental block size: %S\n"
"Blocks: Total: %b\tFree: %f\tAvailable: %a\n"
"Inodes: Total: %c\tFree: %d"
- : " File: %N\n Size: %s\t Blocks: %b\t IO Blocks: %B\t%F\n"
- "Device: %Dh/%dd\t Inode: %i\t Links: %h\n"
+ : " File: %N\n Size: %s\t Blocks: %b\t IO Blocks: %B\t %F\n"
+ "Device: %Dh/%dd\t Inode: %i\t Links: %h\t Device type: %t,%T\n"
"Access: (0%a/%A)\tUid: (%5u/%8U)\tGid: (%5g/%8G)\n"
"Access: %x\nModify: %y\nChange: %z";
diff --git a/toys/posix/file.c b/toys/posix/file.c
index 6b8c677..2370be7 100644
--- a/toys/posix/file.c
+++ b/toys/posix/file.c
@@ -421,7 +421,7 @@
// Can't use loopfiles here because it doesn't call function when can't open
for (arg = toys.optargs; *arg; arg++) {
- char *name = *arg, *what = "cannot open";
+ char *name = *arg, *what = "unknown";
struct stat sb;
int fd = !strcmp(name, "-");
@@ -439,14 +439,20 @@
continue;
}
} else if (S_ISFIFO(sb.st_mode)) what = "fifo";
- else if (S_ISBLK(sb.st_mode)) what = "block special";
- else if (S_ISCHR(sb.st_mode)) what = "character special";
+ else if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
+ sprintf(what = toybuf, "%s special (%u/%u)",
+ S_ISBLK(sb.st_mode) ? "block" : "character",
+ dev_major(sb.st_rdev), dev_minor(sb.st_rdev));
else if (S_ISDIR(sb.st_mode)) what = "directory";
else if (S_ISSOCK(sb.st_mode)) what = "socket";
- else if (S_ISLNK(sb.st_mode)) what = "symbolic link";
- else what = "unknown";
- }
+ else if (S_ISLNK(sb.st_mode)) {
+ char *lnk = xreadlink(name);
- xputs(what);
+ sprintf(what = toybuf, "%ssymbolic link to %s",
+ stat(lnk, &sb) ? "broken " : "", lnk);
+ free(lnk);
+ }
+ xputs(what);
+ } else xprintf("cannot open: %s\n", strerror(errno));
}
}