summaryrefslogtreecommitdiffstats
path: root/libsysutils
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2014-01-29 11:25:01 -0800
committerMark Salyzyn <salyzyn@google.com>2014-01-31 15:27:14 -0800
commit4389588e8ded66148d9e616aa20307cf25144460 (patch)
treead010ea143e919c6b71c0bedc583f20fec2a5998 /libsysutils
parentcaefe564a4b05e717a3baec155b8968ad36e58b6 (diff)
downloadsystem_core-4389588e8ded66148d9e616aa20307cf25144460.zip
system_core-4389588e8ded66148d9e616aa20307cf25144460.tar.gz
system_core-4389588e8ded66148d9e616aa20307cf25144460.tar.bz2
libsysutil: frequent native crash /system/bin/vold
regression from commit a6e965578e44f9ae5f98de822ba5decec381dffc * wrap writev with sigaction SIG_IGN SIGPIPE to emulate the send(,,,MSG_NOSIGNAL) call it had replaced. (cherry pick from commit 83fc720785c4e40f3341daf7c0bf5ee99261fee9) BUG: 12796279 Change-Id: I14363630ada79c0a5b85bb6b2afd0a1c4d5c3109
Diffstat (limited to 'libsysutils')
-rw-r--r--libsysutils/src/SocketClient.cpp36
1 files changed, 24 insertions, 12 deletions
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 @@ void SocketClient::init(int socket, bool owned, bool useCmdNum) {
}
}
-SocketClient::~SocketClient()
-{
+SocketClient::~SocketClient() {
if (mSocketOwned) {
close(mSocket);
}
@@ -180,10 +180,19 @@ int SocketClient::sendDataLockedv(struct iovec *iov, int iovcnt) {
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 @@ int SocketClient::sendDataLockedv(struct iovec *iov, int iovcnt) {
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() {