This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

An exec and signal bug


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]);
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]