diff options
-rwxr-xr-x | CMakeLists.txt | 1 | ||||
-rw-r--r-- | inc/launchpad_io_channel.h | 38 | ||||
-rwxr-xr-x | src/launchpad.c | 315 | ||||
-rw-r--r-- | src/launchpad_io_channel.c | 159 | ||||
-rw-r--r-- | src/log_private.h | 17 |
5 files changed, 314 insertions, 216 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ad32426..5239b49 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,6 +146,7 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES src/launchpad_debug.c src/launchpad_signal.c src/launchpad_config.c + src/launchpad_io_channel.c ) ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES}) diff --git a/inc/launchpad_io_channel.h b/inc/launchpad_io_channel.h new file mode 100644 index 0000000..6498fb3 --- /dev/null +++ b/inc/launchpad_io_channel.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <stdbool.h> + +typedef enum { + IO_IN = 0x01, + IO_OUT = 0x02, + IO_PRI = 0x04, + IO_ERR = 0x08, + IO_HUP = 0x10, + IO_NVAL = 0x20, +} io_condition_e; + +typedef bool (*io_channel_event_cb)(int fd, io_condition_e condition, + void *user_data); + +typedef struct io_channel_s *io_channel_h; + +io_channel_h _io_channel_create(int fd, io_condition_e condition, + io_channel_event_cb, void *user_data); + +void _io_channel_destroy(io_channel_h channel); diff --git a/src/launchpad.c b/src/launchpad.c index e751fbb..b847c2c 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -44,6 +44,7 @@ #include "launchpad_common.h" #include "launchpad_config.h" #include "launchpad_debug.h" +#include "launchpad_io_channel.h" #include "launchpad_signal.h" #include "launchpad_types.h" #include "loader_info.h" @@ -84,7 +85,6 @@ typedef struct { int send_fd; int hydra_fd; int last_exec_time; - guint source; guint timer; char *loader_path; char *loader_extra; @@ -105,8 +105,9 @@ typedef struct { guint live_timer; int state; bool is_hydra; - guint pollfd; - guint hydra_pollfd; + io_channel_h client_channel; + io_channel_h channel; + io_channel_h hydra_channel; } candidate_process_context_t; typedef struct { @@ -152,6 +153,11 @@ static sequencer __sequencer; static int MEMORY_STATUS_LOW; static int MEMORY_STATUS_NORMAL; +static io_channel_h __logger_channel; +static io_channel_h __label_monitor_channel; +static io_channel_h __sigchild_channel; +static io_channel_h __launchpad_channel; + static candidate_process_context_t *__add_slot(int type, int loader_id, int caller_pid, const char *loader_path, const char *extra, int detection_method, int activation_method, @@ -787,7 +793,7 @@ static void __reset_slot(candidate_process_context_t *cpc) cpc->send_fd = -1; cpc->prepared = false; cpc->pid = CANDIDATE_NONE; - cpc->source = 0; + cpc->client_channel = NULL; cpc->timer = 0; cpc->live_timer = 0; } @@ -804,8 +810,8 @@ static void __dispose_candidate_process(candidate_process_context_t *cpc) } if (cpc->live_timer > 0) g_source_remove(cpc->live_timer); - if (cpc->source > 0) - g_source_remove(cpc->source); + if (cpc->client_channel) + _io_channel_destroy(cpc->client_channel); if (cpc->timer > 0) g_source_remove(cpc->timer); if (cpc->send_fd > 0) @@ -1216,172 +1222,57 @@ static int __launchpad_pre_init(int argc, char **argv) return fd; } -static void __destroy_poll_data(gpointer data) -{ - free(data); -} - -static gboolean __glib_check(GSource *src) -{ - GSList *fd_list; - GPollFD *tmp; - - fd_list = src->poll_fds; - do { - tmp = (GPollFD *) fd_list->data; - if ((tmp->revents & (G_IO_IN | G_IO_PRI | G_IO_HUP | - G_IO_NVAL))) - return TRUE; - fd_list = fd_list->next; - } while (fd_list); - - return FALSE; -} - -static gboolean __glib_dispatch(GSource *src, GSourceFunc callback, - gpointer data) -{ - return callback(data); -} - -static gboolean __glib_prepare(GSource *src, gint *timeout) -{ - return FALSE; -} - -static void __glib_finalize(GSource *src) -{ - GSList *fd_list; - GPollFD *gpollfd; - - fd_list = src->poll_fds; - do { - gpollfd = (GPollFD *)fd_list->data; - close(gpollfd->fd); - g_free(gpollfd); - - fd_list = fd_list->next; - } while (fd_list); -} - -static GSourceFuncs funcs = { - .prepare = __glib_prepare, - .check = __glib_check, - .dispatch = __glib_dispatch, - .finalize = __glib_finalize -}; - -static guint __poll_fd(int fd, gushort events, GSourceFunc func, int type, - int loader_id) +static bool __handle_loader_client_event(int fd, io_condition_e cond, + void *data) { - int r; - GPollFD *gpollfd; - GSource *src; - loader_context_t *lc; - - src = g_source_new(&funcs, sizeof(GSource)); - if (!src) { - _E("out of memory"); - return 0; - } - - gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD)); - if (!gpollfd) { - _E("out of memory"); - g_source_destroy(src); - return 0; - } - - gpollfd->events = events; - gpollfd->fd = fd; - - lc = malloc(sizeof(loader_context_t)); - if (lc == NULL) { - g_free(gpollfd); - g_source_destroy(src); - return 0; - } - - lc->gpollfd = gpollfd; - lc->type = type; - lc->loader_id = loader_id; - - g_source_add_poll(src, gpollfd); - g_source_set_callback(src, func, - (gpointer) lc, __destroy_poll_data); - g_source_set_priority(src, G_PRIORITY_DEFAULT); - - r = g_source_attach(src, NULL); - if (r == 0) { - g_free(gpollfd); - g_source_destroy(src); - return 0; - } - - return r; -} - -static gboolean __handle_loader_client_event(gpointer data) -{ - loader_context_t *lc = (loader_context_t *) data; - int type = lc->type; - int loader_id = lc->loader_id; - gushort revents = lc->gpollfd->revents; - candidate_process_context_t *cpc = __find_slot(type, loader_id); + candidate_process_context_t *cpc = data; if (cpc == NULL) - return G_SOURCE_REMOVE; + return false; - if (revents & (G_IO_HUP | G_IO_NVAL)) { - SECURE_LOGE("Type %d candidate process was " \ + if (cond & (IO_HUP | IO_NVAL)) { + SECURE_LOGE("Type %d candidate process was " "(POLLHUP|POLLNVAL), pid: %d", cpc->type, cpc->pid); cpc->pid = CANDIDATE_NONE; __dispose_candidate_process(cpc); __prepare_candidate_process(cpc->type, cpc->loader_id); - return G_SOURCE_REMOVE; + return false; } - return G_SOURCE_CONTINUE; + return true; + } -static gboolean __handle_hydra_client_event(gpointer data) +static bool __handle_hydra_client_event(int fd, io_condition_e cond, + void *data) { - loader_context_t *lc = (loader_context_t *)data; - int type = lc->type; - int loader_id = lc->loader_id; - gushort revents = lc->gpollfd->revents; - candidate_process_context_t *cpc = __find_slot(type, loader_id); + candidate_process_context_t *cpc = data; if (cpc == NULL) - return G_SOURCE_REMOVE; + return false; - if (revents & (G_IO_HUP | G_IO_NVAL)) { - SECURE_LOGE("Type %d hydra process was " \ + if (cond & (IO_HUP | IO_NVAL)) { + SECURE_LOGE("Type %d hydra process was " "(POLLHUP|POLLNVAL), pid: %d", cpc->type, cpc->hydra_pid); __dispose_hydra_process(cpc); __prepare_candidate_process(cpc->type, cpc->loader_id); - return G_SOURCE_REMOVE; + return false; } - return G_SOURCE_CONTINUE; + return true; } -static gboolean __handle_loader_event(gpointer data) +static bool __handle_loader_event(int fd, io_condition_e cond, void *data) { - loader_context_t *lc = (loader_context_t *) data; - int fd = lc->gpollfd->fd; - int type = lc->type; - int loader_id = lc->loader_id; + candidate_process_context_t *cpc = data; int client_fd; int client_pid; int ret; - candidate_process_context_t *cpc = __find_slot(type, loader_id); - if (cpc == NULL) - return G_SOURCE_REMOVE; + return false; if (!cpc->prepared) { ret = __accept_candidate_process(fd, &client_fd, &client_pid); @@ -1394,12 +1285,13 @@ static gboolean __handle_loader_event(gpointer data) cpc->prepared = true; cpc->send_fd = client_fd; - SECURE_LOGD("Type %d candidate process was connected," \ - " pid: %d", type, cpc->pid); - cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP, - __handle_loader_client_event, type, - loader_id); - if (cpc->source == 0) + SECURE_LOGD("Type %d candidate process was connected, " + "pid: %d", cpc->type, cpc->pid); + cpc->client_channel = _io_channel_create(client_fd, + IO_IN | IO_HUP, + __handle_loader_client_event, + cpc); + if (!cpc->client_channel) close(client_fd); } } else { @@ -1407,36 +1299,32 @@ static gboolean __handle_loader_event(gpointer data) _E("Refused candidate process connection"); } - return G_SOURCE_CONTINUE; + return true; } -static gboolean __handle_hydra_event(gpointer data) +static bool __handle_hydra_event(int fd, io_condition_e cond, void *data) { - loader_context_t *lc = (loader_context_t *) data; - int fd = lc->gpollfd->fd; - int type = lc->type; - int loader_id = lc->loader_id; + candidate_process_context_t *cpc = data; int client_fd; int client_pid; int ret; - candidate_process_context_t *cpc = __find_slot(type, loader_id); - if (cpc == NULL) - return G_SOURCE_REMOVE; + return false; if (!cpc->prepared) { ret = __accept_candidate_process(fd, &client_fd, &client_pid); if (ret >= 0) { cpc->hydra_fd = client_fd; - SECURE_LOGD("Type %d hydra process was connected," \ - " pid: %d", type, cpc->hydra_pid); + SECURE_LOGD("Type %d hydra process was connected," + " pid: %d", cpc->type, cpc->hydra_pid); - cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP, - __handle_hydra_client_event, type, - loader_id); - if (cpc->source == 0) + cpc->client_channel = _io_channel_create(client_fd, + IO_IN | IO_HUP, + __handle_hydra_client_event, + cpc); + if (!cpc->client_channel) close(client_fd); } } else { @@ -1444,14 +1332,12 @@ static gboolean __handle_hydra_event(gpointer data) _E("Refused hydra process connection"); } - return G_SOURCE_CONTINUE; + return true; } -static gboolean __handle_sigchild(gpointer data) +static bool __handle_sigchild(int fd, io_condition_e cond, void *data) { candidate_process_context_t *cpc; - loader_context_t *lc = (loader_context_t *) data; - int fd = lc->gpollfd->fd; struct signalfd_siginfo siginfo; ssize_t s; char *appid; @@ -1498,15 +1384,15 @@ static gboolean __handle_sigchild(gpointer data) } } while (s > 0); - return G_SOURCE_CONTINUE; + return true; } -static gboolean __handle_label_monitor(gpointer data) +static bool __handle_label_monitor(int fd, io_condition_e cond, void *data) { candidate_process_context_t *cpc; GList *iter = candidate_slot_list; - _D("__handle_label_monitor()"); + _D("%s()", __FUNCTION__); security_manager_app_labels_monitor_process(label_monitor); while (iter) { @@ -1525,7 +1411,7 @@ static gboolean __handle_label_monitor(gpointer data) iter = g_list_next(iter); } - return G_SOURCE_CONTINUE; + return true; } static float __interpolator(float input, int cpu_max, int cpu_min) @@ -1894,10 +1780,8 @@ static void __update_slot_state(candidate_process_context_t *cpc, int method) } } -static gboolean __handle_launch_event(gpointer data) +static bool __handle_launch_event(int fd, io_condition_e cond, void *data) { - loader_context_t *lc = (loader_context_t *) data; - int fd = lc->gpollfd->fd; bundle *kb = NULL; app_pkt_t *pkt = NULL; appinfo_t *menu_info = NULL; @@ -2075,7 +1959,7 @@ end: traceEnd(TTRACE_TAG_APPLICATION_MANAGER); - return G_SOURCE_CONTINUE; + return true; } static void __destroy_slot(candidate_process_context_t *cpc) @@ -2083,11 +1967,11 @@ static void __destroy_slot(candidate_process_context_t *cpc) if (!cpc) return; - if (cpc->hydra_pollfd) - g_source_remove(cpc->hydra_pollfd); + if (cpc->hydra_channel) + _io_channel_destroy(cpc->hydra_channel); - if (cpc->pollfd) - g_source_remove(cpc->pollfd); + if (cpc->channel) + _io_channel_destroy(cpc->channel); if (cpc->loader_extra) free(cpc->loader_extra); @@ -2138,7 +2022,6 @@ static candidate_process_context_t *__create_slot(int type, int loader_id, cpc->send_fd = -1; cpc->hydra_fd = -1; cpc->last_exec_time = 0; - cpc->source = 0; cpc->timer = 0; cpc->detection_method = detection_method; cpc->timeout_val = timeout_val; @@ -2176,9 +2059,9 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, { candidate_process_context_t *cpc; int fd; - guint pollfd; + io_channel_h channel; int hydra_fd; - guint hydra_pollfd; + io_channel_h hydra_channel; if (__find_slot(type, loader_id) != NULL) return NULL; @@ -2202,15 +2085,14 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, return NULL; } - pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_loader_event, - cpc->type, cpc->loader_id); - if (pollfd == 0) { + channel = _io_channel_create(fd, IO_IN, __handle_loader_event, cpc); + if (!channel) { close(fd); __destroy_slot(cpc); return NULL; } - cpc->pollfd = pollfd; + cpc->channel = channel; if (is_hydra) { hydra_fd = __listen_hydra_process(cpc->type, cpc->loader_id); @@ -2218,22 +2100,19 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, _E("[launchpad] Listening the socket to " \ "the type %d hydra process failed.", cpc->type); - close(fd); __destroy_slot(cpc); return NULL; } - hydra_pollfd = __poll_fd(hydra_fd, G_IO_IN, - (GSourceFunc)__handle_hydra_event, - cpc->type, cpc->loader_id); - if (hydra_pollfd == 0) { + hydra_channel = _io_channel_create(hydra_fd, IO_IN, + __handle_hydra_event, cpc); + if (!hydra_channel) { close(hydra_fd); - close(fd); __destroy_slot(cpc); return NULL; } - cpc->hydra_pollfd = hydra_pollfd; + cpc->hydra_channel = hydra_channel; } @@ -2267,7 +2146,6 @@ static int __remove_slot(int type, int loader_id) static int __init_launchpad_fd(int argc, char **argv) { int fd = -1; - guint pollfd; fd = __launchpad_pre_init(argc, argv); if (fd < 0) { @@ -2275,9 +2153,9 @@ static int __init_launchpad_fd(int argc, char **argv) return -1; } - pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_launch_event, 0, - 0); - if (pollfd == 0) { + __launchpad_channel = _io_channel_create(fd, IO_IN, + __handle_launch_event, NULL); + if (!__launchpad_channel) { close(fd); return -1; } @@ -2288,7 +2166,6 @@ static int __init_launchpad_fd(int argc, char **argv) static int __init_sigchild_fd(void) { int fd = -1; - guint pollfd; fd = _signal_get_sigchld_fd(); if (fd < 0) { @@ -2296,8 +2173,9 @@ static int __init_sigchild_fd(void) return -1; } - pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_sigchild, 0, 0); - if (pollfd == 0) { + __sigchild_channel = _io_channel_create(fd, IO_IN, + __handle_sigchild, NULL); + if (!__sigchild_channel) { close(fd); return -1; } @@ -2309,7 +2187,6 @@ static int __init_label_monitor_fd(void) { int r; int fd = -1; - guint pollfd; r = security_manager_app_labels_monitor_init(&label_monitor); if (r != SECURITY_MANAGER_SUCCESS) @@ -2325,9 +2202,9 @@ static int __init_label_monitor_fd(void) goto err; } - pollfd = __poll_fd(fd, G_IO_IN, - (GSourceFunc)__handle_label_monitor, 0, 0); - if (pollfd == 0) + __label_monitor_channel = _io_channel_create(fd, IO_IN, + __handle_label_monitor, NULL); + if (!__label_monitor_channel) goto err; return 0; @@ -2590,18 +2467,16 @@ static int __register_vconf_events(void) return 0; } -static gboolean __handle_logger(gpointer data) +static bool __handle_logger(int fd, io_condition_e cond, void *data) { - loader_context_t *lc = (loader_context_t *)data; - int fd = lc->gpollfd->fd; - app_pkt_t *pkt = NULL; + app_pkt_t *pkt; struct ucred cr; int clifd = -1; pkt = _accept_recv_pkt_raw(fd, &clifd, &cr); if (!pkt) { _E("Failed to receive the packet"); - return G_SOURCE_CONTINUE; + return true; } if (getuid() != cr.uid) { @@ -2615,20 +2490,18 @@ static gboolean __handle_logger(gpointer data) } SECURE_LOGE("[%d] %s", cr.pid, (const char *)pkt->data); - end: if (clifd != -1) close(clifd); - if (pkt) - free(pkt); - return G_SOURCE_CONTINUE; + free(pkt); + + return true; } static int __init_logger_fd(void) { int fd; - guint pollfd; fd = _create_server_sock(LAUNCHPAD_LOGGER_SOCK); if (fd < 0) { @@ -2636,8 +2509,8 @@ static int __init_logger_fd(void) return -1; } - pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_logger, 0, 0); - if (pollfd == 0) { + __logger_channel = _io_channel_create(fd, IO_IN, __handle_logger, NULL); + if (!__logger_channel) { close(fd); return -1; } @@ -2713,9 +2586,21 @@ static void __after_loop(void) _launcher_info_unload(launcher_info_list); _config_fini(); + if (__label_monitor_channel) + _io_channel_destroy(__label_monitor_channel); + if (label_monitor) security_manager_app_labels_monitor_finish(label_monitor); + if (__logger_channel) + _io_channel_destroy(__logger_channel); + + if (__launchpad_channel) + _io_channel_destroy(__launchpad_channel); + + if (__sigchild_channel) + _io_channel_destroy(__sigchild_channel); + __sequencer_fini(); } diff --git a/src/launchpad_io_channel.c b/src/launchpad_io_channel.c new file mode 100644 index 0000000..f20cb92 --- /dev/null +++ b/src/launchpad_io_channel.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <glib.h> +#include <gio/gio.h> + +#include "launchpad_io_channel.h" +#include "log_private.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +struct io_channel_s { + GIOChannel *io; + guint tag; + int fd; + io_channel_event_cb callback; + void *user_data; +}; + +struct io_condition_s { + io_condition_e io_cond; + GIOCondition g_io_cond; +}; + +static struct io_condition_s __cond_map[] = { + { + .io_cond = IO_IN, + .g_io_cond = G_IO_IN + }, + { + .io_cond = IO_OUT, + .g_io_cond = G_IO_OUT + }, + { + .io_cond = IO_PRI, + .g_io_cond = G_IO_PRI + }, + { + .io_cond = IO_ERR, + .g_io_cond = G_IO_ERR + }, + { + .io_cond = IO_HUP, + .g_io_cond = G_IO_HUP + }, + { + .io_cond = IO_NVAL, + .g_io_cond = G_IO_NVAL, + } +}; + +static io_condition_e __convert_g_io_condition(GIOCondition cond) +{ + io_condition_e condition = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(__cond_map); i++) { + if (__cond_map[i].g_io_cond & cond) + condition |= __cond_map[i].io_cond; + } + + return condition; +} + +static GIOCondition __convert_io_condition(io_condition_e cond) +{ + GIOCondition condition = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(__cond_map); i++) { + if (__cond_map[i].io_cond & cond) + condition |= __cond_map[i].g_io_cond; + } + + return condition; +} + +static gboolean __io_event_cb(GIOChannel *source, GIOCondition condition, + gpointer data) +{ + io_channel_h channel = (io_channel_h)data; + io_condition_e cond = __convert_g_io_condition(condition); + + if (!channel->callback(channel->fd, cond, channel->user_data)) + return G_SOURCE_REMOVE; + + return G_SOURCE_CONTINUE; +} + +io_channel_h _io_channel_create(int fd, io_condition_e cond, + io_channel_event_cb callback, void *user_data) +{ + struct io_channel_s *channel; + + if (fd < 3 || !callback) { + _E("Invalid parameter"); + return NULL; + } + + channel = calloc(1, sizeof(struct io_channel_s)); + if (!channel) { + _E("Out of memory"); + return NULL; + } + + channel->io = g_io_channel_unix_new(fd); + if (!channel->io) { + _E("Failed to create GIOChannel"); + _io_channel_destroy(channel); + return NULL; + } + + channel->tag = g_io_add_watch(channel->io, __convert_io_condition(cond), + __io_event_cb, channel); + if (!channel->tag) { + _E("Failed to add GIO watch"); + _io_channel_destroy(channel); + return NULL; + } + + channel->fd = fd; + channel->callback = callback; + channel->user_data = user_data; + + return channel; +} + +void _io_channel_destroy(io_channel_h channel) +{ + if (!channel) + return; + + if (channel->tag) + g_source_remove(channel->tag); + + if (channel->io) + g_io_channel_unref(channel->io); + + if (channel->fd) + close(channel->fd); + + free(channel); +} diff --git a/src/log_private.h b/src/log_private.h index f214b78..c3b0662 100644 --- a/src/log_private.h +++ b/src/log_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,24 @@ #endif #define LOG_TAG "LAUNCHPAD" +#ifdef _E +#undef _E +#endif #define _E(fmt, arg...) LOGE(fmt, ##arg) + +#ifdef _D +#undef _D +#endif #define _D(fmt, arg...) LOGD(fmt, ##arg) + +#ifdef _W +#undef _W +#endif #define _W(fmt, arg...) LOGW(fmt, ##arg) + +#ifdef _I +#undef _I +#endif #define _I(fmt, arg...) LOGI(fmt, ##arg) #endif /* __LOG_PRIVATE_H__ */ |