ia64: sifaction.h: change sa_flags to an int
[glibc.git] / test-skeleton.c
blob9ee5001440b12805d22a8eb262c7651345a6c1f5
1 /* Skeleton for test programs.
2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
20 #include <assert.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <getopt.h>
24 #include <malloc.h>
25 #include <paths.h>
26 #include <search.h>
27 #include <signal.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <sys/resource.h>
33 #include <sys/wait.h>
34 #include <sys/param.h>
35 #include <time.h>
37 /* The test function is normally called `do_test' and it is called
38 with argc and argv as the arguments. We nevertheless provide the
39 possibility to overwrite this name. */
40 #ifndef TEST_FUNCTION
41 # define TEST_FUNCTION do_test (argc, argv)
42 #endif
44 #ifndef TEST_DATA_LIMIT
45 # define TEST_DATA_LIMIT (64 << 20) /* Data limit (bytes) to run with. */
46 #endif
48 #ifndef TIMEOUT
49 /* Default timeout is two seconds. */
50 # define TIMEOUT 2
51 #endif
53 #define OPT_DIRECT 1000
54 #define OPT_TESTDIR 1001
56 static struct option options[] =
58 #ifdef CMDLINE_OPTIONS
59 CMDLINE_OPTIONS
60 #endif
61 { "direct", no_argument, NULL, OPT_DIRECT },
62 { "test-dir", required_argument, NULL, OPT_TESTDIR },
63 { NULL, 0, NULL, 0 }
66 /* PID of the test itself. */
67 static pid_t pid;
69 /* Directory to place temporary files in. */
70 static const char *test_dir;
72 /* List of temporary files. */
73 struct temp_name_list
75 struct qelem q;
76 char *name;
77 } *temp_name_list;
79 /* Add temporary files in list. */
80 static void
81 __attribute__ ((unused))
82 add_temp_file (const char *name)
84 struct temp_name_list *newp
85 = (struct temp_name_list *) calloc (sizeof (*newp), 1);
86 char *newname = strdup (name);
87 if (newp != NULL && newname != NULL)
89 newp->name = newname;
90 if (temp_name_list == NULL)
91 temp_name_list = (struct temp_name_list *) &newp->q;
92 else
93 insque (newp, temp_name_list);
95 else
96 free (newp);
99 /* Delete all temporary files. */
100 static void
101 delete_temp_files (void)
103 while (temp_name_list != NULL)
105 remove (temp_name_list->name);
106 free (temp_name_list->name);
108 struct temp_name_list *next
109 = (struct temp_name_list *) temp_name_list->q.q_forw;
110 free (temp_name_list);
111 temp_name_list = next;
115 /* Create a temporary file. Return the opened file descriptor on
116 success, or -1 on failure. Write the file name to *FILENAME if
117 FILENAME is not NULL. In this case, the caller is expected to free
118 *FILENAME. */
119 static int
120 __attribute__ ((unused))
121 create_temp_file (const char *base, char **filename)
123 char *fname;
124 int fd;
126 fname = (char *) malloc (strlen (test_dir) + 1 + strlen (base)
127 + sizeof ("XXXXXX"));
128 if (fname == NULL)
130 puts ("out of memory");
131 return -1;
133 strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
135 fd = mkstemp (fname);
136 if (fd == -1)
138 printf ("cannot open temporary file '%s': %m\n", fname);
139 free (fname);
140 return -1;
143 add_temp_file (fname);
144 if (filename != NULL)
145 *filename = fname;
146 else
147 free (fname);
149 return fd;
152 /* Timeout handler. We kill the child and exit with an error. */
153 static void
154 __attribute__ ((noreturn))
155 signal_handler (int sig __attribute__ ((unused)))
157 int killed;
158 int status;
160 assert (pid > 1);
161 /* Kill the whole process group. */
162 kill (-pid, SIGKILL);
163 /* In case setpgid failed in the child, kill it individually too. */
164 kill (pid, SIGKILL);
166 /* Wait for it to terminate. */
167 int i;
168 for (i = 0; i < 5; ++i)
170 killed = waitpid (pid, &status, WNOHANG|WUNTRACED);
171 if (killed != 0)
172 break;
174 /* Delay, give the system time to process the kill. If the
175 nanosleep() call return prematurely, all the better. We
176 won't restart it since this probably means the child process
177 finally died. */
178 struct timespec ts;
179 ts.tv_sec = 0;
180 ts.tv_nsec = 100000000;
181 nanosleep (&ts, NULL);
183 if (killed != 0 && killed != pid)
185 printf ("Failed to kill test process: %m\n");
186 exit (1);
189 #ifdef CLEANUP_HANDLER
190 CLEANUP_HANDLER;
191 #endif
193 if (sig == SIGINT)
195 signal (sig, SIG_DFL);
196 raise (sig);
199 /* If we expected this signal: good! */
200 #ifdef EXPECTED_SIGNAL
201 if (EXPECTED_SIGNAL == SIGALRM)
202 exit (0);
203 #endif
205 if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL))
206 puts ("Timed out: killed the child process");
207 else if (WIFSTOPPED (status))
208 printf ("Timed out: the child process was %s\n",
209 strsignal (WSTOPSIG (status)));
210 else if (WIFSIGNALED (status))
211 printf ("Timed out: the child process got signal %s\n",
212 strsignal (WTERMSIG (status)));
213 else
214 printf ("Timed out: killed the child process but it exited %d\n",
215 WEXITSTATUS (status));
217 /* Exit with an error. */
218 exit (1);
221 /* Avoid all the buffer overflow messages on stderr. */
222 static void
223 __attribute__ ((unused))
224 ignore_stderr (void)
226 int fd = open (_PATH_DEVNULL, O_WRONLY);
227 if (fd == -1)
228 close (STDERR_FILENO);
229 else
231 dup2 (fd, STDERR_FILENO);
232 close (fd);
234 setenv ("LIBC_FATAL_STDERR_", "1", 1);
237 /* Set fortification error handler. Used when tests want to verify that bad
238 code is caught by the library. */
239 static void
240 __attribute__ ((unused))
241 set_fortify_handler (void (*handler) (int sig))
243 struct sigaction sa;
245 sa.sa_handler = handler;
246 sa.sa_flags = 0;
247 sigemptyset (&sa.sa_mask);
249 sigaction (SIGABRT, &sa, NULL);
250 ignore_stderr ();
253 /* We provide the entry point here. */
255 main (int argc, char *argv[])
257 int direct = 0; /* Directly call the test function? */
258 int status;
259 int opt;
260 unsigned int timeoutfactor = 1;
261 pid_t termpid;
263 /* Make uses of freed and uninitialized memory known. */
264 mallopt (M_PERTURB, 42);
266 #ifdef STDOUT_UNBUFFERED
267 setbuf (stdout, NULL);
268 #endif
270 while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
271 switch (opt)
273 case '?':
274 exit (1);
275 case OPT_DIRECT:
276 direct = 1;
277 break;
278 case OPT_TESTDIR:
279 test_dir = optarg;
280 break;
281 #ifdef CMDLINE_PROCESS
282 CMDLINE_PROCESS
283 #endif
286 /* If set, read the test TIMEOUTFACTOR value from the environment.
287 This value is used to scale the default test timeout values. */
288 char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
289 if (envstr_timeoutfactor != NULL)
291 char *envstr_conv = envstr_timeoutfactor;
292 unsigned long int env_fact;
294 env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
295 if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
296 timeoutfactor = MAX (env_fact, 1);
299 /* Set TMPDIR to specified test directory. */
300 if (test_dir != NULL)
302 setenv ("TMPDIR", test_dir, 1);
304 if (chdir (test_dir) < 0)
306 printf ("chdir: %m\n");
307 exit (1);
310 else
312 test_dir = getenv ("TMPDIR");
313 if (test_dir == NULL || test_dir[0] == '\0')
314 test_dir = "/tmp";
317 /* Make sure we see all message, even those on stdout. */
318 setvbuf (stdout, NULL, _IONBF, 0);
320 /* Make sure temporary files are deleted. */
321 atexit (delete_temp_files);
323 /* Correct for the possible parameters. */
324 argv[optind - 1] = argv[0];
325 argv += optind - 1;
326 argc -= optind - 1;
328 /* Call the initializing function, if one is available. */
329 #ifdef PREPARE
330 PREPARE (argc, argv);
331 #endif
333 const char *envstr_direct = getenv ("TEST_DIRECT");
334 if (envstr_direct != NULL)
336 FILE *f = fopen (envstr_direct, "w");
337 if (f == NULL)
339 printf ("cannot open TEST_DIRECT output file '%s': %m\n",
340 envstr_direct);
341 exit (1);
344 fprintf (f, "timeout=%u\ntimeoutfactor=%u\n", TIMEOUT, timeoutfactor);
345 #ifdef EXPECTED_STATUS
346 fprintf (f, "exit=%u\n", EXPECTED_STATUS);
347 #endif
348 #ifdef EXPECTED_SIGNAL
349 switch (EXPECTED_SIGNAL)
351 default: abort ();
352 # define init_sig(signo, name, text) \
353 case signo: fprintf (f, "signal=%s\n", name); break;
354 # include <siglist.h>
355 # undef init_sig
357 #endif
359 if (temp_name_list != NULL)
361 struct temp_name_list *n;
362 fprintf (f, "temp_files=(\n");
363 for (n = temp_name_list;
364 n != NULL;
365 n = (struct temp_name_list *) n->q.q_forw)
366 fprintf (f, " '%s'\n", n->name);
367 fprintf (f, ")\n");
370 fclose (f);
371 direct = 1;
374 /* If we are not expected to fork run the function immediately. */
375 if (direct)
376 return TEST_FUNCTION;
378 /* Set up the test environment:
379 - prevent core dumps
380 - set up the timer
381 - fork and execute the function. */
383 pid = fork ();
384 if (pid == 0)
386 /* This is the child. */
387 #ifdef RLIMIT_CORE
388 /* Try to avoid dumping core. */
389 struct rlimit core_limit;
390 core_limit.rlim_cur = 0;
391 core_limit.rlim_max = 0;
392 setrlimit (RLIMIT_CORE, &core_limit);
393 #endif
395 #ifdef RLIMIT_DATA
396 /* Try to avoid eating all memory if a test leaks. */
397 struct rlimit data_limit;
398 if (getrlimit (RLIMIT_DATA, &data_limit) == 0)
400 if (TEST_DATA_LIMIT == RLIM_INFINITY)
401 data_limit.rlim_cur = data_limit.rlim_max;
402 else if (data_limit.rlim_cur > (rlim_t) TEST_DATA_LIMIT)
403 data_limit.rlim_cur = MIN ((rlim_t) TEST_DATA_LIMIT,
404 data_limit.rlim_max);
405 if (setrlimit (RLIMIT_DATA, &data_limit) < 0)
406 printf ("setrlimit: RLIMIT_DATA: %m\n");
408 else
409 printf ("getrlimit: RLIMIT_DATA: %m\n");
410 #endif
412 /* We put the test process in its own pgrp so that if it bogusly
413 generates any job control signals, they won't hit the whole build. */
414 if (setpgid (0, 0) != 0)
415 printf ("Failed to set the process group ID: %m\n");
417 /* Execute the test function and exit with the return value. */
418 exit (TEST_FUNCTION);
420 else if (pid < 0)
422 printf ("Cannot fork test program: %m\n");
423 exit (1);
426 /* Set timeout. */
427 signal (SIGALRM, signal_handler);
428 alarm (TIMEOUT * timeoutfactor);
430 /* Make sure we clean up if the wrapper gets interrupted. */
431 signal (SIGINT, signal_handler);
433 /* Wait for the regular termination. */
434 termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
435 if (termpid == -1)
437 printf ("Waiting for test program failed: %m\n");
438 exit (1);
440 if (termpid != pid)
442 printf ("Oops, wrong test program terminated: expected %ld, got %ld\n",
443 (long int) pid, (long int) termpid);
444 exit (1);
447 /* Process terminated normaly without timeout etc. */
448 if (WIFEXITED (status))
450 #ifndef EXPECTED_STATUS
451 # ifndef EXPECTED_SIGNAL
452 /* Simply exit with the return value of the test. */
453 return WEXITSTATUS (status);
454 # else
455 printf ("Expected signal '%s' from child, got none\n",
456 strsignal (EXPECTED_SIGNAL));
457 exit (1);
458 # endif
459 #else
460 if (WEXITSTATUS (status) != EXPECTED_STATUS)
462 printf ("Expected status %d, got %d\n",
463 EXPECTED_STATUS, WEXITSTATUS (status));
464 exit (1);
467 return 0;
468 #endif
470 /* Process was killed by timer or other signal. */
471 else
473 #ifndef EXPECTED_SIGNAL
474 printf ("Didn't expect signal from child: got `%s'\n",
475 strsignal (WTERMSIG (status)));
476 exit (1);
477 #else
478 if (WTERMSIG (status) != EXPECTED_SIGNAL)
480 printf ("Incorrect signal from child: got `%s', need `%s'\n",
481 strsignal (WTERMSIG (status)),
482 strsignal (EXPECTED_SIGNAL));
483 exit (1);
486 return 0;
487 #endif