Fix tests-printers handling for cross compiling.
[glibc.git] / test-skeleton.c
blob154096fd8e248c41ee6d45a19fd8c9029f11ac12
1 /* Skeleton for test programs.
2 Copyright (C) 1998-2016 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>
36 #include <stdint.h>
38 /* The test function is normally called `do_test' and it is called
39 with argc and argv as the arguments. We nevertheless provide the
40 possibility to overwrite this name.
42 The TEST_FUNCTION expression should have a type of 'int' and should
43 return 0 to indicate a passing test, 1 to indicate a failing test,
44 or 77 to indicate an unsupported test. Other result values could be
45 used to indicate a failing test, but the result of the expression
46 is passed to exit and exit only returns the lower 8 bits of its input.
47 A non-zero return with some values could cause a test to incorrectly
48 be considered passing when it really failed. For this reason the
49 expression should always return 0, 1, or 77.
51 The test function may print out diagnostic or warning messages as well
52 as messages about failures. These messages should be printed to stdout
53 and not stderr so that the output is properly ordered with respect to
54 the rest of the glibc testsuite run output. */
56 #ifndef TEST_FUNCTION
57 # define TEST_FUNCTION do_test (argc, argv)
58 #endif
60 #ifndef TEST_DATA_LIMIT
61 # define TEST_DATA_LIMIT (64 << 20) /* Data limit (bytes) to run with. */
62 #endif
64 #ifndef TIMEOUT
65 /* Default timeout is twenty seconds. Tests should normally complete faster
66 than this, but if they don't, that's abnormal (a bug) anyways. */
67 # define TIMEOUT 20
68 #endif
70 #define OPT_DIRECT 1000
71 #define OPT_TESTDIR 1001
73 static struct option options[] =
75 #ifdef CMDLINE_OPTIONS
76 CMDLINE_OPTIONS
77 #endif
78 { "direct", no_argument, NULL, OPT_DIRECT },
79 { "test-dir", required_argument, NULL, OPT_TESTDIR },
80 { NULL, 0, NULL, 0 }
83 /* PID of the test itself. */
84 static pid_t pid;
86 /* Directory to place temporary files in. */
87 static const char *test_dir;
89 #define _FAIL(...) \
90 printf ("error: %s:%d: ", __FILE__, __LINE__); \
91 printf (__VA_ARGS__); \
92 printf ("\n"); \
94 #define FAIL_RET(...) \
95 ({ \
96 _FAIL (__VA_ARGS__); \
97 return 1; \
100 #define FAIL_EXIT(value, ...) \
101 ({ \
102 _FAIL (__VA_ARGS__); \
103 exit (value); \
106 #define FAIL_EXIT1(...) FAIL_EXIT(1, __VA_ARGS__)
108 static void
109 oom_error (const char *fn, size_t size)
111 printf ("%s: unable to allocate %zu bytes: %m\n", fn, size);
112 exit (1);
115 /* Allocate N bytes of memory dynamically, with error checking. */
116 __attribute__ ((unused))
117 static void *
118 xmalloc (size_t n)
120 void *p;
122 p = malloc (n);
123 if (p == NULL)
124 oom_error ("malloc", n);
125 return p;
128 /* Allocate memory for N elements of S bytes, with error checking. */
129 __attribute__ ((unused))
130 static void *
131 xcalloc (size_t n, size_t s)
133 void *p;
135 p = calloc (n, s);
136 if (p == NULL)
137 oom_error ("calloc", n * s);
138 return p;
141 /* Change the size of an allocated block of memory P to N bytes,
142 with error checking. */
143 __attribute__ ((unused))
144 static void *
145 xrealloc (void *p, size_t n)
147 void *result = realloc (p, n);
148 if (result == NULL && (n > 0 || p == NULL))
149 oom_error ("realloc", n);
150 return result;
153 /* Call asprintf with error checking. */
154 __attribute__ ((always_inline, format (printf, 1, 2)))
155 static __inline__ char *
156 xasprintf (const char *format, ...)
158 char *result;
159 if (asprintf (&result, format, __builtin_va_arg_pack ()) < 0)
161 printf ("error: asprintf: %m\n");
162 exit (1);
164 return result;
167 /* Write a message to standard output. Can be used in signal
168 handlers. */
169 static void
170 __attribute__ ((unused))
171 write_message (const char *message)
173 ssize_t unused __attribute__ ((unused));
174 unused = write (STDOUT_FILENO, message, strlen (message));
177 /* List of temporary files. */
178 struct temp_name_list
180 struct qelem q;
181 char *name;
182 } *temp_name_list;
184 /* Add temporary files in list. */
185 static void
186 __attribute__ ((unused))
187 add_temp_file (const char *name)
189 struct temp_name_list *newp
190 = (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
191 char *newname = strdup (name);
192 if (newname != NULL)
194 newp->name = newname;
195 if (temp_name_list == NULL)
196 temp_name_list = (struct temp_name_list *) &newp->q;
197 else
198 insque (newp, temp_name_list);
200 else
201 free (newp);
204 /* Delete all temporary files. */
205 static void
206 delete_temp_files (void)
208 while (temp_name_list != NULL)
210 remove (temp_name_list->name);
211 free (temp_name_list->name);
213 struct temp_name_list *next
214 = (struct temp_name_list *) temp_name_list->q.q_forw;
215 free (temp_name_list);
216 temp_name_list = next;
220 /* Create a temporary file. Return the opened file descriptor on
221 success, or -1 on failure. Write the file name to *FILENAME if
222 FILENAME is not NULL. In this case, the caller is expected to free
223 *FILENAME. */
224 static int
225 __attribute__ ((unused))
226 create_temp_file (const char *base, char **filename)
228 char *fname;
229 int fd;
231 fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base)
232 + sizeof ("XXXXXX"));
233 strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
235 fd = mkstemp (fname);
236 if (fd == -1)
238 printf ("cannot open temporary file '%s': %m\n", fname);
239 free (fname);
240 return -1;
243 add_temp_file (fname);
244 if (filename != NULL)
245 *filename = fname;
246 else
247 free (fname);
249 return fd;
252 /* Timeout handler. We kill the child and exit with an error. */
253 static void
254 __attribute__ ((noreturn))
255 signal_handler (int sig __attribute__ ((unused)))
257 int killed;
258 int status;
260 assert (pid > 1);
261 /* Kill the whole process group. */
262 kill (-pid, SIGKILL);
263 /* In case setpgid failed in the child, kill it individually too. */
264 kill (pid, SIGKILL);
266 /* Wait for it to terminate. */
267 int i;
268 for (i = 0; i < 5; ++i)
270 killed = waitpid (pid, &status, WNOHANG|WUNTRACED);
271 if (killed != 0)
272 break;
274 /* Delay, give the system time to process the kill. If the
275 nanosleep() call return prematurely, all the better. We
276 won't restart it since this probably means the child process
277 finally died. */
278 struct timespec ts;
279 ts.tv_sec = 0;
280 ts.tv_nsec = 100000000;
281 nanosleep (&ts, NULL);
283 if (killed != 0 && killed != pid)
285 printf ("Failed to kill test process: %m\n");
286 exit (1);
289 #ifdef CLEANUP_HANDLER
290 CLEANUP_HANDLER;
291 #endif
293 if (sig == SIGINT)
295 signal (sig, SIG_DFL);
296 raise (sig);
299 /* If we expected this signal: good! */
300 #ifdef EXPECTED_SIGNAL
301 if (EXPECTED_SIGNAL == SIGALRM)
302 exit (0);
303 #endif
305 if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL))
306 puts ("Timed out: killed the child process");
307 else if (WIFSTOPPED (status))
308 printf ("Timed out: the child process was %s\n",
309 strsignal (WSTOPSIG (status)));
310 else if (WIFSIGNALED (status))
311 printf ("Timed out: the child process got signal %s\n",
312 strsignal (WTERMSIG (status)));
313 else
314 printf ("Timed out: killed the child process but it exited %d\n",
315 WEXITSTATUS (status));
317 /* Exit with an error. */
318 exit (1);
321 /* Avoid all the buffer overflow messages on stderr. */
322 static void
323 __attribute__ ((unused))
324 ignore_stderr (void)
326 int fd = open (_PATH_DEVNULL, O_WRONLY);
327 if (fd == -1)
328 close (STDERR_FILENO);
329 else
331 dup2 (fd, STDERR_FILENO);
332 close (fd);
334 setenv ("LIBC_FATAL_STDERR_", "1", 1);
337 /* Set fortification error handler. Used when tests want to verify that bad
338 code is caught by the library. */
339 static void
340 __attribute__ ((unused))
341 set_fortify_handler (void (*handler) (int sig))
343 struct sigaction sa;
345 sa.sa_handler = handler;
346 sa.sa_flags = 0;
347 sigemptyset (&sa.sa_mask);
349 sigaction (SIGABRT, &sa, NULL);
350 ignore_stderr ();
353 /* Show people how to run the program. */
354 static void
355 usage (void)
357 size_t i;
359 printf ("Usage: %s [options]\n"
360 "\n"
361 "Environment Variables:\n"
362 " TIMEOUTFACTOR An integer used to scale the timeout\n"
363 " TMPDIR Where to place temporary files\n"
364 "\n",
365 program_invocation_short_name);
366 printf ("Options:\n");
367 for (i = 0; options[i].name; ++i)
369 int indent;
371 indent = printf (" --%s", options[i].name);
372 if (options[i].has_arg == required_argument)
373 indent += printf (" <arg>");
374 printf ("%*s", 25 - indent, "");
375 switch (options[i].val)
377 case OPT_DIRECT:
378 printf ("Run the test directly (instead of forking & monitoring)");
379 break;
380 case OPT_TESTDIR:
381 printf ("Override the TMPDIR env var");
382 break;
384 printf ("\n");
388 /* We provide the entry point here. */
390 main (int argc, char *argv[])
392 int direct = 0; /* Directly call the test function? */
393 int status;
394 int opt;
395 unsigned int timeoutfactor = 1;
396 pid_t termpid;
398 #ifndef TEST_NO_MALLOPT
399 /* Make uses of freed and uninitialized memory known. */
400 mallopt (M_PERTURB, 42);
401 #endif
403 #ifdef STDOUT_UNBUFFERED
404 setbuf (stdout, NULL);
405 #endif
407 while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
408 switch (opt)
410 case '?':
411 usage ();
412 exit (1);
413 case OPT_DIRECT:
414 direct = 1;
415 break;
416 case OPT_TESTDIR:
417 test_dir = optarg;
418 break;
419 #ifdef CMDLINE_PROCESS
420 CMDLINE_PROCESS
421 #endif
424 /* If set, read the test TIMEOUTFACTOR value from the environment.
425 This value is used to scale the default test timeout values. */
426 char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
427 if (envstr_timeoutfactor != NULL)
429 char *envstr_conv = envstr_timeoutfactor;
430 unsigned long int env_fact;
432 env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
433 if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
434 timeoutfactor = MAX (env_fact, 1);
437 /* Set TMPDIR to specified test directory. */
438 if (test_dir != NULL)
440 setenv ("TMPDIR", test_dir, 1);
442 if (chdir (test_dir) < 0)
444 printf ("chdir: %m\n");
445 exit (1);
448 else
450 test_dir = getenv ("TMPDIR");
451 if (test_dir == NULL || test_dir[0] == '\0')
452 test_dir = "/tmp";
455 /* Make sure we see all message, even those on stdout. */
456 setvbuf (stdout, NULL, _IONBF, 0);
458 /* Make sure temporary files are deleted. */
459 atexit (delete_temp_files);
461 /* Correct for the possible parameters. */
462 argv[optind - 1] = argv[0];
463 argv += optind - 1;
464 argc -= optind - 1;
466 /* Call the initializing function, if one is available. */
467 #ifdef PREPARE
468 PREPARE (argc, argv);
469 #endif
471 const char *envstr_direct = getenv ("TEST_DIRECT");
472 if (envstr_direct != NULL)
474 FILE *f = fopen (envstr_direct, "w");
475 if (f == NULL)
477 printf ("cannot open TEST_DIRECT output file '%s': %m\n",
478 envstr_direct);
479 exit (1);
482 fprintf (f, "timeout=%u\ntimeoutfactor=%u\n", TIMEOUT, timeoutfactor);
483 #ifdef EXPECTED_STATUS
484 fprintf (f, "exit=%u\n", EXPECTED_STATUS);
485 #endif
486 #ifdef EXPECTED_SIGNAL
487 switch (EXPECTED_SIGNAL)
489 default: abort ();
490 # define init_sig(signo, name, text) \
491 case signo: fprintf (f, "signal=%s\n", name); break;
492 # include <siglist.h>
493 # undef init_sig
495 #endif
497 if (temp_name_list != NULL)
499 struct temp_name_list *n;
500 fprintf (f, "temp_files=(\n");
501 for (n = temp_name_list;
502 n != NULL;
503 n = (struct temp_name_list *) n->q.q_forw)
504 fprintf (f, " '%s'\n", n->name);
505 fprintf (f, ")\n");
508 fclose (f);
509 direct = 1;
512 /* If we are not expected to fork run the function immediately. */
513 if (direct)
514 return TEST_FUNCTION;
516 /* Set up the test environment:
517 - prevent core dumps
518 - set up the timer
519 - fork and execute the function. */
521 pid = fork ();
522 if (pid == 0)
524 /* This is the child. */
525 #ifdef RLIMIT_CORE
526 /* Try to avoid dumping core. */
527 struct rlimit core_limit;
528 core_limit.rlim_cur = 0;
529 core_limit.rlim_max = 0;
530 setrlimit (RLIMIT_CORE, &core_limit);
531 #endif
533 /* We put the test process in its own pgrp so that if it bogusly
534 generates any job control signals, they won't hit the whole build. */
535 if (setpgid (0, 0) != 0)
536 printf ("Failed to set the process group ID: %m\n");
538 /* Execute the test function and exit with the return value. */
539 exit (TEST_FUNCTION);
541 else if (pid < 0)
543 printf ("Cannot fork test program: %m\n");
544 exit (1);
547 /* Set timeout. */
548 signal (SIGALRM, signal_handler);
549 alarm (TIMEOUT * timeoutfactor);
551 /* Make sure we clean up if the wrapper gets interrupted. */
552 signal (SIGINT, signal_handler);
554 /* Wait for the regular termination. */
555 termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
556 if (termpid == -1)
558 printf ("Waiting for test program failed: %m\n");
559 exit (1);
561 if (termpid != pid)
563 printf ("Oops, wrong test program terminated: expected %ld, got %ld\n",
564 (long int) pid, (long int) termpid);
565 exit (1);
568 /* Process terminated normaly without timeout etc. */
569 if (WIFEXITED (status))
571 #ifndef EXPECTED_STATUS
572 # ifndef EXPECTED_SIGNAL
573 /* Simply exit with the return value of the test. */
574 return WEXITSTATUS (status);
575 # else
576 printf ("Expected signal '%s' from child, got none\n",
577 strsignal (EXPECTED_SIGNAL));
578 exit (1);
579 # endif
580 #else
581 if (WEXITSTATUS (status) != EXPECTED_STATUS)
583 printf ("Expected status %d, got %d\n",
584 EXPECTED_STATUS, WEXITSTATUS (status));
585 exit (1);
588 return 0;
589 #endif
591 /* Process was killed by timer or other signal. */
592 else
594 #ifndef EXPECTED_SIGNAL
595 printf ("Didn't expect signal from child: got `%s'\n",
596 strsignal (WTERMSIG (status)));
597 exit (1);
598 #else
599 if (WTERMSIG (status) != EXPECTED_SIGNAL)
601 printf ("Incorrect signal from child: got `%s', need `%s'\n",
602 strsignal (WTERMSIG (status)),
603 strsignal (EXPECTED_SIGNAL));
604 exit (1);
607 return 0;
608 #endif
612 /* The following functionality is only available if <pthread.h> was
613 included before this file. */
614 #ifdef _PTHREAD_H
616 /* Call pthread_sigmask with error checking. */
617 static void
618 xpthread_sigmask (int how, const sigset_t *set, sigset_t *oldset)
620 if (pthread_sigmask (how, set, oldset) != 0)
622 write_message ("error: pthread_setmask failed\n");
623 _exit (1);
627 /* Call pthread_mutex_lock with error checking. */
628 __attribute__ ((unused))
629 static void
630 xpthread_mutex_lock (pthread_mutex_t *mutex)
632 int ret = pthread_mutex_lock (mutex);
633 if (ret != 0)
635 errno = ret;
636 printf ("error: pthread_mutex_lock: %m\n");
637 exit (1);
641 /* Call pthread_spin_lock with error checking. */
642 __attribute__ ((unused))
643 static void
644 xpthread_spin_lock (pthread_spinlock_t *lock)
646 int ret = pthread_spin_lock (lock);
647 if (ret != 0)
649 errno = ret;
650 printf ("error: pthread_spin_lock: %m\n");
651 exit (1);
655 /* Call pthread_cond_wait with error checking. */
656 __attribute__ ((unused))
657 static void
658 xpthread_cond_wait (pthread_cond_t * cond,
659 pthread_mutex_t * mutex)
661 int ret = pthread_cond_wait (cond, mutex);
662 if (ret != 0)
664 errno = ret;
665 printf ("error: pthread_cond_wait: %m\n");
666 exit (1);
670 /* Call pthread_barrier_wait with error checking. */
671 __attribute__ ((unused))
672 static int
673 xpthread_barrier_wait (pthread_barrier_t *barrier)
675 int ret = pthread_barrier_wait (barrier);
676 if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
678 errno = ret;
679 printf ("error: pthread_barrier_wait: %m\n");
680 exit (1);
682 return ret;
685 /* Call pthread_create with error checking. */
686 static pthread_t
687 xpthread_create (pthread_attr_t *attr,
688 void *(*thread_func) (void *), void *closure)
690 pthread_t thr;
691 int ret = pthread_create (&thr, attr, thread_func, closure);
692 if (ret != 0)
694 errno = ret;
695 printf ("error: pthread_create: %m\n");
696 exit (1);
698 return thr;
701 /* Call pthread_detach with error checking. */
702 static void
703 xpthread_detach (pthread_t thr)
705 int ret = pthread_detach (thr);
706 if (ret != 0)
708 errno = ret;
709 printf ("error: pthread_detach: %m\n");
710 exit (1);
714 /* Call pthread_join with error checking. */
715 __attribute__ ((unused))
716 static void *
717 xpthread_join (pthread_t thr)
719 void *result;
720 int ret = pthread_join (thr, &result);
721 if (ret != 0)
723 errno = ret;
724 printf ("error: pthread_join: %m\n");
725 exit (1);
727 return result;
730 /* Used to implement the delayed_exit function defined below. */
731 static void *
732 delayed_exit_thread (void *seconds_as_ptr)
734 int seconds = (uintptr_t) seconds_as_ptr;
735 struct timespec delay = { seconds, 0 };
736 struct timespec remaining = { 0 };
737 if (nanosleep (&delay, &remaining) != 0)
739 printf ("error: nanosleep: %m\n");
740 _exit (1);
742 /* Exit the process sucessfully. */
743 exit (0);
744 return NULL;
747 /* Exit (with status 0) after SECONDS have elapsed, from a helper
748 thread. The process is terminated with the exit function, so
749 atexit handlers are executed. */
750 __attribute__ ((unused))
751 static void
752 delayed_exit (int seconds)
754 /* Create the new thread with all signals blocked. */
755 sigset_t all_blocked;
756 sigfillset (&all_blocked);
757 sigset_t old_set;
758 xpthread_sigmask (SIG_SETMASK, &all_blocked, &old_set);
759 /* Create a detached thread. */
760 pthread_t thr = xpthread_create
761 (NULL, delayed_exit_thread, (void *) (uintptr_t) seconds);
762 xpthread_detach (thr);
763 /* Restore the original signal mask. */
764 xpthread_sigmask (SIG_SETMASK, &old_set, NULL);
767 #endif /* _PTHREAD_H */