aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-06-27 13:27:01 -0700
committerRob Landley <rob@landley.net>2019-06-28 09:33:31 -0500
commit50f27779b68fb36cdc2ed4d929c8d97a0f69fe9f (patch)
tree93141d5c491ddb66cad84bd94a282c28ed01a865
parentccf574ecc4dd8af8fd045a9d6bbaf5e8bf66a8d2 (diff)
downloadtoybox-50f27779b68fb36cdc2ed4d929c8d97a0f69fe9f.tar.gz
file, stat: various small improvements.
file now shows the target of a symbolic link and calls out broken symbolic links. file now shows the device type for block/character special files. file now shows specific reason when it can't open. stat now includes the device type, plus a little more space between the number of blocks and the human-readable file type. Adjusted tests accordingly, which actually makes more of them pass on the host as a convenient side-effect, but I actually made these changes because I've been finding the desktop file and stat output more convenient in these cases.
-rwxr-xr-xtests/file.test10
-rw-r--r--toys/other/stat.c4
-rw-r--r--toys/posix/file.c20
3 files changed, 22 insertions, 12 deletions
diff --git a/tests/file.test b/tests/file.test
index fa8ea45b..57204e64 100755
--- a/tests/file.test
+++ b/tests/file.test
@@ -11,6 +11,9 @@ echo "#! /usr/bin/env python" > env.python.script
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 @@ toyonly testing "Android NDK short ELF note" \
"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/toys/other/stat.c b/toys/other/stat.c
index c4c1bf42..66c5dc3b 100644
--- a/toys/other/stat.c
+++ b/toys/other/stat.c
@@ -191,8 +191,8 @@ void stat_main(void)
"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 6b8c6779..2370be79 100644
--- a/toys/posix/file.c
+++ b/toys/posix/file.c
@@ -421,7 +421,7 @@ void file_main(void)
// 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 @@ void file_main(void)
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));
}
}