commit:     44dfa57e789d4549166a5c8eea4748f92db8583d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 19:38:40 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=44dfa57e

Have whenceforce() require the -x option to check the execute bit

This renders the behaviour of whenceforth() almost equivalent to type -P
in the absence of the -x option, the exception being that whenceforth()
never consults the hash table.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 32 +++++++++++++++++++++++---------
 test-functions | 57 +++++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/functions.sh b/functions.sh
index 367c4a3..4f6c0a0 100644
--- a/functions.sh
+++ b/functions.sh
@@ -565,23 +565,37 @@ warn()
 }
 
 #
-# Considers the first parameter as the potential name of an executable regular
-# file before attempting to locate it. If not specified as an absolute 
pathname,
-# a PATH search shall be performed in accordance with the Environment Variables
-# section of the Base Definitions. If an executable is found, its path shall be
-# printed. Otherwise, the return value shall be 1. This function is intended as
-# an alternative to type -P in bash. That is, it is useful for determining the
+# Considers the first parameter as a command name before trying to locate it as
+# a regular file. If not specified as an absolute pathname, a PATH search shall
+# be performed in accordance with the Environment Variables section of the Base
+# Definitions. If a file is found, its path shall be printed. Otherwise, the
+# return value shall be 1. If the -x option is specified then the file must
+# also be executable by the present user in order to be matched. This function
+# serves as an alternative to type -P in bash. It is useful for determining the
 # existence and location of an external utility without potentially matching
 # against aliases, builtins and functions (as command -v can).
 #
 whenceforth()
 (
-       local bin path prefix
+       local bin executable opt path prefix
+
+       executable=
+       while getopts :x opt; do
+               case ${opt} in
+                       x)
+                               executable=1
+                               ;;
+                       '?')
+                               _warn_for_args whenceforth "-${OPTARG}"
+                               return 1
+               esac
+       done
+       shift "$(( OPTIND - 1 ))"
 
        case $1 in
                /*)
                        # Absolute command paths must be directly checked.
-                       [ -f "$1" ] && [ -x "$1" ] && bin=$1
+                       test -f "$1" && test ${executable:+-x} "$1" && bin=$1
                        ;;
                *)
                        # Relative command paths must be searched for in PATH.
@@ -603,7 +617,7 @@ whenceforth()
                                        *)
                                                bin=${prefix:-.}/$1
                                esac
-                               [ -f "${bin}" ] && [ -x "${bin}" ] && break
+                               test -f "${bin}" && test ${executable:+-x} 
"${bin}" && break
                        done
        esac \
        && printf '%s\n' "${bin}"

diff --git a/test-functions b/test-functions
index 736836b..68e73eb 100755
--- a/test-functions
+++ b/test-functions
@@ -508,24 +508,40 @@ test_hr() {
 }
 
 test_whenceforth() {
-       set -- \
-               ge  1  PATH                        N/A                       \
-               ge  1  PATH                        .                         \
-               ge  1  PATH                        rather-unlikely-to-exist  \
-               ge  1  PATH                        /var/empty                \
-               ge  1  PATH                        /var/empty/nofile         \
-               eq  0  PATH                        /bin/sh                   \
-               eq  0  PATH                        sh                        \
-               eq  0  ''                          newer/file                \
-               eq  0  .                           newer/file                \
-               eq  0  :/var/empty/x               newer/file                \
-               eq  0  /var/empty/x:               newer/file                \
-               eq  0  /var/empty/x::/var/empty/y  newer/file                \
-               ge  1  ''                          older/file                \
-               ge  1  .                           older/file                \
-               ge  1  :/var/empty/x               older/file                \
-               ge  1  /var/empty/x:               older/file                \
-               ge  1  /var/empty/x::/var/empty/y  older/file
+       set  --  \
+               ge  1  PATH                        N/A                N/A       
         \
+               ge  1  PATH                        .                  N/A       
         \
+               ge  1  PATH                        unlikely-to-exist  N/A       
         \
+               ge  1  PATH                        /var/empty         N/A       
         \
+               ge  1  PATH                        /var/empty/nofile  N/A       
         \
+               eq  0  PATH                        /bin/sh            N/A       
         \
+               eq  0  PATH                        sh                 N/A       
         \
+               ge  1  PATH                        -x                 .         
         \
+               ge  1  PATH                        -x                 
unlikely-to-exist  \
+               ge  1  PATH                        -x                 
/var/empty         \
+               ge  1  PATH                        -x                 
/var/empty/nofile  \
+               eq  0  PATH                        -x                 /bin/sh   
         \
+               eq  0  PATH                        -x                 sh        
         \
+               eq  0  ''                          -x                 
newer/file         \
+               eq  0  .                           -x                 
newer/file         \
+               eq  0  :/var/empty/x               -x                 
newer/file         \
+               eq  0  /var/empty/x:               -x                 
newer/file         \
+               eq  0  /var/empty/x::/var/empty/y  -x                 
newer/file         \
+               eq  0  ''                          -x                 
newer/file         \
+               eq  0  .                           -x                 
newer/file         \
+               eq  0  :/var/empty/x               -x                 
newer/file         \
+               eq  0  /var/empty/x:               -x                 
newer/file         \
+               eq  0  /var/empty/x::/var/empty/y  -x                 
newer/file         \
+               eq  0  ''                          older/file         N/A       
         \
+               eq  0  .                           older/file         N/A       
         \
+               eq  0  :/var/empty/x               older/file         N/A       
         \
+               eq  0  /var/empty/x:               older/file         N/A       
         \
+               eq  0  /var/empty/x::/var/empty/y  older/file         N/A       
         \
+               ge  1  ''                          -x                 
older/file         \
+               ge  1  .                           -x                 
older/file         \
+               ge  1  :/var/empty/x               -x                 
older/file         \
+               ge  1  /var/empty/x:               -x                 
older/file         \
+               ge  1  /var/empty/x::/var/empty/y  -x                 older/file
 
        chmod +x newer/file
 
@@ -533,15 +549,16 @@ test_whenceforth() {
                shift
                path=$1
                shift
-               test_description="whenceforth $(quote_args "$@")"
                if [ "${path}" = PATH ]; then
+                       test_description="whenceforth $(quote_args "$@")"
                        whenceforth "$@" >/dev/null
                else
+                       test_description="PATH=${path} whenceforth $(quote_args 
"$@")"
                        PATH=${path} whenceforth "$@" >/dev/null
                fi
        }
 
-       iterate_tests 4 "$@"
+       iterate_tests 5 "$@"
 }
 
 test_get_nprocs() {

Reply via email to