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 <gtest/gtest.h> 18 19 #include <errno.h> 20 #include <signal.h> 21 22 template <typename Fn> 23 static void TestSigSet1(Fn fn) { 24 // NULL sigset_t*. 25 sigset_t* set_ptr = NULL; 26 errno = 0; 27 ASSERT_EQ(-1, fn(set_ptr)); 28 ASSERT_EQ(EINVAL, errno); 29 30 // Non-NULL. 31 sigset_t set; 32 errno = 0; 33 ASSERT_EQ(0, fn(&set)); 34 ASSERT_EQ(0, errno); 35 } 36 37 template <typename Fn> 38 static void TestSigSet2(Fn fn) { 39 // NULL sigset_t*. 40 sigset_t* set_ptr = NULL; 41 errno = 0; 42 ASSERT_EQ(-1, fn(set_ptr, SIGSEGV)); 43 ASSERT_EQ(EINVAL, errno); 44 45 sigset_t set; 46 sigemptyset(&set); 47 48 int min_signal = SIGHUP; 49 int max_signal = SIGRTMAX; 50 51 #if defined(__BIONIC__) && !defined(__mips__) 52 // bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64. 53 // This means you can't refer to any of the real-time signals. 54 // See http://b/3038348 and http://b/5828899. 55 max_signal = 32; 56 #else 57 // Other C libraries (or bionic for MIPS) are perfectly capable of using their largest signal. 58 ASSERT_GE(sizeof(sigset_t) * 8, static_cast<size_t>(SIGRTMAX)); 59 #endif 60 61 // Bad signal number: too small. 62 errno = 0; 63 ASSERT_EQ(-1, fn(&set, 0)); 64 ASSERT_EQ(EINVAL, errno); 65 66 // Bad signal number: too high. 67 errno = 0; 68 ASSERT_EQ(-1, fn(&set, max_signal + 1)); 69 ASSERT_EQ(EINVAL, errno); 70 71 // Good signal numbers, low and high ends of range. 72 errno = 0; 73 ASSERT_EQ(0, fn(&set, min_signal)); 74 ASSERT_EQ(0, errno); 75 ASSERT_EQ(0, fn(&set, max_signal)); 76 ASSERT_EQ(0, errno); 77 } 78 79 class ScopedSignalHandler { 80 public: 81 ScopedSignalHandler(int signal_number, void (*handler)(int)) : signal_number_(signal_number) { 82 sigemptyset(&action_.sa_mask); 83 action_.sa_flags = 0; 84 action_.sa_handler = handler; 85 sigaction(signal_number_, &action_, &old_action_); 86 } 87 88 ~ScopedSignalHandler() { 89 sigaction(signal_number_, &old_action_, NULL); 90 } 91 92 private: 93 struct sigaction action_; 94 struct sigaction old_action_; 95 const int signal_number_; 96 }; 97 98 TEST(signal, sigismember_invalid) { 99 TestSigSet2(sigismember); 100 } 101 102 TEST(signal, sigaddset_invalid) { 103 TestSigSet2(sigaddset); 104 } 105 106 TEST(signal, sigdelset_invalid) { 107 TestSigSet2(sigdelset); 108 } 109 110 TEST(signal, sigemptyset_invalid) { 111 TestSigSet1(sigemptyset); 112 } 113 114 TEST(signal, sigfillset_invalid) { 115 TestSigSet1(sigfillset); 116 } 117 118 TEST(signal, raise_invalid) { 119 errno = 0; 120 ASSERT_EQ(-1, raise(-1)); 121 ASSERT_EQ(EINVAL, errno); 122 } 123 124 static void raise_in_signal_handler_helper(int signal_number) { 125 ASSERT_EQ(SIGALRM, signal_number); 126 static int count = 0; 127 if (++count == 1) { 128 raise(SIGALRM); 129 } 130 } 131 132 TEST(signal, raise_in_signal_handler) { 133 ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper); 134 raise(SIGALRM); 135 } 136 137 static void HandleSIGALRM(int signal_number) { 138 ASSERT_EQ(SIGALRM, signal_number); 139 } 140 141 TEST(signal, sigwait) { 142 ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM); 143 144 sigset_t wait_set; 145 sigemptyset(&wait_set); 146 sigaddset(&wait_set, SIGALRM); 147 148 alarm(1); 149 150 int received_signal; 151 errno = 0; 152 ASSERT_EQ(0, sigwait(&wait_set, &received_signal)); 153 ASSERT_EQ(0, errno); 154 ASSERT_EQ(SIGALRM, received_signal); 155 } 156