blob: b7ba7826d799e07b56288bbe24ce3936bd448e21 [file] [log] [blame]
Mark Salyzyn018a96d2016-03-01 13:45:42 -08001/*
2 * Copyright (C) 2007-2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <endian.h>
18#include <errno.h>
19#include <fcntl.h>
20#include <inttypes.h>
21#include <poll.h>
22#include <stdarg.h>
23#include <stdatomic.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080027#include <sys/socket.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080028#include <sys/stat.h>
29#include <sys/types.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080030#include <sys/un.h>
31#include <time.h>
32#include <unistd.h>
33
34#include <cutils/sockets.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080035#include <private/android_filesystem_config.h>
36#include <private/android_logger.h>
37
38#include "config_read.h"
39#include "log_portability.h"
Mark Salyzync9e5f372016-09-21 09:24:13 -070040#include "logd_reader.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080041#include "logger.h"
42
43/* branchless on many architectures. */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080044#define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
Mark Salyzyn018a96d2016-03-01 13:45:42 -080045
46static int logdAvailable(log_id_t LogId);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080047static int logdVersion(struct android_log_logger* logger,
48 struct android_log_transport_context* transp);
49static int logdRead(struct android_log_logger_list* logger_list,
Tom Cherry71ba1642019-01-10 10:37:36 -080050 struct android_log_transport_context* transp, struct log_msg* log_msg);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080051static int logdPoll(struct android_log_logger_list* logger_list,
52 struct android_log_transport_context* transp);
53static void logdClose(struct android_log_logger_list* logger_list,
54 struct android_log_transport_context* transp);
55static int logdClear(struct android_log_logger* logger,
56 struct android_log_transport_context* transp);
57static ssize_t logdSetSize(struct android_log_logger* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080058 struct android_log_transport_context* transp, size_t size);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080059static ssize_t logdGetSize(struct android_log_logger* logger,
60 struct android_log_transport_context* transp);
61static ssize_t logdGetReadableSize(struct android_log_logger* logger,
62 struct android_log_transport_context* transp);
63static ssize_t logdGetPrune(struct android_log_logger_list* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080064 struct android_log_transport_context* transp, char* buf, size_t len);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080065static ssize_t logdSetPrune(struct android_log_logger_list* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080066 struct android_log_transport_context* transp, char* buf, size_t len);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080067static ssize_t logdGetStats(struct android_log_logger_list* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080068 struct android_log_transport_context* transp, char* buf, size_t len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -080069
Tom Cherry2d9779e2019-02-08 11:46:19 -080070struct android_log_transport_read logdLoggerRead = {
Tom Cherry71ba1642019-01-10 10:37:36 -080071 .node = {&logdLoggerRead.node, &logdLoggerRead.node},
72 .name = "logd",
73 .available = logdAvailable,
74 .version = logdVersion,
75 .read = logdRead,
76 .poll = logdPoll,
77 .close = logdClose,
78 .clear = logdClear,
79 .getSize = logdGetSize,
80 .setSize = logdSetSize,
81 .getReadableSize = logdGetReadableSize,
82 .getPrune = logdGetPrune,
83 .setPrune = logdSetPrune,
84 .getStats = logdGetStats,
Mark Salyzyn018a96d2016-03-01 13:45:42 -080085};
86
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087static int logdAvailable(log_id_t logId) {
88 if (logId >= LOG_ID_MAX) {
89 return -EINVAL;
90 }
91 if (logId == LOG_ID_SECURITY) {
92 uid_t uid = __android_log_uid();
93 if (uid != AID_SYSTEM) {
94 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080095 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080096 }
97 if (access("/dev/socket/logdw", W_OK) == 0) {
98 return 0;
99 }
100 return -EBADF;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800101}
102
Tom Cherry05de1ba2019-02-12 11:26:23 -0800103// Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
104// O_CLOEXEC is always set.
105static int socket_local_client(const std::string& name, int type) {
106 sockaddr_un addr = {.sun_family = AF_LOCAL};
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800107
Tom Cherry05de1ba2019-02-12 11:26:23 -0800108 std::string path = "/dev/socket/" + name;
109 if (path.size() + 1 > sizeof(addr.sun_path)) {
110 return -1;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800111 }
Tom Cherry05de1ba2019-02-12 11:26:23 -0800112 strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800113
Tom Cherry05de1ba2019-02-12 11:26:23 -0800114 int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0);
115 if (fd == 0) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800116 return -1;
117 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800118
Tom Cherry05de1ba2019-02-12 11:26:23 -0800119 if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
120 close(fd);
121 return -1;
122 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800123
Tom Cherry05de1ba2019-02-12 11:26:23 -0800124 return fd;
125}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800126
127/* worker for sending the command to the logger */
Tom Cherry71ba1642019-01-10 10:37:36 -0800128static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg, char* buf,
129 size_t buf_size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800130 ssize_t ret;
131 size_t len;
132 char* cp;
133 int errno_save = 0;
Tom Cherry05de1ba2019-02-12 11:26:23 -0800134 int sock = socket_local_client("logd", SOCK_STREAM);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800135 if (sock < 0) {
136 return sock;
137 }
138
139 if (msg) {
140 snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned)-1);
141 }
142
143 len = strlen(buf) + 1;
144 ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
145 if (ret <= 0) {
146 goto done;
147 }
148
149 len = buf_size;
150 cp = buf;
151 while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
152 struct pollfd p;
153
154 if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
155 break;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800156 }
157
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800158 len -= ret;
159 cp += ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800160
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800161 memset(&p, 0, sizeof(p));
162 p.fd = sock;
163 p.events = POLLIN;
164
165 /* Give other side 20ms to refill pipe */
166 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
167
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800168 if (ret <= 0) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800169 break;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800170 }
171
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800172 if (!(p.revents & POLLIN)) {
173 ret = 0;
174 break;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800175 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800176 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800177
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800178 if (ret >= 0) {
179 ret += buf_size - len;
180 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800181
182done:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800183 if ((ret == -1) && errno) {
184 errno_save = errno;
185 }
186 close(sock);
187 if (errno_save) {
188 errno = errno_save;
189 }
190 return ret;
191}
192
Tom Cherry2d9779e2019-02-08 11:46:19 -0800193ssize_t __send_log_msg(char* buf, size_t buf_size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800194 return send_log_msg(NULL, NULL, buf, buf_size);
195}
196
197static int check_log_success(char* buf, ssize_t ret) {
198 if (ret < 0) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800199 return ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800200 }
201
202 if (strncmp(buf, "success", 7)) {
203 errno = EINVAL;
204 return -1;
205 }
206
207 return 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800208}
209
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800210static int logdClear(struct android_log_logger* logger,
211 struct android_log_transport_context* transp __unused) {
212 char buf[512];
Mark Salyzync9e5f372016-09-21 09:24:13 -0700213
Tom Cherry71ba1642019-01-10 10:37:36 -0800214 return check_log_success(buf, send_log_msg(logger, "clear %d", buf, sizeof(buf)));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800215}
216
217/* returns the total size of the log's ring buffer */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800218static ssize_t logdGetSize(struct android_log_logger* logger,
219 struct android_log_transport_context* transp __unused) {
220 char buf[512];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800221
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800222 ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
223 if (ret < 0) {
224 return ret;
225 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800226
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800227 if ((buf[0] < '0') || ('9' < buf[0])) {
228 return -1;
229 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800230
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800231 return atol(buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800232}
233
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800234static ssize_t logdSetSize(struct android_log_logger* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -0800235 struct android_log_transport_context* transp __unused, size_t size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800236 char buf[512];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800237
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800238 snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800239
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800240 return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800241}
242
243/*
244 * returns the readable size of the log's ring buffer (that is, amount of the
245 * log consumed)
246 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800247static ssize_t logdGetReadableSize(struct android_log_logger* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -0800248 struct android_log_transport_context* transp __unused) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800249 char buf[512];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800250
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800251 ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
252 if (ret < 0) {
253 return ret;
254 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800255
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800256 if ((buf[0] < '0') || ('9' < buf[0])) {
257 return -1;
258 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800259
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800260 return atol(buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800261}
262
263/*
264 * returns the logger version
265 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800266static int logdVersion(struct android_log_logger* logger __unused,
267 struct android_log_transport_context* transp __unused) {
268 uid_t uid = __android_log_uid();
269 return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800270}
271
272/*
273 * returns statistics
274 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800275static ssize_t logdGetStats(struct android_log_logger_list* logger_list,
Tom Cherry71ba1642019-01-10 10:37:36 -0800276 struct android_log_transport_context* transp __unused, char* buf,
277 size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800278 struct android_log_logger* logger;
279 char* cp = buf;
280 size_t remaining = len;
281 size_t n;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800282
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800283 n = snprintf(cp, remaining, "getStatistics");
284 n = min(n, remaining);
285 remaining -= n;
286 cp += n;
287
288 logger_for_each(logger, logger_list) {
289 n = snprintf(cp, remaining, " %d", logger->logId);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800290 n = min(n, remaining);
291 remaining -= n;
292 cp += n;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800293 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800294
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800295 if (logger_list->pid) {
296 snprintf(cp, remaining, " pid=%u", logger_list->pid);
297 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800298
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800299 return send_log_msg(NULL, NULL, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800300}
301
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800302static ssize_t logdGetPrune(struct android_log_logger_list* logger_list __unused,
Tom Cherry71ba1642019-01-10 10:37:36 -0800303 struct android_log_transport_context* transp __unused, char* buf,
304 size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800305 return send_log_msg(NULL, "getPruneList", buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800306}
307
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800308static ssize_t logdSetPrune(struct android_log_logger_list* logger_list __unused,
Tom Cherry71ba1642019-01-10 10:37:36 -0800309 struct android_log_transport_context* transp __unused, char* buf,
310 size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800311 const char cmd[] = "setPruneList ";
312 const size_t cmdlen = sizeof(cmd) - 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800313
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800314 if (strlen(buf) > (len - cmdlen)) {
315 return -ENOMEM; /* KISS */
316 }
317 memmove(buf + cmdlen, buf, len - cmdlen);
318 buf[len - 1] = '\0';
319 memcpy(buf, cmd, cmdlen);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800320
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800321 return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800322}
323
Tom Cherry71ba1642019-01-10 10:37:36 -0800324static void caught_signal(int signum __unused) {}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800325
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800326static int logdOpen(struct android_log_logger_list* logger_list,
327 struct android_log_transport_context* transp) {
328 struct android_log_logger* logger;
329 struct sigaction ignore;
330 struct sigaction old_sigaction;
331 unsigned int old_alarm = 0;
332 char buffer[256], *cp, c;
333 int e, ret, remaining, sock;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800334
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800335 if (!logger_list) {
336 return -EINVAL;
337 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800338
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800339 sock = atomic_load(&transp->context.sock);
340 if (sock > 0) {
341 return sock;
342 }
Mark Salyzyndb8a2662016-10-10 07:27:42 -0700343
Tom Cherry05de1ba2019-02-12 11:26:23 -0800344 sock = socket_local_client("logdr", SOCK_SEQPACKET);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800345 if (sock == 0) {
346 /* Guarantee not file descriptor zero */
Tom Cherry05de1ba2019-02-12 11:26:23 -0800347 int newsock = socket_local_client("logdr", SOCK_SEQPACKET);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800348 close(sock);
349 sock = newsock;
350 }
351 if (sock <= 0) {
352 if ((sock == -1) && errno) {
353 return -errno;
Mark Salyzyndb8a2662016-10-10 07:27:42 -0700354 }
355 return sock;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800356 }
357
Tom Cherry71ba1642019-01-10 10:37:36 -0800358 strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream");
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800359 cp = buffer + strlen(buffer);
360
361 strcpy(cp, " lids");
362 cp += 5;
363 c = '=';
364 remaining = sizeof(buffer) - (cp - buffer);
365 logger_for_each(logger, logger_list) {
366 ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
367 ret = min(ret, remaining);
368 remaining -= ret;
369 cp += ret;
370 c = ',';
371 }
372
373 if (logger_list->tail) {
374 ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
375 ret = min(ret, remaining);
376 remaining -= ret;
377 cp += ret;
378 }
379
380 if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
381 if (logger_list->mode & ANDROID_LOG_WRAP) {
382 // ToDo: alternate API to allow timeout to be adjusted.
Tom Cherry71ba1642019-01-10 10:37:36 -0800383 ret = snprintf(cp, remaining, " timeout=%u", ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800384 ret = min(ret, remaining);
385 remaining -= ret;
386 cp += ret;
387 }
Tom Cherry71ba1642019-01-10 10:37:36 -0800388 ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, logger_list->start.tv_sec,
389 logger_list->start.tv_nsec);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800390 ret = min(ret, remaining);
391 remaining -= ret;
392 cp += ret;
393 }
394
395 if (logger_list->pid) {
396 ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
397 ret = min(ret, remaining);
398 cp += ret;
399 }
400
401 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
402 /* Deal with an unresponsive logd */
403 memset(&ignore, 0, sizeof(ignore));
404 ignore.sa_handler = caught_signal;
405 sigemptyset(&ignore.sa_mask);
406 /* particularily useful if tombstone is reporting for logd */
407 sigaction(SIGALRM, &ignore, &old_sigaction);
408 old_alarm = alarm(30);
409 }
410 ret = write(sock, buffer, cp - buffer);
411 e = errno;
412 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
413 if (e == EINTR) {
414 e = ETIMEDOUT;
415 }
416 alarm(old_alarm);
417 sigaction(SIGALRM, &old_sigaction, NULL);
418 }
419
420 if (ret <= 0) {
421 close(sock);
422 if ((ret == -1) && e) {
423 return -e;
424 }
425 if (ret == 0) {
426 return -EIO;
427 }
428 return ret;
429 }
430
431 ret = atomic_exchange(&transp->context.sock, sock);
432 if ((ret > 0) && (ret != sock)) {
433 close(ret);
434 }
435 return sock;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800436}
437
438/* Read from the selected logs */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800439static int logdRead(struct android_log_logger_list* logger_list,
Tom Cherry71ba1642019-01-10 10:37:36 -0800440 struct android_log_transport_context* transp, struct log_msg* log_msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800441 int ret, e;
442 struct sigaction ignore;
443 struct sigaction old_sigaction;
444 unsigned int old_alarm = 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800445
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800446 ret = logdOpen(logger_list, transp);
447 if (ret < 0) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800448 return ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800449 }
450
451 memset(log_msg, 0, sizeof(*log_msg));
452
Alan Stokes64acdf72017-08-01 16:43:02 +0100453 unsigned int new_alarm = 0;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800454 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
Alan Stokes64acdf72017-08-01 16:43:02 +0100455 if ((logger_list->mode & ANDROID_LOG_WRAP) &&
456 (logger_list->start.tv_sec || logger_list->start.tv_nsec)) {
457 /* b/64143705 */
458 new_alarm = (ANDROID_LOG_WRAP_DEFAULT_TIMEOUT * 11) / 10 + 10;
459 logger_list->mode &= ~ANDROID_LOG_WRAP;
460 } else {
461 new_alarm = 30;
462 }
463
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800464 memset(&ignore, 0, sizeof(ignore));
465 ignore.sa_handler = caught_signal;
466 sigemptyset(&ignore.sa_mask);
467 /* particularily useful if tombstone is reporting for logd */
468 sigaction(SIGALRM, &ignore, &old_sigaction);
Alan Stokes64acdf72017-08-01 16:43:02 +0100469 old_alarm = alarm(new_alarm);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800470 }
471
472 /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
473 ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
474 e = errno;
475
Alan Stokes64acdf72017-08-01 16:43:02 +0100476 if (new_alarm) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800477 if ((ret == 0) || (e == EINTR)) {
478 e = EAGAIN;
479 ret = -1;
480 }
481 alarm(old_alarm);
482 sigaction(SIGALRM, &old_sigaction, NULL);
483 }
484
485 if ((ret == -1) && e) {
486 return -e;
487 }
488 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800489}
490
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800491static int logdPoll(struct android_log_logger_list* logger_list,
492 struct android_log_transport_context* transp) {
493 struct pollfd p;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800494
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800495 int ret = logdOpen(logger_list, transp);
496 if (ret < 0) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800497 return ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800498 }
499
500 memset(&p, 0, sizeof(p));
501 p.fd = ret;
502 p.events = POLLIN;
503 ret = poll(&p, 1, 20);
504 if ((ret > 0) && !(p.revents & POLLIN)) {
505 ret = 0;
506 }
507 if ((ret == -1) && errno) {
508 return -errno;
509 }
510 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800511}
512
513/* Close all the logs */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800514static void logdClose(struct android_log_logger_list* logger_list __unused,
515 struct android_log_transport_context* transp) {
516 int sock = atomic_exchange(&transp->context.sock, -1);
517 if (sock > 0) {
518 close(sock);
519 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800520}