1da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes/* 2da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * Copyright (C) 2012 The Android Open Source Project 3da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * 4da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * you may not use this file except in compliance with the License. 6da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * You may obtain a copy of the License at 7da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * 8da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * 10da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * Unless required by applicable law or agreed to in writing, software 11da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * See the License for the specific language governing permissions and 14da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes * limitations under the License. 15da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes */ 16da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 17afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes#include <signal.h> 18da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 19afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes#include <gtest/gtest.h> 20da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 21634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui#include <errno.h> 22634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 2313613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris#include "ScopedSignalHandler.h" 2413613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris 2540d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughesstatic size_t SIGNAL_MIN() { 2640d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes return 1; // Signals start at 1 (SIGHUP), not 0. 2740d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes} 2840d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes 2940d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughesstatic size_t SIGNAL_MAX() { 3040d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes size_t result = SIGRTMAX; 3140d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes 3240d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes#if defined(__BIONIC__) && !defined(__mips__) && !defined(__LP64__) 3340d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes // 32-bit bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64. 3440d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes // This means you can't refer to any of the real-time signals. 3540d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes // See http://b/3038348 and http://b/5828899. 3640d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes result = 32; 3740d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes#else 3840d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes // Otherwise, C libraries should be perfectly capable of using their largest signal. 3940d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes if (sizeof(sigset_t) * 8 < static_cast<size_t>(SIGRTMAX)) { 4040d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes abort(); 4140d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes } 4240d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes#endif 4340d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes 4440d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes return result; 4540d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes} 4640d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes 47da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughestemplate <typename Fn> 48da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughesstatic void TestSigSet1(Fn fn) { 49da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes // NULL sigset_t*. 50da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes sigset_t* set_ptr = NULL; 51da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes errno = 0; 52da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(-1, fn(set_ptr)); 53da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(EINVAL, errno); 54da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 55da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes // Non-NULL. 56da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes sigset_t set; 57da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes errno = 0; 58da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(0, fn(&set)); 59da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(0, errno); 60da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 61da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 62da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughestemplate <typename Fn> 63da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughesstatic void TestSigSet2(Fn fn) { 64da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes // NULL sigset_t*. 65da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes sigset_t* set_ptr = NULL; 66da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes errno = 0; 67da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(-1, fn(set_ptr, SIGSEGV)); 68da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(EINVAL, errno); 69da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 70da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes sigset_t set; 71da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes sigemptyset(&set); 72da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 73da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes // Bad signal number: too small. 74da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes errno = 0; 75da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(-1, fn(&set, 0)); 76da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(EINVAL, errno); 77da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 78da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes // Bad signal number: too high. 79da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes errno = 0; 8040d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes ASSERT_EQ(-1, fn(&set, SIGNAL_MAX() + 1)); 81da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(EINVAL, errno); 82da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 83da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes // Good signal numbers, low and high ends of range. 84da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes errno = 0; 8540d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes ASSERT_EQ(0, fn(&set, SIGNAL_MIN())); 86da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(0, errno); 8740d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes ASSERT_EQ(0, fn(&set, SIGNAL_MAX())); 88da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes ASSERT_EQ(0, errno); 89da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 90da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 91da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott HughesTEST(signal, sigismember_invalid) { 92da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes TestSigSet2(sigismember); 93da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 94da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 95da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott HughesTEST(signal, sigaddset_invalid) { 96da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes TestSigSet2(sigaddset); 97da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 98da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 99da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott HughesTEST(signal, sigdelset_invalid) { 100da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes TestSigSet2(sigdelset); 101da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 102da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 103da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott HughesTEST(signal, sigemptyset_invalid) { 104da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes TestSigSet1(sigemptyset); 105da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 106da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes 107da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott HughesTEST(signal, sigfillset_invalid) { 108da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes TestSigSet1(sigfillset); 109da73f655fcbac6e1a8bfd35303cef6f41187d12bElliott Hughes} 110d8a5a6f513c6fa99229e9c82c5c308c7cd6b3d54Chris Dearman 111d8a5a6f513c6fa99229e9c82c5c308c7cd6b3d54Chris DearmanTEST(signal, raise_invalid) { 112d8a5a6f513c6fa99229e9c82c5c308c7cd6b3d54Chris Dearman errno = 0; 113d8a5a6f513c6fa99229e9c82c5c308c7cd6b3d54Chris Dearman ASSERT_EQ(-1, raise(-1)); 114d8a5a6f513c6fa99229e9c82c5c308c7cd6b3d54Chris Dearman ASSERT_EQ(EINVAL, errno); 115d8a5a6f513c6fa99229e9c82c5c308c7cd6b3d54Chris Dearman} 116c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 117fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughesstatic void raise_in_signal_handler_helper(int signal_number) { 118fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ASSERT_EQ(SIGALRM, signal_number); 119fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes static int count = 0; 120fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes if (++count == 1) { 121fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes raise(SIGALRM); 122fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes } 123fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 124fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 125fae89fc4042ee4c360842234dfda7831c313bd44Elliott HughesTEST(signal, raise_in_signal_handler) { 126fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper); 127fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes raise(SIGALRM); 128fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes} 129fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes 130c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughesstatic void HandleSIGALRM(int signal_number) { 131c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(SIGALRM, signal_number); 132c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 133c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 134c5d028fc913de84a781bd61084bf7ae2182fd48eElliott HughesTEST(signal, sigwait) { 135fae89fc4042ee4c360842234dfda7831c313bd44Elliott Hughes ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM); 136c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 137c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigset_t wait_set; 138c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigemptyset(&wait_set); 139c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes sigaddset(&wait_set, SIGALRM); 140c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 141c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes alarm(1); 142c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes 143c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes int received_signal; 144c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes errno = 0; 145c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, sigwait(&wait_set, &received_signal)); 146c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(0, errno); 147c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes ASSERT_EQ(SIGALRM, received_signal); 148c5d028fc913de84a781bd61084bf7ae2182fd48eElliott Hughes} 1491f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes 1501728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic int g_sigsuspend_test_helper_call_count = 0; 1511f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes 1521f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughesstatic void SigSuspendTestHelper(int) { 1531728b2396591853345507a063ed6075dfd251706Elliott Hughes ++g_sigsuspend_test_helper_call_count; 1541f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes} 1551f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes 15640d105ccb3e6283566ce54b693b3088f31aa4f26Elliott HughesTEST(signal, sigsuspend_sigpending) { 1571f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes // Block SIGALRM. 1581f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigset_t just_SIGALRM; 1591f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigemptyset(&just_SIGALRM); 1601f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigaddset(&just_SIGALRM, SIGALRM); 1611f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigset_t original_set; 1621f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 1631f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes 16411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper); 16511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 16640d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes // There should be no pending signals. 16740d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes sigset_t pending; 16840d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes sigemptyset(&pending); 16940d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes ASSERT_EQ(0, sigpending(&pending)); 17040d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { 17140d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes EXPECT_FALSE(sigismember(&pending, i)) << i; 17240d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes } 17340d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes 1741f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes // Raise SIGALRM and check our signal handler wasn't called. 1751f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes raise(SIGALRM); 1761728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(0, g_sigsuspend_test_helper_call_count); 1771f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes 17840d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes // We should now have a pending SIGALRM but nothing else. 17940d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes sigemptyset(&pending); 18040d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes ASSERT_EQ(0, sigpending(&pending)); 18140d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { 18240d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes EXPECT_EQ((i == SIGALRM), sigismember(&pending, i)); 18340d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes } 18440d105ccb3e6283566ce54b693b3088f31aa4f26Elliott Hughes 1851f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes // Use sigsuspend to block everything except SIGALRM... 1861f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigset_t not_SIGALRM; 1871f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigfillset(¬_SIGALRM); 1881f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes sigdelset(¬_SIGALRM, SIGALRM); 1891f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes ASSERT_EQ(-1, sigsuspend(¬_SIGALRM)); 1901f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes ASSERT_EQ(EINTR, errno); 1911f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes // ...and check that we now receive our pending SIGALRM. 1921728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_EQ(1, g_sigsuspend_test_helper_call_count); 1931f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes 1941f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes // Restore the original set. 19511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 1961f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes} 197c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes 198c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughesstatic void EmptySignalHandler(int) {} 199c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughesstatic void EmptySignalAction(int, siginfo_t*, void*) {} 200c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes 201c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott HughesTEST(signal, sigaction) { 202afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes // Both bionic and glibc set SA_RESTORER when talking to the kernel on arm, 203afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes // arm64, x86, and x86-64. The version of glibc we're using also doesn't 204afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes // define SA_RESTORER, but luckily it's the same value everywhere, and mips 205afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes // doesn't use the bit for anything. 206aa13e839f06231b9299bb683a71abd954294b49bElliott Hughes static const unsigned sa_restorer = 0x4000000; 207afe58ad9892de27a7acb0aaded6312ee0f958314Elliott Hughes 208c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes // See what's currently set for SIGALRM. 20911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes struct sigaction original_sa; 21011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes memset(&original_sa, 0, sizeof(original_sa)); 21111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa)); 21211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ASSERT_TRUE(original_sa.sa_handler == NULL); 21311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ASSERT_TRUE(original_sa.sa_sigaction == NULL); 214aa13e839f06231b9299bb683a71abd954294b49bElliott Hughes ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer); 215c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes 216c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes // Set a traditional sa_handler signal handler. 21711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes struct sigaction sa; 218c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes memset(&sa, 0, sizeof(sa)); 219c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes sigaddset(&sa.sa_mask, SIGALRM); 220c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes sa.sa_flags = SA_ONSTACK; 221c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes sa.sa_handler = EmptySignalHandler; 222c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL)); 223c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes 224c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes // Check that we can read it back. 225c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes memset(&sa, 0, sizeof(sa)); 226c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); 227c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_TRUE(sa.sa_handler == EmptySignalHandler); 228c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); 229aa13e839f06231b9299bb683a71abd954294b49bElliott Hughes ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer); 230c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes 231c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes // Set a new-style sa_sigaction signal handler. 232c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes memset(&sa, 0, sizeof(sa)); 233c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes sigaddset(&sa.sa_mask, SIGALRM); 234c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes sa.sa_flags = SA_ONSTACK | SA_SIGINFO; 235c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes sa.sa_sigaction = EmptySignalAction; 236c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL)); 237c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes 238c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes // Check that we can read it back. 239c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes memset(&sa, 0, sizeof(sa)); 240c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa)); 241c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction); 242c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler); 243aa13e839f06231b9299bb683a71abd954294b49bElliott Hughes ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer); 24411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 24511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes // Put everything back how it was. 24611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL)); 247c7e9b2331771e5e87c34a8ee3dc6cc41d35b02feElliott Hughes} 248aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes 249aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott HughesTEST(signal, sys_signame) { 250671e236d5fd2cae169c2a31d0a35e66c4fcc5556Elliott Hughes#if defined(__BIONIC__) 251aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes ASSERT_TRUE(sys_signame[0] == NULL); 252aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes ASSERT_STREQ("HUP", sys_signame[SIGHUP]); 253aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes#else 254aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes GTEST_LOG_(INFO) << "This test does nothing.\n"; 255aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes#endif 256aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes} 257aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes 258aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott HughesTEST(signal, sys_siglist) { 259aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes ASSERT_TRUE(sys_siglist[0] == NULL); 260aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes ASSERT_STREQ("Hangup", sys_siglist[SIGHUP]); 261aa0ebdafc71e1ceac78e0929b94f3bb117d0c8e9Elliott Hughes} 2620990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes 2630990d4fda898ada86e557f872f5cb7d16b138e3cElliott HughesTEST(signal, limits) { 2640990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes // This comes from the kernel. 2650990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes ASSERT_EQ(32, __SIGRTMIN); 2660990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes 2670990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes // We reserve a non-zero number at the bottom for ourselves. 2680990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes ASSERT_GT(SIGRTMIN, __SIGRTMIN); 2690990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes 2700990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes // MIPS has more signals than everyone else. 2710990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes#if defined(__mips__) 2720990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes ASSERT_EQ(128, __SIGRTMAX); 2730990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes#else 2740990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes ASSERT_EQ(64, __SIGRTMAX); 2750990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes#endif 2760990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes 2770990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes // We don't currently reserve any at the top. 2780990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes ASSERT_EQ(SIGRTMAX, __SIGRTMAX); 2790990d4fda898ada86e557f872f5cb7d16b138e3cElliott Hughes} 280634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 281634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuistatic int g_sigqueue_signal_handler_call_count = 0; 282634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 283634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuistatic void SigqueueSignalHandler(int signum, siginfo_t* info, void*) { 284634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(SIGALRM, signum); 285634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(SIGALRM, info->si_signo); 286634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(SI_QUEUE, info->si_code); 287634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(1, info->si_value.sival_int); 288634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ++g_sigqueue_signal_handler_call_count; 289634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui} 290634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 291634816055f51c536d24dea30dfe930b7fe2fa603Yabin CuiTEST(signal, sigqueue) { 292634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO); 293634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigval_t sigval; 294634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigval.sival_int = 1; 295634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui errno = 0; 296634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); 297634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, errno); 298634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(1, g_sigqueue_signal_handler_call_count); 299634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui} 300634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 301634816055f51c536d24dea30dfe930b7fe2fa603Yabin CuiTEST(signal, sigwaitinfo) { 302634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Block SIGALRM. 303634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigset_t just_SIGALRM; 304634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigemptyset(&just_SIGALRM); 305634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigaddset(&just_SIGALRM, SIGALRM); 306634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigset_t original_set; 307634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 308634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 309634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Raise SIGALRM. 310634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigval_t sigval; 311634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigval.sival_int = 1; 312634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); 313634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 314634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Get pending SIGALRM. 315634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui siginfo_t info; 316634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui errno = 0; 317634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(SIGALRM, sigwaitinfo(&just_SIGALRM, &info)); 318634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, errno); 319634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(SIGALRM, info.si_signo); 320634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(1, info.si_value.sival_int); 321634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 322634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 323634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui} 324634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 325634816055f51c536d24dea30dfe930b7fe2fa603Yabin CuiTEST(signal, sigtimedwait) { 326634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Block SIGALRM. 327634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigset_t just_SIGALRM; 328634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigemptyset(&just_SIGALRM); 329634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigaddset(&just_SIGALRM, SIGALRM); 330634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigset_t original_set; 331634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 332634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 333634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Raise SIGALRM. 334634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigval_t sigval; 335634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigval.sival_int = 1; 336634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval)); 337634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 338634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Get pending SIGALRM. 339634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui siginfo_t info; 340634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui struct timespec timeout; 341634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui timeout.tv_sec = 2; 342634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui timeout.tv_nsec = 0; 343634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui errno = 0; 344634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(SIGALRM, sigtimedwait(&just_SIGALRM, &info, &timeout)); 345634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, errno); 346634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 347634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 348634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui} 349634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 350634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cuistatic int64_t NanoTime() { 351634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui struct timespec t; 352634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui t.tv_sec = t.tv_nsec = 0; 353634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui clock_gettime(CLOCK_MONOTONIC, &t); 354634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec; 355634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui} 356634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 357634816055f51c536d24dea30dfe930b7fe2fa603Yabin CuiTEST(signal, sigtimedwait_timeout) { 358634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Block SIGALRM. 359634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigset_t just_SIGALRM; 360634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigemptyset(&just_SIGALRM); 361634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigaddset(&just_SIGALRM, SIGALRM); 362634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui sigset_t original_set; 363634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); 364634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 365634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui // Wait timeout. 366634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui int64_t start_time = NanoTime(); 367634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui siginfo_t info; 368634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui struct timespec timeout; 369634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui timeout.tv_sec = 0; 370634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui timeout.tv_nsec = 1000000; 371634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui errno = 0; 372634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(-1, sigtimedwait(&just_SIGALRM, &info, &timeout)); 373634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(EAGAIN, errno); 374634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_GE(NanoTime() - start_time, 1000000); 375634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui 376634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL)); 377634816055f51c536d24dea30dfe930b7fe2fa603Yabin Cui} 378