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