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(&not_SIGALRM);
1881f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes  sigdelset(&not_SIGALRM, SIGALRM);
1891f5af926fa626734981d6b4dcc0ab54e520032a9Elliott Hughes  ASSERT_EQ(-1, sigsuspend(&not_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