On 20 November 2012 16:08, Glenn Fowler <[email protected]> wrote: > > On Tue, 20 Nov 2012 14:09:19 +0100 Irek Szczesniak wrote: >> On Tue, Nov 20, 2012 at 10:37 AM, Cedric Blancher >> <[email protected]> wrote: >> > On 1 October 2012 19:11, Glenn Fowler <[email protected]> wrote: >> >> >> >> On Mon, 01 Oct 2012 13:49:28 +0200 Michal Hlavinka wrote: >> >>> > #if _lib_posix_spawn < 2 >> >>> > if (waitpid(pid, &err, WNOHANG|WNOWAIT) == pid && EXIT_STATUS(err) >> >>> > == 127) >> >>> > { >> >>> > while (waitpid(pid, NiL, 0) == -1 && errno == EINTR); >> >>> > if (!access(path, X_OK)) >> >>> > errno = ENOEXEC; >> >>> > pid = -1; >> >>> > } >> >>> > #endif >> >> >> >>> It will fail with EINVAL, because of WNOWAIT. This option is not >> >>> supported in waitpid. It's supported only in waitid(). >> >> >> >>> so you'd have to use something like >> >> >> >>> pid_t pid; >> >>> siginfo_t err; >> >>> if (!waitid(P_PID, pid, &err, WEXITED|WNOHANG|WNOWAIT) && err.si_status >> >>> == 127) >> >> >> >> thanks for pointing out the WNOWAIT misuse >> >> >> >> alas even with the correct waitid() usage it does not solve the problem >> >> with all posix-spawn() implementations that use exit code 127 as a catch >> >> all for >> >> posix_spawn() related problems in the child process >> >> >> >> in the particular case of how shell implementations *portably* determine >> >> "binary executable" vs "shell script" (exec fails with ENOEXEC) >> >> such posix_spawn() implementations are useless >> >> >> >> e.g. a shell calling posix_spawn() must be able to differentiate >> >> EAGAIN retry in case some resources become free >> >> E2BIG diagnostic or apply xargs algorithm if appropriate >> >> ENOEXEC either a shell script or a diagnostic >> >> and you can't get that from exit status 127 >> > >> > So GNU/Linux glibc posix_spawn() is still violating the standard here? > >> No, it still does not pass the posix_spawn() parts of the POSIX >> VSX-PCTS2003 test suite, for exactly the reasons Glenn listed in his >> previous email. > > spawn iffe tests have been moved to src/lib/libast/features/spawn to make > monitoring this a bit easier (results in arch/*/src/lib/libast/FEATURE/spawn) > and the tests have been annotated to list the exact reason for rejecting > posix_spawn() > > src/lib/libast/misc/spawnvex.c was relaxed to use posix_spawn() in some cases > where _lib_posix_spawn=1 (posix_spawn() works but exits 127 on ENOEXEC) > sh implementations would use the spawnvex() SPAWN_EXEC flag to disable that > so they differentiate ENOEXEC from other exec errors -- this means that > ksh will only use posix_spawn() implementations that iffe _lib_posix_spawn=2 > > I'll restate why posix_spawn() exit code 127 on ENOEXEC is usesless for sh: > (1) there is no way for the parent to know how long to wait for the > child process exit code check -- how can the shell implement &? > * it can't block all other operations waiting for a bad exit status > * it can't really proceed with other children -- if 127 comes in later, > its too late to retry as a shell script > (2) exit code 127 is in band -- a user process can exit with that code > how can the parent differentiate that?
I don't see how this is useful, too. But I do not understand why Solaris and the other Unix implementations have a posix_spawn() implementation which apparently works with ksh93u+. Why can't the glibc developers just clone this behaviour (which appears to be mandated by POSIX and the POSIX VSX-PCTS2003 test suite) and not insist on their world view of posix_spawn() which is so far away from sanity and doesn't allow the implementation of real world consumers. > > to make the exit 127 implementations useful would require a portable > posix_is_executable(path) that would do the exec mode/perm checks along > with the object magic number checks -- a shell implementation would then > call this before posix_spawn() -- but then how much would this cut into > the savings of posix_spawn() over [v]fork()/exec() > posix_spawn() saves a lot of work in the kernel when it is implemented as a syscall - it saves all the overhead of a full vfork() and exec() will require to first create a whole child process with the parents attributes and then change most of the attributes later. posix_spawn() creates a whole new child process with the *selected* attributes and that's all. That's a lot less parent-child communication and traffic. Ced -- Cedric Blancher <[email protected]> Institute Pasteur _______________________________________________ ast-developers mailing list [email protected] http://lists.research.att.com/mailman/listinfo/ast-developers
