8f6ddebf77616d39da576e09f1a2fa514eb08469
[andemo] / src / android / logger.c
1 #include <stdio.h>
2 #include <assert.h>
3 #include <unistd.h>
4 #include <pthread.h>
5 #include <android/log.h>
6 #include "logger.h"
7
8 #ifndef APP_NAME
9 #define APP_NAME        "xmas_inferno"
10 #endif
11
12 static void *thread_func(void *arg);
13
14 static int pfd[2];
15 static pthread_t thr;
16 static int initialized;
17
18 int start_logger(void)
19 {
20         if(initialized) {
21                 return 1;
22         }
23
24         /* set stdout to line-buffered, and stderr to unbuffered */
25         setvbuf(stdout, 0, _IOLBF, 0);
26         setvbuf(stderr, 0, _IONBF, 0);
27
28         if(pipe(pfd) == -1) {
29                 perror("failed to create logging pipe");
30                 return -1;
31         }
32         assert(pfd[0] > 2 && pfd[1] > 2);
33
34         /* redirect stdout & stderr to the write-end of the pipe */
35         dup2(pfd[1], 1);
36         dup2(pfd[1], 2);
37
38         /* start the logging thread */
39         if(pthread_create(&thr, 0, thread_func, 0) == -1) {
40                 perror("failed to spawn logging thread");
41                 return -1;
42         }
43         pthread_detach(thr);
44         return 0;
45 }
46
47 static void *thread_func(void *arg)
48 {
49         ssize_t rdsz;
50         char buf[257];
51
52         __android_log_print(ANDROID_LOG_DEBUG, APP_NAME, "logger starting up...");
53
54         while((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
55                 if(buf[rdsz - 1] == '\n') {
56                         --rdsz;
57                 }
58                 buf[rdsz] = 0;
59                 __android_log_write(ANDROID_LOG_DEBUG, APP_NAME, buf);
60         }
61
62         __android_log_print(ANDROID_LOG_DEBUG, APP_NAME, "logger shutting down...");
63         return 0;
64 }