Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [[ -x ]] and root

On Jul 16, 10:57am, Colin Holmes wrote:
> Subject: Re: [[ -x ]] and root
> Hi again,
>  I started this thread looking for a way to do a [[ -x file]] while
> running as root.  I got responses from this list (Zefram, mostly) to
> the effect that access() was improperly functioning under Irix 5.3, as
> it was under Linux.  I posted to comp.sys.sgi.bug to find out what they
> thought and here are the more useful results....
> Response 1:
> The access(2) system call is intended for use by setuid
> executables, trying to determine if the real id of the process,
> as opposed to the effective, could access a particular file.
> Implementations of test -x should stat and look at mode bits.
> Response 2:
> It's not a problem, it's the way it's designed and supposed
> to work.

Response 1 is correct as far as it goes, but if response 2 is claiming
that access(X_OK) is ever intended to return 0 for a file that has NONE
of the execute bits set, then I'd like to see more of his explanation.
It almost sounds like they didn't understand the question.

It is definitely the case that access() can return misleading results
if geteuid() != getuid() or (on some systems, including IRIX) if
getegid() != getgid().  However, the results ought to be correct for
at least one of the IDs.

Using stat() and examining mode bits is possible, but on systems that
support supplementary groups you have to get the group ID of the file
and the list of supplemental groups of the process, and then walk the
list to see if the file's group is present.  It's messy to #ifdef for
complete portability, too.

As a workaround in your zsh scripts, glob qualifiers [which do use
stat()] can eliminate files that do not have an execute bit set.

	executable() {
	    setopt localoptions nullglob
	    local x ret=1 files=(${^*}(xEX))
	    for x in $files
	    do [[ -x $x ]] && echo $x && ret=0
	    return $ret

As a quick hack, you can probably replace [[ -x foo ]] in your scripts
with [[ -x $(setopt nobadpattern; echo foo(xEX)) ]].  It's unlikely
that a file with "(xEX)" in its name is going to be encountered.

Messages sorted by: Reverse Date, Date, Thread, Author