On Mon, 30 Oct 2006 06:01:42 +0100 Roland Mainz wrote: > On Solaris 11/B48/i386 with ast-ksh.2006-10-26 the "iffe" test says: > -- snip -- > iffe: test: posix_spawn exists and it works and its worth using ... no > -- snip -- > IMO should should be "yes" on Solaris for "correctness" reasons...
I double checked the iffe posix_spawn tests uses by spawnveg() one of the pitfalls of iffe/autconfig is that *any* failure can be a valid test outcome, so if you don't keep on top of some tests as target systems evolve, some test outcomes may be due to failures not related to the test it turns out there were some syntax errors on solaris I fixed those, but posix_spawn() was still found unworthy the reason is that at least on solaris 10, posix_spawn() returns 0 (success) when the executable file is empty truss shows the underlying execve() getting ENOEXEC (which it should), but that errno fails to make its way back as the posix_spawn() return value note that linux posix_spawn() is not worthy for the same reason the ast spanwveg() implementation recognizes 2 vfork() implementations one where the parent and child share data (_real_vfork), and the other; for the latter it sets up a pipe for the child to communicate the execv() errno back to the parent -- I don't know if similar care needs to be taken on linux and solaris here is an annotated version of the iffe-generated test call it t.c, cc -o t.exe t.c, and it will generate t.exe.sh for the ENOEXEC test --- #define fork ______fork #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) #define _STD_ 1 #define _ARG_(x) x #define _VOID_ void #else #define _STD_ 0 #define _ARG_(x) () #define _VOID_ char #endif #if defined(__cplusplus) #define _BEGIN_EXTERNS_ extern "C" { #define _END_EXTERNS_ } #else #define _BEGIN_EXTERNS_ #define _END_EXTERNS_ #endif #define _NIL_(x) ((x)0) #include <stdio.h> #define _hdr_unistd 1 #define _hdr_stdlib 1 #define _hdr_spawn 1 #include <unistd.h> #include <stdlib.h> #include <spawn.h> #include <sys/types.h> #include <sys/stat.h> #include <spawn.h> #include <signal.h> #include <wait.h> #include <fcntl.h> #include <string.h> #undef fork /* if it uses fork() why bother? */ pid_t fork _ARG_((void)) { return -1; } pid_t _fork _ARG_((void)) { return -1; } pid_t __fork _ARG_((void)) { return -1; } int main(argc, argv) int argc; char** argv; { char* s; pid_t pid; posix_spawnattr_t attr; int n; int status; char* cmd[3]; char tmp[1024]; fprintf(stderr, "%d: %p\n", __LINE__, argv[1]); if (argv[1]) _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN); signal(SIGHUP, SIG_IGN); fprintf(stderr, "%d:\n", __LINE__); if (posix_spawnattr_init(&attr)) _exit(1); fprintf(stderr, "%d:\n", __LINE__); if (posix_spawnattr_setpgroup(&attr, 0)) _exit(1); /* first try an a.out and verify that SIGHUP is ignored */ cmd[0] = argv[0]; cmd[1] = "test"; cmd[2] = 0; fprintf(stderr, "%d:\n", __LINE__); if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0)) _exit(1); status = 1; fprintf(stderr, "%d:\n", __LINE__); if (wait(&status) < 0 || status != 0) _exit(1); /* passing ENOEXEC to the shell is bogus */ n = strlen(cmd[0]); if (n >= (sizeof(tmp) - 3)) _exit(1); strcpy(tmp, cmd[0]); tmp[n] = '.'; tmp[n+1] = 's'; tmp[n+2] = 'h'; tmp[n+3] = 0; fprintf(stderr, "%d:\n", __LINE__); if (close(open(tmp, O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO)) < 0 || chmod(tmp, S_IRWXU|S_IRWXG|S_IRWXO) < 0) _exit(1); cmd[0] = tmp; fprintf(stderr, "%d: %s\n", __LINE__, cmd[0]); if (!posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0)) { wait(&status); _exit(1); } fprintf(stderr, "%d:\n", __LINE__); _exit(0); } --- -- Glenn Fowler -- AT&T Research, Florham Park NJ --