1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <signal.h> 18 19 #include <errno.h> 20 #include <gtest/gtest.h> 21 22 #include "ScopedSignalHandler.h" 23 24 static size_t SIGNAL_MIN() { 25 return 1; // Signals start at 1 (SIGHUP), not 0. 26 } 27 28 static size_t SIGNAL_MAX() { 29 size_t result = SIGRTMAX; 30 31 #if defined(__BIONIC__) && !defined(__mips__) && !defined(__LP64__) 32 // 32-bit bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64. 33 // This means you can't refer to any of the real-time signals. 34 // See http://b/3038348 and http://b/5828899. 35 result = 32; 36 #else 37 // Otherwise, C libraries should be perfectly capable of using their largest signal. 38 if (sizeof(sigset_t) * 8 < static_cast<size_t>(SIGRTMAX)) { 39 abort(); 40 } 41 #endif 42 43 return result; 44 } 45 46 template <typename Fn> 47 static void TestSigSet1(Fn fn) { 48 // NULL sigset_t*. 49 sigset_t* set_ptr = NULL; 50 errno = 0; 51 ASSERT_EQ(-1, fn(set_ptr)); 52 ASSERT_EQ(EINVAL, errno); 53 54 // Non-NULL. 55 sigset_t set; 56 errno = 0; 57 ASSERT_EQ(0, fn(&set)); 58 ASSERT_EQ(0, errno); 59 } 60 61 template <typename Fn> 62 static void TestSigSet2(Fn fn) { 63 // NULL sigset_t*. 64 sigset_t* set_ptr = NULL; 65 errno = 0; 66 ASSERT_EQ(-1, fn(set_ptr, SIGSEGV)); 67 ASSERT_EQ(EINVAL, errno); 68 69 sigset_t set; 70 sigemptyset(&set); 71 72 // Bad signal number: too small. 73 errno = 0; 74 ASSERT_EQ(-1, fn(&set, 0)); 75 ASSERT_EQ(EINVAL, errno); 76 77 // Bad signal number: too high. 78 errno = 0; 79 ASSERT_EQ(-1, fn(&set, SIGNAL_MAX() + 1)); 80 ASSERT_EQ(EINVAL, errno); 81 82 // Good signal numbers, low and high ends of range. 83 errno = 0; 84 ASSERT_EQ(0, fn(&set, SIGNAL_MIN())); 85 ASSERT_EQ(0, errno); 86 ASSERT_EQ(0, fn(&set, SIGNAL_MAX())); 87 ASSERT_EQ(0, errno); 88 } 89 90 TEST(signal, sigismember_invalid) { 91 TestSigSet2(sigismember); 92 } 93 94 TEST(signal, sigaddset_invalid) { 95 TestSigSet2(sigaddset); 96 } 97 98 TEST(signal, sigdelset_invalid) { 99 TestSigSet2(sigdelset); 100 } 101 102 TEST(signal, sigemptyset_invalid) { 103 TestSigSet1(sigemptyset); 104 } 105 106 TEST(signal, sigfillset_invalid) { 107 TestSigSet1(sigfillset); 108 } 109 110 TEST(signal, raise_invalid) { 111 errno = 0; 112 ASSERT_EQ(-1, raise(-1)); 113 ASSERT_EQ(EINVAL, errno); 114 } 115 116 static void raise_in_signal_handler_helper(int signal_number) { 117 ASSERT_EQ(SIGALRM, signal_number); 118 static int count = 0; 119 if (++count == 1) { 120 raise(SIGALRM); 121 } 122 } 123 124 TEST(signal, raise_in_signal_handler) { 125 ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper); 126 raise(SIGALRM); 127 } 128 129 static void HandleSIGALRM(int signal_number) { 130 ASSERT_EQ(SIGALRM, signal_number); 131 } 132 133 TEST(signal, sigwait) { 134 ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM); 135 136 sigset_t wait_set; 137 sigemptyset(&wait_set); 138 sigaddset(&wait_set, SIGALRM); 139 140 alarm(1); 141 142 int received_signal; 143 errno = 0; 144 ASSERT_EQ(0, sigwait(&wait_set, &received_signal)); 145 ASSERT_EQ(0, errno); 146 ASSERT_EQ(SIGALRM, received_signal); 147 } 148 149 static int g_sigsuspend_test_helper_call_count = 0; 150 151 static void SigSuspendTestHelper(int) { 152 ++g_sigsuspend_test_helper_call_count; 153 } 154 155 TEST(signal, sigsuspend_sigpending) { 156 // Block SIGALRM. 157 sigset_t just_SIGALRM; 158 sigemptyset(&just_SIGALRM); 159 sigaddset(&just_SIGALRM, SIGALRM); 160 sigset_t original_set; 161 ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 162 163 ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper); 164 165 // There should be no pending signals. 166 sigset_t pending; 167 sigemptyset(&pending); 168 ASSERT_EQ(0, sigpending(&pending)); 169 for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { 170 EXPECT_FALSE(sigismember(&pending, i)) << i; 171 } 172 173 // Raise SIGALRM and check our signal handler wasn't called. 174 raise(SIGALRM); 175 ASSERT_EQ(0, g_sigsuspend_test_helper_call_count); 176 177 // We should now have a pending SIGALRM but nothing else. 178 sigemptyset(&pending); 179 ASSERT_EQ(0, sigpending(&pending)); 180 for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { 181 EXPECT_EQ((i == SIGALRM), sigismember(&pending, i)); 182 } 183 184 // Use sigsuspend to block everything except SIGALRM... 185 sigset_t not_SIGALRM; 186 sigfillset(¬_SIGALRM); 187 sigdelset(¬_SIGALRM, SIGALRM); 188 ASSERT_EQ(-1, sigsuspend(¬_SIGALRM)); 189 ASSERT_EQ(EINTR, errno); 190 // ...and check that we now receive our pending SIGALRM. 191 ASSERT_EQ(1, g_sigsuspend_test_helper_call_count); 192 193 // Restore the original set. 194 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 195 } 196 197 static void EmptySignalHandler(int) {} 198 static void EmptySignalAction(int, siginfo_t*, void*) {} 199 200 TEST(signal, sigaction) { 201 // Both bionic and glibc set SA_RESTORER when talking to the kernel on arm, 202 // arm64, x86, and x86-64. The version of glibc we're using also doesn't 203 // define SA_RESTORER, but luckily it's the same value everywhere, and mips 204 // doesn't use the bit for anything. 205 static const unsigned sa_restorer = 0x4000000; 206 207 // See what's currently set for SIGALRM. 208 struct sigaction original_sa; 209 memset(&original_sa, 0, sizeof(original_sa)); 210 ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa)); 211 ASSERT_TRUE(original_sa.sa_handler == NULL); 212 ASSERT_TRUE(original_sa.sa_sigaction == NULL); 213 ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer); 214 215 // Set a traditional sa_handler signal handler. 216 struct sigaction sa; 217 memset(&sa, 0, sizeof(sa)); 218 sigaddset(&sa.sa_mask, SIGALRM); 219 sa.sa_flags = SA_ONSTACK; 220 sa.sa_handler = EmptySignalHandler; 221 ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL)); 222 223 // Check that we can read it back. 224 memset(&sa, 0, sizeof(sa)); 225 ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); 226 ASSERT_TRUE(sa.sa_handler == EmptySignalHandler); 227 ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); 228 ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer); 229 230 // Set a new-style sa_sigaction signal handler. 231 memset(&sa, 0, sizeof(sa)); 232 sigaddset(&sa.sa_mask, SIGALRM); 233 sa.sa_flags = SA_ONSTACK | SA_SIGINFO; 234 sa.sa_sigaction = EmptySignalAction; 235 ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL)); 236 237 // Check that we can read it back. 238 memset(&sa, 0, sizeof(sa)); 239 ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); 240 ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction); 241 ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); 242 ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer); 243 244 // Put everything back how it was. 245 ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL)); 246 } 247 248 TEST(signal, sys_signame) { 249 #if defined(__BIONIC__) 250 ASSERT_TRUE(sys_signame[0] == NULL); 251 ASSERT_STREQ("HUP", sys_signame[SIGHUP]); 252 #else 253 GTEST_LOG_(INFO) << "This test does nothing.\n"; 254 #endif 255 } 256 257 TEST(signal, sys_siglist) { 258 ASSERT_TRUE(sys_siglist[0] == NULL); 259 ASSERT_STREQ("Hangup", sys_siglist[SIGHUP]); 260 } 261 262 TEST(signal, limits) { 263 // This comes from the kernel. 264 ASSERT_EQ(32, __SIGRTMIN); 265 266 // We reserve a non-zero number at the bottom for ourselves. 267 ASSERT_GT(SIGRTMIN, __SIGRTMIN); 268 269 // MIPS has more signals than everyone else. 270 #if defined(__mips__) 271 ASSERT_EQ(128, __SIGRTMAX); 272 #else 273 ASSERT_EQ(64, __SIGRTMAX); 274 #endif 275 276 // We don't currently reserve any at the top. 277 ASSERT_EQ(SIGRTMAX, __SIGRTMAX); 278 } 279