X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=test-skeleton.c;h=9ad7585f1abeafb52479a39ef4f836a8bfcdf434;hb=ac64195ccd4f320659fd0058bc7524c6fd0b37b4;hp=0238db6b4dbe367ae3a42f9c14e05b08a1e4ffc6;hpb=85fda49b9674152ca54d49e0028f981566f2554d;p=thirdparty%2Fglibc.git diff --git a/test-skeleton.c b/test-skeleton.c index 0238db6b4db..9ad7585f1ab 100644 --- a/test-skeleton.c +++ b/test-skeleton.c @@ -1,5 +1,5 @@ -/* Skeleton for test programs. - Copyright (C) 1998,2000-2004, 2005, 2009 Free Software Foundation, Inc. +/* Legacy test skeleton. + Copyright (C) 1998-2019 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -14,13 +14,22 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + . */ +/* This test skeleton is to support running existing tests. New tests + should use instead; see the documentation + in that file for instructions, and for a + minimal example. */ + +/* This list of headers is needed so that tests which include + "../test-skeleton.c" at the beginning still compile. */ +#include #include +#include #include #include +#include #include #include #include @@ -31,361 +40,69 @@ #include #include #include +#include -/* The test function is normally called `do_test' and it is called - with argc and argv as the arguments. We nevertheless provide the - possibility to overwrite this name. */ -#ifndef TEST_FUNCTION -# define TEST_FUNCTION do_test (argc, argv) -#endif - -#ifndef TEST_DATA_LIMIT -# define TEST_DATA_LIMIT (64 << 20) /* Data limit (bytes) to run with. */ -#endif +#include +#include +#include +#include -#define OPT_DIRECT 1000 -#define OPT_TESTDIR 1001 - -static struct option options[] = +/* TEST_FUNCTION is no longer used. */ +static int +legacy_test_function (int argc __attribute__ ((unused)), + char **argv __attribute__ ((unused))) { -#ifdef CMDLINE_OPTIONS - CMDLINE_OPTIONS +#ifdef TEST_FUNCTION + return TEST_FUNCTION; +# undef TEST_FUNCTION +#else + return do_test (argc, argv); #endif - { "direct", no_argument, NULL, OPT_DIRECT }, - { "test-dir", required_argument, NULL, OPT_TESTDIR }, - { NULL, 0, NULL, 0 } -}; - -/* PID of the test itself. */ -static pid_t pid; - -/* Directory to place temporary files in. */ -static const char *test_dir; - -/* List of temporary files. */ -struct temp_name_list -{ - struct qelem q; - const char *name; -} *temp_name_list; - -/* Add temporary files in list. */ -static void -__attribute__ ((unused)) -add_temp_file (const char *name) -{ - struct temp_name_list *newp - = (struct temp_name_list *) calloc (sizeof (*newp), 1); - if (newp != NULL) - { - newp->name = name; - if (temp_name_list == NULL) - temp_name_list = (struct temp_name_list *) &newp->q; - else - insque (newp, temp_name_list); - } } +#define TEST_FUNCTION_ARGV legacy_test_function -/* Delete all temporary files. */ +/* PREPARE is a function name in the new skeleton. */ +#ifdef PREPARE static void -delete_temp_files (void) +legacy_prepare_function (int argc __attribute__ ((unused)), + char **argv __attribute__ ((unused))) { - while (temp_name_list != NULL) - { - remove (temp_name_list->name); - temp_name_list = (struct temp_name_list *) temp_name_list->q.q_forw; - } -} - -/* Create a temporary file. */ -static int -__attribute__ ((unused)) -create_temp_file (const char *base, char **filename) -{ - char *fname; - int fd; - - fname = (char *) malloc (strlen (test_dir) + 1 + strlen (base) - + sizeof ("XXXXXX")); - if (fname == NULL) - { - puts ("out of memory"); - return -1; - } - strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX"); - - fd = mkstemp (fname); - if (fd == -1) - { - printf ("cannot open temporary file '%s': %m\n", fname); - free (fname); - return -1; - } - - add_temp_file (fname); - if (filename != NULL) - *filename = fname; - - return fd; + PREPARE (argc, argv); } +# undef PREPARE +# define PREPARE legacy_prepare_function +#endif -/* Timeout handler. We kill the child and exit with an error. */ +/* CLEANUP_HANDLER is a function name in the new skeleton. */ +#ifdef CLEANUP_HANDLER static void -__attribute__ ((noreturn)) -signal_handler (int sig __attribute__ ((unused))) +legacy_cleanup_handler_function (void) { - int killed; - int status; - - /* Send signal. */ - kill (pid, SIGKILL); - - /* Wait for it to terminate. */ - int i; - for (i = 0; i < 5; ++i) - { - killed = waitpid (pid, &status, WNOHANG|WUNTRACED); - if (killed != 0) - break; - - /* Delay, give the system time to process the kill. If the - nanosleep() call return prematurely, all the better. We - won't restart it since this probably means the child process - finally died. */ - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 100000000; - nanosleep (&ts, NULL); - } - if (killed != 0 && killed != pid) - { - perror ("Failed to kill test process"); - exit (1); - } - -#ifdef CLEANUP_HANDLER CLEANUP_HANDLER; -#endif - - if (sig == SIGINT) - { - signal (sig, SIG_DFL); - raise (sig); - } - - /* If we expected this signal: good! */ -#ifdef EXPECTED_SIGNAL - if (EXPECTED_SIGNAL == SIGALRM) - exit (0); -#endif - - if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL)) - fputs ("Timed out: killed the child process\n", stderr); - else if (WIFSTOPPED (status)) - fprintf (stderr, "Timed out: the child process was %s\n", - strsignal (WSTOPSIG (status))); - else if (WIFSIGNALED (status)) - fprintf (stderr, "Timed out: the child process got signal %s\n", - strsignal (WTERMSIG (status))); - else - fprintf (stderr, "Timed out: killed the child process but it exited %d\n", - WEXITSTATUS (status)); - - /* Exit with an error. */ - exit (1); } - -/* We provide the entry point here. */ -int -main (int argc, char *argv[]) -{ - int direct = 0; /* Directly call the test function? */ - int status; - int opt; - unsigned int timeoutfactor = 1; - pid_t termpid; - - /* Make uses of freed and uninitialized memory known. */ - mallopt (M_PERTURB, 42); - -#ifdef STDOUT_UNBUFFERED - setbuf (stdout, NULL); +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER legacy_cleanup_handler_function #endif - while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1) - switch (opt) - { - case '?': - exit (1); - case OPT_DIRECT: - direct = 1; - break; - case OPT_TESTDIR: - test_dir = optarg; - break; +/* CMDLINE_PROCESS is a function name in the new skeleton. */ #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) - { - perror ("chdir"); - 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 - - /* 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 - -#ifdef RLIMIT_DATA - /* Try to avoid eating all memory if a test leaks. */ - struct rlimit data_limit; - if (getrlimit (RLIMIT_DATA, &data_limit) == 0) - { - if (TEST_DATA_LIMIT == RLIM_INFINITY) - data_limit.rlim_cur = data_limit.rlim_max; - else if (data_limit.rlim_cur > (rlim_t) TEST_DATA_LIMIT) - data_limit.rlim_cur = MIN ((rlim_t) TEST_DATA_LIMIT, - data_limit.rlim_max); - if (setrlimit (RLIMIT_DATA, &data_limit) < 0) - perror ("setrlimit: RLIMIT_DATA"); - } - else - perror ("getrlimit: RLIMIT_DATA"); -#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. */ - setpgid (0, 0); - - /* Execute the test function and exit with the return value. */ - exit (TEST_FUNCTION); - } - else if (pid < 0) - { - perror ("Cannot fork test program"); - exit (1); - } - - /* Set timeout. */ -#ifndef TIMEOUT - /* Default timeout is two seconds. */ -# define TIMEOUT 2 -#endif - 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) +static void +legacy_cmdline_process_function (int c) +{ + switch (c) { - printf ("Oops, wrong test program terminated: expected %ld, got %ld\n", - (long int) pid, (long int) termpid); - exit (1); + CMDLINE_PROCESS } - -#ifndef EXPECTED_SIGNAL - /* We don't expect any signal. */ -# define EXPECTED_SIGNAL 0 +} +# undef CMDLINE_PROCESS +# define CMDLINE_PROCESS legacy_cmdline_process_function #endif - if (WTERMSIG (status) != EXPECTED_SIGNAL) - { - if (EXPECTED_SIGNAL != 0) - { - if (WTERMSIG (status) == 0) - fprintf (stderr, - "Expected signal '%s' from child, got none\n", - strsignal (EXPECTED_SIGNAL)); - else - fprintf (stderr, - "Incorrect signal from child: got `%s', need `%s'\n", - strsignal (WTERMSIG (status)), - strsignal (EXPECTED_SIGNAL)); - } - else - fprintf (stderr, "Didn't expect signal from child: got `%s'\n", - strsignal (WTERMSIG (status))); - exit (1); - } - /* Simply exit with the return value of the test. */ -#ifndef EXPECTED_STATUS - return WEXITSTATUS (status); -#else - if (WEXITSTATUS (status) != EXPECTED_STATUS) - { - fprintf (stderr, "Expected status %d, got %d\n", - EXPECTED_STATUS, WEXITSTATUS (status)); - exit (1); - } +/* Include the new test-skeleton. */ +#include - return 0; -#endif -} +/* The following functionality is only available if was + included before this file. */ +#ifdef _PTHREAD_H +# include +#endif /* _PTHREAD_H */