summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2017-03-09 10:09:43 -0600
committerMark Salyzyn2017-03-09 11:36:19 -0600
commit2ed51d708eda64516ec79ac6397f690de38f0075 (patch)
tree9ea938a4ee0461c443dc99e197827fc36ecd643b /liblog/logd_reader.c
parentc1b3c8ef2629eac2a73aa4a95bf43a66edf4cd0f (diff)
downloadplatform-system-core-2ed51d708eda64516ec79ac6397f690de38f0075.tar.gz
platform-system-core-2ed51d708eda64516ec79ac6397f690de38f0075.tar.xz
platform-system-core-2ed51d708eda64516ec79ac6397f690de38f0075.zip
liblog: specify clang format
Switch coding style to match SideEffects: None Test: compile Bug: 27405083 Change-Id: Id426d5c5e3b18f2ceec22b31bbc9781aabf6bcca
Diffstat (limited to 'liblog/logd_reader.c')
-rw-r--r--liblog/logd_reader.c927
1 files changed, 450 insertions, 477 deletions
diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c
index a6c3f7a44..600f4bb0b 100644
--- a/liblog/logd_reader.c
+++ b/liblog/logd_reader.c
@@ -24,9 +24,9 @@
24#include <stdio.h> 24#include <stdio.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h> 26#include <string.h>
27#include <sys/socket.h>
27#include <sys/stat.h> 28#include <sys/stat.h>
28#include <sys/types.h> 29#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/un.h> 30#include <sys/un.h>
31#include <time.h> 31#include <time.h>
32#include <unistd.h> 32#include <unistd.h>
@@ -41,87 +41,86 @@
41#include "logger.h" 41#include "logger.h"
42 42
43/* branchless on many architectures. */ 43/* branchless on many architectures. */
44#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y)))) 44#define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
45 45
46static int logdAvailable(log_id_t LogId); 46static int logdAvailable(log_id_t LogId);
47static int logdVersion(struct android_log_logger *logger, 47static int logdVersion(struct android_log_logger* logger,
48 struct android_log_transport_context *transp); 48 struct android_log_transport_context* transp);
49static int logdRead(struct android_log_logger_list *logger_list, 49static int logdRead(struct android_log_logger_list* logger_list,
50 struct android_log_transport_context *transp, 50 struct android_log_transport_context* transp,
51 struct log_msg *log_msg); 51 struct log_msg* log_msg);
52static int logdPoll(struct android_log_logger_list *logger_list, 52static int logdPoll(struct android_log_logger_list* logger_list,
53 struct android_log_transport_context *transp); 53 struct android_log_transport_context* transp);
54static void logdClose(struct android_log_logger_list *logger_list, 54static void logdClose(struct android_log_logger_list* logger_list,
55 struct android_log_transport_context *transp); 55 struct android_log_transport_context* transp);
56static int logdClear(struct android_log_logger *logger, 56static int logdClear(struct android_log_logger* logger,
57 struct android_log_transport_context *transp); 57 struct android_log_transport_context* transp);
58static ssize_t logdSetSize(struct android_log_logger *logger, 58static ssize_t logdSetSize(struct android_log_logger* logger,
59 struct android_log_transport_context *transp, 59 struct android_log_transport_context* transp,
60 size_t size); 60 size_t size);
61static ssize_t logdGetSize(struct android_log_logger *logger, 61static ssize_t logdGetSize(struct android_log_logger* logger,
62 struct android_log_transport_context *transp); 62 struct android_log_transport_context* transp);
63static ssize_t logdGetReadableSize(struct android_log_logger *logger, 63static ssize_t logdGetReadableSize(struct android_log_logger* logger,
64 struct android_log_transport_context *transp); 64 struct android_log_transport_context* transp);
65static ssize_t logdGetPrune(struct android_log_logger_list *logger, 65static ssize_t logdGetPrune(struct android_log_logger_list* logger,
66 struct android_log_transport_context *transp, 66 struct android_log_transport_context* transp,
67 char *buf, size_t len); 67 char* buf, size_t len);
68static ssize_t logdSetPrune(struct android_log_logger_list *logger, 68static ssize_t logdSetPrune(struct android_log_logger_list* logger,
69 struct android_log_transport_context *transp, 69 struct android_log_transport_context* transp,
70 char *buf, size_t len); 70 char* buf, size_t len);
71static ssize_t logdGetStats(struct android_log_logger_list *logger, 71static ssize_t logdGetStats(struct android_log_logger_list* logger,
72 struct android_log_transport_context *transp, 72 struct android_log_transport_context* transp,
73 char *buf, size_t len); 73 char* buf, size_t len);
74 74
75LIBLOG_HIDDEN struct android_log_transport_read logdLoggerRead = { 75LIBLOG_HIDDEN struct android_log_transport_read logdLoggerRead = {
76 .node = { &logdLoggerRead.node, &logdLoggerRead.node }, 76 .node = { &logdLoggerRead.node, &logdLoggerRead.node },
77 .name = "logd", 77 .name = "logd",
78 .available = logdAvailable, 78 .available = logdAvailable,
79 .version = logdVersion, 79 .version = logdVersion,
80 .read = logdRead, 80 .read = logdRead,
81 .poll = logdPoll, 81 .poll = logdPoll,
82 .close = logdClose, 82 .close = logdClose,
83 .clear = logdClear, 83 .clear = logdClear,
84 .getSize = logdGetSize, 84 .getSize = logdGetSize,
85 .setSize = logdSetSize, 85 .setSize = logdSetSize,
86 .getReadableSize = logdGetReadableSize, 86 .getReadableSize = logdGetReadableSize,
87 .getPrune = logdGetPrune, 87 .getPrune = logdGetPrune,
88 .setPrune = logdSetPrune, 88 .setPrune = logdSetPrune,
89 .getStats = logdGetStats, 89 .getStats = logdGetStats,
90}; 90};
91 91
92static int logdAvailable(log_id_t logId) 92static int logdAvailable(log_id_t logId) {
93{ 93 if (logId >= LOG_ID_MAX) {
94 if (logId >= LOG_ID_MAX) { 94 return -EINVAL;
95 return -EINVAL; 95 }
96 } 96 if (logId == LOG_ID_SECURITY) {
97 if (logId == LOG_ID_SECURITY) { 97 uid_t uid = __android_log_uid();
98 uid_t uid = __android_log_uid(); 98 if (uid != AID_SYSTEM) {
99 if (uid != AID_SYSTEM) { 99 return -EPERM;
100 return -EPERM;
101 }
102 }
103 if (access("/dev/socket/logdw", W_OK) == 0) {
104 return 0;
105 } 100 }
106 return -EBADF; 101 }
102 if (access("/dev/socket/logdw", W_OK) == 0) {
103 return 0;
104 }
105 return -EBADF;
107} 106}
108 107
109/* Private copy of ../libcutils/socket_local_client.c prevent library loops */ 108/* Private copy of ../libcutils/socket_local_client.c prevent library loops */
110 109
111#if defined(_WIN32) 110#if defined(_WIN32)
112 111
113LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type) 112LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId,
114{ 113 int type) {
115 errno = ENOSYS; 114 errno = ENOSYS;
116 return -ENOSYS; 115 return -ENOSYS;
117} 116}
118 117
119#else /* !_WIN32 */ 118#else /* !_WIN32 */
120 119
121#include <sys/socket.h>
122#include <sys/un.h>
123#include <sys/select.h> 120#include <sys/select.h>
121#include <sys/socket.h>
124#include <sys/types.h> 122#include <sys/types.h>
123#include <sys/un.h>
125 124
126/* Private copy of ../libcutils/socket_local.h prevent library loops */ 125/* Private copy of ../libcutils/socket_local.h prevent library loops */
127#define FILESYSTEM_SOCKET_PREFIX "/tmp/" 126#define FILESYSTEM_SOCKET_PREFIX "/tmp/"
@@ -131,78 +130,77 @@ LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type)
131#define LISTEN_BACKLOG 4 130#define LISTEN_BACKLOG 4
132 131
133/* Documented in header file. */ 132/* Documented in header file. */
134LIBLOG_WEAK int socket_make_sockaddr_un(const char *name, int namespaceId, 133LIBLOG_WEAK int socket_make_sockaddr_un(const char* name, int namespaceId,
135 struct sockaddr_un *p_addr, 134 struct sockaddr_un* p_addr,
136 socklen_t *alen) 135 socklen_t* alen) {
137{ 136 memset(p_addr, 0, sizeof(*p_addr));
138 memset (p_addr, 0, sizeof (*p_addr)); 137 size_t namelen;
139 size_t namelen; 138
140 139 switch (namespaceId) {
141 switch (namespaceId) {
142 case ANDROID_SOCKET_NAMESPACE_ABSTRACT: 140 case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
143#if defined(__linux__) 141#if defined(__linux__)
144 namelen = strlen(name); 142 namelen = strlen(name);
145 143
146 /* Test with length +1 for the *initial* '\0'. */ 144 /* Test with length +1 for the *initial* '\0'. */
147 if ((namelen + 1) > sizeof(p_addr->sun_path)) { 145 if ((namelen + 1) > sizeof(p_addr->sun_path)) {
148 goto error; 146 goto error;
149 } 147 }
150 148
151 /* 149 /*
152 * Note: The path in this case is *not* supposed to be 150 * Note: The path in this case is *not* supposed to be
153 * '\0'-terminated. ("man 7 unix" for the gory details.) 151 * '\0'-terminated. ("man 7 unix" for the gory details.)
154 */ 152 */
155 153
156 p_addr->sun_path[0] = 0; 154 p_addr->sun_path[0] = 0;
157 memcpy(p_addr->sun_path + 1, name, namelen); 155 memcpy(p_addr->sun_path + 1, name, namelen);
158#else 156#else
159 /* this OS doesn't have the Linux abstract namespace */ 157 /* this OS doesn't have the Linux abstract namespace */
160 158
161 namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX); 159 namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
162 /* unix_path_max appears to be missing on linux */ 160 /* unix_path_max appears to be missing on linux */
163 if (namelen > sizeof(*p_addr) 161 if (namelen >
164 - offsetof(struct sockaddr_un, sun_path) - 1) { 162 sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
165 goto error; 163 goto error;
166 } 164 }
167 165
168 strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX); 166 strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
169 strcat(p_addr->sun_path, name); 167 strcat(p_addr->sun_path, name);
170#endif 168#endif
171 break; 169 break;
172 170
173 case ANDROID_SOCKET_NAMESPACE_RESERVED: 171 case ANDROID_SOCKET_NAMESPACE_RESERVED:
174 namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX); 172 namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
175 /* unix_path_max appears to be missing on linux */ 173 /* unix_path_max appears to be missing on linux */
176 if (namelen > sizeof(*p_addr) 174 if (namelen >
177 - offsetof(struct sockaddr_un, sun_path) - 1) { 175 sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
178 goto error; 176 goto error;
179 } 177 }
180 178
181 strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX); 179 strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
182 strcat(p_addr->sun_path, name); 180 strcat(p_addr->sun_path, name);
183 break; 181 break;
184 182
185 case ANDROID_SOCKET_NAMESPACE_FILESYSTEM: 183 case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
186 namelen = strlen(name); 184 namelen = strlen(name);
187 /* unix_path_max appears to be missing on linux */ 185 /* unix_path_max appears to be missing on linux */
188 if (namelen > sizeof(*p_addr) 186 if (namelen >
189 - offsetof(struct sockaddr_un, sun_path) - 1) { 187 sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
190 goto error; 188 goto error;
191 } 189 }
192 190
193 strcpy(p_addr->sun_path, name); 191 strcpy(p_addr->sun_path, name);
194 break; 192 break;
195 193
196 default: 194 default:
197 /* invalid namespace id */ 195 /* invalid namespace id */
198 return -1; 196 return -1;
199 } 197 }
200 198
201 p_addr->sun_family = AF_LOCAL; 199 p_addr->sun_family = AF_LOCAL;
202 *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; 200 *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
203 return 0; 201 return 0;
204error: 202error:
205 return -1; 203 return -1;
206} 204}
207 205
208/** 206/**
@@ -212,466 +210,441 @@ error:
212 * 210 *
213 * Used by AndroidSocketImpl 211 * Used by AndroidSocketImpl
214 */ 212 */
215LIBLOG_WEAK int socket_local_client_connect(int fd, const char *name, 213LIBLOG_WEAK int socket_local_client_connect(int fd, const char* name,
216 int namespaceId, int type __unused) 214 int namespaceId, int type __unused) {
217{ 215 struct sockaddr_un addr;
218 struct sockaddr_un addr; 216 socklen_t alen;
219 socklen_t alen; 217 int err;
220 int err;
221 218
222 err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); 219 err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
223 220
224 if (err < 0) { 221 if (err < 0) {
225 goto error; 222 goto error;
226 } 223 }
227 224
228 if(connect(fd, (struct sockaddr *) &addr, alen) < 0) { 225 if (connect(fd, (struct sockaddr*)&addr, alen) < 0) {
229 goto error; 226 goto error;
230 } 227 }
231 228
232 return fd; 229 return fd;
233 230
234error: 231error:
235 return -1; 232 return -1;
236} 233}
237 234
238/** 235/**
239 * connect to peer named "name" 236 * connect to peer named "name"
240 * returns fd or -1 on error 237 * returns fd or -1 on error
241 */ 238 */
242LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type) 239LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId,
243{ 240 int type) {
244 int s; 241 int s;
245 242
246 s = socket(AF_LOCAL, type, 0); 243 s = socket(AF_LOCAL, type, 0);
247 if(s < 0) return -1; 244 if (s < 0) return -1;
248 245
249 if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) { 246 if (0 > socket_local_client_connect(s, name, namespaceId, type)) {
250 close(s); 247 close(s);
251 return -1; 248 return -1;
252 } 249 }
253 250
254 return s; 251 return s;
255} 252}
256 253
257#endif /* !_WIN32 */ 254#endif /* !_WIN32 */
258/* End of ../libcutils/socket_local_client.c */ 255/* End of ../libcutils/socket_local_client.c */
259 256
260/* worker for sending the command to the logger */ 257/* worker for sending the command to the logger */
261static ssize_t send_log_msg(struct android_log_logger *logger, 258static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg,
262 const char *msg, char *buf, size_t buf_size) 259 char* buf, size_t buf_size) {
263{ 260 ssize_t ret;
264 ssize_t ret; 261 size_t len;
265 size_t len; 262 char* cp;
266 char *cp; 263 int errno_save = 0;
267 int errno_save = 0; 264 int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
268 int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, 265 SOCK_STREAM);
269 SOCK_STREAM); 266 if (sock < 0) {
270 if (sock < 0) { 267 return sock;
271 return sock; 268 }
272 }
273
274 if (msg) {
275 snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned) -1);
276 }
277 269
278 len = strlen(buf) + 1; 270 if (msg) {
279 ret = TEMP_FAILURE_RETRY(write(sock, buf, len)); 271 snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned)-1);
280 if (ret <= 0) { 272 }
281 goto done;
282 }
283 273
284 len = buf_size; 274 len = strlen(buf) + 1;
285 cp = buf; 275 ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
286 while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) { 276 if (ret <= 0) {
287 struct pollfd p; 277 goto done;
278 }
288 279
289 if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) { 280 len = buf_size;
290 break; 281 cp = buf;
291 } 282 while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
283 struct pollfd p;
292 284
293 len -= ret; 285 if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
294 cp += ret; 286 break;
287 }
295 288
296 memset(&p, 0, sizeof(p)); 289 len -= ret;
297 p.fd = sock; 290 cp += ret;
298 p.events = POLLIN;
299 291
300 /* Give other side 20ms to refill pipe */ 292 memset(&p, 0, sizeof(p));
301 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20)); 293 p.fd = sock;
294 p.events = POLLIN;
302 295
303 if (ret <= 0) { 296 /* Give other side 20ms to refill pipe */
304 break; 297 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
305 }
306 298
307 if (!(p.revents & POLLIN)) { 299 if (ret <= 0) {
308 ret = 0; 300 break;
309 break;
310 }
311 } 301 }
312 302
313 if (ret >= 0) { 303 if (!(p.revents & POLLIN)) {
314 ret += buf_size - len; 304 ret = 0;
305 break;
315 } 306 }
307 }
308
309 if (ret >= 0) {
310 ret += buf_size - len;
311 }
316 312
317done: 313done:
318 if ((ret == -1) && errno) { 314 if ((ret == -1) && errno) {
319 errno_save = errno; 315 errno_save = errno;
320 } 316 }
321 close(sock); 317 close(sock);
322 if (errno_save) { 318 if (errno_save) {
323 errno = errno_save; 319 errno = errno_save;
324 } 320 }
325 return ret; 321 return ret;
326} 322}
327 323
328LIBLOG_HIDDEN ssize_t __send_log_msg(char *buf, size_t buf_size) 324LIBLOG_HIDDEN ssize_t __send_log_msg(char* buf, size_t buf_size) {
329{ 325 return send_log_msg(NULL, NULL, buf, buf_size);
330 return send_log_msg(NULL, NULL, buf, buf_size);
331} 326}
332 327
333static int check_log_success(char *buf, ssize_t ret) 328static int check_log_success(char* buf, ssize_t ret) {
334{ 329 if (ret < 0) {
335 if (ret < 0) { 330 return ret;
336 return ret; 331 }
337 }
338 332
339 if (strncmp(buf, "success", 7)) { 333 if (strncmp(buf, "success", 7)) {
340 errno = EINVAL; 334 errno = EINVAL;
341 return -1; 335 return -1;
342 } 336 }
343 337
344 return 0; 338 return 0;
345} 339}
346 340
347static int logdClear(struct android_log_logger *logger, 341static int logdClear(struct android_log_logger* logger,
348 struct android_log_transport_context *transp __unused) 342 struct android_log_transport_context* transp __unused) {
349{ 343 char buf[512];
350 char buf[512];
351 344
352 return check_log_success(buf, 345 return check_log_success(buf,
353 send_log_msg(logger, "clear %d", buf, sizeof(buf))); 346 send_log_msg(logger, "clear %d", buf, sizeof(buf)));
354} 347}
355 348
356/* returns the total size of the log's ring buffer */ 349/* returns the total size of the log's ring buffer */
357static ssize_t logdGetSize(struct android_log_logger *logger, 350static ssize_t logdGetSize(struct android_log_logger* logger,
358 struct android_log_transport_context *transp __unused) 351 struct android_log_transport_context* transp __unused) {
359{ 352 char buf[512];
360 char buf[512];
361
362 ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
363 if (ret < 0) {
364 return ret;
365 }
366 353
367 if ((buf[0] < '0') || ('9' < buf[0])) { 354 ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
368 return -1; 355 if (ret < 0) {
369 } 356 return ret;
357 }
358
359 if ((buf[0] < '0') || ('9' < buf[0])) {
360 return -1;
361 }
370 362
371 return atol(buf); 363 return atol(buf);
372} 364}
373 365
374static ssize_t logdSetSize( 366static ssize_t logdSetSize(struct android_log_logger* logger,
375 struct android_log_logger *logger, 367 struct android_log_transport_context* transp __unused,
376 struct android_log_transport_context *transp __unused, 368 size_t size) {
377 size_t size) 369 char buf[512];
378{
379 char buf[512];
380 370
381 snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size); 371 snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
382 372
383 return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf))); 373 return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
384} 374}
385 375
386/* 376/*
387 * returns the readable size of the log's ring buffer (that is, amount of the 377 * returns the readable size of the log's ring buffer (that is, amount of the
388 * log consumed) 378 * log consumed)
389 */ 379 */
390static ssize_t logdGetReadableSize( 380static ssize_t logdGetReadableSize(struct android_log_logger* logger,
391 struct android_log_logger *logger, 381 struct android_log_transport_context* transp
392 struct android_log_transport_context *transp __unused) 382 __unused) {
393{ 383 char buf[512];
394 char buf[512];
395
396 ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
397 if (ret < 0) {
398 return ret;
399 }
400 384
401 if ((buf[0] < '0') || ('9' < buf[0])) { 385 ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
402 return -1; 386 if (ret < 0) {
403 } 387 return ret;
388 }
389
390 if ((buf[0] < '0') || ('9' < buf[0])) {
391 return -1;
392 }
404 393
405 return atol(buf); 394 return atol(buf);
406} 395}
407 396
408/* 397/*
409 * returns the logger version 398 * returns the logger version
410 */ 399 */
411static int logdVersion( 400static int logdVersion(struct android_log_logger* logger __unused,
412 struct android_log_logger *logger __unused, 401 struct android_log_transport_context* transp __unused) {
413 struct android_log_transport_context *transp __unused) 402 uid_t uid = __android_log_uid();
414{ 403 return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
415 uid_t uid = __android_log_uid();
416 return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
417} 404}
418 405
419/* 406/*
420 * returns statistics 407 * returns statistics
421 */ 408 */
422static ssize_t logdGetStats(struct android_log_logger_list *logger_list, 409static ssize_t logdGetStats(struct android_log_logger_list* logger_list,
423 struct android_log_transport_context *transp __unused, 410 struct android_log_transport_context* transp __unused,
424 char *buf, size_t len) 411 char* buf, size_t len) {
425{ 412 struct android_log_logger* logger;
426 struct android_log_logger *logger; 413 char* cp = buf;
427 char *cp = buf; 414 size_t remaining = len;
428 size_t remaining = len; 415 size_t n;
429 size_t n; 416
430 417 n = snprintf(cp, remaining, "getStatistics");
431 n = snprintf(cp, remaining, "getStatistics"); 418 n = min(n, remaining);
419 remaining -= n;
420 cp += n;
421
422 logger_for_each(logger, logger_list) {
423 n = snprintf(cp, remaining, " %d", logger->logId);
432 n = min(n, remaining); 424 n = min(n, remaining);
433 remaining -= n; 425 remaining -= n;
434 cp += n; 426 cp += n;
427 }
435 428
436 logger_for_each(logger, logger_list) { 429 if (logger_list->pid) {
437 n = snprintf(cp, remaining, " %d", logger->logId); 430 snprintf(cp, remaining, " pid=%u", logger_list->pid);
438 n = min(n, remaining); 431 }
439 remaining -= n;
440 cp += n;
441 }
442
443 if (logger_list->pid) {
444 snprintf(cp, remaining, " pid=%u", logger_list->pid);
445 }
446 432
447 return send_log_msg(NULL, NULL, buf, len); 433 return send_log_msg(NULL, NULL, buf, len);
448} 434}
449 435
450static ssize_t logdGetPrune( 436static ssize_t logdGetPrune(struct android_log_logger_list* logger_list __unused,
451 struct android_log_logger_list *logger_list __unused, 437 struct android_log_transport_context* transp __unused,
452 struct android_log_transport_context *transp __unused, 438 char* buf, size_t len) {
453 char *buf, size_t len) 439 return send_log_msg(NULL, "getPruneList", buf, len);
454{
455 return send_log_msg(NULL, "getPruneList", buf, len);
456} 440}
457 441
458static ssize_t logdSetPrune( 442static ssize_t logdSetPrune(struct android_log_logger_list* logger_list __unused,
459 struct android_log_logger_list *logger_list __unused, 443 struct android_log_transport_context* transp __unused,
460 struct android_log_transport_context *transp __unused, 444 char* buf, size_t len) {
461 char *buf, size_t len) 445 const char cmd[] = "setPruneList ";
462{ 446 const size_t cmdlen = sizeof(cmd) - 1;
463 const char cmd[] = "setPruneList ";
464 const size_t cmdlen = sizeof(cmd) - 1;
465 447
466 if (strlen(buf) > (len - cmdlen)) { 448 if (strlen(buf) > (len - cmdlen)) {
467 return -ENOMEM; /* KISS */ 449 return -ENOMEM; /* KISS */
468 } 450 }
469 memmove(buf + cmdlen, buf, len - cmdlen); 451 memmove(buf + cmdlen, buf, len - cmdlen);
470 buf[len - 1] = '\0'; 452 buf[len - 1] = '\0';
471 memcpy(buf, cmd, cmdlen); 453 memcpy(buf, cmd, cmdlen);
472 454
473 return check_log_success(buf, send_log_msg(NULL, NULL, buf, len)); 455 return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
474} 456}
475 457
476 458static void caught_signal(int signum __unused) {
477static void caught_signal(int signum __unused)
478{
479} 459}
480 460
481static int logdOpen(struct android_log_logger_list *logger_list, 461static int logdOpen(struct android_log_logger_list* logger_list,
482 struct android_log_transport_context *transp) 462 struct android_log_transport_context* transp) {
483{ 463 struct android_log_logger* logger;
484 struct android_log_logger *logger; 464 struct sigaction ignore;
485 struct sigaction ignore; 465 struct sigaction old_sigaction;
486 struct sigaction old_sigaction; 466 unsigned int old_alarm = 0;
487 unsigned int old_alarm = 0; 467 char buffer[256], *cp, c;
488 char buffer[256], *cp, c; 468 int e, ret, remaining, sock;
489 int e, ret, remaining, sock; 469
490 470 if (!logger_list) {
491 if (!logger_list) { 471 return -EINVAL;
492 return -EINVAL; 472 }
493 } 473
494 474 sock = atomic_load(&transp->context.sock);
495 sock = atomic_load(&transp->context.sock); 475 if (sock > 0) {
496 if (sock > 0) { 476 return sock;
497 return sock; 477 }
498 } 478
499 479 sock = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
500 sock = socket_local_client("logdr", 480 SOCK_SEQPACKET);
501 ANDROID_SOCKET_NAMESPACE_RESERVED, 481 if (sock == 0) {
502 SOCK_SEQPACKET); 482 /* Guarantee not file descriptor zero */
503 if (sock == 0) { 483 int newsock = socket_local_client(
504 /* Guarantee not file descriptor zero */ 484 "logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
505 int newsock = socket_local_client("logdr", 485 close(sock);
506 ANDROID_SOCKET_NAMESPACE_RESERVED, 486 sock = newsock;
507 SOCK_SEQPACKET); 487 }
508 close(sock); 488 if (sock <= 0) {
509 sock = newsock; 489 if ((sock == -1) && errno) {
510 } 490 return -errno;
511 if (sock <= 0) {
512 if ((sock == -1) && errno) {
513 return -errno;
514 }
515 return sock;
516 }
517
518 strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ?
519 "dumpAndClose" : "stream");
520 cp = buffer + strlen(buffer);
521
522 strcpy(cp, " lids");
523 cp += 5;
524 c = '=';
525 remaining = sizeof(buffer) - (cp - buffer);
526 logger_for_each(logger, logger_list) {
527 ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
528 ret = min(ret, remaining);
529 remaining -= ret;
530 cp += ret;
531 c = ',';
532 }
533
534 if (logger_list->tail) {
535 ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
536 ret = min(ret, remaining);
537 remaining -= ret;
538 cp += ret;
539 }
540
541 if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
542 if (logger_list->mode & ANDROID_LOG_WRAP) {
543 // ToDo: alternate API to allow timeout to be adjusted.
544 ret = snprintf(cp, remaining, " timeout=%u",
545 ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
546 ret = min(ret, remaining);
547 remaining -= ret;
548 cp += ret;
549 }
550 ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32,
551 logger_list->start.tv_sec,
552 logger_list->start.tv_nsec);
553 ret = min(ret, remaining);
554 remaining -= ret;
555 cp += ret;
556 }
557
558 if (logger_list->pid) {
559 ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
560 ret = min(ret, remaining);
561 cp += ret;
562 }
563
564 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
565 /* Deal with an unresponsive logd */
566 memset(&ignore, 0, sizeof(ignore));
567 ignore.sa_handler = caught_signal;
568 sigemptyset(&ignore.sa_mask);
569 /* particularily useful if tombstone is reporting for logd */
570 sigaction(SIGALRM, &ignore, &old_sigaction);
571 old_alarm = alarm(30);
572 } 491 }
573 ret = write(sock, buffer, cp - buffer); 492 return sock;
574 e = errno; 493 }
575 if (logger_list->mode & ANDROID_LOG_NONBLOCK) { 494
576 if (e == EINTR) { 495 strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose"
577 e = ETIMEDOUT; 496 : "stream");
578 } 497 cp = buffer + strlen(buffer);
579 alarm(old_alarm); 498
580 sigaction(SIGALRM, &old_sigaction, NULL); 499 strcpy(cp, " lids");
500 cp += 5;
501 c = '=';
502 remaining = sizeof(buffer) - (cp - buffer);
503 logger_for_each(logger, logger_list) {
504 ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
505 ret = min(ret, remaining);
506 remaining -= ret;
507 cp += ret;
508 c = ',';
509 }
510
511 if (logger_list->tail) {
512 ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
513 ret = min(ret, remaining);
514 remaining -= ret;
515 cp += ret;
516 }
517
518 if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
519 if (logger_list->mode & ANDROID_LOG_WRAP) {
520 // ToDo: alternate API to allow timeout to be adjusted.
521 ret = snprintf(cp, remaining, " timeout=%u",
522 ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
523 ret = min(ret, remaining);
524 remaining -= ret;
525 cp += ret;
526 }
527 ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32,
528 logger_list->start.tv_sec, logger_list->start.tv_nsec);
529 ret = min(ret, remaining);
530 remaining -= ret;
531 cp += ret;
532 }
533
534 if (logger_list->pid) {
535 ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
536 ret = min(ret, remaining);
537 cp += ret;
538 }
539
540 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
541 /* Deal with an unresponsive logd */
542 memset(&ignore, 0, sizeof(ignore));
543 ignore.sa_handler = caught_signal;
544 sigemptyset(&ignore.sa_mask);
545 /* particularily useful if tombstone is reporting for logd */
546 sigaction(SIGALRM, &ignore, &old_sigaction);
547 old_alarm = alarm(30);
548 }
549 ret = write(sock, buffer, cp - buffer);
550 e = errno;
551 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
552 if (e == EINTR) {
553 e = ETIMEDOUT;
554 }
555 alarm(old_alarm);
556 sigaction(SIGALRM, &old_sigaction, NULL);
557 }
558
559 if (ret <= 0) {
560 close(sock);
561 if ((ret == -1) && e) {
562 return -e;
581 } 563 }
582 564 if (ret == 0) {
583 if (ret <= 0) { 565 return -EIO;
584 close(sock);
585 if ((ret == -1) && e) {
586 return -e;
587 }
588 if (ret == 0) {
589 return -EIO;
590 }
591 return ret;
592 } 566 }
567 return ret;
568 }
593 569
594 ret = atomic_exchange(&transp->context.sock, sock); 570 ret = atomic_exchange(&transp->context.sock, sock);
595 if ((ret > 0) && (ret != sock)) { 571 if ((ret > 0) && (ret != sock)) {
596 close(ret); 572 close(ret);
597 } 573 }
598 return sock; 574 return sock;
599} 575}
600 576
601/* Read from the selected logs */ 577/* Read from the selected logs */
602static int logdRead(struct android_log_logger_list *logger_list, 578static int logdRead(struct android_log_logger_list* logger_list,
603 struct android_log_transport_context *transp, 579 struct android_log_transport_context* transp,
604 struct log_msg *log_msg) 580 struct log_msg* log_msg) {
605{ 581 int ret, e;
606 int ret, e; 582 struct sigaction ignore;
607 struct sigaction ignore; 583 struct sigaction old_sigaction;
608 struct sigaction old_sigaction; 584 unsigned int old_alarm = 0;
609 unsigned int old_alarm = 0; 585
610 586 ret = logdOpen(logger_list, transp);
611 ret = logdOpen(logger_list, transp); 587 if (ret < 0) {
612 if (ret < 0) {
613 return ret;
614 }
615
616 memset(log_msg, 0, sizeof(*log_msg));
617
618 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
619 memset(&ignore, 0, sizeof(ignore));
620 ignore.sa_handler = caught_signal;
621 sigemptyset(&ignore.sa_mask);
622 /* particularily useful if tombstone is reporting for logd */
623 sigaction(SIGALRM, &ignore, &old_sigaction);
624 old_alarm = alarm(30);
625 }
626
627 /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
628 ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
629 e = errno;
630
631 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
632 if ((ret == 0) || (e == EINTR)) {
633 e = EAGAIN;
634 ret = -1;
635 }
636 alarm(old_alarm);
637 sigaction(SIGALRM, &old_sigaction, NULL);
638 }
639
640 if ((ret == -1) && e) {
641 return -e;
642 }
643 return ret; 588 return ret;
589 }
590
591 memset(log_msg, 0, sizeof(*log_msg));
592
593 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
594 memset(&ignore, 0, sizeof(ignore));
595 ignore.sa_handler = caught_signal;
596 sigemptyset(&ignore.sa_mask);
597 /* particularily useful if tombstone is reporting for logd */
598 sigaction(SIGALRM, &ignore, &old_sigaction);
599 old_alarm = alarm(30);
600 }
601
602 /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
603 ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
604 e = errno;
605
606 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
607 if ((ret == 0) || (e == EINTR)) {
608 e = EAGAIN;
609 ret = -1;
610 }
611 alarm(old_alarm);
612 sigaction(SIGALRM, &old_sigaction, NULL);
613 }
614
615 if ((ret == -1) && e) {
616 return -e;
617 }
618 return ret;
644} 619}
645 620
646static int logdPoll(struct android_log_logger_list *logger_list, 621static int logdPoll(struct android_log_logger_list* logger_list,
647 struct android_log_transport_context *transp) 622 struct android_log_transport_context* transp) {
648{ 623 struct pollfd p;
649 struct pollfd p;
650
651 int ret = logdOpen(logger_list, transp);
652 if (ret < 0) {
653 return ret;
654 }
655 624
656 memset(&p, 0, sizeof(p)); 625 int ret = logdOpen(logger_list, transp);
657 p.fd = ret; 626 if (ret < 0) {
658 p.events = POLLIN;
659 ret = poll(&p, 1, 20);
660 if ((ret > 0) && !(p.revents & POLLIN)) {
661 ret = 0;
662 }
663 if ((ret == -1) && errno) {
664 return -errno;
665 }
666 return ret; 627 return ret;
628 }
629
630 memset(&p, 0, sizeof(p));
631 p.fd = ret;
632 p.events = POLLIN;
633 ret = poll(&p, 1, 20);
634 if ((ret > 0) && !(p.revents & POLLIN)) {
635 ret = 0;
636 }
637 if ((ret == -1) && errno) {
638 return -errno;
639 }
640 return ret;
667} 641}
668 642
669/* Close all the logs */ 643/* Close all the logs */
670static void logdClose(struct android_log_logger_list *logger_list __unused, 644static void logdClose(struct android_log_logger_list* logger_list __unused,
671 struct android_log_transport_context *transp) 645 struct android_log_transport_context* transp) {
672{ 646 int sock = atomic_exchange(&transp->context.sock, -1);
673 int sock = atomic_exchange(&transp->context.sock, -1); 647 if (sock > 0) {
674 if (sock > 0) { 648 close(sock);
675 close (sock); 649 }
676 }
677} 650}