Andrew Ilijic noticed that our ls exit status differs from coreutils
while writing tests. From coreutils' `ls --help`:

 0  if OK,
 1  if minor problems (e.g., cannot access subdirectory),
 2  if serious trouble (e.g., cannot access command-line argument).

Invalid/unknown command-line arguments count as 2.
---
 tests/ls.test   | 13 +++++++++++--
 toys/posix/ls.c |  8 +++++---
 2 files changed, 16 insertions(+), 5 deletions(-)
From 5922b989022095ec8db90a843bc0947dd46e68a1 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <[email protected]>
Date: Thu, 31 Oct 2019 09:43:09 -0700
Subject: [PATCH] ls.c: match coreutils exit status.

Andrew Ilijic noticed that our ls exit status differs from coreutils
while writing tests. From coreutils' `ls --help`:

 0  if OK,
 1  if minor problems (e.g., cannot access subdirectory),
 2  if serious trouble (e.g., cannot access command-line argument).

Invalid/unknown command-line arguments count as 2.
---
 tests/ls.test   | 13 +++++++++++--
 toys/posix/ls.c |  8 +++++---
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/tests/ls.test b/tests/ls.test
index ce88b04b..57cef207 100755
--- a/tests/ls.test
+++ b/tests/ls.test
@@ -55,8 +55,17 @@ rm -rf lstest/* && touch lstest/file1.txt && INODE=`stat -c %i lstest/file1.txt`
 testing "with -i" "$IN && ls -i 2>/dev/null; $OUT" "$INODE file1.txt\n" "" ""
 unset INODE
 
-testing "missing" "$IN && ls does-not-exist 2>err ; grep -q 'ls:.*missing.*: No
-such file' err || echo missing error; $OUT" "" "" ""
+testing "missing" "$IN && ls does-not-exist 2>err ; echo \$? ; grep -q 'ls:.*does-not-exist.*: No such file' err || echo missing error; $OUT" "2\n" "" ""
+
+testing "normal exit" "ls >/dev/null 2>&1; echo \$?" "0\n" "" ""
+testing "unknown arg" "ls --no-such-option 2>/dev/null ; echo \$?" "2\n" "" ""
+
+# If we're not root, we can also test the exit status on failure to stat...
+mkdir -m 0000 lstest/d3
+skipnot [ $(id -u) -ne 0 ]
+testing "inaccessible arg" "ls lstest/d3 >/dev/null 2>&1; echo \$?" "2\n" "" ""
+skipnot [ $(id -u) -ne 0 ]
+testing "inaccessible sub" "ls -R lstest >/dev/null 2>&1; echo \$?" "1\n" "" ""
 
 # Removing test dir for cleanup purpose
 rm -rf lstest
diff --git a/toys/posix/ls.c b/toys/posix/ls.c
index 809e2504..697bc12e 100644
--- a/toys/posix/ls.c
+++ b/toys/posix/ls.c
@@ -12,7 +12,7 @@
  *   Posix says the -l date format should vary based on how recent it is
  *   and we do --time-style=long-iso instead
 
-USE_LS(NEWTOY(ls, "(color):;(full-time)(show-control-chars)ZgoACFHLRSabcdfhikl@mnpqrstuw#=80<0x1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL][!qb]", TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_LS(NEWTOY(ls, "(color):;(full-time)(show-control-chars)ZgoACFHLRSabcdfhikl@mnpqrstuw#=80<0x1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL][!qb]", TOYFLAG_BIN|TOYFLAG_LOCALE|TOYFLAG_ARGFAIL(2)))
 
 config LS
   bool "ls"
@@ -321,7 +321,8 @@ static void listfiles(int dirfd, struct dirtree *indir)
     dt = indir->child;
     if (dt && S_ISDIR(dt->st.st_mode) && !dt->next && !(flags&(FLAG_d|FLAG_R)))
     {
-      listfiles(open(dt->name, 0), TT.singledir = dt);
+      if ((dirfd = open(dt->name, 0)) == -1) toys.exitval = 2;
+      listfiles(dirfd, TT.singledir = dt);
 
       return;
     }
@@ -592,10 +593,11 @@ void ls_main(void)
     // note: double_list->prev temporarily goes in dirtree->parent
     if (dt) {
       if (dt->again&2) {
+        toys.exitval = 2;
         perror_msg_raw(*s);
         free(dt);
       } else dlist_add_nomalloc((void *)&TT.files->child, (void *)dt);
-    } else toys.exitval = 1;
+    } else toys.exitval = 2;
   }
 
   // Convert double_list into dirtree.
-- 
2.24.0.rc1.363.gb1bccd3e3d-goog

_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to