This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
An exec and signal bug
- To: libc-hacker@cygnus.com (GNU C Library), torvalds@transmeta.com (Linus Torvalds), linux-kernel@vger.rutgers.edu (linux kernel)
- Subject: An exec and signal bug
- From: hjl@lucon.org (H.J. Lu)
- Date: Tue, 10 Nov 1998 11:23:36 -0800 (PST)
Hi, Linus,
This is an exec/signal bug discovered by the POSIX test. On linux,
I got
# gcc test.c
# a.out
zsh: 21000 abort ./a.out
On Solaris and HP-UX, I got
# gcc test.c
# a.out
PASS
Thanks.
--
H.J. Lu (hjl@gnu.org)
---
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
static int sig_recvd = 0;
static
void
sig_catch (int sg_num)
{
sig_recvd = sg_num;
}
static
int
sig_init (int signum, sigset_t *sigmask, void (*sigfunc)(),
int sigflags)
{
struct sigaction act;
act.sa_flags = sigflags;
act.sa_mask = *sigmask;
act.sa_handler = sigfunc;
return(sigaction(signum, &act, (struct sigaction *)NULL));
}
static
void
parent (const char *prog)
{
sigset_t set;
sigemptyset(&set);
if (sig_init (SIGHUP, &set, sig_catch, 0) < 0)
{
perror ("parent sigaction");
exit (1);
}
sigemptyset(&set);
sigaddset(&set, SIGHUP);
if(sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) != 0)
{
perror ("sigprocmask");
exit (1);
}
if (kill(getpid (), SIGHUP) < 0)
{
perror ("kill");
exit (1);
}
if (sig_recvd)
{
printf ("sigprocmask() did not block signal\n");
exit (2);
}
if (execl (prog, prog, "1", NULL))
{
perror ("execl");
exit (1);
}
exit (1);
}
static
void
child ()
{
sigset_t set;
sigemptyset(&set);
if (sig_init (SIGHUP, &set, sig_catch, 0) < 0)
{
perror ("child sigaction");
exit (1);
}
sigemptyset(&set);
sigaddset(&set, SIGHUP);
if(sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)NULL) != 0)
{
perror ("sigprocmask");
exit (1);
}
if (sig_recvd == SIGHUP)
{
printf ("PASS\n");
exit (0);
}
else
abort ();
}
int
main (int argc, char **argv)
{
if (argc > 1)
child ();
else
parent (argv [0]);
}