Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: posix_spawn issue?



    Date:        Sat, 1 May 2021 23:40:14 +0200
    From:        Joerg Sonnenberger <joerg%bec.de@localhost>
    Message-ID:  <YI3KvsyYV/ilD6Xt%bec.de@localhost>

  | The obvious differences I see:
  | - SHELL is ignored by gmake in the posix_spawn path

Doesn't matter, the alternative (execvp path) also ignores it (and
in any case, this only matters for running shell scripts without a #!,
and those are rare indeed).

The two differences I see, is that the posix_spawn path does its own
search of path looking for something to exec, and (aside from its
absurd EINTR loop - from where did they get the notion that *all* system
calls can be interrupted by EINTR - never mind) only ever tries posix_spawn()
once on the path it finds.   I cannot find the find_in_given_path() function
to see how it works (it appears as if it should be in something called
"findprog.h" but I don't see that in src directory) but typically it will
simply run access() or stat() on path[n]/cmd and when it finds something with
'x' permission, stop.

On the other hand execvp() tries an execve() on every path[n]/cmd it finds,
stopping when it works (obviously - the process doing it is gone) or when
it gets ENOEXEC (in which case it tries the SHELL trick).

That's different if there's an entry earlier on PATH with 'x' permission,
but which is not executable for some reason other than ENOEXEC.

However, that difference being actually significant is rare to encounter,
the ksh series of shells (and bash) do their PATH searches that way, where
everyone else does it the execvp() way (the original Bourne Shell way), and
it is rare for anyone to ever even notice that the search algorithms are
quite different.

Second, the way that path is obtained is different in the two cases.

The posix_spawn() path uses PATH from the environment being passed to
the child, execvp() uses PATH from the environment of the current process
(which even though this happens after a fork() (or vfork(), makes no
difference) is still the parent's environment, not that being passed down).

Further, when PATH isn't found in whichever of those places is being
used, the posix_spawn() path uses something called _CS_PATH (which I also
cannot locate) and execvp() uses _PATH_DEFPATH (from <paths.h>).  The latter
includes /usr/pkg/bin (and /usr/local/bin), does the former?   If it is
unchanged from what comes from the git sources, probably not, and if there's
any likely difference that is going to matter, this would be my guess.

The 127 mentioned is the standard exit code for command not found, so
something going wrong with the path search is almost certainly the issue here.

kre




Home | Main Index | Thread Index | Old Index