xref: /freebsd/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c (revision 18054d0220cfc8df9c9568c437bd6fbb59d53c3c)
1  /* $NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $ */
2  
3  /*-
4   * Copyright (c) 2011 The NetBSD Foundation, Inc.
5   * All rights reserved.
6   *
7   * This code is derived from software contributed to The NetBSD Foundation
8   * by Jukka Ruohonen.
9   *
10   * Redistribution and use in source and binary forms, with or without
11   * modification, are permitted provided that the following conditions
12   * are met:
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   * 2. Redistributions in binary form must reproduce the above copyright
16   *    notice, this list of conditions and the following disclaimer in the
17   *    documentation and/or other materials provided with the distribution.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20   * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21   * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29   * POSSIBILITY OF SUCH DAMAGE.
30   */
31  #include <sys/cdefs.h>
32  __RCSID("$NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $");
33  
34  #include <sys/wait.h>
35  
36  #include <atf-c.h>
37  #include <stdio.h>
38  #include <stdlib.h>
39  #include <string.h>
40  #include <unistd.h>
41  
42  static bool	fail;
43  static void	func(void);
44  
45  static void
46  func(void)
47  {
48  	fail = false;
49  }
50  
51  ATF_TC(exit_atexit);
52  ATF_TC_HEAD(exit_atexit, tc)
53  {
54  	atf_tc_set_md_var(tc, "descr", "A basic test of atexit(3)");
55  }
56  
57  ATF_TC_BODY(exit_atexit, tc)
58  {
59  	pid_t pid;
60  	int sta;
61  
62  	pid = fork();
63  	ATF_REQUIRE(pid >= 0);
64  
65  	if (pid == 0) {
66  
67  		if (atexit(func) != 0)
68  			_exit(EXIT_FAILURE);
69  
70  		fail = true;
71  
72  		_exit(EXIT_SUCCESS);
73  	}
74  
75  	(void)wait(&sta);
76  
77  	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
78  		atf_tc_fail("atexit(3) failed");
79  
80  	if (fail != false)
81  		atf_tc_fail("atexit(3) was not called");
82  }
83  
84  ATF_TC(exit_basic);
85  ATF_TC_HEAD(exit_basic, tc)
86  {
87  	atf_tc_set_md_var(tc, "descr", "A basic test of exit(3)");
88  }
89  
90  ATF_TC_BODY(exit_basic, tc)
91  {
92  	pid_t pid;
93  	int sta;
94  
95  	pid = fork();
96  	ATF_REQUIRE(pid >= 0);
97  
98  	if (pid == 0) {
99  		exit(EXIT_SUCCESS);
100  		exit(EXIT_FAILURE);
101  	}
102  
103  	(void)wait(&sta);
104  
105  	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
106  		atf_tc_fail("exit(3) did not exit successfully");
107  }
108  
109  ATF_TC(exit_status);
110  ATF_TC_HEAD(exit_status, tc)
111  {
112  	atf_tc_set_md_var(tc, "descr", "Test exit(3) status");
113  }
114  
115  ATF_TC_BODY(exit_status, tc)
116  {
117  	const int n = 10;
118  	int i, sta;
119  	pid_t pid;
120  
121  	for (i = 0; i < n; i++) {
122  
123  		pid = fork();
124  
125  		if (pid < 0)
126  			exit(EXIT_FAILURE);
127  
128  		if (pid == 0)
129  			exit(i);
130  
131  		(void)wait(&sta);
132  
133  		if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != i)
134  			atf_tc_fail("invalid exit(3) status");
135  	}
136  }
137  
138  ATF_TC(exit_tmpfile);
139  ATF_TC_HEAD(exit_tmpfile, tc)
140  {
141  	atf_tc_set_md_var(tc, "descr", "Temporary files are unlinked?");
142  }
143  
144  ATF_TC_BODY(exit_tmpfile, tc)
145  {
146  	int sta, fd = -1;
147  	char buf[12];
148  	pid_t pid;
149  	FILE *f;
150  
151  	(void)strlcpy(buf, "exit.XXXXXX", sizeof(buf));
152  
153  	pid = fork();
154  	ATF_REQUIRE(pid >= 0);
155  
156  	if (pid == 0) {
157  
158  		fd = mkstemp(buf);
159  
160  		if (fd < 0)
161  			exit(EXIT_FAILURE);
162  
163  		exit(EXIT_SUCCESS);
164  	}
165  
166  	(void)wait(&sta);
167  
168  	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
169  		atf_tc_fail("failed to create temporary file");
170  
171  	f = fdopen(fd, "r");
172  
173  	if (f != NULL)
174  		atf_tc_fail("exit(3) did not clear temporary file");
175  }
176  
177  ATF_TP_ADD_TCS(tp)
178  {
179  
180  	ATF_TP_ADD_TC(tp, exit_atexit);
181  	ATF_TP_ADD_TC(tp, exit_basic);
182  	ATF_TP_ADD_TC(tp, exit_status);
183  	ATF_TP_ADD_TC(tp, exit_tmpfile);
184  
185  	return atf_no_error();
186  }
187