summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--liblog/log_read.c39
-rw-r--r--logd/tests/logd_test.cpp21
2 files changed, 57 insertions, 3 deletions
diff --git a/liblog/log_read.c b/liblog/log_read.c
index 0ff94bf..11fe848 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -17,6 +17,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <poll.h>
#include <signal.h>
#include <stddef.h>
#define NOMINMAX /* for windows to suppress definition of min in stdlib.h */
@@ -273,6 +274,8 @@ static ssize_t send_log_msg(struct logger *logger,
const char *msg, char *buf, size_t buf_size)
{
ssize_t ret;
+ size_t len;
+ char *cp;
int errno_save = 0;
int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
@@ -284,12 +287,44 @@ static ssize_t send_log_msg(struct logger *logger,
snprintf(buf, buf_size, msg, logger ? logger->id : (unsigned) -1);
}
- ret = write(sock, buf, strlen(buf) + 1);
+ len = strlen(buf) + 1;
+ ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
if (ret <= 0) {
goto done;
}
- ret = read(sock, buf, buf_size);
+ len = buf_size;
+ cp = buf;
+ while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
+ struct pollfd p;
+
+ if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
+ break;
+ }
+
+ len -= ret;
+ cp += ret;
+
+ memset(&p, 0, sizeof(p));
+ p.fd = sock;
+ p.events = POLLIN;
+
+ /* Give other side 20ms to refill pipe */
+ ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
+
+ if (ret <= 0) {
+ break;
+ }
+
+ if (!(p.revents & POLLIN)) {
+ ret = 0;
+ break;
+ }
+ }
+
+ if (ret >= 0) {
+ ret += buf_size - len;
+ }
done:
if ((ret == -1) && errno) {
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 9ad8973..23e6146 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -15,6 +15,7 @@
*/
#include <fcntl.h>
+#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
@@ -37,7 +38,25 @@ static void my_android_logger_get_statistics(char *buf, size_t len)
SOCK_STREAM);
if (sock >= 0) {
if (write(sock, buf, strlen(buf) + 1) > 0) {
- read(sock, buf, len);
+ ssize_t ret;
+ while ((ret = read(sock, buf, len)) > 0) {
+ if ((size_t)ret == len) {
+ break;
+ }
+ len -= ret;
+ buf += ret;
+
+ struct pollfd p = {
+ .fd = sock,
+ .events = POLLIN,
+ .revents = 0
+ };
+
+ ret = poll(&p, 1, 20);
+ if ((ret <= 0) || !(p.revents & POLLIN)) {
+ break;
+ }
+ }
}
close(sock);
}