On Mon, Jul 23, 2012 at 2:24 PM, Glenn Fowler <g...@research.att.com> wrote:
>
> On Mon, 23 Jul 2012 12:24:10 +0200 Michal Hlavinka wrote:
>> On 07/23/2012 04:45 AM, Glenn Fowler wrote:
>> >
>> > I'm finally caught up with the ast-* posts from the last 3 weeks
>> > the posix_spawn thread inspired a new iffe C code test feature
>> > that allows the tests to annotate reasons for test failure
>> > (besides the test not compiling at all, which can be a valid test too)
>> >     NOTE("reason text");
>> > can be called (preferably once per failure) and "reason text" will appear
>> > in the iffe --verbose (-v) output on stderr
>> >
>> > the new version of iffe will be posted later on Monday
>> ...
>> ...
>> >
>> > here is the annotated posix_spawn test
>> > --
>> > linux fails with "ENOEXEC invokes sh"
>
>> It was fixed in glibc upstream:
>> http://sourceware.org/bugzilla/show_bug.cgi?id=13134
>> It works in all active Fedora releases. It'll work in rhel7. I'll check
>> what I can do about present rhel releases.
>
> thanks Michal
> I should have added that I also read the "fixed" part of the issue

Erm... it's still not working in ast-ksh.2012-09-11. The iffe probe
still prints an error:
-- snip --
iffe: test: posix_spawn exists and it works and its worth using ...
ENOEXEC produces exit status 127 (GOOD) ... yes
-- snip --
... the "GOOD" may be a bit misleading ("GOOD" means "working" ... but
the iffe probe must return "BEST" to reflect that the
|posix_spawn()|-implementatoin is fully POSIX/SUS-conformant...).

Below is a testcase which should exit with an exit code of 2 and
stdout something matching to *BEST*:
-- snip --
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <spawn.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define NOTE(x) fprintf(stderr, x "\n")

/* if it uses fork() why bother? */
#undef fork
pid_t fork (void) { NOTE("uses fork()"); return -1; }
pid_t _fork (void) { NOTE("uses _fork()"); return -1; }
pid_t __fork (void) { NOTE("uses __fork()"); return -1; }
int
main(int        argc, char**    argv)
{
        char*                   s;
        pid_t                   pid;
        posix_spawnattr_t       attr;
        int                     n;
        int                     status;
        char*                   cmd[3];
        char                    tmp[1024];
        if (argv[1])
                exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
        signal(SIGHUP, SIG_IGN);
        if (posix_spawnattr_init(&attr))
        {
                NOTE("posix_spawnattr_init() FAILED");
                exit(0);
        }
        if (posix_spawnattr_setpgroup(&attr, 0))
        {
                NOTE("posix_spawnattr_setpgroup() FAILED");
                exit(0);
        }
        if (posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP))
        {
                NOTE("posix_spawnattr_setflags() FAILED");
                exit(0);
        }
        /* first try an a.out and verify that SIGHUP is ignored */
        cmd[0] = argv[0];
        cmd[1] = "test";
        cmd[2] = 0;
        if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0))
        {
                NOTE("posix_spawn() FAILED");
                exit(0);
        }
        status = 1;
        if (wait(&status) < 0)
        {
                NOTE("wait() FAILED");
                exit(0);
        }
        if (status != 0)
        {
                NOTE("SIGHUP ignored in parent not ignored in child");
                exit(0);
        }
        /* must return exec-type errors or its useless to us *unless* there
is no [v]fork() */
        n = strlen(cmd[0]);
        if (n >= (sizeof(tmp) - 3))
        {
                NOTE("test executable path too long");
                exit(0);
        }
        strcpy(tmp, cmd[0]);
        tmp[n] = '.';
        tmp[n+1] = 's';
        tmp[n+2] = 'h';
        tmp[n+3] = 0;
        if ((n = open(tmp, O_CREAT|O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO)) < 0 ||
            chmod(tmp, S_IRWXU|S_IRWXG|S_IRWXO) < 0 ||
            write(n, "exit 99\n", 8) != 8 ||
            close(n) < 0)
        {
                NOTE("test script create FAILED");
                exit(0);
        }
        cmd[0] = tmp;
        n = 0; /* 0 means reject */
        pid = -1;
        if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0))
        {
                n = 2;
                NOTE("ENOEXEC produces posix_spawn() error (BEST)");
        }
        else if (pid == -1)
                NOTE("ENOEXEC returns pid == -1");
        else if (wait(&status) != pid)
                NOTE("ENOEXEC produces no child process");
        else if (!WIFEXITED(status))
                NOTE("ENOEXEC produces signal exit");
        else
        {
                status = WEXITSTATUS(status);
                if (status == 127)
                {
                        n = 1;
                        NOTE("ENOEXEC produces exit status 127");
                }
                else if (status == 99)
                        NOTE("ENOEXEC invokes sh");
                else if (status == 0)
                        NOTE("ENOEXEC reports no error");
        }
        exit(n);
}
-- snip --

Solaris 11FCS and AIX pass this test...

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) roland.ma...@nrubsig.org
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)
_______________________________________________
ast-developers mailing list
ast-developers@research.att.com
https://mailman.research.att.com/mailman/listinfo/ast-developers

Reply via email to