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 Workervoid 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