blob: eaa157a32d3387a5f6a3a3a03425e1466373b17e [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
Mark Salyzyn018a96d2016-03-01 13:45:42 -080017#include <errno.h>
18#include <fcntl.h>
19#include <inttypes.h>
20#include <poll.h>
21#include <stdarg.h>
22#include <stdatomic.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
Elliott Hughes6efbda72019-10-02 12:27:03 -070026#include <sys/param.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
Mark Salyzyn018a96d2016-03-01 13:45:42 -080038#include "log_portability.h"
Mark Salyzync9e5f372016-09-21 09:24:13 -070039#include "logd_reader.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080040#include "logger.h"
41
Tom Cherry828db1a2019-11-14 10:39:40 -080042static int LogdAvailable(log_id_t LogId);
43static int LogdVersion(struct logger* logger, struct android_log_transport_context* transp);
44static int LogdRead(struct logger_list* logger_list, struct android_log_transport_context* transp,
45 struct log_msg* log_msg);
46static int LogdPoll(struct logger_list* logger_list, struct android_log_transport_context* transp);
47static void LogdClose(struct logger_list* logger_list,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080048 struct android_log_transport_context* transp);
Tom Cherry828db1a2019-11-14 10:39:40 -080049static int LogdClear(struct logger* logger, struct android_log_transport_context* transp);
50static ssize_t LogdSetSize(struct logger* logger, struct android_log_transport_context* transp,
51 size_t size);
52static ssize_t LogdGetSize(struct logger* logger, struct android_log_transport_context* transp);
53static ssize_t LogdGetReadableSize(struct logger* logger,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080054 struct android_log_transport_context* transp);
Tom Cherry828db1a2019-11-14 10:39:40 -080055static ssize_t LogdGetPrune(struct logger_list* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080056 struct android_log_transport_context* transp, char* buf, size_t len);
Tom Cherry828db1a2019-11-14 10:39:40 -080057static ssize_t LogdSetPrune(struct logger_list* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080058 struct android_log_transport_context* transp, char* buf, size_t len);
Tom Cherry828db1a2019-11-14 10:39:40 -080059static ssize_t LogdGetStats(struct logger_list* logger,
Tom Cherry71ba1642019-01-10 10:37:36 -080060 struct android_log_transport_context* transp, char* buf, size_t len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -080061
Tom Cherry2d9779e2019-02-08 11:46:19 -080062struct android_log_transport_read logdLoggerRead = {
Tom Cherry71ba1642019-01-10 10:37:36 -080063 .name = "logd",
Tom Cherry828db1a2019-11-14 10:39:40 -080064 .available = LogdAvailable,
65 .version = LogdVersion,
66 .close = LogdClose,
67 .read = LogdRead,
68 .poll = LogdPoll,
69 .clear = LogdClear,
70 .setSize = LogdSetSize,
71 .getSize = LogdGetSize,
72 .getReadableSize = LogdGetReadableSize,
73 .getPrune = LogdGetPrune,
74 .setPrune = LogdSetPrune,
75 .getStats = LogdGetStats,
Mark Salyzyn018a96d2016-03-01 13:45:42 -080076};
77
Tom Cherry828db1a2019-11-14 10:39:40 -080078static int LogdAvailable(log_id_t logId) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080079 if (logId >= LOG_ID_MAX) {
80 return -EINVAL;
81 }
82 if (logId == LOG_ID_SECURITY) {
83 uid_t uid = __android_log_uid();
84 if (uid != AID_SYSTEM) {
85 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080086 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087 }
88 if (access("/dev/socket/logdw", W_OK) == 0) {
89 return 0;
90 }
91 return -EBADF;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080092}
93
Tom Cherry05de1ba2019-02-12 11:26:23 -080094// Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
95// O_CLOEXEC is always set.
96static int socket_local_client(const std::string& name, int type) {
97 sockaddr_un addr = {.sun_family = AF_LOCAL};
Mark Salyzyn018a96d2016-03-01 13:45:42 -080098
Tom Cherry05de1ba2019-02-12 11:26:23 -080099 std::string path = "/dev/socket/" + name;
100 if (path.size() + 1 > sizeof(addr.sun_path)) {
101 return -1;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800102 }
Tom Cherry05de1ba2019-02-12 11:26:23 -0800103 strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800104
Tom Cherry05de1ba2019-02-12 11:26:23 -0800105 int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0);
Tom Cherry29d0e892019-10-08 10:18:20 -0700106 if (fd == -1) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800107 return -1;
108 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800109
Tom Cherry05de1ba2019-02-12 11:26:23 -0800110 if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
111 close(fd);
112 return -1;
113 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800114
Tom Cherry05de1ba2019-02-12 11:26:23 -0800115 return fd;
116}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800117
118/* worker for sending the command to the logger */
Tom Cherry828db1a2019-11-14 10:39:40 -0800119static ssize_t send_log_msg(struct logger* logger, const char* msg, char* buf, size_t buf_size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800120 ssize_t ret;
121 size_t len;
122 char* cp;
123 int errno_save = 0;
Tom Cherry05de1ba2019-02-12 11:26:23 -0800124 int sock = socket_local_client("logd", SOCK_STREAM);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800125 if (sock < 0) {
126 return sock;
127 }
128
129 if (msg) {
130 snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned)-1);
131 }
132
133 len = strlen(buf) + 1;
134 ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
135 if (ret <= 0) {
136 goto done;
137 }
138
139 len = buf_size;
140 cp = buf;
141 while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
142 struct pollfd p;
143
144 if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
145 break;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800146 }
147
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800148 len -= ret;
149 cp += ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800150
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800151 memset(&p, 0, sizeof(p));
152 p.fd = sock;
153 p.events = POLLIN;
154
155 /* Give other side 20ms to refill pipe */
156 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
157
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800158 if (ret <= 0) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800159 break;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800160 }
161
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800162 if (!(p.revents & POLLIN)) {
163 ret = 0;
164 break;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800165 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800166 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800167
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800168 if (ret >= 0) {
169 ret += buf_size - len;
170 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800171
172done:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800173 if ((ret == -1) && errno) {
174 errno_save = errno;
175 }
176 close(sock);
177 if (errno_save) {
178 errno = errno_save;
179 }
180 return ret;
181}
182
Tom Cherry2d9779e2019-02-08 11:46:19 -0800183ssize_t __send_log_msg(char* buf, size_t buf_size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800184 return send_log_msg(NULL, NULL, buf, buf_size);
185}
186
187static int check_log_success(char* buf, ssize_t ret) {
188 if (ret < 0) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800189 return ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800190 }
191
192 if (strncmp(buf, "success", 7)) {
193 errno = EINVAL;
194 return -1;
195 }
196
197 return 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800198}
199
Tom Cherry828db1a2019-11-14 10:39:40 -0800200static int LogdClear(struct logger* logger, struct android_log_transport_context*) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800201 char buf[512];
Mark Salyzync9e5f372016-09-21 09:24:13 -0700202
Tom Cherry71ba1642019-01-10 10:37:36 -0800203 return check_log_success(buf, send_log_msg(logger, "clear %d", buf, sizeof(buf)));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800204}
205
206/* returns the total size of the log's ring buffer */
Tom Cherry828db1a2019-11-14 10:39:40 -0800207static ssize_t LogdGetSize(struct logger* logger, struct android_log_transport_context*) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800208 char buf[512];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800209
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800210 ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
211 if (ret < 0) {
212 return ret;
213 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800214
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800215 if ((buf[0] < '0') || ('9' < buf[0])) {
216 return -1;
217 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800218
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800219 return atol(buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800220}
221
Tom Cherry828db1a2019-11-14 10:39:40 -0800222static ssize_t LogdSetSize(struct logger* logger, struct android_log_transport_context*,
223 size_t size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800224 char buf[512];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800225
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800226 snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800227
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800228 return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800229}
230
231/*
232 * returns the readable size of the log's ring buffer (that is, amount of the
233 * log consumed)
234 */
Tom Cherry828db1a2019-11-14 10:39:40 -0800235static ssize_t LogdGetReadableSize(struct logger* logger, struct android_log_transport_context*) {
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 ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
239 if (ret < 0) {
240 return ret;
241 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800242
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800243 if ((buf[0] < '0') || ('9' < buf[0])) {
244 return -1;
245 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800246
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800247 return atol(buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800248}
249
250/*
251 * returns the logger version
252 */
Tom Cherry828db1a2019-11-14 10:39:40 -0800253static int LogdVersion(struct logger*, struct android_log_transport_context*) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800254 uid_t uid = __android_log_uid();
255 return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800256}
257
258/*
259 * returns statistics
260 */
Tom Cherry828db1a2019-11-14 10:39:40 -0800261static ssize_t LogdGetStats(struct logger_list* logger_list, struct android_log_transport_context*,
262 char* buf, size_t len) {
263 struct logger* logger;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800264 char* cp = buf;
265 size_t remaining = len;
266 size_t n;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800267
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800268 n = snprintf(cp, remaining, "getStatistics");
Elliott Hughes6efbda72019-10-02 12:27:03 -0700269 n = MIN(n, remaining);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800270 remaining -= n;
271 cp += n;
272
273 logger_for_each(logger, logger_list) {
274 n = snprintf(cp, remaining, " %d", logger->logId);
Elliott Hughes6efbda72019-10-02 12:27:03 -0700275 n = MIN(n, remaining);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800276 remaining -= n;
277 cp += n;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800278 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800279
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800280 if (logger_list->pid) {
281 snprintf(cp, remaining, " pid=%u", logger_list->pid);
282 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800283
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800284 return send_log_msg(NULL, NULL, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800285}
286
Tom Cherry828db1a2019-11-14 10:39:40 -0800287static ssize_t LogdGetPrune(struct logger_list*, struct android_log_transport_context*, char* buf,
Tom Cherry71ba1642019-01-10 10:37:36 -0800288 size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800289 return send_log_msg(NULL, "getPruneList", buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800290}
291
Tom Cherry828db1a2019-11-14 10:39:40 -0800292static ssize_t LogdSetPrune(struct logger_list*, struct android_log_transport_context*, char* buf,
Tom Cherry71ba1642019-01-10 10:37:36 -0800293 size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800294 const char cmd[] = "setPruneList ";
295 const size_t cmdlen = sizeof(cmd) - 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800296
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800297 if (strlen(buf) > (len - cmdlen)) {
298 return -ENOMEM; /* KISS */
299 }
300 memmove(buf + cmdlen, buf, len - cmdlen);
301 buf[len - 1] = '\0';
302 memcpy(buf, cmd, cmdlen);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800303
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800304 return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800305}
306
Tom Cherry828db1a2019-11-14 10:39:40 -0800307static int logdOpen(struct logger_list* logger_list, struct android_log_transport_context* transp) {
308 struct logger* logger;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800309 char buffer[256], *cp, c;
Tom Cherry53980212019-10-08 09:05:26 -0700310 int ret, remaining, sock;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800311
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800312 if (!logger_list) {
313 return -EINVAL;
314 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800315
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800316 sock = atomic_load(&transp->context.sock);
317 if (sock > 0) {
318 return sock;
319 }
Mark Salyzyndb8a2662016-10-10 07:27:42 -0700320
Tom Cherry05de1ba2019-02-12 11:26:23 -0800321 sock = socket_local_client("logdr", SOCK_SEQPACKET);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800322 if (sock <= 0) {
323 if ((sock == -1) && errno) {
324 return -errno;
Mark Salyzyndb8a2662016-10-10 07:27:42 -0700325 }
326 return sock;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800327 }
328
Tom Cherry71ba1642019-01-10 10:37:36 -0800329 strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream");
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800330 cp = buffer + strlen(buffer);
331
332 strcpy(cp, " lids");
333 cp += 5;
334 c = '=';
335 remaining = sizeof(buffer) - (cp - buffer);
336 logger_for_each(logger, logger_list) {
337 ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
Elliott Hughes6efbda72019-10-02 12:27:03 -0700338 ret = MIN(ret, remaining);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800339 remaining -= ret;
340 cp += ret;
341 c = ',';
342 }
343
344 if (logger_list->tail) {
345 ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
Elliott Hughes6efbda72019-10-02 12:27:03 -0700346 ret = MIN(ret, remaining);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800347 remaining -= ret;
348 cp += ret;
349 }
350
351 if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
352 if (logger_list->mode & ANDROID_LOG_WRAP) {
353 // ToDo: alternate API to allow timeout to be adjusted.
Tom Cherry71ba1642019-01-10 10:37:36 -0800354 ret = snprintf(cp, remaining, " timeout=%u", ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
Elliott Hughes6efbda72019-10-02 12:27:03 -0700355 ret = MIN(ret, remaining);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800356 remaining -= ret;
357 cp += ret;
358 }
Tom Cherry71ba1642019-01-10 10:37:36 -0800359 ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, logger_list->start.tv_sec,
360 logger_list->start.tv_nsec);
Elliott Hughes6efbda72019-10-02 12:27:03 -0700361 ret = MIN(ret, remaining);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800362 remaining -= ret;
363 cp += ret;
364 }
365
366 if (logger_list->pid) {
367 ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
Elliott Hughes6efbda72019-10-02 12:27:03 -0700368 ret = MIN(ret, remaining);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800369 cp += ret;
370 }
371
Tom Cherry53980212019-10-08 09:05:26 -0700372 ret = TEMP_FAILURE_RETRY(write(sock, buffer, cp - buffer));
373 int write_errno = errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800374
375 if (ret <= 0) {
376 close(sock);
Tom Cherry53980212019-10-08 09:05:26 -0700377 if (ret == -1) {
378 return -write_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800379 }
380 if (ret == 0) {
381 return -EIO;
382 }
383 return ret;
384 }
385
386 ret = atomic_exchange(&transp->context.sock, sock);
387 if ((ret > 0) && (ret != sock)) {
388 close(ret);
389 }
390 return sock;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800391}
392
393/* Read from the selected logs */
Tom Cherry828db1a2019-11-14 10:39:40 -0800394static int LogdRead(struct logger_list* logger_list, struct android_log_transport_context* transp,
395 struct log_msg* log_msg) {
Tom Cherry53980212019-10-08 09:05:26 -0700396 int ret = logdOpen(logger_list, transp);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800397 if (ret < 0) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800398 return ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800399 }
400
401 memset(log_msg, 0, sizeof(*log_msg));
402
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800403 /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
Tom Cherry53980212019-10-08 09:05:26 -0700404 ret = TEMP_FAILURE_RETRY(recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0));
405 if ((logger_list->mode & ANDROID_LOG_NONBLOCK) && ret == 0) {
406 return -EAGAIN;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800407 }
408
Tom Cherry53980212019-10-08 09:05:26 -0700409 if (ret == -1) {
410 return -errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800411 }
412 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800413}
414
Tom Cherry828db1a2019-11-14 10:39:40 -0800415static int LogdPoll(struct logger_list* logger_list, struct android_log_transport_context* transp) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800416 struct pollfd p;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800417
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800418 int ret = logdOpen(logger_list, transp);
419 if (ret < 0) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800420 return ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800421 }
422
423 memset(&p, 0, sizeof(p));
424 p.fd = ret;
425 p.events = POLLIN;
426 ret = poll(&p, 1, 20);
427 if ((ret > 0) && !(p.revents & POLLIN)) {
428 ret = 0;
429 }
430 if ((ret == -1) && errno) {
431 return -errno;
432 }
433 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800434}
435
436/* Close all the logs */
Tom Cherry828db1a2019-11-14 10:39:40 -0800437static void LogdClose(struct logger_list*, struct android_log_transport_context* transp) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800438 int sock = atomic_exchange(&transp->context.sock, -1);
439 if (sock > 0) {
440 close(sock);
441 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800442}