2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include <bundle_internal.h>
31 #include "aul_debug_info.h"
33 #define PATH_AUL "/usr/share/aul"
34 #define TAG_DEBUGGER "[DEBUGGER]"
35 #define TAG_NAME "NAME"
36 #define TAG_EXTRA_KEY "EXTRA_KEY"
37 #define TAG_EXTRA_ENV "EXTRA_ENV"
38 #define TAG_UNLINK "UNLINK"
39 #define TAG_ATTACH "ATTACH"
40 #define TAG_LAST_EXTRA_KEY "LAST_EXTRA_KEY"
41 #define TAG_DEFAULT_OPT "DEFAULT_OPT"
43 #define FREE_AND_NULL(x) do { \
50 struct debugger_info_s {
53 GList *extra_key_list;
54 GList *extra_env_list;
56 GList *last_extra_key_list;
57 GList *default_opt_list;
70 static struct debug_info_s __info;
72 static struct debugger_info_s *__create_debugger_info(void)
74 struct debugger_info_s *info;
76 info = calloc(1, sizeof(struct debugger_info_s));
85 static void __destroy_debugger_info(gpointer data)
87 struct debugger_info_s *info = (struct debugger_info_s *)data;
92 if (info->default_opt_list)
93 g_list_free_full(info->default_opt_list, free);
94 if (info->last_extra_key_list)
95 g_list_free_full(info->last_extra_key_list, free);
98 if (info->unlink_list)
99 g_list_free_full(info->unlink_list, free);
100 if (info->extra_env_list)
101 g_list_free_full(info->extra_env_list, free);
102 if (info->extra_key_list)
103 g_list_free_full(info->extra_key_list, free);
109 static struct debugger_info_s *__find_debugger_info(const char *name)
111 struct debugger_info_s *debugger;
114 iter = __info.debugger_list;
116 debugger = (struct debugger_info_s *)iter->data;
117 if (debugger && debugger->name &&
118 !strcmp(debugger->name, name))
121 iter = g_list_next(iter);
127 static GList *__parse_file(GList *list, const char *path)
133 struct debugger_info_s *info = NULL;
135 fp = fopen(path, "rt");
139 while (fgets(buf, sizeof(buf), fp) != NULL) {
142 sscanf(buf, "%ms %ms", &tok1, &tok2);
143 if (tok1 && strcasecmp(TAG_DEBUGGER, tok1) == 0) {
145 _D("name: %s", info->name);
146 list = g_list_append(list, info);
149 info = __create_debugger_info();
158 if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
163 if (strcasecmp(TAG_NAME, tok1) == 0) {
164 info->name = strdup(tok2);
165 if (info->name == NULL) {
167 __destroy_debugger_info(info);
171 } else if (strcasecmp(TAG_EXTRA_KEY, tok1) == 0) {
172 info->extra_key_list = g_list_append(
173 info->extra_key_list, strdup(tok2));
174 } else if (strcasecmp(TAG_EXTRA_ENV, tok1) == 0) {
175 info->extra_env_list = g_list_append(
176 info->extra_env_list, strdup(tok2));
177 } else if (strcasecmp(TAG_UNLINK, tok1) == 0) {
178 info->unlink_list = g_list_append(info->unlink_list,
180 } else if (strcasecmp(TAG_ATTACH, tok1) == 0) {
181 info->attach = strdup(tok2);
182 if (info->attach == NULL) {
183 _E("attach is NULL");
184 __destroy_debugger_info(info);
188 } else if (strcasecmp(TAG_LAST_EXTRA_KEY, tok1) == 0) {
189 info->last_extra_key_list = g_list_append(
190 info->last_extra_key_list,
192 } else if (strcasecmp(TAG_DEFAULT_OPT, tok1) == 0) {
193 info->default_opt_list = g_list_append(
194 info->default_opt_list,
201 _D("name: %s", info->name);
202 list = g_list_append(list, info);
213 static int __load_debugger_info(const char *path)
216 struct dirent *dentry = NULL;
227 while ((dentry = readdir(dp)) != NULL) {
228 if (dentry->d_name[0] == '.')
231 ext = strrchr(dentry->d_name, '.');
232 if (ext && strcmp(ext, ".debugger") == 0) {
233 snprintf(buf, sizeof(buf), "%s/%s",
234 path, dentry->d_name);
235 __info.debugger_list = __parse_file(
236 __info.debugger_list, buf);
244 static void __unload_debugger_info(void)
246 if (__info.debugger_list == NULL)
249 g_list_free_full(__info.debugger_list, __destroy_debugger_info);
250 __info.debugger_list = NULL;
253 API int aul_debug_info_init(void)
257 if (__info.initialized)
260 r = __load_debugger_info(PATH_AUL);
262 _E("Failed to loader debugger information");
266 __info.initialized = true;
270 API int aul_debug_info_fini(void)
272 if (!__info.initialized)
275 __unload_debugger_info();
277 __info.initialized = false;
281 static void __copy_data(bundle *src, bundle *dst, const char *key)
283 const char **str_arr;
287 if (bundle_get_type(src, key) == BUNDLE_TYPE_STR_ARRAY) {
288 str_arr = bundle_get_str_array(src, key, &len);
290 bundle_del(dst, key);
291 bundle_add_str_array(dst, key, str_arr, len);
294 bundle_get_str(src, key, &str);
296 bundle_del(dst, key);
297 bundle_add_str(dst, key, str);
302 static void __foreach_cb(gpointer data, gpointer user_data)
304 struct cb_data_s *cb_data = (struct cb_data_s *)user_data;
305 const char *key = (const char *)data;
307 if (!key || !cb_data) {
308 _E("Critical error!");
312 __copy_data(cb_data->src, cb_data->dst, key);
313 _D("[__DEBUG_INFO__] key(%s)", key);
316 static void __set_debug_info(struct debugger_info_s *debugger,
317 bundle *src, bundle *dst)
320 struct cb_data_s cb_data = {
325 __copy_data(src, dst, AUL_K_SDK);
326 if (debugger->extra_key_list)
327 g_list_foreach(debugger->extra_key_list, __foreach_cb, &cb_data);
328 if (debugger->extra_env_list)
329 g_list_foreach(debugger->extra_env_list, __foreach_cb, &cb_data);
330 if (debugger->unlink_list)
331 g_list_foreach(debugger->unlink_list, __foreach_cb, &cb_data);
332 if (debugger->last_extra_key_list)
333 g_list_foreach(debugger->last_extra_key_list, __foreach_cb, &cb_data);
334 if (debugger->default_opt_list)
335 g_list_foreach(debugger->default_opt_list, __foreach_cb, &cb_data);
337 val = bundle_get_val(src, AUL_K_ORG_CALLER_PID);
339 val = bundle_get_val(src, AUL_K_CALLER_PID);
342 bundle_del(dst, AUL_K_ORG_CALLER_PID);
343 bundle_add(dst, AUL_K_ORG_CALLER_PID, val);
346 _D("[__DEBUG_INFO__] Debugger(%s)", debugger->name);
349 API int aul_debug_info_set(bundle *src, bundle *dst)
352 struct debugger_info_s *debugger;
355 _E("Invalid parameter");
359 if (!__info.initialized) {
360 _E("Debug info is not initilaized");
364 name = bundle_get_val(src, AUL_K_SDK);
366 _E("Invalid parameter");
370 debugger = __find_debugger_info(name);
372 _E("Failed to find debugger(%s)", name);
376 __set_debug_info(debugger, src, dst);