-#ifdef STDOUT_UNBUFFERED
- setbuf (stdout, NULL);
-#endif
-
- while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
- switch (opt)
- {
- case '?':
- usage ();
- exit (1);
- case OPT_DIRECT:
- direct = 1;
- break;
- case OPT_TESTDIR:
- test_dir = optarg;
- break;
-#ifdef CMDLINE_PROCESS
- CMDLINE_PROCESS
-#endif
- }
-
- /* If set, read the test TIMEOUTFACTOR value from the environment.
- This value is used to scale the default test timeout values. */
- char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
- if (envstr_timeoutfactor != NULL)
- {
- char *envstr_conv = envstr_timeoutfactor;
- unsigned long int env_fact;
-
- env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
- if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
- timeoutfactor = MAX (env_fact, 1);
- }
-
- /* Set TMPDIR to specified test directory. */
- if (test_dir != NULL)
- {
- setenv ("TMPDIR", test_dir, 1);
-
- if (chdir (test_dir) < 0)
- {
- printf ("chdir: %m\n");
- exit (1);
- }
- }
- else
- {
- test_dir = getenv ("TMPDIR");
- if (test_dir == NULL || test_dir[0] == '\0')
- test_dir = "/tmp";
- }
-
- /* Make sure we see all message, even those on stdout. */
- setvbuf (stdout, NULL, _IONBF, 0);
-
- /* Make sure temporary files are deleted. */
- atexit (delete_temp_files);
-
- /* Correct for the possible parameters. */
- argv[optind - 1] = argv[0];
- argv += optind - 1;
- argc -= optind - 1;
-
- /* Call the initializing function, if one is available. */
-#ifdef PREPARE
- PREPARE (argc, argv);
-#endif
-
- const char *envstr_direct = getenv ("TEST_DIRECT");
- if (envstr_direct != NULL)
- {
- FILE *f = fopen (envstr_direct, "w");
- if (f == NULL)
- {
- printf ("cannot open TEST_DIRECT output file '%s': %m\n",
- envstr_direct);
- exit (1);
- }
-
- fprintf (f, "timeout=%u\ntimeoutfactor=%u\n", TIMEOUT, timeoutfactor);
-#ifdef EXPECTED_STATUS
- fprintf (f, "exit=%u\n", EXPECTED_STATUS);
-#endif
-#ifdef EXPECTED_SIGNAL
- switch (EXPECTED_SIGNAL)
- {
- default: abort ();
-# define init_sig(signo, name, text) \
- case signo: fprintf (f, "signal=%s\n", name); break;
-# include <siglist.h>
-# undef init_sig
- }
-#endif
-
- if (temp_name_list != NULL)
- {
- struct temp_name_list *n;
- fprintf (f, "temp_files=(\n");
- for (n = temp_name_list;
- n != NULL;
- n = (struct temp_name_list *) n->q.q_forw)
- fprintf (f, " '%s'\n", n->name);
- fprintf (f, ")\n");
- }
-
- fclose (f);
- direct = 1;
- }
-
- /* If we are not expected to fork run the function immediately. */
- if (direct)
- return TEST_FUNCTION;
-
- /* Set up the test environment:
- - prevent core dumps
- - set up the timer
- - fork and execute the function. */
-
- pid = fork ();
- if (pid == 0)
- {
- /* This is the child. */
-#ifdef RLIMIT_CORE
- /* Try to avoid dumping core. */
- struct rlimit core_limit;
- core_limit.rlim_cur = 0;
- core_limit.rlim_max = 0;
- setrlimit (RLIMIT_CORE, &core_limit);
-#endif
-
- /* We put the test process in its own pgrp so that if it bogusly
- generates any job control signals, they won't hit the whole build. */
- if (setpgid (0, 0) != 0)
- printf ("Failed to set the process group ID: %m\n");
-
- /* Execute the test function and exit with the return value. */
- exit (TEST_FUNCTION);
- }
- else if (pid < 0)
- {
- printf ("Cannot fork test program: %m\n");
- exit (1);
- }
-
- /* Set timeout. */
- signal (SIGALRM, signal_handler);
- alarm (TIMEOUT * timeoutfactor);
-
- /* Make sure we clean up if the wrapper gets interrupted. */
- signal (SIGINT, signal_handler);
-
- /* Wait for the regular termination. */
- termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
- if (termpid == -1)
- {
- printf ("Waiting for test program failed: %m\n");
- exit (1);
- }
- if (termpid != pid)
- {
- printf ("Oops, wrong test program terminated: expected %ld, got %ld\n",
- (long int) pid, (long int) termpid);
- exit (1);
- }
-
- /* Process terminated normaly without timeout etc. */
- if (WIFEXITED (status))
- {
-#ifndef EXPECTED_STATUS
-# ifndef EXPECTED_SIGNAL
- /* Simply exit with the return value of the test. */
- return WEXITSTATUS (status);
-# else
- printf ("Expected signal '%s' from child, got none\n",
- strsignal (EXPECTED_SIGNAL));
- exit (1);
-# endif
-#else
- if (WEXITSTATUS (status) != EXPECTED_STATUS)
- {
- printf ("Expected status %d, got %d\n",
- EXPECTED_STATUS, WEXITSTATUS (status));
- exit (1);
- }
-
- return 0;
-#endif
- }
- /* Process was killed by timer or other signal. */
- else
- {
-#ifndef EXPECTED_SIGNAL
- printf ("Didn't expect signal from child: got `%s'\n",
- strsignal (WTERMSIG (status)));
- exit (1);
-#else
- if (WTERMSIG (status) != EXPECTED_SIGNAL)
- {
- printf ("Incorrect signal from child: got `%s', need `%s'\n",
- strsignal (WTERMSIG (status)),
- strsignal (EXPECTED_SIGNAL));
- exit (1);
- }
-
- return 0;
-#endif
- }
-}