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