blob: f6ba9ed34d393dc39e302a76c80ad7aac3544483 [file] [log] [blame]
Elliott Hughes14e3ff92017-10-06 16:58:36 -07001/*
2 * Copyright (C) 2017 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
Elliott Hughes71ba5892018-02-07 12:44:45 -080017#pragma once
Elliott Hughes14e3ff92017-10-06 16:58:36 -070018
19#include <signal.h>
20
Josh Gao4956c372019-12-19 16:35:51 -080021#include "platform/bionic/macros.h"
Elliott Hughes14e3ff92017-10-06 16:58:36 -070022
Elliott Hughes3093e712020-04-23 15:53:17 -070023// This code needs to really block all the signals, not just the user-visible
24// ones. We call __rt_sigprocmask(2) directly so we don't mask out our own
25// signals (https://issuetracker.google.com/153624226 was a pthread_exit(3)
26// crash because a request to dump the thread's stack came in as it was exiting).
27extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
28
Elliott Hughes14e3ff92017-10-06 16:58:36 -070029class ScopedSignalBlocker {
30 public:
Elliott Hughes71ba5892018-02-07 12:44:45 -080031 // Block all signals.
Elliott Hughes14e3ff92017-10-06 16:58:36 -070032 explicit ScopedSignalBlocker() {
Elliott Hughes5905d6f2018-01-30 15:09:51 -080033 sigset64_t set;
34 sigfillset64(&set);
Elliott Hughes3093e712020-04-23 15:53:17 -070035 __rt_sigprocmask(SIG_BLOCK, &set, &old_set_, sizeof(sigset64_t));
Elliott Hughes71ba5892018-02-07 12:44:45 -080036 }
37
38 // Block just the specified signal.
39 explicit ScopedSignalBlocker(int signal) {
40 sigset64_t set = {};
41 sigaddset64(&set, signal);
Elliott Hughes3093e712020-04-23 15:53:17 -070042 __rt_sigprocmask(SIG_BLOCK, &set, &old_set_, sizeof(sigset64_t));
Elliott Hughes14e3ff92017-10-06 16:58:36 -070043 }
44
45 ~ScopedSignalBlocker() {
46 reset();
47 }
48
49 void reset() {
Elliott Hughes3093e712020-04-23 15:53:17 -070050 __rt_sigprocmask(SIG_SETMASK, &old_set_, nullptr, sizeof(sigset64_t));
Elliott Hughes14e3ff92017-10-06 16:58:36 -070051 }
52
Elliott Hughes5905d6f2018-01-30 15:09:51 -080053 sigset64_t old_set_;
Elliott Hughes14e3ff92017-10-06 16:58:36 -070054
Elliott Hughes5e62b342018-10-25 11:00:00 -070055 BIONIC_DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
Elliott Hughes14e3ff92017-10-06 16:58:36 -070056};