1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 #include <time.h>
29 #include <stdio.h>
30 #include <pthread.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/uio.h>
34 #include <arpa/inet.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <fcntl.h>
41 #include <cutils/logger.h>
42 #include "logd.h"
44 #include <pthread.h>
46 #define LOG_BUF_SIZE 1024
48 typedef enum {
49 LOG_ID_MAIN = 0,
50 LOG_ID_RADIO,
51 LOG_ID_MAX
52 } log_id_t;
54 static int __write_to_log_init(log_id_t, struct iovec *vec);
55 static int (*write_to_log)(log_id_t, struct iovec *vec) = __write_to_log_init;
56 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
58 static int log_fds[(int)LOG_ID_MAX] = { -1, -1 };
60 static int __write_to_log_null(log_id_t log_fd, struct iovec *vec)
61 {
62 return -1;
63 }
65 static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec)
66 {
67 ssize_t ret;
68 int log_fd;
70 if ((int)log_id >= 0 && (int)log_id < (int)LOG_ID_MAX) {
71 log_fd = log_fds[(int)log_id];
72 } else {
73 return EBADF;
74 }
76 do {
77 ret = writev(log_fd, vec, 3);
78 } while (ret < 0 && errno == EINTR);
80 return ret;
81 }
83 static int __write_to_log_init(log_id_t log_id, struct iovec *vec)
84 {
85 pthread_mutex_lock(&log_init_lock);
87 if (write_to_log == __write_to_log_init) {
88 log_fds[LOG_ID_MAIN] = open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);
89 log_fds[LOG_ID_RADIO] = open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);
91 write_to_log = __write_to_log_kernel;
93 if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0) {
94 close(log_fds[LOG_ID_MAIN]);
95 close(log_fds[LOG_ID_RADIO]);
96 log_fds[LOG_ID_MAIN] = -1;
97 log_fds[LOG_ID_RADIO] = -1;
98 write_to_log = __write_to_log_null;
99 }
100 }
102 pthread_mutex_unlock(&log_init_lock);
104 return write_to_log(log_id, vec);
105 }
107 static int __android_log_write(int prio, const char *tag, const char *msg)
108 {
109 struct iovec vec[3];
110 log_id_t log_id = LOG_ID_MAIN;
112 if (!tag)
113 tag = "";
115 if (!strcmp(tag, "HTC_RIL"))
116 log_id = LOG_ID_RADIO;
118 vec[0].iov_base = (unsigned char *) &prio;
119 vec[0].iov_len = 1;
120 vec[1].iov_base = (void *) tag;
121 vec[1].iov_len = strlen(tag) + 1;
122 vec[2].iov_base = (void *) msg;
123 vec[2].iov_len = strlen(msg) + 1;
125 return write_to_log(log_id, vec);
126 }
129 static int __android_log_vprint(int prio, const char *tag, const char *fmt,
130 va_list ap)
131 {
132 char buf[LOG_BUF_SIZE];
134 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
136 return __android_log_write(prio, tag, buf);
137 }
139 int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...)
140 {
141 va_list ap;
142 char buf[LOG_BUF_SIZE];
144 va_start(ap, fmt);
145 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
146 va_end(ap);
148 return __android_log_write(prio, tag, buf);
149 }
151 int __libc_android_log_assert(const char *cond, const char *tag,
152 const char *fmt, ...)
153 {
154 va_list ap;
155 char buf[LOG_BUF_SIZE];
157 va_start(ap, fmt);
158 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
159 va_end(ap);
161 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
163 exit(1);
165 return -1;
166 }