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