tests: extract stdout redirection
[platform/core/system/dlog.git] / tests / test_libdlogutil.c
1 /* DLOG
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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 #include <dlogutil.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <assert.h>
21 #include <unistd.h>
22 #include <stdbool.h>
23 #include <logcommon.h>
24 #include <sys/ioctl.h>
25 #include <linux/logger.h>
26
27 /* This is supposed to check a 1000ms timeout, so ideally this would be just a
28  * little bit over 1000 (to account for non-timeout overhead). But the kernel
29  * does not actually guarantee that we will wake up at once, the timeout is just
30  * a minimum. On busy and/or emulated systems the total wait can stretch for a
31  * fairly long time. Here the value is an arbitrary compromise that happens to
32  * pass the test on my tortured system without being too absurd. */
33 #define ONE_SECOND_LENIENCE_MS 1300
34
35 enum test_mode {
36         MODE_DUMP,
37         MODE_TIMER,
38         MODE_CONTINUOUS,
39         MODE_MONITOR,
40         MODE_PRIORITY,
41         MODE_PRIORITY_EXACT,
42         MODE_LIMIT,
43         MODE_PID_CORRECT,
44         MODE_PID_WRONG,
45         MODE_TID_CORRECT,
46         MODE_TID_WRONG,
47         MODE_TAG_CORRECT,
48         MODE_TAG_WRONG,
49         MODE_PREFIX_CORRECT,
50         MODE_PREFIX_WRONG,
51         MODE_SORTING,
52         MODE_TRAITS,
53         MODE_CLEAR,
54         MODE_ALIAS,
55         MODE_NEGATIVE,
56         MODE_MISC,
57         MODE_INVALID,
58 };
59
60 const char *mode_names[] = {
61         [MODE_DUMP] = "dump",
62         [MODE_TIMER] = "timer",
63         [MODE_CONTINUOUS] = "continuous",
64         [MODE_MONITOR] = "monitor",
65         [MODE_PRIORITY] = "priority",
66         [MODE_PRIORITY_EXACT] = "priority_exact",
67         [MODE_LIMIT] = "limit",
68         [MODE_PID_CORRECT] = "pid_correct",
69         [MODE_PID_WRONG] = "pid_wrong",
70         [MODE_TID_CORRECT] = "tid_correct",
71         [MODE_TID_WRONG] = "tid_wrong",
72         [MODE_TAG_CORRECT] = "tag_correct",
73         [MODE_TAG_WRONG] = "tag_wrong",
74         [MODE_PREFIX_CORRECT] = "prefix_correct",
75         [MODE_PREFIX_WRONG] = "prefix_wrong",
76         [MODE_SORTING] = "sorting",
77         [MODE_TRAITS] = "traits",
78         [MODE_CLEAR] = "clear",
79         [MODE_ALIAS] = "alias",
80         [MODE_NEGATIVE] = "negative",
81         [MODE_MISC] = "misc",
82 };
83
84 const char *mode_desc[] = {
85         [MODE_DUMP] = "test getting logs in the dump mode",
86         [MODE_TIMER] = "same, but waiting on each log to simulate work",
87         [MODE_CONTINUOUS] = "test getting logs in the continuous mode",
88         [MODE_MONITOR] = "test that monitor mode skips all the old logs",
89         [MODE_PRIORITY] = "only warning and above, we should get only error logs",
90         [MODE_PRIORITY_EXACT] = "only warning, we should get no logs",
91         [MODE_LIMIT] = "limit to 100 logs without filtering, we should get exactly 50 error and exactly 50 info logs",
92         [MODE_PID_CORRECT] = "filter PID to the correct one, we should get same results as in the normal test mode",
93         [MODE_PID_WRONG] = "filter PID to the wrong one, we should get no logs",
94         [MODE_TID_CORRECT] = "filter TID to the correct one, we should get same results as in the normal test mode",
95         [MODE_TID_WRONG] = "filter TID to the wrong one, we should get no logs",
96         [MODE_TAG_CORRECT] = "filter the tag to the correct one, we should get same results as in the normal testmode",
97         [MODE_TAG_WRONG] = "filter the tag to a wrong one, we should get no logs",
98         [MODE_PREFIX_CORRECT] = "filter the tag to the correct one via prefix, we should get same results as in the normal test mode",
99         [MODE_PREFIX_WRONG] = "filter the tag to a wrong one via prefix, we should get same results as in the normal test mode",
100
101         [MODE_SORTING] = "test timestamp sorting -- in this case, the PID is ignored",
102         [MODE_TRAITS] = "test buffer traits functionality -- in this case, the PID is ignored",
103         [MODE_CLEAR] = "test clearing functionality -- in this case, the PID is ignored",
104         [MODE_ALIAS] = "test buffer aliasing -- in this case, the PID is ignored",
105         [MODE_NEGATIVE] = "test whether libdlogutil errors out correctly",
106         [MODE_MISC] = "run some miscellaneous calls",
107 };
108
109 void print_usage_and_die(const char *name)
110 {
111         fprintf(stderr, "Usage: %s TEST PID TYPE\n"
112                 "where PID is the process id of the logging process (or 0),\n"
113                 "TYPE is \"pipe\" or \"logger\" depending on the backend used,\n"
114                 "and TEST chooses a test and is one of the following:\n", name);
115
116         for (size_t i = 0; i < MODE_INVALID; ++i)
117                 fprintf(stderr, " - %s: %s\n", mode_names[i], mode_desc[i]);
118
119         exit(EXIT_FAILURE);
120 }
121
122 enum test_mode choose_mode(const char *name)
123 {
124         for (size_t i = 0; i < MODE_INVALID; ++i)
125                 if (!strcmp(name, mode_names[i]))
126                         return i;
127
128         return MODE_INVALID;
129 }
130
131 void assert_suffix(const char *string, const char *suffix)
132 {
133         int add = (int)strlen(string) - strlen(suffix);
134         assert(add >= 0 && !strcmp(string + add, suffix));
135 }
136
137 /* The amount of logs is deterministic and based on buffer size,
138  * log header size, the amount of logs sent and their contents. */
139 #define PIPE_ERRORS 4681
140 #define PIPE_INFOS 4681
141
142 void get_logs_main(enum test_mode mode, backend_t backend, pid_t pid)
143 {
144         bool continuous = mode == MODE_CONTINUOUS;
145         bool monitor = mode == MODE_MONITOR;
146
147         int error_count = 0;
148         int info_count = 0;
149
150         int r;
151
152         dlogutil_config_s *c = dlogutil_config_create();
153         assert(c);
154
155         dlogutil_config_buffer_add(c, LOG_ID_MAIN);
156
157         switch (mode) {
158                 case MODE_PRIORITY:
159                         assert(dlogutil_config_filter_filterspec(c, "*:W") == 0);
160                         break;
161                 case MODE_PRIORITY_EXACT:
162                         assert(dlogutil_config_filter_filterspec(c, "*:=W") == 0);
163                         break;
164                 case MODE_PID_CORRECT:
165                         assert(dlogutil_config_filter_pid(c, pid) == 0);
166                         break;
167                 case MODE_PID_WRONG:
168                         assert(dlogutil_config_filter_pid(c, pid ^ 1) == 0);
169                         break;
170                 case MODE_TID_CORRECT:
171                         assert(dlogutil_config_filter_tid(c, pid) == 0);
172                         break;
173                 case MODE_TID_WRONG:
174                         assert(dlogutil_config_filter_tid(c, pid ^ 1) == 0);
175                         break;
176                 case MODE_TAG_CORRECT:
177                         dlogutil_config_filter_filterspec(c, "SRPOL_LOGGER");
178                         break;
179                 case MODE_TAG_WRONG:
180                         dlogutil_config_filter_filterspec(c, "SRPOL_WRONG");
181                         break;
182                 case MODE_PREFIX_CORRECT:
183                         dlogutil_config_filter_filterspec(c, "SRPOL*");
184                         break;
185                 case MODE_PREFIX_WRONG:
186                         dlogutil_config_filter_filterspec(c, "WRONG*");
187                         break;
188                 default:
189                         break;
190         }
191
192         dlogutil_state_s *s = NULL;
193         if (continuous)
194                 r = dlogutil_config_mode_set_continuous(c);
195         else if (monitor)
196                 r = dlogutil_config_mode_set_monitor(c);
197         else
198                 r = dlogutil_config_mode_set_dump(c, mode == MODE_LIMIT ? 100 : DLOGUTIL_MAX_DUMP_SIZE);
199         assert(r == 0);
200
201         assert(dlogutil_config_connect(c, &s) == 0);
202         assert(s);
203
204         struct timespec a, b;
205         dlogutil_entry_s *e;
206
207         for (;;) {
208                 e = NULL;
209                 clock_gettime(CLOCK_MONOTONIC, &a);
210                 r = dlogutil_get_log(s, continuous || monitor ? 1000 : -1, &e);
211                 clock_gettime(CLOCK_MONOTONIC, &b);
212                 unsigned dt = (b.tv_sec - a.tv_sec) * 1000 + (b.tv_nsec - a.tv_nsec) / 1000000;
213
214                 if (e) {
215                         assert(r == 0);
216                         assert(dt < ONE_SECOND_LENIENCE_MS);
217
218                         log_priority prio;
219                         r = dlogutil_entry_get_priority(e, &prio);
220                         assert(r == 0);
221
222                         const char *tag, *msg;
223                         r = dlogutil_entry_get_tag(e, &tag);
224                         assert(r == 0);
225                         r = dlogutil_entry_get_message(e, &msg);
226                         assert(r == 0);
227
228                         // !pid also means we are fine looking at random logs
229                         assert(!pid || !strcmp(tag, "SRPOL_LOGGER"));
230
231                         pid_t apid, atid;
232                         r = dlogutil_entry_get_pid(e, &apid);
233                         assert(r == 0);
234                         r = dlogutil_entry_get_tid(e, &atid);
235                         assert(r == 0);
236
237                         assert(!pid || pid == apid);
238                         assert(!pid || pid == atid);
239
240                         switch (prio) {
241                                 case DLOG_ERROR:
242                                         error_count += 1;
243                                         assert_suffix(msg, "test data, level: error");
244                                         break;
245                                 case DLOG_INFO:
246                                         info_count += 1;
247                                         assert_suffix(msg, "test data, level: info");
248                                         break;
249                                 default:
250                                         assert(false);
251                         }
252
253                         if (mode == MODE_TIMER)
254                                 nanosleep(&(struct timespec) {
255                                         .tv_sec = 0,
256                                         .tv_nsec = rand() % (1 << 18),
257                                 }, NULL);
258
259                         free(e);
260                 } else {
261                         if (continuous || monitor) {
262                                 assert(r == TIZEN_ERROR_TIMED_OUT);
263                                 assert(dt >= 1000);
264                         } else {
265                                 assert(r == TIZEN_ERROR_NO_DATA);
266                                 assert(dt < ONE_SECOND_LENIENCE_MS);
267                         }
268                         break;
269                 }
270         }
271
272         dlogutil_state_destroy(s);
273         dlogutil_config_destroy(c);
274
275         switch (mode) {
276                 case MODE_DUMP:
277                 case MODE_TIMER:
278                 case MODE_CONTINUOUS:
279                 case MODE_PID_CORRECT:
280                 case MODE_TID_CORRECT:
281                 case MODE_TAG_CORRECT:
282                 case MODE_PREFIX_CORRECT:
283                         if (backend == BACKEND_PIPE) {
284                                 assert(error_count == PIPE_ERRORS);
285                                 assert(info_count == PIPE_INFOS);
286                         } else {
287                                 assert(abs(error_count - info_count) <= 1);
288                         }
289                         break;
290                 case MODE_PRIORITY:
291                         if (backend == BACKEND_PIPE)
292                                 assert(error_count == PIPE_ERRORS);
293                         else
294                                 assert(error_count > 0);
295                         assert(info_count == 0);
296                         break;
297                 case MODE_MONITOR:
298                 case MODE_PRIORITY_EXACT:
299                 case MODE_PID_WRONG:
300                 case MODE_TID_WRONG:
301                 case MODE_TAG_WRONG:
302                 case MODE_PREFIX_WRONG:
303                         assert(error_count == 0);
304                         assert(info_count == 0);
305                         break;
306                 case MODE_LIMIT:
307                         assert(error_count == 50);
308                         assert(info_count == 50);
309                         break;
310                 default:
311                         assert(false);
312         }
313 }
314
315 unsigned int MB(unsigned int x)
316 {
317         return 1024 * 1024 * x;
318 }
319
320 void traits_main(backend_t backend)
321 {
322         assert(backend != BACKEND_ZERO_COPY);
323
324         dlogutil_config_s *config = dlogutil_config_create();
325         assert(config);
326
327         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
328         assert(dlogutil_config_buffer_add(config, LOG_ID_KMSG) == 0);
329
330         dlogutil_state_s *state;
331         assert(dlogutil_config_connect(config, &state) == 0);
332         dlogutil_config_destroy(config);
333
334         const char *name;
335         assert(dlogutil_buffer_get_name(LOG_ID_MAIN, &name) == 0);
336         assert(!strcmp(name, "main"));
337
338         assert(dlogutil_buffer_get_name(LOG_ID_KMSG, &name) == 0);
339         assert(!strcmp(name, "kmsg"));
340
341         unsigned int capacity, usage;
342         assert(dlogutil_buffer_get_capacity(state, LOG_ID_MAIN, &capacity) == 0);
343         assert(dlogutil_buffer_get_usage(state, LOG_ID_MAIN, &usage) == 0);
344         if (backend == BACKEND_PIPE)
345                         assert(capacity == MB(1));
346         else {
347                         int fd = open("/dev/log_main", O_RDONLY);
348                         int real_capacity = ioctl(fd, LOGGER_GET_LOG_BUF_SIZE);
349                         close(fd);
350                         assert(capacity == real_capacity);
351         }
352
353
354         assert(dlogutil_buffer_get_capacity(state, LOG_ID_KMSG, &capacity) == 0);
355         assert(dlogutil_buffer_get_usage(state, LOG_ID_KMSG, &usage) == 0);
356         assert(capacity == MB(1));
357
358         dlogutil_sorting_order_e type;
359         assert(dlogutil_buffer_get_default_ts_type(LOG_ID_MAIN, &type) == 0);
360         assert(type == (backend == BACKEND_PIPE ? DLOGUTIL_SORT_RECV_MONO : DLOGUTIL_SORT_SENT_REAL));
361
362         bool available;
363         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_SENT_MONO, &available) == 0);
364         assert(available == (backend == BACKEND_PIPE));
365
366         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_SENT_REAL, &available) == 0);
367         assert(available);
368
369         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_RECV_MONO, &available) == 0);
370         assert(available == (backend == BACKEND_PIPE));
371
372         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_RECV_REAL, &available) == 0);
373         assert(available == (backend == BACKEND_PIPE));
374
375         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_SENT_MONO, &available) == 0);
376         assert(available);
377
378         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_SENT_REAL, &available) == 0);
379         assert(!available);
380
381         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_RECV_MONO, &available) == 0);
382         assert(available);
383
384         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_RECV_REAL, &available) == 0);
385         assert(available);
386
387         dlogutil_state_destroy(state);
388 }
389
390 void clear_main(void)
391 {
392         dlogutil_config_s *c = dlogutil_config_create();
393         assert(c);
394         assert(dlogutil_config_buffer_add(c, LOG_ID_MAIN) == 0);
395
396         dlogutil_state_s *s;
397
398         assert(dlogutil_config_connect(c, &s) == 0);
399         assert(dlogutil_buffer_clear(s, LOG_ID_MAIN) == 0);
400         dlogutil_state_destroy(s);
401
402         // avoid a race condition; let the clear take place
403         nanosleep(&(struct timespec) {
404                 .tv_sec = 1,
405                 .tv_nsec = 0,
406         }, NULL);
407
408         assert(dlogutil_config_mode_set_dump(c, DLOGUTIL_MAX_DUMP_SIZE) == 0);
409         assert(dlogutil_config_connect(c, &s) == 0);
410         dlogutil_entry_s *e;
411         assert(dlogutil_get_log(s, 1000, &e) == TIZEN_ERROR_NO_DATA);
412         dlogutil_state_destroy(s);
413
414         dlogutil_config_destroy(c);
415 }
416
417 bool sorting_check(dlogutil_sorting_order_e o)
418 {
419         dlogutil_config_s *config = dlogutil_config_create();
420         assert(config);
421
422         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
423         assert(dlogutil_config_sorting_enable(config) == 0);
424         assert(dlogutil_config_order_set(config, o) == 0);
425         assert(dlogutil_config_mode_set_dump(config, DLOGUTIL_MAX_DUMP_SIZE) == 0);
426
427         dlogutil_state_s *s;
428         assert(dlogutil_config_connect(config, &s) == 0);
429
430         struct timespec t = {
431                 .tv_sec = 0,
432                 .tv_nsec = 0,
433         };
434
435         bool ret = true;
436         for (;;) {
437                 dlogutil_entry_s *e;
438                 int r = dlogutil_get_log(s, -1, &e);
439                 if (r == TIZEN_ERROR_NO_DATA)
440                         break;
441                 assert(r == 0);
442
443                 struct timespec t_new;
444                 r = dlogutil_entry_get_timestamp(e, o, &t_new);
445                 if (r == TIZEN_ERROR_NO_DATA) {
446                         ret = false;
447                         break;
448                 }
449
450                 assert(t.tv_sec <= t_new.tv_sec);
451                 assert(t.tv_sec < t_new.tv_sec || t.tv_nsec <= t_new.tv_nsec);
452
453                 t = t_new;
454                 free(e);
455         }
456
457         dlogutil_state_destroy(s);
458         dlogutil_config_destroy(config);
459         return ret;
460 }
461
462 void sorting_main(int left)
463 {
464 #define ONE(ts) left -= sorting_check(ts) ? 1 : 0
465
466         ONE(DLOGUTIL_SORT_RECV_MONO);
467         ONE(DLOGUTIL_SORT_RECV_REAL);
468         ONE(DLOGUTIL_SORT_SENT_MONO);
469         ONE(DLOGUTIL_SORT_SENT_REAL);
470
471 #undef ONE
472
473         assert(left == 0);
474 }
475
476 void alias_main(backend_t backend)
477 {
478         assert(backend != BACKEND_ZERO_COPY);
479
480         dlogutil_config_s *config = dlogutil_config_create();
481         assert(config);
482         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
483         assert(dlogutil_config_buffer_add(config, LOG_ID_APPS) == 0);
484         assert(dlogutil_config_buffer_add(config, LOG_ID_RADIO) == 0);
485         assert(dlogutil_config_buffer_add(config, LOG_ID_SYSTEM) == 0);
486         assert(dlogutil_config_buffer_add(config, LOG_ID_KMSG) == 0);
487
488         dlogutil_state_s *state;
489         assert(dlogutil_config_connect(config, &state) == 0);
490         dlogutil_config_destroy(config);
491
492         log_id_t id;
493         assert(dlogutil_buffer_get_alias(state, LOG_ID_MAIN, &id) == 0);
494         assert(id == LOG_ID_MAIN);
495         assert(dlogutil_buffer_get_alias(state, LOG_ID_APPS, &id) == 0);
496         assert(id == (backend == BACKEND_PIPE ? LOG_ID_APPS : LOG_ID_INVALID));
497         assert(dlogutil_buffer_get_alias(state, LOG_ID_RADIO, &id) == 0);
498         assert(id == (backend == BACKEND_PIPE ? LOG_ID_RADIO : LOG_ID_RADIO));
499         assert(dlogutil_buffer_get_alias(state, LOG_ID_SYSTEM, &id) == 0);
500         assert(id == (backend == BACKEND_PIPE ? LOG_ID_SYSTEM : LOG_ID_MAIN));
501         assert(dlogutil_buffer_get_alias(state, LOG_ID_KMSG, &id) == 0);
502         assert(id == LOG_ID_KMSG);
503
504         dlogutil_state_destroy(state);
505 }
506
507 void negative_main(void)
508 {
509         dlogutil_config_s *config = dlogutil_config_create();
510         assert(config);
511         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
512
513         dlogutil_state_s *state;
514         assert(dlogutil_config_connect(config, &state) == 0);
515         dlogutil_config_destroy(config);
516
517         void *bad_ptr = (void *)0xFA1l;
518
519         // Invalid single buffer
520         const log_id_t invalid_ids[] =
521                 { LOG_ID_INVALID
522                 , LOG_ID_INVALID - 1
523                 , LOG_ID_MAX
524                 , LOG_ID_MAX + 1
525                 , (log_id_t) -17
526                 , (log_id_t) 42
527         };
528         for (size_t i = 0; i < NELEMS(invalid_ids); ++i) {
529                 const log_id_t id = invalid_ids[i];
530                 assert(dlogutil_buffer_clear(state, id) ==
531                         TIZEN_ERROR_INVALID_PARAMETER);
532                 assert(dlogutil_buffer_get_capacity(state, id, bad_ptr) ==
533                         TIZEN_ERROR_INVALID_PARAMETER);
534                 assert(dlogutil_buffer_get_usage(state, id, bad_ptr) ==
535                         TIZEN_ERROR_INVALID_PARAMETER);
536         }
537
538         // Retrieval of data into NULL
539         assert(dlogutil_buffer_get_capacity(state, LOG_ID_MAIN, NULL) ==
540                 TIZEN_ERROR_INVALID_PARAMETER);
541         assert(dlogutil_buffer_get_usage(state, LOG_ID_MAIN, NULL) ==
542                 TIZEN_ERROR_INVALID_PARAMETER);
543         // Actual cleanup
544         dlogutil_state_destroy(state);
545 }
546
547 void misc_calls(void)
548 {
549         dlogutil_config_s *config = dlogutil_config_create();
550
551         dlogutil_config_sorting_disable(config);
552         dlogutil_config_sorting_enable(config);
553         dlogutil_config_buffer_add(config, LOG_ID_MAIN);
554         dlogutil_config_buffer_add(config, LOG_ID_APPS);
555
556         dlogutil_state_s *state;
557         assert(dlogutil_config_connect(config, &state) == 0);
558         dlogutil_config_destroy(config);
559
560         dlogutil_entry_s *e;
561         int r = dlogutil_get_log(state, -1, &e);
562         if (r == 0) {
563                 pid_t x;
564                 dlogutil_entry_get_tid(e, &x);
565                 dlogutil_entry_get_pid(e, &x);
566                 log_priority p;
567                 dlogutil_entry_get_priority(e, &p);
568                 free(e);
569         } else {
570                 dlogutil_entry_get_tid(NULL, NULL);
571                 dlogutil_entry_get_pid(NULL, NULL);
572                 dlogutil_entry_get_priority(NULL, NULL);
573         }
574
575         dlogutil_state_destroy(state);
576 }
577
578 int main(int argc, char **argv)
579 {
580         if (argc != 4)
581                 print_usage_and_die(argv[0]);
582         enum test_mode t = choose_mode(argv[1]);
583         if (t == MODE_INVALID)
584                 print_usage_and_die(argv[0]);
585
586         pid_t pid = atoi(argv[2]);
587
588         backend_t backend = BACKEND_ANDROID_LOGGER;
589         if (!strcmp(argv[3], "pipe"))
590                 backend = BACKEND_PIPE;
591         else if (!strcmp(argv[3], "zero-copy"))
592                 backend = BACKEND_ZERO_COPY;
593         else if (strcmp(argv[3], "logger"))
594                 print_usage_and_die(argv[0]);
595
596         switch (t) {
597                 case MODE_DUMP:
598                 case MODE_TIMER:
599                 case MODE_CONTINUOUS:
600                 case MODE_MONITOR:
601                 case MODE_PRIORITY:
602                 case MODE_PRIORITY_EXACT:
603                 case MODE_LIMIT:
604                 case MODE_PID_CORRECT:
605                 case MODE_PID_WRONG:
606                 case MODE_TID_CORRECT:
607                 case MODE_TID_WRONG:
608                 case MODE_TAG_CORRECT:
609                 case MODE_TAG_WRONG:
610                 case MODE_PREFIX_CORRECT:
611                 case MODE_PREFIX_WRONG:
612                         get_logs_main(t, backend, pid);
613                         break;
614                 case MODE_SORTING:
615                         sorting_main(backend == BACKEND_PIPE ? 4 : 1);
616                         break;
617                 case MODE_TRAITS:
618                         traits_main(backend);
619                         break;
620                 case MODE_CLEAR:
621                         clear_main();
622                         break;
623                 case MODE_ALIAS:
624                         alias_main(backend);
625                         break;
626                 case MODE_NEGATIVE:
627                         negative_main();
628                         break;
629                 case MODE_MISC:
630                         misc_calls();
631                         break;
632                 default:
633                         assert(false);
634         }
635
636         return EXIT_SUCCESS;
637 }