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