|
Packit |
6c4009 |
/* sigset_SIG_HOLD_bug.c [BZ #1951] */
|
|
Packit |
6c4009 |
#include <errno.h>
|
|
Packit |
6c4009 |
#include <error.h>
|
|
Packit |
6c4009 |
#include <inttypes.h>
|
|
Packit |
6c4009 |
#include <signal.h>
|
|
Packit |
6c4009 |
#include <stdio.h>
|
|
Packit |
6c4009 |
#include <stdlib.h>
|
|
Packit |
6c4009 |
#include <string.h>
|
|
Packit |
6c4009 |
#include <unistd.h>
|
|
Packit |
6c4009 |
#include <sys/types.h>
|
|
Packit |
6c4009 |
#include <sys/wait.h>
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#define TEST_SIG SIGINT
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Print mask of blocked signals for this process */
|
|
Packit |
6c4009 |
static void
|
|
Packit |
6c4009 |
printSigMask (const char *msg)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
sigset_t currMask;
|
|
Packit |
6c4009 |
int sig;
|
|
Packit |
6c4009 |
int cnt;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (msg != NULL)
|
|
Packit |
6c4009 |
printf ("%s", msg);
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (sigprocmask (SIG_BLOCK, NULL, &currMask) == -1)
|
|
Packit |
6c4009 |
error (1, errno, "sigaction");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
cnt = 0;
|
|
Packit |
6c4009 |
for (sig = 1; sig < NSIG; sig++)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
if (sigismember (&currMask, sig))
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
cnt++;
|
|
Packit |
6c4009 |
printf ("\t\t%d (%s)\n", sig, strsignal (sig));
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (cnt == 0)
|
|
Packit |
6c4009 |
printf ("\t\t<empty signal set>\n");
|
|
Packit |
6c4009 |
} /* printSigMask */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
static void
|
|
Packit |
6c4009 |
handler (int sig)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
printf ("Caught signal %d\n", sig);
|
|
Packit |
6c4009 |
printSigMask ("Signal mask in handler\n");
|
|
Packit |
6c4009 |
printf ("Handler returning\n");
|
|
Packit |
6c4009 |
_exit (1);
|
|
Packit |
6c4009 |
} /* handler */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
static void
|
|
Packit |
6c4009 |
printDisposition (sighandler_t disp)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
if (disp == SIG_HOLD)
|
|
Packit |
6c4009 |
printf ("SIG_HOLD");
|
|
Packit |
6c4009 |
else if (disp == SIG_DFL)
|
|
Packit |
6c4009 |
printf ("SIG_DFL");
|
|
Packit |
6c4009 |
else if (disp == SIG_IGN)
|
|
Packit |
6c4009 |
printf ("SIG_IGN");
|
|
Packit |
6c4009 |
else
|
|
Packit |
6c4009 |
printf ("handled at %" PRIxPTR, (uintptr_t) disp);
|
|
Packit |
6c4009 |
} /* printDisposition */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
static int
|
|
Packit |
6c4009 |
returnTest1 (void)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
sighandler_t prev;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("===== TEST 1 =====\n");
|
|
Packit |
6c4009 |
printf ("Blocking signal with sighold()\n");
|
|
Packit |
6c4009 |
if (sighold (TEST_SIG) == -1)
|
|
Packit |
6c4009 |
error (1, errno, "sighold");
|
|
Packit |
6c4009 |
printSigMask ("Signal mask after sighold()\n");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("About to use sigset() to establish handler\n");
|
|
Packit |
6c4009 |
prev = sigset (TEST_SIG, handler);
|
|
Packit |
6c4009 |
if (prev == SIG_ERR)
|
|
Packit |
6c4009 |
error(1, errno, "sigset");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("Previous disposition: ");
|
|
Packit |
6c4009 |
printDisposition (prev);
|
|
Packit |
6c4009 |
printf (" (should be SIG_HOLD)\n");
|
|
Packit |
6c4009 |
if (prev != SIG_HOLD)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
printf("TEST FAILED!!!\n");
|
|
Packit |
6c4009 |
return 1;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
return 0;
|
|
Packit |
6c4009 |
} /* returnTest1 */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
static int
|
|
Packit |
6c4009 |
returnTest2 (void)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
sighandler_t prev;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("\n===== TEST 2 =====\n");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("About to use sigset() to set SIG_HOLD\n");
|
|
Packit |
6c4009 |
prev = sigset (TEST_SIG, SIG_HOLD);
|
|
Packit |
6c4009 |
if (prev == SIG_ERR)
|
|
Packit |
6c4009 |
error (1, errno, "sigset");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("Previous disposition: ");
|
|
Packit |
6c4009 |
printDisposition (prev);
|
|
Packit |
6c4009 |
printf (" (should be SIG_DFL)\n");
|
|
Packit |
6c4009 |
if (prev != SIG_DFL)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
printf("TEST FAILED!!!\n");
|
|
Packit |
6c4009 |
return 1;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
return 0;
|
|
Packit |
6c4009 |
} /* returnTest2 */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
static int
|
|
Packit |
6c4009 |
returnTest3 (void)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
sighandler_t prev;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("\n===== TEST 3 =====\n");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("About to use sigset() to set SIG_HOLD\n");
|
|
Packit |
6c4009 |
prev = sigset (TEST_SIG, SIG_HOLD);
|
|
Packit |
6c4009 |
if (prev == SIG_ERR)
|
|
Packit |
6c4009 |
error (1, errno, "sigset");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("About to use sigset() to set SIG_HOLD (again)\n");
|
|
Packit |
6c4009 |
prev = sigset (TEST_SIG, SIG_HOLD);
|
|
Packit |
6c4009 |
if (prev == SIG_ERR)
|
|
Packit |
6c4009 |
error (1, errno, "sigset");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("Previous disposition: ");
|
|
Packit |
6c4009 |
printDisposition (prev);
|
|
Packit |
6c4009 |
printf (" (should be SIG_HOLD)\n");
|
|
Packit |
6c4009 |
if (prev != SIG_HOLD)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
printf("TEST FAILED!!!\n");
|
|
Packit |
6c4009 |
return 1;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
return 0;
|
|
Packit |
6c4009 |
} /* returnTest3 */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
int
|
|
Packit |
6c4009 |
main (int argc, char *argv[])
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
pid_t childPid;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
childPid = fork();
|
|
Packit |
6c4009 |
if (childPid == -1)
|
|
Packit |
6c4009 |
error (1, errno, "fork");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (childPid == 0)
|
|
Packit |
6c4009 |
exit (returnTest1 ());
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
int status;
|
|
Packit |
6c4009 |
if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
|
|
Packit |
6c4009 |
error (1, errno, "waitpid");
|
|
Packit |
6c4009 |
int result = !WIFEXITED (status) || WEXITSTATUS (status) != 0;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
childPid = fork();
|
|
Packit |
6c4009 |
if (childPid == -1)
|
|
Packit |
6c4009 |
error (1, errno, "fork");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (childPid == 0)
|
|
Packit |
6c4009 |
exit (returnTest2 ());
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
|
|
Packit |
6c4009 |
error (1, errno, "waitpid");
|
|
Packit |
6c4009 |
result |= !WIFEXITED (status) || WEXITSTATUS (status) != 0;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
childPid = fork();
|
|
Packit |
6c4009 |
if (childPid == -1)
|
|
Packit |
6c4009 |
error (1, errno, "fork");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (childPid == 0)
|
|
Packit |
6c4009 |
exit (returnTest3 ());
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
|
|
Packit |
6c4009 |
error (1, errno, "waitpid");
|
|
Packit |
6c4009 |
result |= !WIFEXITED (status) || WEXITSTATUS (status) != 0;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
return result;
|
|
Packit |
6c4009 |
} /* main */
|