Blame support/support_test_main.c

Packit 6c4009
/* Main worker function for the test driver.
Packit 6c4009
   Copyright (C) 1998-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <support/test-driver.h>
Packit 6c4009
#include <support/check.h>
Packit 6c4009
#include <support/temp_file-internal.h>
Packit Service 94fa28
#include <support/support.h>
Packit 6c4009
Packit 6c4009
#include <assert.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <getopt.h>
Packit 6c4009
#include <malloc.h>
Packit 6c4009
#include <signal.h>
Packit 6c4009
#include <stdbool.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <sys/param.h>
Packit 6c4009
#include <sys/resource.h>
Packit Service 750479
#include <sys/time.h>
Packit 6c4009
#include <sys/types.h>
Packit 6c4009
#include <sys/wait.h>
Packit 6c4009
#include <time.h>
Packit 6c4009
#include <unistd.h>
Packit 6c4009
Packit Service 94fa28
#include <xstdio.h>
Packit Service 94fa28
Packit 6c4009
static const struct option default_options[] =
Packit 6c4009
{
Packit 6c4009
  TEST_DEFAULT_OPTIONS
Packit 6c4009
  { NULL, 0, NULL, 0 }
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/* Show people how to run the program.  */
Packit 6c4009
static void
Packit 6c4009
usage (const struct option *options)
Packit 6c4009
{
Packit 6c4009
  size_t i;
Packit 6c4009
Packit 6c4009
  printf ("Usage: %s [options]\n"
Packit 6c4009
          "\n"
Packit 6c4009
          "Environment Variables:\n"
Packit 6c4009
          "  TIMEOUTFACTOR          An integer used to scale the timeout\n"
Packit 6c4009
          "  TMPDIR                 Where to place temporary files\n"
Packit 6c4009
          "  TEST_COREDUMPS         Do not disable coredumps if set\n"
Packit 6c4009
          "\n",
Packit 6c4009
          program_invocation_short_name);
Packit 6c4009
  printf ("Options:\n");
Packit 6c4009
  for (i = 0; options[i].name; ++i)
Packit 6c4009
    {
Packit 6c4009
      int indent;
Packit 6c4009
Packit 6c4009
      indent = printf ("  --%s", options[i].name);
Packit 6c4009
      if (options[i].has_arg == required_argument)
Packit 6c4009
        indent += printf (" <arg>");
Packit 6c4009
      printf ("%*s", 25 - indent, "");
Packit 6c4009
      switch (options[i].val)
Packit 6c4009
        {
Packit 6c4009
        case 'v':
Packit 6c4009
          printf ("Increase the output verbosity");
Packit 6c4009
          break;
Packit 6c4009
        case OPT_DIRECT:
Packit 6c4009
          printf ("Run the test directly (instead of forking & monitoring)");
Packit 6c4009
          break;
Packit 6c4009
        case OPT_TESTDIR:
Packit 6c4009
          printf ("Override the TMPDIR env var");
Packit 6c4009
          break;
Packit 6c4009
        }
Packit 6c4009
      printf ("\n");
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* The PID of the test process.  */
Packit 6c4009
static pid_t test_pid;
Packit 6c4009
Packit 6c4009
/* The cleanup handler passed to test_main.  */
Packit 6c4009
static void (*cleanup_function) (void);
Packit 6c4009
Packit Service 750479
static void
Packit Service 750479
print_timestamp (const char *what, struct timeval tv)
Packit Service 750479
{
Packit Service 750479
  struct tm tm;
Packit Service 750479
  if (gmtime_r (&tv.tv_sec, &tm) == NULL)
Packit Service 750479
    printf ("%s: %lld.%06d\n",
Packit Service 750479
            what, (long long int) tv.tv_sec, (int) tv.tv_usec);
Packit Service 750479
  else
Packit Service 750479
    printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
Packit Service 750479
            what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
Packit Service 750479
            tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
Packit Service 750479
}
Packit Service 750479
Packit 6c4009
/* Timeout handler.  We kill the child and exit with an error.  */
Packit 6c4009
static void
Packit 6c4009
__attribute__ ((noreturn))
Packit 6c4009
signal_handler (int sig)
Packit 6c4009
{
Packit 6c4009
  int killed;
Packit 6c4009
  int status;
Packit 6c4009
Packit Service 750479
  /* Do this first to avoid further interference from the
Packit Service 750479
     subprocess.  */
Packit Service 750479
  struct timeval now;
Packit Service 750479
  bool now_available = gettimeofday (&now, NULL) == 0;
Packit Service 750479
  struct stat64 st;
Packit Service 750479
  bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
Packit Service 750479
Packit 6c4009
  assert (test_pid > 1);
Packit 6c4009
  /* Kill the whole process group.  */
Packit 6c4009
  kill (-test_pid, SIGKILL);
Packit 6c4009
  /* In case setpgid failed in the child, kill it individually too.  */
Packit 6c4009
  kill (test_pid, SIGKILL);
Packit 6c4009
Packit 6c4009
  /* Wait for it to terminate.  */
Packit 6c4009
  int i;
Packit 6c4009
  for (i = 0; i < 5; ++i)
Packit 6c4009
    {
Packit 6c4009
      killed = waitpid (test_pid, &status, WNOHANG|WUNTRACED);
Packit 6c4009
      if (killed != 0)
Packit 6c4009
        break;
Packit 6c4009
Packit 6c4009
      /* Delay, give the system time to process the kill.  If the
Packit 6c4009
         nanosleep() call return prematurely, all the better.  We
Packit 6c4009
         won't restart it since this probably means the child process
Packit 6c4009
         finally died.  */
Packit 6c4009
      struct timespec ts;
Packit 6c4009
      ts.tv_sec = 0;
Packit 6c4009
      ts.tv_nsec = 100000000;
Packit 6c4009
      nanosleep (&ts, NULL);
Packit 6c4009
    }
Packit 6c4009
  if (killed != 0 && killed != test_pid)
Packit 6c4009
    {
Packit 6c4009
      printf ("Failed to kill test process: %m\n");
Packit 6c4009
      exit (1);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (cleanup_function != NULL)
Packit 6c4009
    cleanup_function ();
Packit 6c4009
Packit 6c4009
  if (sig == SIGINT)
Packit 6c4009
    {
Packit 6c4009
      signal (sig, SIG_DFL);
Packit 6c4009
      raise (sig);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL))
Packit 6c4009
    puts ("Timed out: killed the child process");
Packit 6c4009
  else if (WIFSTOPPED (status))
Packit 6c4009
    printf ("Timed out: the child process was %s\n",
Packit 6c4009
            strsignal (WSTOPSIG (status)));
Packit 6c4009
  else if (WIFSIGNALED (status))
Packit 6c4009
    printf ("Timed out: the child process got signal %s\n",
Packit 6c4009
            strsignal (WTERMSIG (status)));
Packit 6c4009
  else
Packit 6c4009
    printf ("Timed out: killed the child process but it exited %d\n",
Packit 6c4009
            WEXITSTATUS (status));
Packit 6c4009
Packit Service 750479
  if (now_available)
Packit Service 750479
    print_timestamp ("Termination time", now);
Packit Service 750479
  if (st_available)
Packit Service 750479
    print_timestamp ("Last write to standard output",
Packit Service 750479
                     (struct timeval) { st.st_mtim.tv_sec,
Packit Service 750479
                         st.st_mtim.tv_nsec / 1000 });
Packit Service 750479
Packit 6c4009
  /* Exit with an error.  */
Packit 6c4009
  exit (1);
Packit 6c4009
}
Packit 6c4009
Packit Service 94fa28
/* This must be volatile as it will be modified by the debugger.  */
Packit Service 94fa28
static volatile int wait_for_debugger = 0;
Packit Service 94fa28
Packit 6c4009
/* Run test_function or test_function_argv.  */
Packit 6c4009
static int
Packit 6c4009
run_test_function (int argc, char **argv, const struct test_config *config)
Packit 6c4009
{
Packit Service 94fa28
  const char *wfd = getenv("WAIT_FOR_DEBUGGER");
Packit Service 94fa28
  if (wfd != NULL)
Packit Service 94fa28
    wait_for_debugger = atoi (wfd);
Packit Service 94fa28
  if (wait_for_debugger)
Packit Service 94fa28
    {
Packit Service 94fa28
      pid_t mypid;
Packit Service 94fa28
      FILE *gdb_script;
Packit Service 94fa28
      char *gdb_script_name;
Packit Service 94fa28
      int inside_container = 0;
Packit Service 94fa28
Packit Service 94fa28
      mypid = getpid();
Packit Service 94fa28
      if (mypid < 3)
Packit Service 94fa28
	{
Packit Service 94fa28
	  const char *outside_pid = getenv("PID_OUTSIDE_CONTAINER");
Packit Service 94fa28
	  if (outside_pid)
Packit Service 94fa28
	    {
Packit Service 94fa28
	      mypid = atoi (outside_pid);
Packit Service 94fa28
	      inside_container = 1;
Packit Service 94fa28
	    }
Packit Service 94fa28
	}
Packit Service 94fa28
Packit Service 94fa28
      gdb_script_name = (char *) xmalloc (strlen (argv[0]) + strlen (".gdb") + 1);
Packit Service 94fa28
      sprintf (gdb_script_name, "%s.gdb", argv[0]);
Packit Service 94fa28
      gdb_script = xfopen (gdb_script_name, "w");
Packit Service 94fa28
Packit Service 94fa28
      fprintf (stderr, "Waiting for debugger, test process is pid %d\n", mypid);
Packit Service 94fa28
      fprintf (stderr, "gdb -x %s\n", gdb_script_name);
Packit Service 94fa28
      if (inside_container)
Packit Service 94fa28
	fprintf (gdb_script, "set sysroot %s/testroot.root\n", support_objdir_root);
Packit Service 94fa28
      fprintf (gdb_script, "file\n");
Packit Service 94fa28
      fprintf (gdb_script, "file %s\n", argv[0]);
Packit Service 94fa28
      fprintf (gdb_script, "symbol-file %s\n", argv[0]);
Packit Service 94fa28
      fprintf (gdb_script, "exec-file %s\n", argv[0]);
Packit Service 94fa28
      fprintf (gdb_script, "attach %ld\n", (long int) mypid);
Packit Service 94fa28
      fprintf (gdb_script, "set wait_for_debugger = 0\n");
Packit Service 94fa28
      fclose (gdb_script);
Packit Service 94fa28
    }
Packit Service 94fa28
Packit Service 94fa28
  /* Wait for the debugger to set wait_for_debugger to zero.  */
Packit Service 94fa28
  while (wait_for_debugger)
Packit Service 94fa28
    usleep (1000);
Packit Service 94fa28
Packit 6c4009
  if (config->test_function != NULL)
Packit 6c4009
    return config->test_function ();
Packit 6c4009
  else if (config->test_function_argv != NULL)
Packit 6c4009
    return config->test_function_argv (argc, argv);
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      printf ("error: no test function defined\n");
Packit 6c4009
      exit (1);
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static bool test_main_called;
Packit 6c4009
Packit 6c4009
const char *test_dir = NULL;
Packit 6c4009
unsigned int test_verbose = 0;
Packit 6c4009
Packit 6c4009
/* If test failure reporting has been linked in, it may contribute
Packit 6c4009
   additional test failures.  */
Packit 6c4009
static int
Packit 6c4009
adjust_exit_status (int status)
Packit 6c4009
{
Packit 6c4009
  if (support_report_failure != NULL)
Packit 6c4009
    return support_report_failure (status);
Packit 6c4009
  return status;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
support_test_main (int argc, char **argv, const struct test_config *config)
Packit 6c4009
{
Packit 6c4009
  if (test_main_called)
Packit 6c4009
    {
Packit 6c4009
      printf ("error: test_main called for a second time\n");
Packit 6c4009
      exit (1);
Packit 6c4009
    }
Packit 6c4009
  test_main_called = true;
Packit 6c4009
  const struct option *options;
Packit 6c4009
  if (config->options != NULL)
Packit 6c4009
    options = config->options;
Packit 6c4009
  else
Packit 6c4009
    options = default_options;
Packit 6c4009
Packit 6c4009
  cleanup_function = config->cleanup_function;
Packit 6c4009
Packit 6c4009
  int direct = 0;       /* Directly call the test function?  */
Packit 6c4009
  int status;
Packit 6c4009
  int opt;
Packit 6c4009
  unsigned int timeoutfactor = 1;
Packit 6c4009
  pid_t termpid;
Packit 6c4009
Packit Service 94fa28
  /* If we're debugging the test, we need to disable timeouts and use
Packit Service 94fa28
     the initial pid (esp if we're running inside a container).  */
Packit Service 94fa28
  if (getenv("WAIT_FOR_DEBUGGER") != NULL)
Packit Service 94fa28
    direct = 1;
Packit Service 94fa28
Packit 6c4009
  if (!config->no_mallopt)
Packit 6c4009
    {
Packit 6c4009
      /* Make uses of freed and uninitialized memory known.  Do not
Packit 6c4009
         pull in a definition for mallopt if it has not been defined
Packit 6c4009
         already.  */
Packit 6c4009
      extern __typeof__ (mallopt) mallopt __attribute__ ((weak));
Packit 6c4009
      if (mallopt != NULL)
Packit 6c4009
        mallopt (M_PERTURB, 42);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  while ((opt = getopt_long (argc, argv, config->optstring, options, NULL))
Packit 6c4009
	 != -1)
Packit 6c4009
    switch (opt)
Packit 6c4009
      {
Packit 6c4009
      case '?':
Packit 6c4009
        usage (options);
Packit 6c4009
        exit (1);
Packit 6c4009
      case 'v':
Packit 6c4009
        ++test_verbose;
Packit 6c4009
        break;
Packit 6c4009
      case OPT_DIRECT:
Packit 6c4009
        direct = 1;
Packit 6c4009
        break;
Packit 6c4009
      case OPT_TESTDIR:
Packit 6c4009
        test_dir = optarg;
Packit 6c4009
        break;
Packit 6c4009
      default:
Packit 6c4009
        if (config->cmdline_function != NULL)
Packit 6c4009
          config->cmdline_function (opt);
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
  /* If set, read the test TIMEOUTFACTOR value from the environment.
Packit 6c4009
     This value is used to scale the default test timeout values. */
Packit 6c4009
  char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
Packit 6c4009
  if (envstr_timeoutfactor != NULL)
Packit 6c4009
    {
Packit 6c4009
      char *envstr_conv = envstr_timeoutfactor;
Packit 6c4009
      unsigned long int env_fact;
Packit 6c4009
Packit 6c4009
      env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
Packit 6c4009
      if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
Packit 6c4009
        timeoutfactor = MAX (env_fact, 1);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Set TMPDIR to specified test directory.  */
Packit 6c4009
  if (test_dir != NULL)
Packit 6c4009
    {
Packit 6c4009
      setenv ("TMPDIR", test_dir, 1);
Packit 6c4009
Packit 6c4009
      if (chdir (test_dir) < 0)
Packit 6c4009
        {
Packit 6c4009
          printf ("chdir: %m\n");
Packit 6c4009
          exit (1);
Packit 6c4009
        }
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      test_dir = getenv ("TMPDIR");
Packit 6c4009
      if (test_dir == NULL || test_dir[0] == '\0')
Packit 6c4009
        test_dir = "/tmp";
Packit 6c4009
    }
Packit 6c4009
  if (support_set_test_dir != NULL)
Packit 6c4009
    support_set_test_dir (test_dir);
Packit 6c4009
Packit 6c4009
  int timeout = config->timeout;
Packit 6c4009
  if (timeout == 0)
Packit 6c4009
    timeout =  DEFAULT_TIMEOUT;
Packit 6c4009
Packit 6c4009
  /* Make sure we see all message, even those on stdout.  */
Packit 6c4009
  if (!config->no_setvbuf)
Packit 6c4009
    setvbuf (stdout, NULL, _IONBF, 0);
Packit 6c4009
Packit 6c4009
  /* Make sure temporary files are deleted.  */
Packit 6c4009
  if (support_delete_temp_files != NULL)
Packit 6c4009
      atexit (support_delete_temp_files);
Packit 6c4009
Packit 6c4009
  /* Correct for the possible parameters.  */
Packit 6c4009
  argv[optind - 1] = argv[0];
Packit 6c4009
  argv += optind - 1;
Packit 6c4009
  argc -= optind - 1;
Packit 6c4009
Packit 6c4009
  /* Call the initializing function, if one is available.  */
Packit 6c4009
  if (config->prepare_function != NULL)
Packit 6c4009
    config->prepare_function (argc, argv);
Packit 6c4009
Packit 6c4009
  const char *envstr_direct = getenv ("TEST_DIRECT");
Packit 6c4009
  if (envstr_direct != NULL)
Packit 6c4009
    {
Packit 6c4009
      FILE *f = fopen (envstr_direct, "w");
Packit 6c4009
      if (f == NULL)
Packit 6c4009
        {
Packit 6c4009
          printf ("cannot open TEST_DIRECT output file '%s': %m\n",
Packit 6c4009
                  envstr_direct);
Packit 6c4009
          exit (1);
Packit 6c4009
        }
Packit 6c4009
Packit 6c4009
      fprintf (f, "timeout=%u\ntimeoutfactor=%u\n",
Packit 6c4009
               config->timeout, timeoutfactor);
Packit 6c4009
      if (config->expected_status != 0)
Packit 6c4009
        fprintf (f, "exit=%u\n", config->expected_status);
Packit 6c4009
      if (config->expected_signal != 0)
Packit 6c4009
        fprintf (f, "signal=%s\n", strsignal (config->expected_signal));
Packit 6c4009
Packit 6c4009
      if (support_print_temp_files != NULL)
Packit 6c4009
        support_print_temp_files (f);
Packit 6c4009
Packit 6c4009
      fclose (f);
Packit 6c4009
      direct = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  bool disable_coredumps;
Packit 6c4009
  {
Packit 6c4009
    const char *coredumps = getenv ("TEST_COREDUMPS");
Packit 6c4009
    disable_coredumps = coredumps == NULL || coredumps[0] == '\0';
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  /* If we are not expected to fork run the function immediately.  */
Packit 6c4009
  if (direct)
Packit 6c4009
    return adjust_exit_status (run_test_function (argc, argv, config));
Packit 6c4009
Packit 6c4009
  /* Set up the test environment:
Packit 6c4009
     - prevent core dumps
Packit 6c4009
     - set up the timer
Packit 6c4009
     - fork and execute the function.  */
Packit 6c4009
Packit 6c4009
  test_pid = fork ();
Packit 6c4009
  if (test_pid == 0)
Packit 6c4009
    {
Packit 6c4009
      /* This is the child.  */
Packit 6c4009
      if (disable_coredumps)
Packit 6c4009
        {
Packit 6c4009
          /* Try to avoid dumping core.  This is necessary because we
Packit 6c4009
             run the test from the source tree, and the coredumps
Packit 6c4009
             would end up there (and not in the build tree).  */
Packit 6c4009
          struct rlimit core_limit;
Packit 6c4009
          core_limit.rlim_cur = 0;
Packit 6c4009
          core_limit.rlim_max = 0;
Packit 6c4009
          setrlimit (RLIMIT_CORE, &core_limit);
Packit 6c4009
        }
Packit 6c4009
Packit 6c4009
      /* We put the test process in its own pgrp so that if it bogusly
Packit 6c4009
         generates any job control signals, they won't hit the whole build.  */
Packit 6c4009
      if (setpgid (0, 0) != 0)
Packit 6c4009
        printf ("Failed to set the process group ID: %m\n");
Packit 6c4009
Packit 6c4009
      /* Execute the test function and exit with the return value.   */
Packit 6c4009
      exit (run_test_function (argc, argv, config));
Packit 6c4009
    }
Packit 6c4009
  else if (test_pid < 0)
Packit 6c4009
    {
Packit 6c4009
      printf ("Cannot fork test program: %m\n");
Packit 6c4009
      exit (1);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Set timeout.  */
Packit 6c4009
  signal (SIGALRM, signal_handler);
Packit 6c4009
  alarm (timeout * timeoutfactor);
Packit 6c4009
Packit 6c4009
  /* Make sure we clean up if the wrapper gets interrupted.  */
Packit 6c4009
  signal (SIGINT, signal_handler);
Packit 6c4009
Packit 6c4009
  /* Wait for the regular termination.  */
Packit 6c4009
  termpid = TEMP_FAILURE_RETRY (waitpid (test_pid, &status, 0));
Packit 6c4009
  if (termpid == -1)
Packit 6c4009
    {
Packit 6c4009
      printf ("Waiting for test program failed: %m\n");
Packit 6c4009
      exit (1);
Packit 6c4009
    }
Packit 6c4009
  if (termpid != test_pid)
Packit 6c4009
    {
Packit 6c4009
      printf ("Oops, wrong test program terminated: expected %ld, got %ld\n",
Packit 6c4009
              (long int) test_pid, (long int) termpid);
Packit 6c4009
      exit (1);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Process terminated normaly without timeout etc.  */
Packit 6c4009
  if (WIFEXITED (status))
Packit 6c4009
    {
Packit 6c4009
      if (config->expected_status == 0)
Packit 6c4009
        {
Packit 6c4009
          if (config->expected_signal == 0)
Packit 6c4009
            /* Exit with the return value of the test.  */
Packit 6c4009
            return adjust_exit_status (WEXITSTATUS (status));
Packit 6c4009
          else
Packit 6c4009
            {
Packit 6c4009
              printf ("Expected signal '%s' from child, got none\n",
Packit 6c4009
                      strsignal (config->expected_signal));
Packit 6c4009
              exit (1);
Packit 6c4009
            }
Packit 6c4009
        }
Packit 6c4009
      else
Packit 6c4009
        {
Packit 6c4009
          /* Non-zero exit status is expected */
Packit 6c4009
          if (WEXITSTATUS (status) != config->expected_status)
Packit 6c4009
            {
Packit 6c4009
              printf ("Expected status %d, got %d\n",
Packit 6c4009
                      config->expected_status, WEXITSTATUS (status));
Packit 6c4009
              exit (1);
Packit 6c4009
            }
Packit 6c4009
        }
Packit 6c4009
      return adjust_exit_status (0);
Packit 6c4009
    }
Packit 6c4009
  /* Process was killed by timer or other signal.  */
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      if (config->expected_signal == 0)
Packit 6c4009
        {
Packit 6c4009
          printf ("Didn't expect signal from child: got `%s'\n",
Packit 6c4009
                  strsignal (WTERMSIG (status)));
Packit 6c4009
          exit (1);
Packit 6c4009
        }
Packit 6c4009
      else if (WTERMSIG (status) != config->expected_signal)
Packit 6c4009
        {
Packit 6c4009
          printf ("Incorrect signal from child: got `%s', need `%s'\n",
Packit 6c4009
                  strsignal (WTERMSIG (status)),
Packit 6c4009
                  strsignal (config->expected_signal));
Packit 6c4009
          exit (1);
Packit 6c4009
        }
Packit 6c4009
Packit 6c4009
      return adjust_exit_status (0);
Packit 6c4009
    }
Packit 6c4009
}