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