blob: 7c3608bf7614132c21a4c15bd8384df50b8720bb [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001/*
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>
40
41#include <cutils/logger.h>
42#include "logd.h"
43
44#include <pthread.h>
45
46#define LOG_BUF_SIZE 1024
47
48typedef enum {
49 LOG_ID_MAIN = 0,
50 LOG_ID_RADIO,
51 LOG_ID_MAX
52} log_id_t;
53
54static int __write_to_log_init(log_id_t, struct iovec *vec);
55static int (*write_to_log)(log_id_t, struct iovec *vec) = __write_to_log_init;
56static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
57
58static int log_fds[(int)LOG_ID_MAX] = { -1, -1 };
59
60static int __write_to_log_null(log_id_t log_fd, struct iovec *vec)
61{
62 return -1;
63}
64
65static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec)
66{
67 ssize_t ret;
68 int log_fd;
69
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 }
75
76 do {
77 ret = writev(log_fd, vec, 3);
78 } while (ret < 0 && errno == EINTR);
79
80 return ret;
81}
82
83static int __write_to_log_init(log_id_t log_id, struct iovec *vec)
84{
85 pthread_mutex_lock(&log_init_lock);
86
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);
90
91 write_to_log = __write_to_log_kernel;
92
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 }
101
102 pthread_mutex_unlock(&log_init_lock);
103
104 return write_to_log(log_id, vec);
105}
106
107static 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;
111
112 if (!tag)
113 tag = "";
114
115 if (!strcmp(tag, "HTC_RIL"))
116 log_id = LOG_ID_RADIO;
117
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;
124
125 return write_to_log(log_id, vec);
126}
127
128
129static int __android_log_vprint(int prio, const char *tag, const char *fmt,
130 va_list ap)
131{
132 char buf[LOG_BUF_SIZE];
133
134 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
135
136 return __android_log_write(prio, tag, buf);
137}
138
139int __libc_android_log_print(int prio, const char *tag, const char *fmt, ...)
140{
141 va_list ap;
142 char buf[LOG_BUF_SIZE];
143
144 va_start(ap, fmt);
145 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
146 va_end(ap);
147
148 return __android_log_write(prio, tag, buf);
149}
150
151int __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];
156
157 va_start(ap, fmt);
158 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
159 va_end(ap);
160
161 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
162
163 exit(1);
164
165 return -1;
166}