Update copyright dates with scripts/update-copyrights.
[platform/upstream/glibc.git] / test-skeleton.c
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.
5
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.
10
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.
15
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/>.  */
19
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
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
43
44 #ifndef TEST_DATA_LIMIT
45 # define TEST_DATA_LIMIT (64 << 20) /* Data limit (bytes) to run with.  */
46 #endif
47
48 #ifndef TIMEOUT
49   /* Default timeout is two seconds.  */
50 # define TIMEOUT 2
51 #endif
52
53 #define OPT_DIRECT 1000
54 #define OPT_TESTDIR 1001
55
56 static struct option options[] =
57 {
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 }
64 };
65
66 /* PID of the test itself.  */
67 static pid_t pid;
68
69 /* Directory to place temporary files in.  */
70 static const char *test_dir;
71
72 /* List of temporary files.  */
73 struct temp_name_list
74 {
75   struct qelem q;
76   char *name;
77 } *temp_name_list;
78
79 /* Add temporary files in list.  */
80 static void
81 __attribute__ ((unused))
82 add_temp_file (const char *name)
83 {
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)
88     {
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);
94     }
95   else
96     free (newp);
97 }
98
99 /* Delete all temporary files.  */
100 static void
101 delete_temp_files (void)
102 {
103   while (temp_name_list != NULL)
104     {
105       remove (temp_name_list->name);
106       free (temp_name_list->name);
107
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;
112     }
113 }
114
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)
122 {
123   char *fname;
124   int fd;
125
126   fname = (char *) malloc (strlen (test_dir) + 1 + strlen (base)
127                            + sizeof ("XXXXXX"));
128   if (fname == NULL)
129     {
130       puts ("out of memory");
131       return -1;
132     }
133   strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
134
135   fd = mkstemp (fname);
136   if (fd == -1)
137     {
138       printf ("cannot open temporary file '%s': %m\n", fname);
139       free (fname);
140       return -1;
141     }
142
143   add_temp_file (fname);
144   if (filename != NULL)
145     *filename = fname;
146   else
147     free (fname);
148
149   return fd;
150 }
151
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)))
156 {
157   int killed;
158   int status;
159
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);
165
166   /* Wait for it to terminate.  */
167   int i;
168   for (i = 0; i < 5; ++i)
169     {
170       killed = waitpid (pid, &status, WNOHANG|WUNTRACED);
171       if (killed != 0)
172         break;
173
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);
182     }
183   if (killed != 0 && killed != pid)
184     {
185       printf ("Failed to kill test process: %m\n");
186       exit (1);
187     }
188
189 #ifdef CLEANUP_HANDLER
190   CLEANUP_HANDLER;
191 #endif
192
193   if (sig == SIGINT)
194     {
195       signal (sig, SIG_DFL);
196       raise (sig);
197     }
198
199   /* If we expected this signal: good!  */
200 #ifdef EXPECTED_SIGNAL
201   if (EXPECTED_SIGNAL == SIGALRM)
202     exit (0);
203 #endif
204
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));
216
217   /* Exit with an error.  */
218   exit (1);
219 }
220
221 /* Avoid all the buffer overflow messages on stderr.  */
222 static void
223 __attribute__ ((unused))
224 ignore_stderr (void)
225 {
226   int fd = open (_PATH_DEVNULL, O_WRONLY);
227   if (fd == -1)
228     close (STDERR_FILENO);
229   else
230     {
231       dup2 (fd, STDERR_FILENO);
232       close (fd);
233     }
234   setenv ("LIBC_FATAL_STDERR_", "1", 1);
235 }
236
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))
242 {
243   struct sigaction sa;
244
245   sa.sa_handler = handler;
246   sa.sa_flags = 0;
247   sigemptyset (&sa.sa_mask);
248
249   sigaction (SIGABRT, &sa, NULL);
250   ignore_stderr ();
251 }
252
253 /* Show people how to run the program.  */
254 static void
255 usage (void)
256 {
257   size_t i;
258
259   printf ("Usage: %s [options]\n"
260           "\n"
261           "Environment Variables:\n"
262           "  TIMEOUTFACTOR          An integer used to scale the timeout\n"
263           "  TMPDIR                 Where to place temporary files\n"
264           "\n",
265           program_invocation_short_name);
266   printf ("Options:\n");
267   for (i = 0; options[i].name; ++i)
268     {
269       int indent;
270
271       indent = printf ("  --%s", options[i].name);
272       if (options[i].has_arg == required_argument)
273         indent += printf (" <arg>");
274       printf ("%*s", 25 - indent, "");
275       switch (options[i].val)
276         {
277         case OPT_DIRECT:
278           printf ("Run the test directly (instead of forking & monitoring)");
279           break;
280         case OPT_TESTDIR:
281           printf ("Override the TMPDIR env var");
282           break;
283         }
284       printf ("\n");
285     }
286 }
287
288 /* We provide the entry point here.  */
289 int
290 main (int argc, char *argv[])
291 {
292   int direct = 0;       /* Directly call the test function?  */
293   int status;
294   int opt;
295   unsigned int timeoutfactor = 1;
296   pid_t termpid;
297
298   /* Make uses of freed and uninitialized memory known.  */
299   mallopt (M_PERTURB, 42);
300
301 #ifdef STDOUT_UNBUFFERED
302   setbuf (stdout, NULL);
303 #endif
304
305   while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
306     switch (opt)
307       {
308       case '?':
309         usage ();
310         exit (1);
311       case OPT_DIRECT:
312         direct = 1;
313         break;
314       case OPT_TESTDIR:
315         test_dir = optarg;
316         break;
317 #ifdef CMDLINE_PROCESS
318         CMDLINE_PROCESS
319 #endif
320       }
321
322   /* If set, read the test TIMEOUTFACTOR value from the environment.
323      This value is used to scale the default test timeout values. */
324   char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
325   if (envstr_timeoutfactor != NULL)
326     {
327       char *envstr_conv = envstr_timeoutfactor;
328       unsigned long int env_fact;
329
330       env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
331       if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
332         timeoutfactor = MAX (env_fact, 1);
333     }
334
335   /* Set TMPDIR to specified test directory.  */
336   if (test_dir != NULL)
337     {
338       setenv ("TMPDIR", test_dir, 1);
339
340       if (chdir (test_dir) < 0)
341         {
342           printf ("chdir: %m\n");
343           exit (1);
344         }
345     }
346   else
347     {
348       test_dir = getenv ("TMPDIR");
349       if (test_dir == NULL || test_dir[0] == '\0')
350         test_dir = "/tmp";
351     }
352
353   /* Make sure we see all message, even those on stdout.  */
354   setvbuf (stdout, NULL, _IONBF, 0);
355
356   /* Make sure temporary files are deleted.  */
357   atexit (delete_temp_files);
358
359   /* Correct for the possible parameters.  */
360   argv[optind - 1] = argv[0];
361   argv += optind - 1;
362   argc -= optind - 1;
363
364   /* Call the initializing function, if one is available.  */
365 #ifdef PREPARE
366   PREPARE (argc, argv);
367 #endif
368
369   const char *envstr_direct = getenv ("TEST_DIRECT");
370   if (envstr_direct != NULL)
371     {
372       FILE *f = fopen (envstr_direct, "w");
373       if (f == NULL)
374         {
375           printf ("cannot open TEST_DIRECT output file '%s': %m\n",
376                   envstr_direct);
377           exit (1);
378         }
379
380       fprintf (f, "timeout=%u\ntimeoutfactor=%u\n", TIMEOUT, timeoutfactor);
381 #ifdef EXPECTED_STATUS
382       fprintf (f, "exit=%u\n", EXPECTED_STATUS);
383 #endif
384 #ifdef EXPECTED_SIGNAL
385       switch (EXPECTED_SIGNAL)
386         {
387         default: abort ();
388 # define init_sig(signo, name, text) \
389         case signo: fprintf (f, "signal=%s\n", name); break;
390 # include <siglist.h>
391 # undef init_sig
392         }
393 #endif
394
395       if (temp_name_list != NULL)
396         {
397           struct temp_name_list *n;
398           fprintf (f, "temp_files=(\n");
399           for (n = temp_name_list;
400                n != NULL;
401                n = (struct temp_name_list *) n->q.q_forw)
402             fprintf (f, "  '%s'\n", n->name);
403           fprintf (f, ")\n");
404         }
405
406       fclose (f);
407       direct = 1;
408     }
409
410   /* If we are not expected to fork run the function immediately.  */
411   if (direct)
412     return TEST_FUNCTION;
413
414   /* Set up the test environment:
415      - prevent core dumps
416      - set up the timer
417      - fork and execute the function.  */
418
419   pid = fork ();
420   if (pid == 0)
421     {
422       /* This is the child.  */
423 #ifdef RLIMIT_CORE
424       /* Try to avoid dumping core.  */
425       struct rlimit core_limit;
426       core_limit.rlim_cur = 0;
427       core_limit.rlim_max = 0;
428       setrlimit (RLIMIT_CORE, &core_limit);
429 #endif
430
431 #ifdef RLIMIT_DATA
432       /* Try to avoid eating all memory if a test leaks.  */
433       struct rlimit data_limit;
434       if (getrlimit (RLIMIT_DATA, &data_limit) == 0)
435         {
436           if (TEST_DATA_LIMIT == RLIM_INFINITY)
437             data_limit.rlim_cur = data_limit.rlim_max;
438           else if (data_limit.rlim_cur > (rlim_t) TEST_DATA_LIMIT)
439             data_limit.rlim_cur = MIN ((rlim_t) TEST_DATA_LIMIT,
440                                        data_limit.rlim_max);
441           if (setrlimit (RLIMIT_DATA, &data_limit) < 0)
442             printf ("setrlimit: RLIMIT_DATA: %m\n");
443         }
444       else
445         printf ("getrlimit: RLIMIT_DATA: %m\n");
446 #endif
447
448       /* We put the test process in its own pgrp so that if it bogusly
449          generates any job control signals, they won't hit the whole build.  */
450       if (setpgid (0, 0) != 0)
451         printf ("Failed to set the process group ID: %m\n");
452
453       /* Execute the test function and exit with the return value.   */
454       exit (TEST_FUNCTION);
455     }
456   else if (pid < 0)
457     {
458       printf ("Cannot fork test program: %m\n");
459       exit (1);
460     }
461
462   /* Set timeout.  */
463   signal (SIGALRM, signal_handler);
464   alarm (TIMEOUT * timeoutfactor);
465
466   /* Make sure we clean up if the wrapper gets interrupted.  */
467   signal (SIGINT, signal_handler);
468
469   /* Wait for the regular termination.  */
470   termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
471   if (termpid == -1)
472     {
473       printf ("Waiting for test program failed: %m\n");
474       exit (1);
475     }
476   if (termpid != pid)
477     {
478       printf ("Oops, wrong test program terminated: expected %ld, got %ld\n",
479               (long int) pid, (long int) termpid);
480       exit (1);
481     }
482
483   /* Process terminated normaly without timeout etc.  */
484   if (WIFEXITED (status))
485     {
486 #ifndef EXPECTED_STATUS
487 # ifndef EXPECTED_SIGNAL
488       /* Simply exit with the return value of the test.  */
489       return WEXITSTATUS (status);
490 # else
491       printf ("Expected signal '%s' from child, got none\n",
492               strsignal (EXPECTED_SIGNAL));
493       exit (1);
494 # endif
495 #else
496       if (WEXITSTATUS (status) != EXPECTED_STATUS)
497         {
498           printf ("Expected status %d, got %d\n",
499                   EXPECTED_STATUS, WEXITSTATUS (status));
500           exit (1);
501         }
502
503       return 0;
504 #endif
505     }
506   /* Process was killed by timer or other signal.  */
507   else
508     {
509 #ifndef EXPECTED_SIGNAL
510       printf ("Didn't expect signal from child: got `%s'\n",
511               strsignal (WTERMSIG (status)));
512       exit (1);
513 #else
514       if (WTERMSIG (status) != EXPECTED_SIGNAL)
515         {
516           printf ("Incorrect signal from child: got `%s', need `%s'\n",
517                   strsignal (WTERMSIG (status)),
518                   strsignal (EXPECTED_SIGNAL));
519           exit (1);
520         }
521
522       return 0;
523 #endif
524     }
525 }