Merge tag 'android-13.0.0_r32' into int/13/fp3

Android 13.0.0 release 32

* tag 'android-13.0.0_r32':
  statsd: Fix unsafe signal api usage

Change-Id: I78a300d8dac85a75f4755ddfa80626562a08e46e
diff --git a/statsd/src/main.cpp b/statsd/src/main.cpp
index bd2c0e4..67bb65d 100644
--- a/statsd/src/main.cpp
+++ b/statsd/src/main.cpp
@@ -39,20 +39,12 @@
 
 shared_ptr<StatsService> gStatsService = nullptr;
 sp<StatsSocketListener> gSocketListener = nullptr;
+int gCtrlPipe[2];
 
 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 (gSocketListener != nullptr) gSocketListener->stopListener();
-    if (gStatsService != nullptr) gStatsService->Terminate();
     ALOGW("statsd terminated on receiving signal %d.", sig);
-    exit(1);
+    const char c = 'q';
+    write(gCtrlPipe[1], &c, 1);
 }
 
 void registerSignalHandlers()
@@ -60,11 +52,15 @@
     struct sigaction sa;
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = 0;
-    sa.sa_handler = signalHandler;
+
+    sa.sa_handler = SIG_IGN;
+    // 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.
     sigaction(SIGPIPE, &sa, nullptr);
-    sigaction(SIGHUP, &sa, nullptr);
-    sigaction(SIGINT, &sa, nullptr);
-    sigaction(SIGQUIT, &sa, nullptr);
+
+    pipe2(gCtrlPipe, O_CLOEXEC);
+    sa.sa_handler = signalHandler;
     sigaction(SIGTERM, &sa, nullptr);
 }
 
@@ -92,8 +88,6 @@
         return -1;
     }
 
-    registerSignalHandlers();
-
     gStatsService->sayHiToStatsCompanion();
 
     gStatsService->Startup();
@@ -106,6 +100,22 @@
         exit(1);
     }
 
+    // Use self-pipe to notify this thread to gracefully quit
+    // when receiving SIGTERM
+    registerSignalHandlers();
+    std::thread([] {
+        while (true) {
+            char c;
+            int i = read(gCtrlPipe[0], &c, 1);
+            if (i < 0) {
+                if (errno == EINTR) continue;
+            }
+            gSocketListener->stopListener();
+            gStatsService->Terminate();
+            exit(1);
+        }
+    }).detach();
+
     // Loop forever -- the reports run on this thread in a handler, and the
     // binder calls remain responsive in their pool of one thread.
     while (true) {