/* Tests for waitid.
   Copyright (C) 2004-2018 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
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

#define TIMEOUT 15

static void
test_child (void)
{
  /* Wait a second to be sure the parent set his variables before we
     produce a SIGCHLD.  */
  sleep (1);

  /* First thing, we stop ourselves.  */
  raise (SIGSTOP);

  /* Hey, we got continued!  */
  while (1)
    pause ();
}

#ifndef WEXITED
# define WEXITED	0
# define WCONTINUED	0
# define WSTOPPED	WUNTRACED
#endif

static sig_atomic_t expecting_sigchld, spurious_sigchld;
#ifdef SA_SIGINFO
static siginfo_t sigchld_info;

static void
sigchld (int signo, siginfo_t *info, void *ctx)
{
  if (signo != SIGCHLD)
    {
      printf ("SIGCHLD handler got signal %d instead!\n", signo);
      _exit (EXIT_FAILURE);
    }

  if (! expecting_sigchld)
    {
      spurious_sigchld = 1;
      printf ("spurious SIGCHLD: signo %d code %d status %d pid %d\n",
	      info->si_signo, info->si_code, info->si_status, info->si_pid);
    }
  else
    {
      sigchld_info = *info;
      expecting_sigchld = 0;
    }
}

static void
check_sigchld (const char *phase, int *ok, int code, int status, pid_t pid)
{
  if (expecting_sigchld)
    {
      printf ("missing SIGCHLD on %s\n", phase);
      *ok = EXIT_FAILURE;
      expecting_sigchld = 0;
      return;
    }

  if (sigchld_info.si_signo != SIGCHLD)
    {
      printf ("SIGCHLD for %s signal %d\n", phase, sigchld_info.si_signo);
      *ok = EXIT_FAILURE;
    }
  if (sigchld_info.si_code != code)
    {
      printf ("SIGCHLD for %s code %d\n", phase, sigchld_info.si_code);
      *ok = EXIT_FAILURE;
    }
  if (sigchld_info.si_status != status)
    {
      printf ("SIGCHLD for %s status %d\n", phase, sigchld_info.si_status);
      *ok = EXIT_FAILURE;
    }
  if (sigchld_info.si_pid != pid)
    {
      printf ("SIGCHLD for %s pid %d\n", phase, sigchld_info.si_pid);
      *ok = EXIT_FAILURE;
    }
}
# define CHECK_SIGCHLD(phase, code_check, status_check) \
  check_sigchld ((phase), &status, (code_check), (status_check), pid)
#else
# define CHECK_SIGCHLD(phase, code, status) ((void) 0)
#endif

static int
do_test (int argc, char *argv[])
{
#ifdef SA_SIGINFO
  struct sigaction sa;
  sa.sa_flags = SA_SIGINFO|SA_RESTART;
  sa.sa_sigaction = &sigchld;
  if (sigemptyset (&sa.sa_mask) < 0 || sigaction (SIGCHLD, &sa, NULL) < 0)
    {
      printf ("setting SIGCHLD handler: %m\n");
      return EXIT_FAILURE;
    }
#endif

  expecting_sigchld = 1;

  pid_t pid = fork ();
  if (pid < 0)
    {
      printf ("fork: %m\n");
      return EXIT_FAILURE;
    }
  else if (pid == 0)
    {
      test_child ();
      _exit (127);
    }

  int status = EXIT_SUCCESS;
#define RETURN(ok) \
    do { if (status == EXIT_SUCCESS) status = (ok); goto out; } while (0)

  /* Give the child a chance to stop.  */
  sleep (3);

  CHECK_SIGCHLD ("stopped (before waitid)", CLD_STOPPED, SIGSTOP);

  /* Now try a wait that should not succeed.  */
  siginfo_t info;
  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  int fail = waitid (P_PID, pid, &info, WEXITED|WCONTINUED|WNOHANG);
  switch (fail)
    {
    default:
      printf ("waitid returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WNOHANG on stopped: %m\n");
      RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
    case 0:
      if (info.si_signo == 0)
	break;
      if (info.si_signo == SIGCHLD)
	printf ("waitid WNOHANG on stopped status %d\n", info.si_status);
      else
	printf ("waitid WNOHANG on stopped signal %d\n", info.si_signo);
      RETURN (EXIT_FAILURE);
    }

  /* Next the wait that should succeed right away.  */
  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  info.si_pid = -1;
  info.si_status = -1;
  fail = waitid (P_PID, pid, &info, WSTOPPED|WNOHANG);
  switch (fail)
    {
    default:
      printf ("waitid WSTOPPED|WNOHANG returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WSTOPPED|WNOHANG on stopped: %m\n");
      RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
    case 0:
      if (info.si_signo != SIGCHLD)
	{
	  printf ("waitid WSTOPPED|WNOHANG on stopped signal %d\n",
		  info.si_signo);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_code != CLD_STOPPED)
	{
	  printf ("waitid WSTOPPED|WNOHANG on stopped code %d\n",
		  info.si_code);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_status != SIGSTOP)
	{
	  printf ("waitid WSTOPPED|WNOHANG on stopped status %d\n",
		  info.si_status);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_pid != pid)
	{
	  printf ("waitid WSTOPPED|WNOHANG on stopped pid %d != %d\n",
		  info.si_pid, pid);
	  RETURN (EXIT_FAILURE);
	}
    }

  expecting_sigchld = WCONTINUED != 0;

  if (kill (pid, SIGCONT) != 0)
    {
      printf ("kill (%d, SIGCONT): %m\n", pid);
      RETURN (EXIT_FAILURE);
    }

  /* Wait for the child to have continued.  */
  sleep (2);

#if WCONTINUED != 0
  if (expecting_sigchld)
    {
      printf ("no SIGCHLD seen for SIGCONT (optional)\n");
      expecting_sigchld = 0;
    }
  else
    CHECK_SIGCHLD ("continued (before waitid)", CLD_CONTINUED, SIGCONT);

  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  info.si_pid = -1;
  info.si_status = -1;
  fail = waitid (P_PID, pid, &info, WCONTINUED|WNOWAIT);
  switch (fail)
    {
    default:
      printf ("waitid WCONTINUED|WNOWAIT returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WCONTINUED|WNOWAIT on continued: %m\n");
      RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
    case 0:
      if (info.si_signo != SIGCHLD)
	{
	  printf ("waitid WCONTINUED|WNOWAIT on continued signal %d\n",
		  info.si_signo);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_code != CLD_CONTINUED)
	{
	  printf ("waitid WCONTINUED|WNOWAIT on continued code %d\n",
		  info.si_code);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_status != SIGCONT)
	{
	  printf ("waitid WCONTINUED|WNOWAIT on continued status %d\n",
		  info.si_status);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_pid != pid)
	{
	  printf ("waitid WCONTINUED|WNOWAIT on continued pid %d != %d\n",
		  info.si_pid, pid);
	  RETURN (EXIT_FAILURE);
	}
    }

  /* That should leave the CLD_CONTINUED state waiting to be seen again.  */
  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  info.si_pid = -1;
  info.si_status = -1;
  fail = waitid (P_PID, pid, &info, WCONTINUED);
  switch (fail)
    {
    default:
      printf ("waitid WCONTINUED returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WCONTINUED on continued: %m\n");
      RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
    case 0:
      if (info.si_signo != SIGCHLD)
	{
	  printf ("waitid WCONTINUED on continued signal %d\n", info.si_signo);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_code != CLD_CONTINUED)
	{
	  printf ("waitid WCONTINUED on continued code %d\n", info.si_code);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_status != SIGCONT)
	{
	  printf ("waitid WCONTINUED on continued status %d\n",
		  info.si_status);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_pid != pid)
	{
	  printf ("waitid WCONTINUED on continued pid %d != %d\n",
		  info.si_pid, pid);
	  RETURN (EXIT_FAILURE);
	}
    }

  /* Now try a wait that should not succeed.  */
  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  fail = waitid (P_PID, pid, &info, WCONTINUED|WNOHANG);
  switch (fail)
    {
    default:
      printf ("waitid returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WCONTINUED|WNOHANG on waited continued: %m\n");
      RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
    case 0:
      if (info.si_signo == 0)
	break;
      if (info.si_signo == SIGCHLD)
	printf ("waitid WCONTINUED|WNOHANG on waited continued status %d\n",
		info.si_status);
      else
	printf ("waitid WCONTINUED|WNOHANG on waited continued signal %d\n",
		info.si_signo);
      RETURN (EXIT_FAILURE);
    }

  /* Now stop him again and test waitpid with WCONTINUED.  */
  expecting_sigchld = 1;
  if (kill (pid, SIGSTOP) != 0)
    {
      printf ("kill (%d, SIGSTOP): %m\n", pid);
      RETURN (EXIT_FAILURE);
    }

  /* Give the child a chance to stop.  The waitpid call below will block
     until it has stopped, but if we are real quick and enter the waitpid
     system call before the SIGCHLD has been generated, then it will be
     discarded and never delivered.  */
  sleep (3);

  pid_t wpid = waitpid (pid, &fail, WUNTRACED);
  if (wpid < 0)
    {
      printf ("waitpid WUNTRACED on stopped: %m\n");
      RETURN (EXIT_FAILURE);
    }
  else if (wpid != pid)
    {
      printf ("waitpid WUNTRACED on stopped returned %d != %d (status %x)\n",
	      wpid, pid, fail);
      RETURN (EXIT_FAILURE);
    }
  else if (!WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail)
	   || WIFCONTINUED (fail) || WSTOPSIG (fail) != SIGSTOP)
    {
      printf ("waitpid WUNTRACED on stopped: status %x\n", fail);
      RETURN (EXIT_FAILURE);
    }
  CHECK_SIGCHLD ("stopped (after waitpid)", CLD_STOPPED, SIGSTOP);

  expecting_sigchld = 1;
  if (kill (pid, SIGCONT) != 0)
    {
      printf ("kill (%d, SIGCONT): %m\n", pid);
      RETURN (EXIT_FAILURE);
    }

  /* Wait for the child to have continued.  */
  sleep (2);

  if (expecting_sigchld)
    {
      printf ("no SIGCHLD seen for SIGCONT (optional)\n");
      expecting_sigchld = 0;
    }
  else
    CHECK_SIGCHLD ("continued (before waitpid)", CLD_CONTINUED, SIGCONT);

  wpid = waitpid (pid, &fail, WCONTINUED);
  if (wpid < 0)
    {
      if (errno == EINVAL)
	printf ("waitpid does not support WCONTINUED\n");
      else
	{
	  printf ("waitpid WCONTINUED on continued: %m\n");
	  RETURN (EXIT_FAILURE);
	}
    }
  else if (wpid != pid)
    {
      printf ("\
waitpid WCONTINUED on continued returned %d != %d (status %x)\n",
	     wpid, pid, fail);
      RETURN (EXIT_FAILURE);
    }
  else if (WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail)
	   || !WIFCONTINUED (fail))
    {
      printf ("waitpid WCONTINUED on continued: status %x\n", fail);
      RETURN (EXIT_FAILURE);
    }
#endif

  expecting_sigchld = 1;

  /* Die, child, die!  */
  if (kill (pid, SIGKILL) != 0)
    {
      printf ("kill (%d, SIGKILL): %m\n", pid);
      RETURN (EXIT_FAILURE);
    }

#ifdef WNOWAIT
  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  info.si_pid = -1;
  info.si_status = -1;
  fail = waitid (P_PID, pid, &info, WEXITED|WNOWAIT);
  switch (fail)
    {
    default:
      printf ("waitid WNOWAIT returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WNOWAIT on killed: %m\n");
      RETURN (errno == ENOTSUP ? EXIT_SUCCESS : EXIT_FAILURE);
    case 0:
      if (info.si_signo != SIGCHLD)
	{
	  printf ("waitid WNOWAIT on killed signal %d\n", info.si_signo);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_code != CLD_KILLED)
	{
	  printf ("waitid WNOWAIT on killed code %d\n", info.si_code);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_status != SIGKILL)
	{
	  printf ("waitid WNOWAIT on killed status %d\n", info.si_status);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_pid != pid)
	{
	  printf ("waitid WNOWAIT on killed pid %d != %d\n", info.si_pid, pid);
	  RETURN (EXIT_FAILURE);
	}
    }
#else
  /* Allow enough time to be sure the child died; we didn't synchronize.  */
  sleep (2);
#endif

  CHECK_SIGCHLD ("killed", CLD_KILLED, SIGKILL);

  info.si_signo = 0;		/* A successful call sets it to SIGCHLD.  */
  info.si_pid = -1;
  info.si_status = -1;
  fail = waitid (P_PID, pid, &info, WEXITED|WNOHANG);
  switch (fail)
    {
    default:
      printf ("waitid WNOHANG returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    case -1:
      printf ("waitid WNOHANG on killed: %m\n");
      RETURN (EXIT_FAILURE);
    case 0:
      if (info.si_signo != SIGCHLD)
	{
	  printf ("waitid WNOHANG on killed signal %d\n", info.si_signo);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_code != CLD_KILLED)
	{
	  printf ("waitid WNOHANG on killed code %d\n", info.si_code);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_status != SIGKILL)
	{
	  printf ("waitid WNOHANG on killed status %d\n", info.si_status);
	  RETURN (EXIT_FAILURE);
	}
      if (info.si_pid != pid)
	{
	  printf ("waitid WNOHANG on killed pid %d != %d\n", info.si_pid, pid);
	  RETURN (EXIT_FAILURE);
	}
    }

  fail = waitid (P_PID, pid, &info, WEXITED);
  if (fail == -1)
    {
      if (errno != ECHILD)
	{
	  printf ("waitid WEXITED on killed: %m\n");
	  RETURN (EXIT_FAILURE);
	}
    }
  else
    {
      printf ("waitid WEXITED returned bogus value %d\n", fail);
      RETURN (EXIT_FAILURE);
    }

#undef RETURN
 out:
  if (spurious_sigchld)
    status = EXIT_FAILURE;
  signal (SIGCHLD, SIG_IGN);
  kill (pid, SIGKILL);		/* Make sure it's dead if we bailed early.  */
  return status;
}

#include "../test-skeleton.c"
