libsysutil: frequent native crash /system/bin/vold

BUG: 12796279

regression from commit a6e965578e44f9ae5f98de822ba5decec381dffc

* wrap writev with sigaction SIG_IGN SIGPIPE to emulate the
  send(,,,MSG_NOSIGNAL) call it had replaced.

Change-Id: I14363630ada79c0a5b85bb6b2afd0a1c4d5c3109
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index 3625d93..d3ce8f5 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -1,10 +1,11 @@
 #include <alloca.h>
 #include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
 #include <pthread.h>
+#include <signal.h>
 #include <string.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 #define LOG_TAG "SocketClient"
 #include <cutils/log.h>
@@ -43,8 +44,7 @@
     }
 }
 
-SocketClient::~SocketClient()
-{
+SocketClient::~SocketClient() {
     if (mSocketOwned) {
         close(mSocket);
     }
@@ -180,10 +180,19 @@
         return 0;
     }
 
+    int ret = 0;
+    int e = 0; // SLOGW and sigaction are not inert regarding errno
     int current = 0;
 
+    struct sigaction new_action, old_action;
+    memset(&new_action, 0, sizeof(new_action));
+    new_action.sa_handler = SIG_IGN;
+    sigaction(SIGPIPE, &new_action, &old_action);
+
     for (;;) {
-        ssize_t rc = writev(mSocket, iov + current, iovcnt - current);
+        ssize_t rc = TEMP_FAILURE_RETRY(
+            writev(mSocket, iov + current, iovcnt - current));
+
         if (rc > 0) {
             size_t written = rc;
             while ((current < iovcnt) && (written >= iov[current].iov_len)) {
@@ -198,18 +207,21 @@
             continue;
         }
 
-        if (rc < 0 && errno == EINTR)
-            continue;
-
         if (rc == 0) {
+            e = EIO;
             SLOGW("0 length write :(");
-            errno = EIO;
         } else {
-            SLOGW("write error (%s)", strerror(errno));
+            e = errno;
+            SLOGW("write error (%s)", strerror(e));
         }
-        return -1;
+        ret = -1;
+        break;
     }
-    return 0;
+
+    sigaction(SIGPIPE, &old_action, &new_action);
+
+    errno = e;
+    return ret;
 }
 
 void SocketClient::incRef() {