• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <sys/types.h>
20 
21 /* deal with possible sys/cdefs.h conflict with fcntl.h */
22 #ifdef __unused
23 #define __unused_defined __unused
24 #undef __unused
25 #endif
26 
27 #include <fcntl.h> /* Pick up O_* macros */
28 
29 /* restore definitions from above */
30 #ifdef __unused_defined
31 #define __unused __attribute__((__unused__))
32 #endif
33 
34 #include <stdint.h>
35 
36 #include <log/log_id.h>
37 #include <log/log_time.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /*
44  * Native log reading interface section. See logcat for sample code.
45  *
46  * The preferred API is an exec of logcat. Likely uses of this interface
47  * are if native code suffers from exec or filtration being too costly,
48  * access to raw information, or parsing is an issue.
49  */
50 
51 #pragma clang diagnostic push
52 #pragma clang diagnostic ignored "-Wzero-length-array"
53 /*
54  * The userspace structure for version 1 of the logger_entry ABI.
55  */
56 #ifndef __struct_logger_entry_defined
57 #define __struct_logger_entry_defined
58 struct logger_entry {
59   uint16_t len;   /* length of the payload */
60   uint16_t __pad; /* no matter what, we get 2 bytes of padding */
61   int32_t pid;    /* generating process's pid */
62   int32_t tid;    /* generating process's tid */
63   int32_t sec;    /* seconds since Epoch */
64   int32_t nsec;   /* nanoseconds */
65   char msg[0]; /* the entry's payload */
66 };
67 #endif
68 
69 /*
70  * The userspace structure for version 2 of the logger_entry ABI.
71  */
72 #ifndef __struct_logger_entry_v2_defined
73 #define __struct_logger_entry_v2_defined
74 struct logger_entry_v2 {
75   uint16_t len;      /* length of the payload */
76   uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
77   int32_t pid;       /* generating process's pid */
78   int32_t tid;       /* generating process's tid */
79   int32_t sec;       /* seconds since Epoch */
80   int32_t nsec;      /* nanoseconds */
81   uint32_t euid;     /* effective UID of logger */
82   char msg[0]; /* the entry's payload */
83 } __attribute__((__packed__));
84 #endif
85 
86 /*
87  * The userspace structure for version 3 of the logger_entry ABI.
88  */
89 #ifndef __struct_logger_entry_v3_defined
90 #define __struct_logger_entry_v3_defined
91 struct logger_entry_v3 {
92   uint16_t len;      /* length of the payload */
93   uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
94   int32_t pid;       /* generating process's pid */
95   int32_t tid;       /* generating process's tid */
96   int32_t sec;       /* seconds since Epoch */
97   int32_t nsec;      /* nanoseconds */
98   uint32_t lid;      /* log id of the payload */
99   char msg[0]; /* the entry's payload */
100 } __attribute__((__packed__));
101 #endif
102 
103 /*
104  * The userspace structure for version 4 of the logger_entry ABI.
105  */
106 #ifndef __struct_logger_entry_v4_defined
107 #define __struct_logger_entry_v4_defined
108 struct logger_entry_v4 {
109   uint16_t len;      /* length of the payload */
110   uint16_t hdr_size; /* sizeof(struct logger_entry_v4) */
111   int32_t pid;       /* generating process's pid */
112   uint32_t tid;      /* generating process's tid */
113   uint32_t sec;      /* seconds since Epoch */
114   uint32_t nsec;     /* nanoseconds */
115   uint32_t lid;      /* log id of the payload, bottom 4 bits currently */
116   uint32_t uid;      /* generating process's uid */
117   char msg[0]; /* the entry's payload */
118 };
119 #endif
120 #pragma clang diagnostic pop
121 
122 /*
123  * The maximum size of the log entry payload that can be
124  * written to the logger. An attempt to write more than
125  * this amount will result in a truncated log entry.
126  */
127 #define LOGGER_ENTRY_MAX_PAYLOAD 4068
128 
129 /*
130  * The maximum size of a log entry which can be read.
131  * An attempt to read less than this amount may result
132  * in read() returning EINVAL.
133  */
134 #define LOGGER_ENTRY_MAX_LEN (5 * 1024)
135 
136 #ifndef __struct_log_msg_defined
137 #define __struct_log_msg_defined
138 struct log_msg {
139   union {
140     unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
141     struct logger_entry_v4 entry;
142     struct logger_entry_v4 entry_v4;
143     struct logger_entry_v3 entry_v3;
144     struct logger_entry_v2 entry_v2;
145     struct logger_entry entry_v1;
146   } __attribute__((aligned(4)));
147 #ifdef __cplusplus
148   /* Matching log_time operators */
149   bool operator==(const log_msg& T) const {
150     return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec);
151   }
152   bool operator!=(const log_msg& T) const {
153     return !(*this == T);
154   }
155   bool operator<(const log_msg& T) const {
156     return (entry.sec < T.entry.sec) ||
157            ((entry.sec == T.entry.sec) && (entry.nsec < T.entry.nsec));
158   }
159   bool operator>=(const log_msg& T) const {
160     return !(*this < T);
161   }
162   bool operator>(const log_msg& T) const {
163     return (entry.sec > T.entry.sec) ||
164            ((entry.sec == T.entry.sec) && (entry.nsec > T.entry.nsec));
165   }
166   bool operator<=(const log_msg& T) const {
167     return !(*this > T);
168   }
nseclog_msg169   uint64_t nsec() const {
170     return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
171   }
172 
173   /* packet methods */
idlog_msg174   log_id_t id() {
175     return static_cast<log_id_t>(entry.lid);
176   }
msglog_msg177   char* msg() {
178     unsigned short hdr_size = entry.hdr_size;
179     if (!hdr_size) {
180       hdr_size = sizeof(entry_v1);
181     }
182     if ((hdr_size < sizeof(entry_v1)) || (hdr_size > sizeof(entry))) {
183       return nullptr;
184     }
185     return reinterpret_cast<char*>(buf) + hdr_size;
186   }
lenlog_msg187   unsigned int len() {
188     return (entry.hdr_size ? entry.hdr_size
189                            : static_cast<uint16_t>(sizeof(entry_v1))) +
190            entry.len;
191   }
192 #endif
193 };
194 #endif
195 
196 struct logger;
197 
198 log_id_t android_logger_get_id(struct logger* logger);
199 
200 int android_logger_clear(struct logger* logger);
201 long android_logger_get_log_size(struct logger* logger);
202 int android_logger_set_log_size(struct logger* logger, unsigned long size);
203 long android_logger_get_log_readable_size(struct logger* logger);
204 int android_logger_get_log_version(struct logger* logger);
205 
206 struct logger_list;
207 
208 ssize_t android_logger_get_statistics(struct logger_list* logger_list,
209                                       char* buf, size_t len);
210 ssize_t android_logger_get_prune_list(struct logger_list* logger_list,
211                                       char* buf, size_t len);
212 int android_logger_set_prune_list(struct logger_list* logger_list, char* buf,
213                                   size_t len);
214 
215 #define ANDROID_LOG_RDONLY O_RDONLY
216 #define ANDROID_LOG_WRONLY O_WRONLY
217 #define ANDROID_LOG_RDWR O_RDWR
218 #define ANDROID_LOG_ACCMODE O_ACCMODE
219 #ifndef O_NONBLOCK
220 #define ANDROID_LOG_NONBLOCK 0x00000800
221 #else
222 #define ANDROID_LOG_NONBLOCK O_NONBLOCK
223 #endif
224 #define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */
225 #define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */
226 #define ANDROID_LOG_PSTORE 0x80000000
227 
228 struct logger_list* android_logger_list_alloc(int mode, unsigned int tail,
229                                               pid_t pid);
230 struct logger_list* android_logger_list_alloc_time(int mode, log_time start,
231                                                    pid_t pid);
232 void android_logger_list_free(struct logger_list* logger_list);
233 /* In the purest sense, the following two are orthogonal interfaces */
234 int android_logger_list_read(struct logger_list* logger_list,
235                              struct log_msg* log_msg);
236 
237 /* Multiple log_id_t opens */
238 struct logger* android_logger_open(struct logger_list* logger_list, log_id_t id);
239 #define android_logger_close android_logger_free
240 /* Single log_id_t open */
241 struct logger_list* android_logger_list_open(log_id_t id, int mode,
242                                              unsigned int tail, pid_t pid);
243 #define android_logger_list_close android_logger_list_free
244 
245 #ifdef __cplusplus
246 }
247 #endif
248