mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
[BZ #1951]
2006-04-23 Ulrich Drepper <drepper@redhat.com> [BZ #1951] * sysdeps/posix/sigset.c (sigset): Return correct value reflecting previous signal state. * signal/Makefile (tests): Add tst-sigset2. * signal/tst-sigset2.c: New file.
This commit is contained in:
parent
9055724a92
commit
727a6832f0
@ -1,3 +1,11 @@
|
||||
2006-04-23 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
[BZ #1951]
|
||||
* sysdeps/posix/sigset.c (sigset): Return correct value reflecting
|
||||
previous signal state.
|
||||
* signal/Makefile (tests): Add tst-sigset2.
|
||||
* signal/tst-sigset2.c: New file.
|
||||
|
||||
2006-04-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* argp/argp.h (__option_is_short): Check upper limit of
|
||||
|
@ -1,5 +1,4 @@
|
||||
# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,2003
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright (C) 1991-1998,2003,2006 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -38,7 +37,7 @@ routines := signal raise killpg \
|
||||
allocrtsig sigtimedwait sigwaitinfo sigqueue \
|
||||
sighold sigrelse sigignore sigset
|
||||
|
||||
tests := tst-signal tst-sigset tst-sigsimple tst-raise
|
||||
tests := tst-signal tst-sigset tst-sigsimple tst-raise tst-sigset2
|
||||
|
||||
distribute := sigsetops.h testrtsig.h sigset-cvt-mask.h
|
||||
|
||||
|
184
signal/tst-sigset2.c
Normal file
184
signal/tst-sigset2.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* sigset_SIG_HOLD_bug.c [BZ #1951] */
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define TEST_SIG SIGINT
|
||||
|
||||
|
||||
/* Print mask of blocked signals for this process */
|
||||
static void
|
||||
printSigMask (const char *msg)
|
||||
{
|
||||
sigset_t currMask;
|
||||
int sig;
|
||||
int cnt;
|
||||
|
||||
if (msg != NULL)
|
||||
printf ("%s", msg);
|
||||
|
||||
if (sigprocmask (SIG_BLOCK, NULL, &currMask) == -1)
|
||||
error (1, errno, "sigaction");
|
||||
|
||||
cnt = 0;
|
||||
for (sig = 1; sig < NSIG; sig++)
|
||||
{
|
||||
if (sigismember (&currMask, sig))
|
||||
{
|
||||
cnt++;
|
||||
printf ("\t\t%d (%s)\n", sig, strsignal (sig));
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
printf ("\t\t<empty signal set>\n");
|
||||
} /* printSigMask */
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
printf ("Caught signal %d\n", sig);
|
||||
printSigMask ("Signal mask in handler\n");
|
||||
printf ("Handler returning\n");
|
||||
_exit (1);
|
||||
} /* handler */
|
||||
|
||||
static void
|
||||
printDisposition (sighandler_t disp)
|
||||
{
|
||||
if (disp == SIG_HOLD)
|
||||
printf ("SIG_HOLD");
|
||||
else if (disp == SIG_DFL)
|
||||
printf ("SIG_DFL");
|
||||
else if (disp == SIG_IGN)
|
||||
printf ("SIG_IGN");
|
||||
else
|
||||
printf ("handled at %" PRIxPTR, (uintptr_t) disp);
|
||||
} /* printDisposition */
|
||||
|
||||
static int
|
||||
returnTest1 (void)
|
||||
{
|
||||
sighandler_t prev;
|
||||
|
||||
printf ("===== TEST 1 =====\n");
|
||||
printf ("Blocking signal with sighold()\n");
|
||||
if (sighold (TEST_SIG) == -1)
|
||||
error (1, errno, "sighold");
|
||||
printSigMask ("Signal mask after sighold()\n");
|
||||
|
||||
printf ("About to use sigset() to establish handler\n");
|
||||
prev = sigset (TEST_SIG, handler);
|
||||
if (prev == SIG_ERR)
|
||||
error(1, errno, "sigset");
|
||||
|
||||
printf ("Previous disposition: ");
|
||||
printDisposition (prev);
|
||||
printf (" (should be SIG_HOLD)\n");
|
||||
if (prev != SIG_HOLD)
|
||||
{
|
||||
printf("TEST FAILED!!!\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} /* returnTest1 */
|
||||
|
||||
static int
|
||||
returnTest2 (void)
|
||||
{
|
||||
sighandler_t prev;
|
||||
|
||||
printf ("\n===== TEST 2 =====\n");
|
||||
|
||||
printf ("About to use sigset() to set SIG_HOLD\n");
|
||||
prev = sigset (TEST_SIG, SIG_HOLD);
|
||||
if (prev == SIG_ERR)
|
||||
error (1, errno, "sigset");
|
||||
|
||||
printf ("Previous disposition: ");
|
||||
printDisposition (prev);
|
||||
printf (" (should be SIG_DFL)\n");
|
||||
if (prev != SIG_DFL)
|
||||
{
|
||||
printf("TEST FAILED!!!\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} /* returnTest2 */
|
||||
|
||||
static int
|
||||
returnTest3 (void)
|
||||
{
|
||||
sighandler_t prev;
|
||||
|
||||
printf ("\n===== TEST 3 =====\n");
|
||||
|
||||
printf ("About to use sigset() to set SIG_HOLD\n");
|
||||
prev = sigset (TEST_SIG, SIG_HOLD);
|
||||
if (prev == SIG_ERR)
|
||||
error (1, errno, "sigset");
|
||||
|
||||
printf ("About to use sigset() to set SIG_HOLD (again)\n");
|
||||
prev = sigset (TEST_SIG, SIG_HOLD);
|
||||
if (prev == SIG_ERR)
|
||||
error (1, errno, "sigset");
|
||||
|
||||
printf ("Previous disposition: ");
|
||||
printDisposition (prev);
|
||||
printf (" (should be SIG_HOLD)\n");
|
||||
if (prev != SIG_HOLD)
|
||||
{
|
||||
printf("TEST FAILED!!!\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} /* returnTest3 */
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
pid_t childPid;
|
||||
|
||||
childPid = fork();
|
||||
if (childPid == -1)
|
||||
error (1, errno, "fork");
|
||||
|
||||
if (childPid == 0)
|
||||
exit (returnTest1 ());
|
||||
|
||||
int status;
|
||||
if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
|
||||
error (1, errno, "waitpid");
|
||||
int result = !WIFEXITED (status) || WEXITSTATUS (status) != 0;
|
||||
|
||||
childPid = fork();
|
||||
if (childPid == -1)
|
||||
error (1, errno, "fork");
|
||||
|
||||
if (childPid == 0)
|
||||
exit (returnTest2 ());
|
||||
|
||||
if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
|
||||
error (1, errno, "waitpid");
|
||||
result |= !WIFEXITED (status) || WEXITSTATUS (status) != 0;
|
||||
|
||||
childPid = fork();
|
||||
if (childPid == -1)
|
||||
error (1, errno, "fork");
|
||||
|
||||
if (childPid == 0)
|
||||
exit (returnTest3 ());
|
||||
|
||||
if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
|
||||
error (1, errno, "waitpid");
|
||||
result |= !WIFEXITED (status) || WEXITSTATUS (status) != 0;
|
||||
|
||||
return result;
|
||||
} /* main */
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1998, 2000, 2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1998, 2000, 2005, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -29,8 +29,10 @@ sigset (sig, disp)
|
||||
int sig;
|
||||
__sighandler_t disp;
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
sigset_t set;
|
||||
sigset_t oset;
|
||||
|
||||
#ifdef SIG_HOLD
|
||||
/* Handle SIG_HOLD first. */
|
||||
@ -45,10 +47,18 @@ sigset (sig, disp)
|
||||
return SIG_ERR;
|
||||
|
||||
/* Add the signal set to the current signal mask. */
|
||||
if (__sigprocmask (SIG_BLOCK, &set, NULL) < 0)
|
||||
if (__sigprocmask (SIG_BLOCK, &set, &oset) < 0)
|
||||
return SIG_ERR;
|
||||
|
||||
return SIG_HOLD;
|
||||
/* If the signal was already blocked signal this to the caller. */
|
||||
if (__sigismember (&oset, sig))
|
||||
return SIG_HOLD;
|
||||
|
||||
/* We need to determine whether a specific handler is installed. */
|
||||
if (__sigaction (sig, NULL, &oact) < 0)
|
||||
return SIG_ERR;
|
||||
|
||||
return oact.sa_handler;
|
||||
}
|
||||
#endif /* SIG_HOLD */
|
||||
|
||||
@ -75,8 +85,9 @@ sigset (sig, disp)
|
||||
return SIG_ERR;
|
||||
|
||||
/* Remove the signal set from the current signal mask. */
|
||||
if (__sigprocmask (SIG_UNBLOCK, &set, NULL) < 0)
|
||||
if (__sigprocmask (SIG_UNBLOCK, &set, &oset) < 0)
|
||||
return SIG_ERR;
|
||||
|
||||
return oact.sa_handler;
|
||||
/* If the signal was already blocked return SIG_HOLD. */
|
||||
return __sigismember (&oset, sig) ? SIG_HOLD : oact.sa_handler;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user