14295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/*
2d0a83fddf18de1a567692a0eeb43228601c83fcfMark Salyzyn** Copyright 2013-2014, The Android Open Source Project
34295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn**
44295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** Licensed under the Apache License, Version 2.0 (the "License");
54295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** you may not use this file except in compliance with the License.
64295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** You may obtain a copy of the License at
74295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn**
84295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn**     http://www.apache.org/licenses/LICENSE-2.0
94295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn**
104295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** Unless required by applicable law or agreed to in writing, software
114295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** distributed under the License is distributed on an "AS IS" BASIS,
124295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** See the License for the specific language governing permissions and
144295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn** limitations under the License.
154295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn*/
164295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
174295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#include <errno.h>
184295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#include <fcntl.h>
19fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <inttypes.h>
20696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn#include <poll.h>
21154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <signal.h>
226eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn#include <stdbool.h>
23154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <stddef.h>
24154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#define NOMINMAX /* for windows to suppress definition of min in stdlib.h */
254295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#include <stdlib.h>
26154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <string.h>
27a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#include <sys/cdefs.h>
28154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <unistd.h>
29154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
304295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#include <cutils/list.h>
31154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <cutils/sockets.h>
324295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#include <log/log.h>
334295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#include <log/logger.h>
346eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn#include <private/android_filesystem_config.h>
356eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn#include <private/android_logger.h>
364295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
37154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* branchless on many architectures. */
38154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
39154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
40956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn#if (defined(USE_MINGW) || defined(HAVE_WINSOCK))
41956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn#define WEAK static
42956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn#else
43154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#define WEAK __attribute__((weak))
44956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn#endif
45a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#ifndef __unused
46a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#define __unused __attribute__((unused))
47a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#endif
48154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
49154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* Private copy of ../libcutils/socket_local_client.c prevent library loops */
50154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
51154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#ifdef HAVE_WINSOCK
52154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
53154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynint WEAK socket_local_client(const char *name, int namespaceId, int type)
54154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn{
55154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    errno = ENOSYS;
56154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return -ENOSYS;
57154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn}
58154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
59154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#else /* !HAVE_WINSOCK */
60154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
61154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <sys/socket.h>
62154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <sys/un.h>
63154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <sys/select.h>
64154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <sys/types.h>
65154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
66154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* Private copy of ../libcutils/socket_local.h prevent library loops */
67154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#define FILESYSTEM_SOCKET_PREFIX "/tmp/"
68154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"
69154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* End of ../libcutils/socket_local.h */
70154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
71154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#define LISTEN_BACKLOG 4
721345f38e4419607ea9c5b24109e5bd6df52dcffaMark Salyzyn
73154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* Documented in header file. */
74154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynint WEAK socket_make_sockaddr_un(const char *name, int namespaceId,
75154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                                 struct sockaddr_un *p_addr, socklen_t *alen)
76154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn{
77154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    memset (p_addr, 0, sizeof (*p_addr));
78154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    size_t namelen;
791345f38e4419607ea9c5b24109e5bd6df52dcffaMark Salyzyn
80154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    switch (namespaceId) {
81154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
829768d24fa096e312e472a43e13cf2867c1bf581dElliott Hughes#if defined(__linux__)
83154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        namelen  = strlen(name);
841345f38e4419607ea9c5b24109e5bd6df52dcffaMark Salyzyn
85154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* Test with length +1 for the *initial* '\0'. */
86154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if ((namelen + 1) > sizeof(p_addr->sun_path)) {
87154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            goto error;
88154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
894295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
90154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /*
91154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn         * Note: The path in this case is *not* supposed to be
92154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn         * '\0'-terminated. ("man 7 unix" for the gory details.)
93154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn         */
94154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
95154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        p_addr->sun_path[0] = 0;
96154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        memcpy(p_addr->sun_path + 1, name, namelen);
979768d24fa096e312e472a43e13cf2867c1bf581dElliott Hughes#else
98154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* this OS doesn't have the Linux abstract namespace */
99154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
100154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
101154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* unix_path_max appears to be missing on linux */
102154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (namelen > sizeof(*p_addr)
103154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                - offsetof(struct sockaddr_un, sun_path) - 1) {
104154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            goto error;
105154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
1064295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
107154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
108154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcat(p_addr->sun_path, name);
1099768d24fa096e312e472a43e13cf2867c1bf581dElliott Hughes#endif
110154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        break;
111154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
112154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    case ANDROID_SOCKET_NAMESPACE_RESERVED:
113154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
114154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* unix_path_max appears to be missing on linux */
115154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (namelen > sizeof(*p_addr)
116154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                - offsetof(struct sockaddr_un, sun_path) - 1) {
117154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            goto error;
118154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
119154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
120154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
121154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcat(p_addr->sun_path, name);
122154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        break;
123154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
124154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
125154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        namelen = strlen(name);
126154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* unix_path_max appears to be missing on linux */
127154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (namelen > sizeof(*p_addr)
128154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                - offsetof(struct sockaddr_un, sun_path) - 1) {
129154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            goto error;
130154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
131154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
132154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcpy(p_addr->sun_path, name);
133154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        break;
134154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
135154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    default:
136154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* invalid namespace id */
137154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return -1;
138154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
139154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
140154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    p_addr->sun_family = AF_LOCAL;
141154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
142154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return 0;
143154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynerror:
144154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return -1;
145154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn}
146154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
147154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/**
148154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * connect to peer named "name" on fd
149154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * returns same fd or -1 on error.
150154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * fd is not closed on error. that's your job.
151154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn *
152154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * Used by AndroidSocketImpl
153154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn */
154154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynint WEAK socket_local_client_connect(int fd, const char *name, int namespaceId,
155a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn                                     int type __unused)
156154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn{
157154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    struct sockaddr_un addr;
158154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    socklen_t alen;
159154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    int err;
160154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
161154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
162154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
163154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (err < 0) {
164154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        goto error;
165154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
166154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
167154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {
168154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        goto error;
169154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
170154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
171154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return fd;
172154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
173154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynerror:
174154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return -1;
175154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn}
176154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
177154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/**
178154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * connect to peer named "name"
179154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * returns fd or -1 on error
180154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn */
181154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynint WEAK socket_local_client(const char *name, int namespaceId, int type)
182154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn{
183154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    int s;
184154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
185154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    s = socket(AF_LOCAL, type, 0);
186154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if(s < 0) return -1;
187154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
188154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {
189154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        close(s);
190154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return -1;
191154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
192154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
193154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return s;
194154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn}
195154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
196154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#endif /* !HAVE_WINSOCK */
197154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* End of ../libcutils/socket_local_client.c */
1984295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
1994295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn#define logger_for_each(logger, logger_list) \
2004295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    for (logger = node_to_item((logger_list)->node.next, struct logger, node); \
2014295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn         logger != node_to_item(&(logger_list)->node, struct logger, node); \
2024295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn         logger = node_to_item((logger)->node.next, struct logger, node))
2034295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2044295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* In the future, we would like to make this list extensible */
2054295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstatic const char *LOG_NAME[LOG_ID_MAX] = {
2064295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    [LOG_ID_MAIN] = "main",
2074295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    [LOG_ID_RADIO] = "radio",
2084295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    [LOG_ID_EVENTS] = "events",
20999f47a9e7c4374f2bbfc18e4a97aa7848245ea33Mark Salyzyn    [LOG_ID_SYSTEM] = "system",
21099f47a9e7c4374f2bbfc18e4a97aa7848245ea33Mark Salyzyn    [LOG_ID_CRASH] = "crash",
2119e750a42b002f48622b54b247bb1ddd7abfa3fd1Mark Salyzyn    [LOG_ID_KERNEL] = "kernel",
2124295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn};
2134295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
214154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynconst char *android_log_id_to_name(log_id_t log_id)
215154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn{
2164295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (log_id >= LOG_ID_MAX) {
2174295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        log_id = LOG_ID_MAIN;
2184295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2194295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return LOG_NAME[log_id];
2204295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
2214295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
222154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynlog_id_t android_name_to_log_id(const char *logName)
2234295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
2244295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    const char *b;
2254295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    int ret;
2264295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2274295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logName) {
2284295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        return -1; /* NB: log_id_t is unsigned */
2294295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2304295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    b = strrchr(logName, '/');
2314295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!b) {
2324295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        b = logName;
2334295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    } else {
2344295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        ++b;
2354295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2364295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2374295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    for(ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {
2384295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        const char *l = LOG_NAME[ret];
2394295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        if (l && !strcmp(b, l)) {
2404295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            return ret;
2414295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        }
2424295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2434295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return -1;   /* should never happen */
2444295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
2454295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2464295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstruct logger_list {
2474295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct listnode node;
2484295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    int mode;
2494295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    unsigned int tail;
250fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    log_time start;
2514295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    pid_t pid;
252154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    int sock;
2534295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn};
2544295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2554295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstruct logger {
2564295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct listnode node;
2574295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct logger_list *top;
2584295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    log_id_t id;
2594295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn};
2604295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2614295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* android_logger_alloc unimplemented, no use case */
2624295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* android_logger_free not exported */
2634295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstatic void android_logger_free(struct logger *logger)
2644295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
2654295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logger) {
2664295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        return;
2674295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2684295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2694295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    list_remove(&logger->node);
2704295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2714295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    free(logger);
2724295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
2734295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
274154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* android_logger_alloc unimplemented, no use case */
275154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
276154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn/* method for getting the associated sublog id */
2774295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynlog_id_t android_logger_get_id(struct logger *logger)
2784295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
2794295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return logger->id;
2804295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
2814295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
2824295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* worker for sending the command to the logger */
283154f4608aac6218af0e25c98b71d0803278c047eMark Salyzynstatic ssize_t send_log_msg(struct logger *logger,
284154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                            const char *msg, char *buf, size_t buf_size)
2854295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
286154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    ssize_t ret;
287696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    size_t len;
288696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    char *cp;
2898084a53897b424ee751599c36c587f8463759516Greg Hackmann    int errno_save = 0;
290154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
291154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                                   SOCK_STREAM);
292154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (sock < 0) {
2938084a53897b424ee751599c36c587f8463759516Greg Hackmann        return sock;
2944295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2954295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
296154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (msg) {
297154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        snprintf(buf, buf_size, msg, logger ? logger->id : (unsigned) -1);
2984295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
2994295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
300696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    len = strlen(buf) + 1;
301696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
302154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (ret <= 0) {
303154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        goto done;
3044295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
3054295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
306696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    len = buf_size;
307696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    cp = buf;
308696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
309696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        struct pollfd p;
310696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
311696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
312696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn            break;
313696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        }
314696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
315696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        len -= ret;
316696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        cp += ret;
317696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
318696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        memset(&p, 0, sizeof(p));
319696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        p.fd = sock;
320696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        p.events = POLLIN;
321696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
322696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        /* Give other side 20ms to refill pipe */
323696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
324696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
325696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        if (ret <= 0) {
326696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn            break;
327696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        }
328696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
329696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        if (!(p.revents & POLLIN)) {
330696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn            ret = 0;
331696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn            break;
332696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        }
333696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    }
334696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn
335696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    if (ret >= 0) {
336696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn        ret += buf_size - len;
337696817d3524e2fb8bbbcc2ec3526f4383f789163Mark Salyzyn    }
3384295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
339154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyndone:
340154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if ((ret == -1) && errno) {
3418084a53897b424ee751599c36c587f8463759516Greg Hackmann        errno_save = errno;
342154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
343154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    close(sock);
3448084a53897b424ee751599c36c587f8463759516Greg Hackmann    if (errno_save) {
3458084a53897b424ee751599c36c587f8463759516Greg Hackmann        errno = errno_save;
3468084a53897b424ee751599c36c587f8463759516Greg Hackmann    }
3474295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return ret;
3484295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
3494295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
350dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzynstatic int check_log_success(char *buf, ssize_t ret)
3514295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
352154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (ret < 0) {
353154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return ret;
354154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
355154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
356154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (strncmp(buf, "success", 7)) {
3578084a53897b424ee751599c36c587f8463759516Greg Hackmann        errno = EINVAL;
358154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return -1;
359154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
360154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
361154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return 0;
3624295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
3634295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
3646eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn/* Determine the credentials of the caller */
3656eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzynstatic bool uid_has_log_permission(uid_t uid)
3666eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn{
3676eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    return (uid == AID_SYSTEM) || (uid == AID_LOG) || (uid == AID_ROOT);
3686eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn}
3696eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
3706eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzynstatic uid_t get_best_effective_uid()
3716eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn{
3726eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    uid_t euid;
3736eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    uid_t uid;
3746eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    gid_t gid;
3756eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    ssize_t i;
3766eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    static uid_t last_uid = (uid_t) -1;
3776eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
3786eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (last_uid != (uid_t) -1) {
3796eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return last_uid;
3806eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
3816eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    uid = getuid();
3826eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (uid_has_log_permission(uid)) {
3836eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return last_uid = uid;
3846eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
3856eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    euid = geteuid();
3866eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (uid_has_log_permission(euid)) {
3876eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return last_uid = euid;
3886eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
3896eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    gid = getgid();
3906eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (uid_has_log_permission(gid)) {
3916eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return last_uid = gid;
3926eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
3936eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    gid = getegid();
3946eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (uid_has_log_permission(gid)) {
3956eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return last_uid = gid;
3966eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
3976eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    i = getgroups((size_t) 0, NULL);
3986eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (i > 0) {
3996eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        gid_t list[i];
4006eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
4016eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        getgroups(i, list);
4026eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        while (--i >= 0) {
4036eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (uid_has_log_permission(list[i])) {
4046eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                return last_uid = list[i];
4056eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
4066eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
4076eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
4086eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    return last_uid = uid;
4096eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn}
4106eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
411dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzynint android_logger_clear(struct logger *logger)
412dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn{
413dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    char buf[512];
414dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
4156eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (logger->top->mode & ANDROID_LOG_PSTORE) {
4166eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if (uid_has_log_permission(get_best_effective_uid())) {
4176eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return unlink("/sys/fs/pstore/pmsg-ramoops-0");
4186eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
4196eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        errno = EPERM;
4206eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return -1;
4216eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
422dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    return check_log_success(buf,
423dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn        send_log_msg(logger, "clear %d", buf, sizeof(buf)));
424dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn}
425dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
4264295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* returns the total size of the log's ring buffer */
427dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzynlong android_logger_get_log_size(struct logger *logger)
4284295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
429154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    char buf[512];
430154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
431154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
432154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (ret < 0) {
433154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return ret;
434154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
435154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
436154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if ((buf[0] < '0') || ('9' < buf[0])) {
437154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return -1;
438154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
439154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
440dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    return atol(buf);
4414295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
4424295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
443dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzynint android_logger_set_log_size(struct logger *logger, unsigned long size)
444dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn{
445dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    char buf[512];
446dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
447dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    snprintf(buf, sizeof(buf), "setLogSize %d %lu",
448dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn        logger ? logger->id : (unsigned) -1, size);
449dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
450dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
451dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn}
452dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
4534295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/*
4544295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn * returns the readable size of the log's ring buffer (that is, amount of the
4554295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn * log consumed)
4564295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn */
457dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzynlong android_logger_get_log_readable_size(struct logger *logger)
4584295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
459154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    char buf[512];
460154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
461154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
462154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (ret < 0) {
463154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return ret;
464154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
465154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
466154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if ((buf[0] < '0') || ('9' < buf[0])) {
467154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return -1;
468154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
469154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
470dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    return atol(buf);
4714295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
4724295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
4734295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/*
4744295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn * returns the logger version
4754295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn */
476a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzynint android_logger_get_log_version(struct logger *logger __unused)
4774295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
478154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    return 3;
4794295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
4804295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
48134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn/*
48234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * returns statistics
48334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn */
48434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynssize_t android_logger_get_statistics(struct logger_list *logger_list,
48534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                                      char *buf, size_t len)
48634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn{
48734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    struct logger *logger;
48834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    char *cp = buf;
48934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t remaining = len;
49034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t n;
49134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
49234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    n = snprintf(cp, remaining, "getStatistics");
49334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    n = min(n, remaining);
49434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    remaining -= n;
49534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    cp += n;
49634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
49734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    logger_for_each(logger, logger_list) {
49834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        n = snprintf(cp, remaining, " %d", logger->id);
49934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        n = min(n, remaining);
50034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        remaining -= n;
50134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        cp += n;
50234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
50334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    return send_log_msg(NULL, NULL, buf, len);
50434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
50534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
506a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzynssize_t android_logger_get_prune_list(struct logger_list *logger_list __unused,
507dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn                                      char *buf, size_t len)
508dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn{
509dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    return send_log_msg(NULL, "getPruneList", buf, len);
510dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn}
511dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
512a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzynint android_logger_set_prune_list(struct logger_list *logger_list __unused,
513dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn                                  char *buf, size_t len)
514dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn{
515dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    const char cmd[] = "setPruneList ";
516dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    const size_t cmdlen = sizeof(cmd) - 1;
517dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
518dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    if (strlen(buf) > (len - cmdlen)) {
519dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn        return -ENOMEM; /* KISS */
520dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    }
521dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    memmove(buf + cmdlen, buf, len - cmdlen);
522dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    buf[len - 1] = '\0';
523dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    memcpy(buf, cmd, cmdlen);
524dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
525dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn    return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
526dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn}
527dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn
5284295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstruct logger_list *android_logger_list_alloc(int mode,
5294295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                                              unsigned int tail,
5304295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                                              pid_t pid)
5314295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
5324295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct logger_list *logger_list;
5334295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
5344295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger_list = calloc(1, sizeof(*logger_list));
5354295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logger_list) {
5364295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        return NULL;
5374295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
538154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
5394295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    list_init(&logger_list->node);
5404295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger_list->mode = mode;
541fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->start.tv_sec = 0;
542fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->start.tv_nsec = 0;
5434295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger_list->tail = tail;
5444295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger_list->pid = pid;
545154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    logger_list->sock = -1;
546154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
5474295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return logger_list;
5484295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
5494295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
550fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzynstruct logger_list *android_logger_list_alloc_time(int mode,
551fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                                                   log_time start,
552fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                                                   pid_t pid)
553fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn{
554fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    struct logger_list *logger_list;
555fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
556fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list = calloc(1, sizeof(*logger_list));
557fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    if (!logger_list) {
558fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        return NULL;
559fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
560fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
561fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    list_init(&logger_list->node);
562fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->mode = mode;
563fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->start = start;
564fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->tail = 0;
565fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->pid = pid;
566fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    logger_list->sock = -1;
567fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
568fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    return logger_list;
569fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn}
570fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
5714295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* android_logger_list_register unimplemented, no use case */
5724295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* android_logger_list_unregister unimplemented, no use case */
5734295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
5744295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* Open the named log and add it to the logger list */
5754295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstruct logger *android_logger_open(struct logger_list *logger_list,
5764295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                                   log_id_t id)
5774295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
5784295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct logger *logger;
5794295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
5804295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logger_list || (id >= LOG_ID_MAX)) {
5814295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        goto err;
5824295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
5834295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
5844295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger_for_each(logger, logger_list) {
5854295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        if (logger->id == id) {
5864295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            goto ok;
5874295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        }
5884295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
5894295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
5904295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger = calloc(1, sizeof(*logger));
5914295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logger) {
5924295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        goto err;
5934295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
5944295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
5954295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger->id = id;
5964295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    list_add_tail(&logger_list->node, &logger->node);
5974295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger->top = logger_list;
5984295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    goto ok;
5994295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
6004295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynerr:
6014295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    logger = NULL;
6024295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynok:
6034295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return logger;
6044295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
6054295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
6064295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* Open the single named log and make it part of a new logger list */
6074295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynstruct logger_list *android_logger_list_open(log_id_t id,
6084295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                                             int mode,
6094295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                                             unsigned int tail,
6104295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                                             pid_t pid)
6114295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
6124295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct logger_list *logger_list = android_logger_list_alloc(mode, tail, pid);
6134295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logger_list) {
6144295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        return NULL;
6154295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
6164295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
6174295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!android_logger_open(logger_list, id)) {
6184295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        android_logger_list_free(logger_list);
6194295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        return NULL;
6204295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
6214295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
6224295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return logger_list;
6234295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
6244295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
6256eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzynstatic int android_logger_list_read_pstore(struct logger_list *logger_list,
6266eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                           struct log_msg *log_msg)
6276eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn{
6286eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    ssize_t ret;
6296eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    off_t current, next;
6306eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    uid_t uid;
6316eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    struct logger *logger;
6326eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    struct __attribute__((__packed__)) {
6336eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        android_pmsg_log_header_t p;
6346eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        android_log_header_t l;
6356eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    } buf;
6366eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    static uint8_t preread_count;
6376eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6386eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    memset(log_msg, 0, sizeof(*log_msg));
6396eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6406eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (logger_list->sock < 0) {
6416eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        int fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY);
6426eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6436eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if (fd < 0) {
6446eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return -errno;
6456eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
6466eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        logger_list->sock = fd;
6476eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        preread_count = 0;
6486eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
6496eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6506eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    ret = 0;
6516eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    while(1) {
6526eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if (preread_count < sizeof(buf)) {
6536eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            ret = TEMP_FAILURE_RETRY(read(logger_list->sock,
6546eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                          &buf.p.magic + preread_count,
6556eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                          sizeof(buf) - preread_count));
6566eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (ret < 0) {
6576eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                return -errno;
6586eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
6596eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            preread_count += ret;
6606eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
6616eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if (preread_count != sizeof(buf)) {
6626eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return preread_count ? -EIO : -EAGAIN;
6636eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
6646eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if ((buf.p.magic != LOGGER_MAGIC)
6656eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn         || (buf.p.len <= sizeof(buf))
6666eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn         || (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD))
6676eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn         || (buf.l.id >= LOG_ID_MAX)
6686eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn         || (buf.l.realtime.tv_nsec >= NS_PER_SEC)) {
6696eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            do {
6706eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count);
6716eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            } while (preread_count && (buf.p.magic != LOGGER_MAGIC));
6726eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            continue;
6736eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
6746eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        preread_count = 0;
6756eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6766eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        logger_for_each(logger, logger_list) {
6776eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (buf.l.id != logger->id) {
6786eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                continue;
6796eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
6806eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6816eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if ((logger_list->start.tv_sec || logger_list->start.tv_nsec)
6826eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn             && ((logger_list->start.tv_sec > buf.l.realtime.tv_sec)
6836eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn              || ((logger_list->start.tv_sec == buf.l.realtime.tv_sec)
6846eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn               && (logger_list->start.tv_nsec > buf.l.realtime.tv_nsec)))) {
6856eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                break;
6866eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
6876eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6886eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (logger_list->pid && (logger_list->pid != buf.p.pid)) {
6896eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                break;
6906eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
6916eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6926eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            uid = get_best_effective_uid();
6936eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (!uid_has_log_permission(uid) && (uid != buf.p.uid)) {
6946eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                break;
6956eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
6966eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
6976eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            ret = TEMP_FAILURE_RETRY(read(logger_list->sock,
6986eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                          log_msg->entry_v3.msg,
6996eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                          buf.p.len - sizeof(buf)));
7006eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (ret < 0) {
7016eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                return -errno;
7026eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
7036eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            if (ret != (ssize_t)(buf.p.len - sizeof(buf))) {
7046eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                return -EIO;
7056eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            }
7066eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
7076eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.len = buf.p.len - sizeof(buf);
7086eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3);
7096eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.pid = buf.p.pid;
7106eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.tid = buf.l.tid;
7116eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.sec = buf.l.realtime.tv_sec;
7126eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.nsec = buf.l.realtime.tv_nsec;
7136eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            log_msg->entry_v3.lid = buf.l.id;
7146eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
7156eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return ret;
7166eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
7176eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
7186eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        current = TEMP_FAILURE_RETRY(lseek(logger_list->sock,
7196eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                           (off_t)0, SEEK_CUR));
7206eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if (current < 0) {
7216eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return -errno;
7226eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
7236eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        next = TEMP_FAILURE_RETRY(lseek(logger_list->sock,
7246eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                        (off_t)(buf.p.len - sizeof(buf)),
7256eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn                                        SEEK_CUR));
7266eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if (next < 0) {
7276eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return -errno;
7286eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
7296eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) {
7306eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn            return -EIO;
7316eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        }
7326eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
7336eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn}
7346eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
735a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzynstatic void caught_signal(int signum __unused)
7364295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
7374295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
7384295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
7394295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* Read from the selected logs */
7404295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynint android_logger_list_read(struct logger_list *logger_list,
7414295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn                             struct log_msg *log_msg)
7424295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
743154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    int ret, e;
7444295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    struct logger *logger;
745154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    struct sigaction ignore;
746154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    struct sigaction old_sigaction;
747154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    unsigned int old_alarm = 0;
7484295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
7494295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (!logger_list) {
750154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        return -EINVAL;
7514295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
7524295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
7536eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    if (logger_list->mode & ANDROID_LOG_PSTORE) {
7546eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn        return android_logger_list_read_pstore(logger_list, log_msg);
7556eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn    }
7566eef4171195f83541b3ee62cdcc4eac863c5edd9Mark Salyzyn
7572d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn    if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
758154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        memset(&ignore, 0, sizeof(ignore));
759154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        ignore.sa_handler = caught_signal;
760154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        sigemptyset(&ignore.sa_mask);
7614295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
7624295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
763154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (logger_list->sock < 0) {
764154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        char buffer[256], *cp, c;
7654295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
766154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        int sock = socket_local_client("logdr",
767154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                                       ANDROID_SOCKET_NAMESPACE_RESERVED,
768154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                                       SOCK_SEQPACKET);
769154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (sock < 0) {
770154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if ((sock == -1) && errno) {
771154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                return -errno;
7724295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            }
773154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            return sock;
7744295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        }
7754295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
776154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcpy(buffer,
7772d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn               (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream");
778154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        cp = buffer + strlen(buffer);
7794295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
780154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        strcpy(cp, " lids");
781154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        cp += 5;
782154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        c = '=';
783154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        int remaining = sizeof(buffer) - (cp - buffer);
7844295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        logger_for_each(logger, logger_list) {
785154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            ret = snprintf(cp, remaining, "%c%u", c, logger->id);
786154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            ret = min(ret, remaining);
787154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            remaining -= ret;
788154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            cp += ret;
789154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            c = ',';
790154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
7914295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
792154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (logger_list->tail) {
793154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
794154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            ret = min(ret, remaining);
795154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            remaining -= ret;
796154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            cp += ret;
797154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
7984295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
799fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
800fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32,
801fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                           logger_list->start.tv_sec,
802fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                           logger_list->start.tv_nsec);
803fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            ret = min(ret, remaining);
804fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            remaining -= ret;
805fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            cp += ret;
806fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        }
807fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
808154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (logger_list->pid) {
809154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
810154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            ret = min(ret, remaining);
811154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            remaining -= ret;
812154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            cp += ret;
813154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
8144295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
8152d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn        if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
816154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            /* Deal with an unresponsive logd */
817154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            sigaction(SIGALRM, &ignore, &old_sigaction);
818154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            old_alarm = alarm(30);
819154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
820154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        ret = write(sock, buffer, cp - buffer);
821154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        e = errno;
8222d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn        if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
823154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if (e == EINTR) {
824154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                e = ETIMEDOUT;
8254295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            }
826154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            alarm(old_alarm);
827154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            sigaction(SIGALRM, &old_sigaction, NULL);
828154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
8294295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
830154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        if (ret <= 0) {
831154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            close(sock);
832154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if ((ret == -1) && e) {
833154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                return -e;
8344295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            }
835154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if (ret == 0) {
836154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                return -EIO;
8374295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            }
838154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            return ret;
839154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
8404295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
841154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        logger_list->sock = sock;
842154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
8434295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
844154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    ret = 0;
845154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    while(1) {
846154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        memset(log_msg, 0, sizeof(*log_msg));
8474295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
8482d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn        if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
849154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            /* particularily useful if tombstone is reporting for logd */
850154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            sigaction(SIGALRM, &ignore, &old_sigaction);
851154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            old_alarm = alarm(30);
852154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        }
853154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
854154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        ret = recv(logger_list->sock, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
855154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        e = errno;
8562d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn        if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
857154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if ((ret == 0) || (e == EINTR)) {
858154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                e = EAGAIN;
859154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                ret = -1;
8604295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            }
861154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            alarm(old_alarm);
862154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            sigaction(SIGALRM, &old_sigaction, NULL);
8634295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        }
8644295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
8654295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        if (ret <= 0) {
866154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if ((ret == -1) && e) {
867154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                return -e;
8684295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn            }
869154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            return ret;
8704295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        }
8714295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
872154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        logger_for_each(logger, logger_list) {
873154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            if (log_msg->entry.lid == logger->id) {
874154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn                return ret;
875154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn            }
8764295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        }
8774295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
878154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    /* NOTREACH */
8794295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    return ret;
8804295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
8814295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
8824295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn/* Close all the logs */
8834295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzynvoid android_logger_list_free(struct logger_list *logger_list)
8844295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn{
8854295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    if (logger_list == NULL) {
8864295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        return;
8874295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
8884295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
8894295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    while (!list_empty(&logger_list->node)) {
8904295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        struct listnode *node = list_head(&logger_list->node);
8914295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        struct logger *logger = node_to_item(node, struct logger, node);
8924295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn        android_logger_free(logger);
8934295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    }
8944295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn
895154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    if (logger_list->sock >= 0) {
896154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn        close (logger_list->sock);
897154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn    }
898154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
8994295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn    free(logger_list);
9004295841ebe68a2ebf50ed7adf0a603c523d5af52Mark Salyzyn}
901