mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	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.
		
			
				
	
	
		
			185 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 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 */
 |