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 --


Reply via email to