Question on posix_spawnp on Linux
When trying to emulate the behavior of system(3), I noticed a different
behavior of posix_spawnp on Linux (AMD and IBM) from SUN and AIX. Here's
the code snippet to spawn a child process and have it run:
/bin/sh -c "ls -l /etc"
(return value checking is omitted):
pid_t pid;
sigset_t sigset;
int rc = 0;
posix_spawnattr_t attr;
short flags = 0;
int status, ret;
extern char** environ;
char *const argv[] = { "/bin/sh", "-c", "ls -l /etc", NULL };
rc = posix_spawnattr_init( &attr );
// Set all signal actions to defaults in child
sigfillset( &sigset );
rc = posix_spawnattr_setsigdefault( &attr, &sigset );
// Empty signal mask in child
sigemptyset( &sigset );
rc = posix_spawnattr_setsigmask( &attr, &sigset );
flags |= (POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
rc = posix_spawnattr_setflags( &attr, flags );
rc = posix_spawnp( &pid, argv[0], NULL, &attr, argv, environ );
posix_spawnattr_destroy( &attr );
ret = waitpid( pid, &status, 0 );
if( ret == -1 ) {
// waitpid has failed
rc = errno;
}
if( status != 0 ) {
printf("status = %d\n", status);
if( WIFEXITED( status ) ) {
ret = WEXITSTATUS( status );
} else {
ret = -1;
}
printf("ret = %d\n", ret);
}
On Linux, the call to posix_spawnp() here spawns the child process which
immediately becomes defunct and does NOT run the command passed in.
status is 32512 and ret 127.
On SUN and AIX, the code as it is works as expected, and status is 0.
However, on Linux, if NULL instead of $attr is passed into posix_spawnp
here, it works as expected. This is also true on SUN and AIX. So NULL
appears to make the code portable across SUN, AIX and Linux.
I'd like to understand why there is the difference and if using NULL in
place of &attr is indeed the right approach to emulate system(3). Any
insights would be really appreciated.
|