xref: /aosp_15_r20/external/perfetto/src/base/ctrl_c_handler.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/ctrl_c_handler.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
20*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/compiler.h"
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
22*6dbdd20aSAndroid Build Coastguard Worker 
23*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
24*6dbdd20aSAndroid Build Coastguard Worker #include <Windows.h>
25*6dbdd20aSAndroid Build Coastguard Worker #include <io.h>
26*6dbdd20aSAndroid Build Coastguard Worker #else
27*6dbdd20aSAndroid Build Coastguard Worker #include <signal.h>
28*6dbdd20aSAndroid Build Coastguard Worker #include <unistd.h>
29*6dbdd20aSAndroid Build Coastguard Worker #endif
30*6dbdd20aSAndroid Build Coastguard Worker 
31*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
32*6dbdd20aSAndroid Build Coastguard Worker namespace base {
33*6dbdd20aSAndroid Build Coastguard Worker 
34*6dbdd20aSAndroid Build Coastguard Worker namespace {
35*6dbdd20aSAndroid Build Coastguard Worker CtrlCHandlerFunction g_handler = nullptr;
36*6dbdd20aSAndroid Build Coastguard Worker }
37*6dbdd20aSAndroid Build Coastguard Worker 
InstallCtrlCHandler(CtrlCHandlerFunction handler)38*6dbdd20aSAndroid Build Coastguard Worker void InstallCtrlCHandler(CtrlCHandlerFunction handler) {
39*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(g_handler == nullptr);
40*6dbdd20aSAndroid Build Coastguard Worker   g_handler = handler;
41*6dbdd20aSAndroid Build Coastguard Worker 
42*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
43*6dbdd20aSAndroid Build Coastguard Worker   auto trampoline = [](DWORD type) -> int {
44*6dbdd20aSAndroid Build Coastguard Worker     if (type == CTRL_C_EVENT) {
45*6dbdd20aSAndroid Build Coastguard Worker       g_handler();
46*6dbdd20aSAndroid Build Coastguard Worker       return true;
47*6dbdd20aSAndroid Build Coastguard Worker     }
48*6dbdd20aSAndroid Build Coastguard Worker     return false;
49*6dbdd20aSAndroid Build Coastguard Worker   };
50*6dbdd20aSAndroid Build Coastguard Worker   ::SetConsoleCtrlHandler(trampoline, true);
51*6dbdd20aSAndroid Build Coastguard Worker #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
52*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
53*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
54*6dbdd20aSAndroid Build Coastguard Worker   // Setup signal handler.
55*6dbdd20aSAndroid Build Coastguard Worker   struct sigaction sa {};
56*6dbdd20aSAndroid Build Coastguard Worker 
57*6dbdd20aSAndroid Build Coastguard Worker // Glibc headers for sa_sigaction trigger this.
58*6dbdd20aSAndroid Build Coastguard Worker #pragma GCC diagnostic push
59*6dbdd20aSAndroid Build Coastguard Worker #if defined(__clang__)
60*6dbdd20aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
61*6dbdd20aSAndroid Build Coastguard Worker #endif
62*6dbdd20aSAndroid Build Coastguard Worker   sa.sa_handler = [](int) { g_handler(); };
63*6dbdd20aSAndroid Build Coastguard Worker   sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
64*6dbdd20aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop
65*6dbdd20aSAndroid Build Coastguard Worker   sigaction(SIGINT, &sa, nullptr);
66*6dbdd20aSAndroid Build Coastguard Worker   sigaction(SIGTERM, &sa, nullptr);
67*6dbdd20aSAndroid Build Coastguard Worker #else
68*6dbdd20aSAndroid Build Coastguard Worker   // Do nothing on NaCL and Fuchsia.
69*6dbdd20aSAndroid Build Coastguard Worker   ignore_result(handler);
70*6dbdd20aSAndroid Build Coastguard Worker #endif
71*6dbdd20aSAndroid Build Coastguard Worker }
72*6dbdd20aSAndroid Build Coastguard Worker 
73*6dbdd20aSAndroid Build Coastguard Worker }  // namespace base
74*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
75