1*49a6e16fSderaadt /* $OpenBSD: t_sigaction.c,v 1.2 2021/12/13 16:56:48 deraadt Exp $ */
2a545a52cSbluhm /* $NetBSD: t_sigaction.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */
3a545a52cSbluhm
4a545a52cSbluhm /*-
5a545a52cSbluhm * Copyright (c) 2010 The NetBSD Foundation, Inc.
6a545a52cSbluhm * All rights reserved.
7a545a52cSbluhm *
8a545a52cSbluhm * Redistribution and use in source and binary forms, with or without
9a545a52cSbluhm * modification, are permitted provided that the following conditions
10a545a52cSbluhm * are met:
11a545a52cSbluhm * 1. Redistributions of source code must retain the above copyright
12a545a52cSbluhm * notice, this list of conditions and the following disclaimer.
13a545a52cSbluhm * 2. Redistributions in binary form must reproduce the above copyright
14a545a52cSbluhm * notice, this list of conditions and the following disclaimer in the
15a545a52cSbluhm * documentation and/or other materials provided with the distribution.
16a545a52cSbluhm *
17a545a52cSbluhm * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18a545a52cSbluhm * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19a545a52cSbluhm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20a545a52cSbluhm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21a545a52cSbluhm * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22a545a52cSbluhm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23a545a52cSbluhm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24a545a52cSbluhm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25a545a52cSbluhm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26a545a52cSbluhm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27a545a52cSbluhm * POSSIBILITY OF SUCH DAMAGE.
28a545a52cSbluhm */
29a545a52cSbluhm
30a545a52cSbluhm #include "macros.h"
31a545a52cSbluhm
32a545a52cSbluhm #include <sys/wait.h>
33a545a52cSbluhm
34a545a52cSbluhm #include <signal.h>
35a545a52cSbluhm #include <stdbool.h>
36a545a52cSbluhm #include <stdlib.h>
37a545a52cSbluhm #include <string.h>
38a545a52cSbluhm #include <unistd.h>
39a545a52cSbluhm
40a545a52cSbluhm #include "atf-c.h"
41a545a52cSbluhm
42a545a52cSbluhm #include "h_macros.h"
43a545a52cSbluhm
44a545a52cSbluhm static bool handler_called = false;
45a545a52cSbluhm
46a545a52cSbluhm static void
handler(int signo __unused)47a545a52cSbluhm handler(int signo __unused)
48a545a52cSbluhm {
49a545a52cSbluhm handler_called = true;
50a545a52cSbluhm }
51a545a52cSbluhm
52a545a52cSbluhm static void
sa_resethand_child(const int flags)53a545a52cSbluhm sa_resethand_child(const int flags)
54a545a52cSbluhm {
55a545a52cSbluhm struct sigaction sa;
56a545a52cSbluhm
57a545a52cSbluhm sa.sa_flags = flags;
58a545a52cSbluhm sa.sa_handler = &handler;
59a545a52cSbluhm sigemptyset(&sa.sa_mask);
60a545a52cSbluhm
61a545a52cSbluhm sigaction(SIGUSR1, &sa, NULL);
62a545a52cSbluhm kill(getpid(), SIGUSR1);
63a545a52cSbluhm exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE);
64a545a52cSbluhm }
65a545a52cSbluhm
66a545a52cSbluhm static void
wait_and_check_child(const pid_t pid,const char * fail_message)67a545a52cSbluhm wait_and_check_child(const pid_t pid, const char *fail_message)
68a545a52cSbluhm {
69a545a52cSbluhm int status;
70a545a52cSbluhm
71a545a52cSbluhm (void)waitpid(pid, &status, 0);
72a545a52cSbluhm
73a545a52cSbluhm if (WIFEXITED(status))
74a545a52cSbluhm ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
75a545a52cSbluhm else
76a545a52cSbluhm atf_tc_fail("%s; raw exit status was %d", fail_message, status);
77a545a52cSbluhm }
78a545a52cSbluhm
79a545a52cSbluhm static void
catch(int sig __unused)80a545a52cSbluhm catch(int sig __unused)
81a545a52cSbluhm {
82a545a52cSbluhm return;
83a545a52cSbluhm }
84a545a52cSbluhm
85a545a52cSbluhm ATF_TC(sigaction_basic);
ATF_TC_HEAD(sigaction_basic,tc)86a545a52cSbluhm ATF_TC_HEAD(sigaction_basic, tc)
87a545a52cSbluhm {
88a545a52cSbluhm
89a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache"
90a545a52cSbluhm "synchronization after copying out the trampoline code.");
91a545a52cSbluhm }
92a545a52cSbluhm
ATF_TC_BODY(sigaction_basic,tc)93a545a52cSbluhm ATF_TC_BODY(sigaction_basic, tc)
94a545a52cSbluhm {
95a545a52cSbluhm static struct sigaction sa;
96a545a52cSbluhm
97a545a52cSbluhm sa.sa_handler = catch;
98a545a52cSbluhm
99a545a52cSbluhm sigaction(SIGUSR1, &sa, 0);
100a545a52cSbluhm kill(getpid(), SIGUSR1);
101a545a52cSbluhm atf_tc_pass();
102a545a52cSbluhm }
103a545a52cSbluhm
104a545a52cSbluhm ATF_TC(sigaction_noflags);
ATF_TC_HEAD(sigaction_noflags,tc)105a545a52cSbluhm ATF_TC_HEAD(sigaction_noflags, tc)
106a545a52cSbluhm {
107a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "Checks programming a signal with "
108a545a52cSbluhm "sigaction(2) but without any flags");
109a545a52cSbluhm }
110a545a52cSbluhm
ATF_TC_BODY(sigaction_noflags,tc)111a545a52cSbluhm ATF_TC_BODY(sigaction_noflags, tc)
112a545a52cSbluhm {
113a545a52cSbluhm const pid_t pid = fork();
114a545a52cSbluhm if (pid == -1)
115a545a52cSbluhm atf_tc_fail_errno("fork(2) failed");
116a545a52cSbluhm else if (pid == 0)
117a545a52cSbluhm sa_resethand_child(0);
118a545a52cSbluhm else
119a545a52cSbluhm wait_and_check_child(pid, "Child process did not exit cleanly;"
120a545a52cSbluhm " it failed to process the signal");
121a545a52cSbluhm }
122a545a52cSbluhm
123a545a52cSbluhm ATF_TC(sigaction_resethand);
ATF_TC_HEAD(sigaction_resethand,tc)124a545a52cSbluhm ATF_TC_HEAD(sigaction_resethand, tc)
125a545a52cSbluhm {
126a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works");
127a545a52cSbluhm }
128a545a52cSbluhm
ATF_TC_BODY(sigaction_resethand,tc)129a545a52cSbluhm ATF_TC_BODY(sigaction_resethand, tc)
130a545a52cSbluhm {
131a545a52cSbluhm const pid_t pid = fork();
132a545a52cSbluhm if (pid == -1)
133a545a52cSbluhm atf_tc_fail_errno("fork(2) failed");
134a545a52cSbluhm else if (pid == 0)
135a545a52cSbluhm sa_resethand_child(SA_RESETHAND);
136a545a52cSbluhm else {
137a545a52cSbluhm wait_and_check_child(pid, "Child process did not exit cleanly;"
138a545a52cSbluhm " it either failed to process the signal or SA_RESETHAND"
139a545a52cSbluhm " is broken");
140a545a52cSbluhm }
141a545a52cSbluhm }
142a545a52cSbluhm
ATF_TP_ADD_TCS(tp)143a545a52cSbluhm ATF_TP_ADD_TCS(tp)
144a545a52cSbluhm {
145a545a52cSbluhm
146a545a52cSbluhm ATF_TP_ADD_TC(tp, sigaction_basic);
147a545a52cSbluhm ATF_TP_ADD_TC(tp, sigaction_noflags);
148a545a52cSbluhm ATF_TP_ADD_TC(tp, sigaction_resethand);
149a545a52cSbluhm
150a545a52cSbluhm return atf_no_error();
151a545a52cSbluhm }
152