From 04d75c37baef052930fe4119796719e843de0f66 Mon Sep 17 00:00:00 2001 From: Ruchir Rastogi Date: Mon, 13 Apr 2020 17:06:57 -0700 Subject: [PATCH] ShellSubscriber: install SIGPIPE handler Install a handler that ignores SIGPIPE. Before this, SIGPIPE was not being handled, which caused a SIGKILL to be sent to statsd. Note that even if SIGPIPE is handled, writes to closed pipes will return EPIPE. Bug: 153595161 Test: procedure specified in b/153595161 1. cat statsd config | adb shell cmd stats data-subscribe 2. Terminate the shell command 3. cat statsd config | adb shell cmd stats data-subscribe Change-Id: Ib5e679ccd7cdf7182452466b316488439871db99 --- cmds/statsd/src/main.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp index d79b6a21c19fa..e3945334aeca9 100644 --- a/cmds/statsd/src/main.cpp +++ b/cmds/statsd/src/main.cpp @@ -38,20 +38,27 @@ using std::make_shared; shared_ptr gStatsService = nullptr; -void sigHandler(int sig) { - if (gStatsService != nullptr) { - gStatsService->Terminate(); +void signalHandler(int sig) { + if (sig == SIGPIPE) { + // ShellSubscriber uses SIGPIPE as a signal to detect the end of the + // client process. Don't prematurely exit(1) here. Instead, ignore the + // signal and allow the write call to return EPIPE. + ALOGI("statsd received SIGPIPE. Ignoring signal."); + return; } + + if (gStatsService != nullptr) gStatsService->Terminate(); ALOGW("statsd terminated on receiving signal %d.", sig); exit(1); } -void registerSigHandler() +void registerSignalHandlers() { struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - sa.sa_handler = sigHandler; + sa.sa_handler = signalHandler; + sigaction(SIGPIPE, &sa, nullptr); sigaction(SIGHUP, &sa, nullptr); sigaction(SIGINT, &sa, nullptr); sigaction(SIGQUIT, &sa, nullptr); @@ -79,7 +86,7 @@ int main(int /*argc*/, char** /*argv*/) { return -1; } - registerSigHandler(); + registerSignalHandlers(); gStatsService->sayHiToStatsCompanion();