]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdlib/tst-atexit-common.c
math/math.h (HUGE_VAL): Improve commentary.
[thirdparty/glibc.git] / stdlib / tst-atexit-common.c
CommitLineData
5f3b183d
PP
1/* Helper file for tst-{atexit,at_quick_exit,cxa_atexit,on_exit}.
2 Copyright (C) 2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
8325b477 24#include <sys/wait.h>
5f3b183d
PP
25
26#define MAX_ATEXIT 20 /* Large enough for current set of invocations. */
27static char crumbs[MAX_ATEXIT];
28static int next_slot = 0;
29
8325b477
PP
30/* Helper: flush stdout and _exit. */
31static void
32_exit_with_flush (int code)
33{
34 fflush (stdout);
35 _exit (code);
36}
37
5f3b183d
PP
38static void
39fn0 (void)
40{
41 crumbs[next_slot++] = '0';
42}
43
44static void
45fn1 (void)
46{
47 crumbs[next_slot++] = '1';
48}
49
50static void
51fn2 (void)
52{
53 crumbs[next_slot++] = '2';
54 ATEXIT (fn1);
55}
56
57static void
58fn3 (void)
59{
60 crumbs[next_slot++] = '3';
61 ATEXIT (fn2);
62 ATEXIT (fn0);
63}
64
65static void
66fn_final (void)
67{
68 /* Arbitrary sequence matching current registrations. */
69 const char expected[] = "3021121130211";
70
71 if (strcmp (crumbs, expected) == 0)
8325b477 72 _exit_with_flush (0);
5f3b183d
PP
73
74 printf ("crumbs: %s\n", crumbs);
75 printf ("expected: %s\n", expected);
8325b477 76 _exit_with_flush (1);
5f3b183d
PP
77}
78
79/* This is currently just a basic test to verify that exit handlers execute
80 in LIFO order, even when the handlers register additional new handlers.
81
82 TODO: Additional tests that we should do:
83 1. POSIX says we need to support at least ATEXIT_MAX
8325b477 84 2. ... */
5f3b183d
PP
85
86static int
87do_test (void)
88{
89 /* Register this first so it can verify expected order of the rest. */
90 ATEXIT (fn_final);
91
92 ATEXIT (fn1);
93 ATEXIT (fn3);
94 ATEXIT (fn1);
95 ATEXIT (fn2);
96 ATEXIT (fn1);
97 ATEXIT (fn3);
98
8325b477
PP
99 /* Verify that handlers registered above are inherited across fork. */
100 const pid_t child = fork ();
101 switch (child)
102 {
103 case -1:
104 printf ("fork: %m\n");
105 _exit_with_flush (3);
106 case 0: /* Child. */
107 break;
108 default:
109 {
110 int status;
111 const pid_t exited = waitpid (child, &status, 0);
112 if (child != exited)
113 {
114 printf ("unexpected child: %d, expected %d\n", exited, child);
115 _exit_with_flush (4);
116 }
117 if (status != 0)
118 {
119 if (WIFEXITED (status))
120 printf ("unexpected exit status %d from child %d\n",
121 WEXITSTATUS (status), child);
122 else if (WIFSIGNALED (status))
123 printf ("unexpected signal %d from child %d\n",
124 WTERMSIG (status), child);
125 else
126 printf ("unexpected status %d from child %d\n", status, child);
127 _exit_with_flush (5);
128 }
129 }
130 break;
131 }
132
5f3b183d
PP
133 EXIT (2); /* If we see this exit code, fn_final must have not worked. */
134}
135
136#define TEST_FUNCTION do_test
137#include <support/test-driver.c>