xref: /netbsd-src/tests/lib/libc/setjmp/t_setjmp.c (revision b43f86b8367a5c10c1ae30b570d7daa677221a9e)
1*b43f86b8Schristos /* $NetBSD: t_setjmp.c,v 1.3 2021/03/21 16:36:32 christos Exp $ */
2cfe38ef7Spgoyette 
3cfe38ef7Spgoyette /*-
4cfe38ef7Spgoyette  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5cfe38ef7Spgoyette  * All rights reserved.
6cfe38ef7Spgoyette  *
7cfe38ef7Spgoyette  * Redistribution and use in source and binary forms, with or without
8cfe38ef7Spgoyette  * modification, are permitted provided that the following conditions
9cfe38ef7Spgoyette  * are met:
10cfe38ef7Spgoyette  * 1. Redistributions of source code must retain the above copyright
11cfe38ef7Spgoyette  *    notice, this list of conditions and the following disclaimer.
12cfe38ef7Spgoyette  * 2. Redistributions in binary form must reproduce the above copyright
13cfe38ef7Spgoyette  *    notice, this list of conditions and the following disclaimer in the
14cfe38ef7Spgoyette  *    documentation and/or other materials provided with the distribution.
15cfe38ef7Spgoyette  *
16cfe38ef7Spgoyette  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17cfe38ef7Spgoyette  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18cfe38ef7Spgoyette  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19cfe38ef7Spgoyette  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20cfe38ef7Spgoyette  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21cfe38ef7Spgoyette  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22cfe38ef7Spgoyette  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23cfe38ef7Spgoyette  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24cfe38ef7Spgoyette  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25cfe38ef7Spgoyette  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26cfe38ef7Spgoyette  * POSSIBILITY OF SUCH DAMAGE.
27cfe38ef7Spgoyette  */
28cfe38ef7Spgoyette 
29cfe38ef7Spgoyette /*
30cfe38ef7Spgoyette  * Copyright (c) 1994 Christopher G. Demetriou
31cfe38ef7Spgoyette  * All rights reserved.
32cfe38ef7Spgoyette  *
33cfe38ef7Spgoyette  * Redistribution and use in source and binary forms, with or without
34cfe38ef7Spgoyette  * modification, are permitted provided that the following conditions
35cfe38ef7Spgoyette  * are met:
36cfe38ef7Spgoyette  * 1. Redistributions of source code must retain the above copyright
37cfe38ef7Spgoyette  *    notice, this list of conditions and the following disclaimer.
38cfe38ef7Spgoyette  * 2. Redistributions in binary form must reproduce the above copyright
39cfe38ef7Spgoyette  *    notice, this list of conditions and the following disclaimer in the
40cfe38ef7Spgoyette  *    documentation and/or other materials provided with the distribution.
41cfe38ef7Spgoyette  * 3. All advertising materials mentioning features or use of this software
42cfe38ef7Spgoyette  *    must display the following acknowledgement:
43cfe38ef7Spgoyette  *          This product includes software developed for the
44cfe38ef7Spgoyette  *          NetBSD Project.  See http://www.NetBSD.org/ for
45cfe38ef7Spgoyette  *          information about NetBSD.
46cfe38ef7Spgoyette  * 4. The name of the author may not be used to endorse or promote products
47cfe38ef7Spgoyette  *    derived from this software without specific prior written permission.
48cfe38ef7Spgoyette  *
49cfe38ef7Spgoyette  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50cfe38ef7Spgoyette  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51cfe38ef7Spgoyette  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52cfe38ef7Spgoyette  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53cfe38ef7Spgoyette  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54cfe38ef7Spgoyette  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55cfe38ef7Spgoyette  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56cfe38ef7Spgoyette  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57cfe38ef7Spgoyette  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58cfe38ef7Spgoyette  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59cfe38ef7Spgoyette  *
60cfe38ef7Spgoyette  * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
61cfe38ef7Spgoyette  */
62cfe38ef7Spgoyette 
63cfe38ef7Spgoyette #include <sys/cdefs.h>
64cfe38ef7Spgoyette __COPYRIGHT("@(#) Copyright (c) 2008\
65cfe38ef7Spgoyette  The NetBSD Foundation, inc. All rights reserved.");
66*b43f86b8Schristos __RCSID("$NetBSD: t_setjmp.c,v 1.3 2021/03/21 16:36:32 christos Exp $");
67cfe38ef7Spgoyette 
68cfe38ef7Spgoyette #include <sys/types.h>
69cfe38ef7Spgoyette 
70cfe38ef7Spgoyette #include <errno.h>
71cfe38ef7Spgoyette #include <setjmp.h>
72cfe38ef7Spgoyette #include <signal.h>
73*b43f86b8Schristos #include <stdbool.h>
74cfe38ef7Spgoyette #include <stdio.h>
75cfe38ef7Spgoyette #include <stdlib.h>
76cfe38ef7Spgoyette #include <string.h>
77cfe38ef7Spgoyette #include <unistd.h>
78cfe38ef7Spgoyette 
79cfe38ef7Spgoyette #include <atf-c.h>
80cfe38ef7Spgoyette 
81cfe38ef7Spgoyette #define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
82cfe38ef7Spgoyette 
83cfe38ef7Spgoyette #define TEST_SETJMP 0
84cfe38ef7Spgoyette #define TEST_U_SETJMP 1
85cfe38ef7Spgoyette #define TEST_SIGSETJMP_SAVE 2
86cfe38ef7Spgoyette #define TEST_SIGSETJMP_NOSAVE 3
87*b43f86b8Schristos #define TEST_LONGJMP_ZERO 4
88*b43f86b8Schristos #define TEST_U_LONGJMP_ZERO 5
89cfe38ef7Spgoyette 
90cfe38ef7Spgoyette static int expectsignal;
91cfe38ef7Spgoyette 
92cfe38ef7Spgoyette static void
aborthandler(int signo __unused)932162d236Schristos aborthandler(int signo __unused)
94cfe38ef7Spgoyette {
95cfe38ef7Spgoyette 	ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded");
96cfe38ef7Spgoyette 	atf_tc_pass();
97cfe38ef7Spgoyette }
98cfe38ef7Spgoyette 
99cfe38ef7Spgoyette static void
h_check(int test)100cfe38ef7Spgoyette h_check(int test)
101cfe38ef7Spgoyette {
102cfe38ef7Spgoyette 	struct sigaction sa;
103cfe38ef7Spgoyette 	jmp_buf jb;
104cfe38ef7Spgoyette 	sigjmp_buf sjb;
105cfe38ef7Spgoyette 	sigset_t ss;
106cfe38ef7Spgoyette 	int i, x;
107*b43f86b8Schristos 	volatile bool did_longjmp;
108cfe38ef7Spgoyette 
109cfe38ef7Spgoyette 	i = getpid();
110*b43f86b8Schristos 	did_longjmp = false;
111cfe38ef7Spgoyette 
112*b43f86b8Schristos 	if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE ||
113*b43f86b8Schristos 	    test == TEST_LONGJMP_ZERO)
114cfe38ef7Spgoyette 		expectsignal = 0;
115*b43f86b8Schristos 	else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE ||
116*b43f86b8Schristos 	    test == TEST_U_LONGJMP_ZERO)
117cfe38ef7Spgoyette 		expectsignal = 1;
118cfe38ef7Spgoyette 	else
119cfe38ef7Spgoyette 		atf_tc_fail("unknown test");
120cfe38ef7Spgoyette 
121cfe38ef7Spgoyette 	sa.sa_handler = aborthandler;
122cfe38ef7Spgoyette 	sigemptyset(&sa.sa_mask);
123cfe38ef7Spgoyette 	sa.sa_flags = 0;
124cfe38ef7Spgoyette 	REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1);
125cfe38ef7Spgoyette 	REQUIRE_ERRNO(sigemptyset(&ss) != -1);
126cfe38ef7Spgoyette 	REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1);
127cfe38ef7Spgoyette 	REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1);
128cfe38ef7Spgoyette 
129*b43f86b8Schristos 	if (test == TEST_SETJMP || test == TEST_LONGJMP_ZERO)
130cfe38ef7Spgoyette 		x = setjmp(jb);
131*b43f86b8Schristos 	else if (test == TEST_U_SETJMP || test == TEST_U_LONGJMP_ZERO)
132cfe38ef7Spgoyette 		x = _setjmp(jb);
133cfe38ef7Spgoyette 	else
134cfe38ef7Spgoyette 		x = sigsetjmp(sjb, !expectsignal);
135cfe38ef7Spgoyette 
136cfe38ef7Spgoyette 	if (x != 0) {
137*b43f86b8Schristos 		if (test == TEST_LONGJMP_ZERO || test == TEST_U_LONGJMP_ZERO)
138*b43f86b8Schristos 			ATF_REQUIRE_MSG(x == 1, "setjmp returned wrong value");
139*b43f86b8Schristos 		else
140cfe38ef7Spgoyette 			ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value");
141*b43f86b8Schristos 
142cfe38ef7Spgoyette 		kill(i, SIGABRT);
143cfe38ef7Spgoyette 		ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed");
144cfe38ef7Spgoyette 		atf_tc_pass();
145*b43f86b8Schristos 	} else if (did_longjmp) {
146*b43f86b8Schristos 		atf_tc_fail("setjmp returned zero after longjmp");
147cfe38ef7Spgoyette 	}
148cfe38ef7Spgoyette 
149cfe38ef7Spgoyette 	REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1);
150cfe38ef7Spgoyette 
151*b43f86b8Schristos 	did_longjmp = true;
152cfe38ef7Spgoyette 	if (test == TEST_SETJMP)
153cfe38ef7Spgoyette 		longjmp(jb, i);
154*b43f86b8Schristos 	else if (test == TEST_LONGJMP_ZERO)
155*b43f86b8Schristos 		longjmp(jb, 0);
156cfe38ef7Spgoyette 	else if (test == TEST_U_SETJMP)
157cfe38ef7Spgoyette 		_longjmp(jb, i);
158*b43f86b8Schristos 	else if (test == TEST_U_LONGJMP_ZERO)
159*b43f86b8Schristos 		_longjmp(jb, 0);
160cfe38ef7Spgoyette 	else
161cfe38ef7Spgoyette 		siglongjmp(sjb, i);
162cfe38ef7Spgoyette 
163cfe38ef7Spgoyette 	atf_tc_fail("jmp failed");
164cfe38ef7Spgoyette }
165cfe38ef7Spgoyette 
166cfe38ef7Spgoyette ATF_TC(setjmp);
ATF_TC_HEAD(setjmp,tc)167cfe38ef7Spgoyette ATF_TC_HEAD(setjmp, tc)
168cfe38ef7Spgoyette {
169cfe38ef7Spgoyette 	atf_tc_set_md_var(tc, "descr", "Checks setjmp(3)");
170cfe38ef7Spgoyette }
ATF_TC_BODY(setjmp,tc)171cfe38ef7Spgoyette ATF_TC_BODY(setjmp, tc)
172cfe38ef7Spgoyette {
173cfe38ef7Spgoyette 	h_check(TEST_SETJMP);
174cfe38ef7Spgoyette }
175cfe38ef7Spgoyette 
176cfe38ef7Spgoyette ATF_TC(_setjmp);
ATF_TC_HEAD(_setjmp,tc)177cfe38ef7Spgoyette ATF_TC_HEAD(_setjmp, tc)
178cfe38ef7Spgoyette {
179cfe38ef7Spgoyette 	atf_tc_set_md_var(tc, "descr", "Checks _setjmp(3)");
180cfe38ef7Spgoyette }
ATF_TC_BODY(_setjmp,tc)181cfe38ef7Spgoyette ATF_TC_BODY(_setjmp, tc)
182cfe38ef7Spgoyette {
183cfe38ef7Spgoyette 	h_check(TEST_U_SETJMP);
184cfe38ef7Spgoyette }
185cfe38ef7Spgoyette 
186cfe38ef7Spgoyette ATF_TC(sigsetjmp_save);
ATF_TC_HEAD(sigsetjmp_save,tc)187cfe38ef7Spgoyette ATF_TC_HEAD(sigsetjmp_save, tc)
188cfe38ef7Spgoyette {
189cfe38ef7Spgoyette 	atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask enabled");
190cfe38ef7Spgoyette }
ATF_TC_BODY(sigsetjmp_save,tc)191cfe38ef7Spgoyette ATF_TC_BODY(sigsetjmp_save, tc)
192cfe38ef7Spgoyette {
193cfe38ef7Spgoyette 	h_check(TEST_SIGSETJMP_SAVE);
194cfe38ef7Spgoyette }
195cfe38ef7Spgoyette 
196cfe38ef7Spgoyette ATF_TC(sigsetjmp_nosave);
ATF_TC_HEAD(sigsetjmp_nosave,tc)197cfe38ef7Spgoyette ATF_TC_HEAD(sigsetjmp_nosave, tc)
198cfe38ef7Spgoyette {
199cfe38ef7Spgoyette 	atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled");
200cfe38ef7Spgoyette }
ATF_TC_BODY(sigsetjmp_nosave,tc)201cfe38ef7Spgoyette ATF_TC_BODY(sigsetjmp_nosave, tc)
202cfe38ef7Spgoyette {
203cfe38ef7Spgoyette 	h_check(TEST_SIGSETJMP_NOSAVE);
204cfe38ef7Spgoyette }
205cfe38ef7Spgoyette 
206*b43f86b8Schristos ATF_TC(longjmp_zero);
ATF_TC_HEAD(longjmp_zero,tc)207*b43f86b8Schristos ATF_TC_HEAD(longjmp_zero, tc)
208*b43f86b8Schristos {
209*b43f86b8Schristos 	atf_tc_set_md_var(tc, "descr", "Checks longjmp(3) with a zero value");
210*b43f86b8Schristos }
ATF_TC_BODY(longjmp_zero,tc)211*b43f86b8Schristos ATF_TC_BODY(longjmp_zero, tc)
212*b43f86b8Schristos {
213*b43f86b8Schristos 	h_check(TEST_LONGJMP_ZERO);
214*b43f86b8Schristos }
215*b43f86b8Schristos 
216*b43f86b8Schristos ATF_TC(_longjmp_zero);
ATF_TC_HEAD(_longjmp_zero,tc)217*b43f86b8Schristos ATF_TC_HEAD(_longjmp_zero, tc)
218*b43f86b8Schristos {
219*b43f86b8Schristos 	atf_tc_set_md_var(tc, "descr", "Checks _longjmp(3) with a zero value");
220*b43f86b8Schristos }
ATF_TC_BODY(_longjmp_zero,tc)221*b43f86b8Schristos ATF_TC_BODY(_longjmp_zero, tc)
222*b43f86b8Schristos {
223*b43f86b8Schristos 	h_check(TEST_U_LONGJMP_ZERO);
224*b43f86b8Schristos }
225*b43f86b8Schristos 
ATF_TP_ADD_TCS(tp)226cfe38ef7Spgoyette ATF_TP_ADD_TCS(tp)
227cfe38ef7Spgoyette {
228cfe38ef7Spgoyette 	ATF_TP_ADD_TC(tp, setjmp);
229cfe38ef7Spgoyette 	ATF_TP_ADD_TC(tp, _setjmp);
230cfe38ef7Spgoyette 	ATF_TP_ADD_TC(tp, sigsetjmp_save);
231cfe38ef7Spgoyette 	ATF_TP_ADD_TC(tp, sigsetjmp_nosave);
232*b43f86b8Schristos 	ATF_TP_ADD_TC(tp, longjmp_zero);
233*b43f86b8Schristos 	ATF_TP_ADD_TC(tp, _longjmp_zero);
234cfe38ef7Spgoyette 
235cfe38ef7Spgoyette 	return atf_no_error();
236cfe38ef7Spgoyette }
237