1/*
2 * Copyright (C) 2005-2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _LIBS_LOG_LOG_READ_H
18#define _LIBS_LOG_LOG_READ_H
19
20/* deal with possible sys/cdefs.h conflict with fcntl.h */
21#ifdef __unused
22#define __unused_defined __unused
23#undef __unused
24#endif
25
26#include <fcntl.h> /* Pick up O_* macros */
27
28/* restore definitions from above */
29#ifdef __unused_defined
30#define __unused __attribute__((__unused__))
31#endif
32
33#include <stdint.h>
34
35#include <log/log_id.h>
36#include <log/log_time.h>
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/*
43 * Native log reading interface section. See logcat for sample code.
44 *
45 * The preferred API is an exec of logcat. Likely uses of this interface
46 * are if native code suffers from exec or filtration being too costly,
47 * access to raw information, or parsing is an issue.
48 */
49
50/*
51 * The userspace structure for version 1 of the logger_entry ABI.
52 */
53#ifndef __struct_logger_entry_defined
54#define __struct_logger_entry_defined
55struct logger_entry {
56  uint16_t len;   /* length of the payload */
57  uint16_t __pad; /* no matter what, we get 2 bytes of padding */
58  int32_t pid;    /* generating process's pid */
59  int32_t tid;    /* generating process's tid */
60  int32_t sec;    /* seconds since Epoch */
61  int32_t nsec;   /* nanoseconds */
62#ifndef __cplusplus
63  char msg[0]; /* the entry's payload */
64#endif
65};
66#endif
67
68/*
69 * The userspace structure for version 2 of the logger_entry ABI.
70 */
71#ifndef __struct_logger_entry_v2_defined
72#define __struct_logger_entry_v2_defined
73struct logger_entry_v2 {
74  uint16_t len;      /* length of the payload */
75  uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
76  int32_t pid;       /* generating process's pid */
77  int32_t tid;       /* generating process's tid */
78  int32_t sec;       /* seconds since Epoch */
79  int32_t nsec;      /* nanoseconds */
80  uint32_t euid;     /* effective UID of logger */
81#ifndef __cplusplus
82  char msg[0]; /* the entry's payload */
83#endif
84} __attribute__((__packed__));
85#endif
86
87/*
88 * The userspace structure for version 3 of the logger_entry ABI.
89 */
90#ifndef __struct_logger_entry_v3_defined
91#define __struct_logger_entry_v3_defined
92struct logger_entry_v3 {
93  uint16_t len;      /* length of the payload */
94  uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
95  int32_t pid;       /* generating process's pid */
96  int32_t tid;       /* generating process's tid */
97  int32_t sec;       /* seconds since Epoch */
98  int32_t nsec;      /* nanoseconds */
99  uint32_t lid;      /* log id of the payload */
100#ifndef __cplusplus
101  char msg[0]; /* the entry's payload */
102#endif
103} __attribute__((__packed__));
104#endif
105
106/*
107 * The userspace structure for version 4 of the logger_entry ABI.
108 */
109#ifndef __struct_logger_entry_v4_defined
110#define __struct_logger_entry_v4_defined
111struct logger_entry_v4 {
112  uint16_t len;      /* length of the payload */
113  uint16_t hdr_size; /* sizeof(struct logger_entry_v4) */
114  int32_t pid;       /* generating process's pid */
115  uint32_t tid;      /* generating process's tid */
116  uint32_t sec;      /* seconds since Epoch */
117  uint32_t nsec;     /* nanoseconds */
118  uint32_t lid;      /* log id of the payload, bottom 4 bits currently */
119  uint32_t uid;      /* generating process's uid */
120#ifndef __cplusplus
121  char msg[0]; /* the entry's payload */
122#endif
123};
124#endif
125
126/*
127 * The maximum size of the log entry payload that can be
128 * written to the logger. An attempt to write more than
129 * this amount will result in a truncated log entry.
130 */
131#define LOGGER_ENTRY_MAX_PAYLOAD 4068
132
133/*
134 * The maximum size of a log entry which can be read.
135 * An attempt to read less than this amount may result
136 * in read() returning EINVAL.
137 */
138#define LOGGER_ENTRY_MAX_LEN (5 * 1024)
139
140#ifndef __struct_log_msg_defined
141#define __struct_log_msg_defined
142struct log_msg {
143  union {
144    unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
145    struct logger_entry_v4 entry;
146    struct logger_entry_v4 entry_v4;
147    struct logger_entry_v3 entry_v3;
148    struct logger_entry_v2 entry_v2;
149    struct logger_entry entry_v1;
150  } __attribute__((aligned(4)));
151#ifdef __cplusplus
152  /* Matching log_time operators */
153  bool operator==(const log_msg& T) const {
154    return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec);
155  }
156  bool operator!=(const log_msg& T) const {
157    return !(*this == T);
158  }
159  bool operator<(const log_msg& T) const {
160    return (entry.sec < T.entry.sec) ||
161           ((entry.sec == T.entry.sec) && (entry.nsec < T.entry.nsec));
162  }
163  bool operator>=(const log_msg& T) const {
164    return !(*this < T);
165  }
166  bool operator>(const log_msg& T) const {
167    return (entry.sec > T.entry.sec) ||
168           ((entry.sec == T.entry.sec) && (entry.nsec > T.entry.nsec));
169  }
170  bool operator<=(const log_msg& T) const {
171    return !(*this > T);
172  }
173  uint64_t nsec() const {
174    return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
175  }
176
177  /* packet methods */
178  log_id_t id() {
179    return static_cast<log_id_t>(entry.lid);
180  }
181  char* msg() {
182    unsigned short hdr_size = entry.hdr_size;
183    if (!hdr_size) {
184      hdr_size = sizeof(entry_v1);
185    }
186    if ((hdr_size < sizeof(entry_v1)) || (hdr_size > sizeof(entry))) {
187      return NULL;
188    }
189    return reinterpret_cast<char*>(buf) + hdr_size;
190  }
191  unsigned int len() {
192    return (entry.hdr_size ? entry.hdr_size
193                           : static_cast<uint16_t>(sizeof(entry_v1))) +
194           entry.len;
195  }
196#endif
197};
198#endif
199
200#ifndef __ANDROID_USE_LIBLOG_READER_INTERFACE
201#ifndef __ANDROID_API__
202#define __ANDROID_USE_LIBLOG_READER_INTERFACE 3
203#elif __ANDROID_API__ > 23 /* > Marshmallow */
204#define __ANDROID_USE_LIBLOG_READER_INTERFACE 3
205#elif __ANDROID_API__ > 22 /* > Lollipop */
206#define __ANDROID_USE_LIBLOG_READER_INTERFACE 2
207#elif __ANDROID_API__ > 19 /* > KitKat */
208#define __ANDROID_USE_LIBLOG_READER_INTERFACE 1
209#else
210#define __ANDROID_USE_LIBLOG_READER_INTERFACE 0
211#endif
212#endif
213
214#if __ANDROID_USE_LIBLOG_READER_INTERFACE
215
216struct logger;
217
218log_id_t android_logger_get_id(struct logger* logger);
219
220int android_logger_clear(struct logger* logger);
221long android_logger_get_log_size(struct logger* logger);
222int android_logger_set_log_size(struct logger* logger, unsigned long size);
223long android_logger_get_log_readable_size(struct logger* logger);
224int android_logger_get_log_version(struct logger* logger);
225
226struct logger_list;
227
228#if __ANDROID_USE_LIBLOG_READER_INTERFACE > 1
229ssize_t android_logger_get_statistics(struct logger_list* logger_list,
230                                      char* buf, size_t len);
231ssize_t android_logger_get_prune_list(struct logger_list* logger_list,
232                                      char* buf, size_t len);
233int android_logger_set_prune_list(struct logger_list* logger_list, char* buf,
234                                  size_t len);
235#endif
236
237#define ANDROID_LOG_RDONLY O_RDONLY
238#define ANDROID_LOG_WRONLY O_WRONLY
239#define ANDROID_LOG_RDWR O_RDWR
240#define ANDROID_LOG_ACCMODE O_ACCMODE
241#ifndef O_NONBLOCK
242#define ANDROID_LOG_NONBLOCK 0x00000800
243#else
244#define ANDROID_LOG_NONBLOCK O_NONBLOCK
245#endif
246#if __ANDROID_USE_LIBLOG_READER_INTERFACE > 2
247#define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */
248#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */
249#endif
250#if __ANDROID_USE_LIBLOG_READER_INTERFACE > 1
251#define ANDROID_LOG_PSTORE 0x80000000
252#endif
253
254struct logger_list* android_logger_list_alloc(int mode, unsigned int tail,
255                                              pid_t pid);
256struct logger_list* android_logger_list_alloc_time(int mode, log_time start,
257                                                   pid_t pid);
258void android_logger_list_free(struct logger_list* logger_list);
259/* In the purest sense, the following two are orthogonal interfaces */
260int android_logger_list_read(struct logger_list* logger_list,
261                             struct log_msg* log_msg);
262
263/* Multiple log_id_t opens */
264struct logger* android_logger_open(struct logger_list* logger_list, log_id_t id);
265#define android_logger_close android_logger_free
266/* Single log_id_t open */
267struct logger_list* android_logger_list_open(log_id_t id, int mode,
268                                             unsigned int tail, pid_t pid);
269#define android_logger_list_close android_logger_list_free
270
271#endif /* __ANDROID_USE_LIBLOG_READER_INTERFACE */
272
273#ifdef __cplusplus
274}
275#endif
276
277#endif /* _LIBS_LOG_LOG_H */
278