Whenever we expect our "bin/f" and "sh/f" files to execute (and to
succeed), provide "expr" and "sh" as argv[0], respectively. This is
to
work around BusyBox, where the central busybox binary selects its behavior
based on argv[0]. See e.g.
<
https://bugs.busybox.net/show_bug.cgi?id=15481>.
Also cope with "realpath" (from BusyBox) not accepting the "--"
end-of-options argument separator. See
<
https://bugs.busybox.net/show_bug.cgi?id=15466>.
This patch is worth viewing with "git show --color-words" as well.
Signed-off-by: Laszlo Ersek <lersek(a)redhat.com>
---
lib/test-fork-safe-execvpe.sh | 35 +++++++++++++-------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/lib/test-fork-safe-execvpe.sh b/lib/test-fork-safe-execvpe.sh
index f055f7b05814..0e2dd942c9b7 100755
--- a/lib/test-fork-safe-execvpe.sh
+++ b/lib/test-fork-safe-execvpe.sh
@@ -24,7 +24,11 @@ set -e
# utility is not in POSIX, but Linux, FreeBSD and OpenBSD all have it.
bname=$(basename -- "$0" .sh)
dname=$(dirname -- "$0")
-execvpe=$(realpath -- "$dname/$bname")
+if ! execvpe=$(realpath -- "$dname/$bname"); then
+ # Work around <
https://bugs.busybox.net/show_bug.cgi?id=15466>. For example,
+ # Alpine Linux in the libnbd CI uses BusyBox.
+ execvpe=$(realpath "$dname/$bname")
+fi
# This is an elaborate way to control the PATH variable around the $execvpe
# helper binary as narrowly as possible.
@@ -35,6 +39,13 @@ execvpe=$(realpath -- "$dname/$bname")
# $2 and onward are passed to $execvpe; $2 becomes "program-to-exec" for the
# helper and $3 becomes argv[0] for the program executed by the helper.
#
+# (Outside of the "run" function below, "run0" should only ever be
called for
+# working around BusyBox. (Alpine Linux in the libnbd CI uses BusyBox.)
+# BusyBox's utilities "expr", "sh" etc. are just symlinks to the
central
+# "busybox" binary executable, and that executable keys its behavior off the
+# name under which it is invoked -- that is, $3 here. See
+# <
https://bugs.busybox.net/show_bug.cgi?id=15481>.)
+#
# The command itself (including the PATH setting) is written to "cmd" (for
error
# reporting purposes only); the standard output and error are saved in "out"
and
# "err" respectively; the exit status is written to "status". This
function
@@ -218,7 +229,7 @@ run "" nxregf/f/; execve_fail nxregf/f/ ENOTDIR
run "" symlink/f; execve_fail symlink/f ELOOP
# This runs "expr 1 + 1".
-run "" bin/f 1 + 1; success bin/f,2
+run0 "" bin/f expr 1 + 1; success bin/f,2
# This triggers the ENOEXEC branch in nbd_internal_fork_safe_execvpe().
# nbd_internal_fork_safe_execvpe() will first try
@@ -231,7 +242,7 @@ run "" bin/f 1 + 1; success bin/f,2
#
# The shell script will get "sh/f" for $0 and "arg1" for $1, and
print those
# out.
-run "" sh/f arg1; success sh/f,"sh/f arg1"
+run0 "" sh/f sh arg1; success sh/f,"sh/f arg1"
# In the tests below, the "file" parameter of execvpe() will not contain a
# <slash> character.
@@ -267,21 +278,21 @@ execve_fail empty/f,fifo/f,subdir/f,nxregf/f,symlink/f ELOOP
# seen), and (b) that nbd_internal_fork_safe_execvpe() succeeds for the *last*
# candidate. Repeat the test with "expr" (called "f" under
"bin") and the shell
# script (called "f" under "sh", triggering the ENOEXEC branch).
-run bin f 1 + 1; success bin/f,2
-run sh f arg1; success sh/f,"sh/f arg1"
+run0 bin f expr 1 + 1; success bin/f,2
+run0 sh f sh arg1; success sh/f,"sh/f arg1"
# Demonstrate that the order of candidates matters. The first invocation finds
# "expr" (called "f" under "bin"), the second invocation
finds the shell script
# under "sh" (triggering the ENOEXEC branch).
-run empty:bin:sh f 1 + 1; success empty/f,bin/f,sh/f,2
-run empty:sh:bin f arg1; success empty/f,sh/f,bin/f,"sh/f arg1"
+run0 empty:bin:sh f expr 1 + 1; success empty/f,bin/f,sh/f,2
+run0 empty:sh:bin f sh arg1; success empty/f,sh/f,bin/f,"sh/f arg1"
# Check the expansion of zero-length prefixes in PATH to ".", plus the
# (non-)insertion of the "/" separator.
-run a/: f; execve_fail a/f,./f ENOENT
-run :a/ f; execve_fail ./f,a/f ENOENT
-run : f; execve_fail ./f,./f ENOENT
+run a/: f; execve_fail a/f,./f ENOENT
+run :a/ f; execve_fail ./f,a/f ENOENT
+run : f; execve_fail ./f,./f ENOENT
pushd bin
-run : f 1 + 1; success ./f,./f,2
+run0 : f expr 1 + 1; success ./f,./f,2
popd
-run :a/:::b/: f; execve_fail ./f,a/f,./f,./f,b/f,./f ENOENT
+run :a/:::b/: f; execve_fail ./f,a/f,./f,./f,b/f,./f ENOENT