Blame stdlib/tst-setcontext4.c

Packit Service 82fcde
/* Testcase checks, if setcontext(), swapcontext() restores signal-mask
Packit Service 82fcde
   and if pending signals are delivered after those calls.
Packit Service 82fcde
   Copyright (C) 2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <sys/types.h>
Packit Service 82fcde
#include <signal.h>
Packit Service 82fcde
#include <ucontext.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
Packit Service 82fcde
volatile int global;
Packit Service 82fcde
volatile sig_atomic_t handlerCalled;
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
check (const char *funcName)
Packit Service 82fcde
{
Packit Service 82fcde
  sigset_t set;
Packit Service 82fcde
Packit Service 82fcde
  /* check if SIGUSR2 is unblocked after setcontext-call.  */
Packit Service 82fcde
  sigprocmask (SIG_BLOCK, NULL, &set);
Packit Service 82fcde
Packit Service 82fcde
  if (sigismember (&set, SIGUSR2) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (sigismember (&set, SIGUSR1) != 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
signalmask (int how, int signum)
Packit Service 82fcde
{
Packit Service 82fcde
  sigset_t set;
Packit Service 82fcde
  sigemptyset (&set);
Packit Service 82fcde
  sigaddset (&set, signum);
Packit Service 82fcde
  if (sigprocmask (how, &set, NULL) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
signalpending (int signum, const char *msg)
Packit Service 82fcde
{
Packit Service 82fcde
  sigset_t set;
Packit Service 82fcde
  sigemptyset (&set);
Packit Service 82fcde
  if (sigpending (&set) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("FAIL: sigpending: %m\n");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  if (sigismember (&set, SIGUSR2) != 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("FAIL: Signal %d is not pending %s\n", signum, msg);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
handler (int __attribute__ ((unused)) signum)
Packit Service 82fcde
{
Packit Service 82fcde
  handlerCalled ++;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
do_test (void)
Packit Service 82fcde
{
Packit Service 82fcde
  ucontext_t ctx, oldctx;
Packit Service 82fcde
  struct sigaction action;
Packit Service 82fcde
  pid_t pid;
Packit Service 82fcde
Packit Service 82fcde
  pid = getpid ();
Packit Service 82fcde
Packit Service 82fcde
  /* unblock SIGUSR2 */
Packit Service 82fcde
  signalmask (SIG_UNBLOCK, SIGUSR2);
Packit Service 82fcde
Packit Service 82fcde
  /* block SIGUSR1 */
Packit Service 82fcde
  signalmask (SIG_BLOCK, SIGUSR1);
Packit Service 82fcde
Packit Service 82fcde
  /* register handler for SIGUSR2  */
Packit Service 82fcde
  action.sa_flags = 0;
Packit Service 82fcde
  action.sa_handler = handler;
Packit Service 82fcde
  sigemptyset (&action.sa_mask);
Packit Service 82fcde
  sigaction (SIGUSR2, &action, NULL);
Packit Service 82fcde
Packit Service 82fcde
  if (getcontext (&ctx) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("FAIL: getcontext: %m\n");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  global++;
Packit Service 82fcde
Packit Service 82fcde
  if (global == 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("after getcontext");
Packit Service 82fcde
Packit Service 82fcde
      /* block SIGUSR2  */
Packit Service 82fcde
      signalmask (SIG_BLOCK, SIGUSR2);
Packit Service 82fcde
Packit Service 82fcde
      /* send SIGUSR2 to me  */
Packit Service 82fcde
      handlerCalled = 0;
Packit Service 82fcde
      kill (pid, SIGUSR2);
Packit Service 82fcde
Packit Service 82fcde
      /* was SIGUSR2 handler called?  */
Packit Service 82fcde
      if (handlerCalled != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  puts ("FAIL: signal handler was called, but signal was blocked.");
Packit Service 82fcde
	  exit (1);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* is SIGUSR2 pending?  */
Packit Service 82fcde
      signalpending (SIGUSR2, "before setcontext");
Packit Service 82fcde
Packit Service 82fcde
      /* SIGUSR2 will be unblocked by setcontext-call.  */
Packit Service 82fcde
      if (setcontext (&ctx) != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("FAIL: setcontext: %m\n");
Packit Service 82fcde
	  exit (1);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else if (global == 2)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("after setcontext");
Packit Service 82fcde
Packit Service 82fcde
      /* check SIGUSR1/2  */
Packit Service 82fcde
      check ("setcontext");
Packit Service 82fcde
Packit Service 82fcde
      /* was SIGUSR2 handler called? */
Packit Service 82fcde
      if (handlerCalled != 1)
Packit Service 82fcde
	{
Packit Service 82fcde
	  puts ("FAIL: signal handler was not called after setcontext.");
Packit Service 82fcde
	  exit (1);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* block SIGUSR2 */
Packit Service 82fcde
      signalmask (SIG_BLOCK, SIGUSR2);
Packit Service 82fcde
Packit Service 82fcde
      /* send SIGUSR2 to me  */
Packit Service 82fcde
      handlerCalled = 0;
Packit Service 82fcde
      kill (pid, SIGUSR2);
Packit Service 82fcde
Packit Service 82fcde
      /* was SIGUSR2 handler called?  */
Packit Service 82fcde
      if (handlerCalled != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  puts ("FAIL: signal handler was called, but signal was blocked.");
Packit Service 82fcde
	  exit (1);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* is SIGUSR2 pending?  */
Packit Service 82fcde
      signalpending (SIGUSR2, "before swapcontext");
Packit Service 82fcde
Packit Service 82fcde
      if (swapcontext (&oldctx, &ctx) != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("FAIL: swapcontext: %m\n");
Packit Service 82fcde
	  exit (1);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      puts ("FAIL: returned from (&oldctx, &ctx)");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  else if ( global != 3 )
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("FAIL: 'global' not incremented three times");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  puts ("after swapcontext");
Packit Service 82fcde
  /* check SIGUSR1/2  */
Packit Service 82fcde
  check ("swapcontext");
Packit Service 82fcde
Packit Service 82fcde
  /* was SIGUSR2 handler called? */
Packit Service 82fcde
  if (handlerCalled != 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("FAIL: signal handler was not called after swapcontext.");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* check sigmask in old context of swapcontext-call  */
Packit Service 82fcde
  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks.");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#include <support/test-driver.c>