From 7951d09e6a7d1029481935ac3399084dbc673427 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 12 Jan 2018 17:31:29 +0900 Subject: [PATCH] ini: first implementation Change-Id: I9e2fd2892279fbc84d1265802b5b33ef6d68dc27 --- configure.ac | 11 +- include/tdm_backend.h | 23 ++++ packaging/libtdm.spec | 2 + src/Makefile.am | 1 + src/tdm.c | 12 ++ src/tdm_config.c | 283 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_config.h | 67 ++++++++++++ src/tdm_private.h | 1 + tools/tdm_test_server.c | 4 +- 9 files changed, 402 insertions(+), 2 deletions(-) create mode 100644 src/tdm_config.c create mode 100644 src/tdm_config.h diff --git a/configure.ac b/configure.ac index 9a706cf..02919f8 100644 --- a/configure.ac +++ b/configure.ac @@ -44,7 +44,7 @@ fi PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner >= 1.7.0) -PKG_CHECK_MODULES(TDM, dlog libtbm libpng pixman-1 wayland-server) +PKG_CHECK_MODULES(TDM, dlog libtbm libpng pixman-1 wayland-server iniparser) PKG_CHECK_MODULES(TDM_CLIENT, dlog wayland-client) PKG_CHECK_MODULES(TTRACE, @@ -72,6 +72,14 @@ AC_ARG_WITH(tdm-module-path, AS_HELP_STRING([--with-tdm-module-path=PATH], [tdm AC_DEFINE_UNQUOTED(TDM_MODULE_PATH, "${TDM_MODULE_PATH}", [Directory for the modules of tdm]) AC_SUBST(TDM_MODULE_PATH) +# set the data dir for the tdm config +DEFAULT_TDM_DATA_PATH="${datadir}/tdm" +AC_ARG_WITH(tdm-data-path, AS_HELP_STRING([--with-tdm-data-path=PATH], [tdm data dir]), + [ TDM_DATA_PATH="$withval" ], + [ TDM_DATA_PATH="${DEFAULT_TDM_DATA_PATH}" ]) +AC_DEFINE_UNQUOTED(TDM_DATA_PATH, "${TDM_DATA_PATH}", [Directory for the data of tdm]) +AC_SUBST(TDM_DATA_PATH) + AC_SUBST([TDM_MAJOR_VERSION], [tdm_major_version]) AC_SUBST([TDM_MINOR_VERSION], [tdm_minor_version]) AC_SUBST([TDM_MICRO_VERSION], [tdm_micro_version]) @@ -105,4 +113,5 @@ echo "TDM_LIBS : $TDM_LIBS" echo "TDM_CLIENT_CFLAGS : $TDM_CLIENT_CFLAGS" echo "TDM_CLIENT_LIBS : $TDM_CLIENT_LIBS" echo "TDM_MODULE_PATH : $TDM_MODULE_PATH" +echo "TDM_DATA_PATH : $TDM_DATA_PATH" echo "" diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 09b1377..de6fb24 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -1446,6 +1446,29 @@ void tdm_event_loop_source_remove(tdm_event_loop_source *source); /** + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_string + */ +int +tdm_config_get_int(const char *key, int default_value); + +/** + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_int + */ +const char * +tdm_config_get_string(const char *key, const char *default_value); + + +/** * @brief Trigger a 'need to validate' event. * @param[in] output The output the event should be triggered for. * @note The global display lock has to be locked before the call to this function. diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 876648f..7140089 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -13,6 +13,7 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(libpng) BuildRequires: pkgconfig(ttrace) BuildRequires: pkgconfig(wayland-server) +BuildRequires: pkgconfig(iniparser) BuildRequires: pkgconfig(pixman-1) BuildRequires: gtest-devel @@ -82,6 +83,7 @@ LDFLAGS+=" -lgcov" %endif %reconfigure --disable-static --with-utests=${UTEST} \ + --with-tdm-data-path=%{TZ_SYS_RO_SHARE}/tdm \ CFLAGS="${CFLAGS} -Wall -Werror" \ CXXFLAGS="${CXXFLAGS} -Wall -Werror" \ LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed" diff --git a/src/Makefile.am b/src/Makefile.am index feabb5d..7ec1cd4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ libtdm_la_CFLAGS = \ libtdm_la_SOURCES = \ $(top_srcdir)/protocol/tdm-protocol.c \ tdm_backend.c \ + tdm_config.c \ tdm_server.c \ tdm_vblank.c \ tdm_event_loop.c \ diff --git a/src/tdm.c b/src/tdm.c index 312bac9..96bed27 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -943,6 +943,14 @@ tdm_display_init(tdm_error *error) start = stamp1 = tdm_helper_get_time(); + ret = tdm_config_init(); + if (ret != TDM_ERROR_NONE) + goto failed_config; + + stamp2 = tdm_helper_get_time(); + TDM_DBG("config init time: %.3f ms", (stamp2 - stamp1) * 1000.0); + stamp1 = stamp2; + private_display = calloc(1, sizeof(tdm_private_display)); if (!private_display) { /* LCOV_EXCL_START */ @@ -1077,6 +1085,8 @@ failed_vblank: failed_mutex_init: free(private_display); failed_alloc: + tdm_config_deinit(); +failed_config: if (error) *error = ret; pthread_mutex_unlock(&gLock); @@ -1131,6 +1141,8 @@ tdm_display_deinit(tdm_display *dpy) tdm_debug_dump_dir = NULL; } + tdm_config_deinit(); + pthread_mutex_unlock(&gLock); TDM_INFO("done"); diff --git a/src/tdm_config.c b/src/tdm_config.c new file mode 100644 index 0000000..6686769 --- /dev/null +++ b/src/tdm_config.c @@ -0,0 +1,283 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tdm_log.h" +#include "tdm_macro.h" +#include "tdm_list.h" +#include "tdm.h" +#include "tdm_private.h" +#include "tdm_config.h" + +#define TDM_CONFIG_FILENAME "tdm.ini" +#define TDM_CONFIG_GENERAL_SECTION "general" + +static dictionary *g_dic = NULL; +static pthread_mutex_t g_dic_lock; + +static int +_tdm_config_check_file_owner(const char *filepath) +{ + struct stat sb; + + if (stat(filepath, &sb) < 0) { + TDM_WRN("%s: %m", filepath); + return -1; + } + + if (sb.st_uid != getuid()) { + TDM_WRN("'%s': not owned by %u", filepath, getuid()); + return -1; + } + + return 0; +} + +static dictionary * +_tdm_config_load_file(const char *dir, const char *filename) +{ + char filepath[TDM_PATH_LEN]; + dictionary *dic; + + snprintf(filepath, sizeof filepath, "%s/%s", dir, filename); + + if (_tdm_config_check_file_owner(filepath) < 0) + return NULL; + + dic = iniparser_load(filepath); + TDM_RETURN_VAL_IF_FAIL(dic != NULL, NULL); + + if (!iniparser_find_entry(dic, TDM_CONFIG_GENERAL_SECTION)) { + TDM_ERR("no '%s' section: '%s'", TDM_CONFIG_GENERAL_SECTION, filepath); + iniparser_freedict(dic); + return NULL; + } + + TDM_INFO("opened successed: '%s'", filepath); + + return dic; +} + +static dictionary * +_tdm_config_load(void) +{ + dictionary *dic = NULL; + +#if 0 + /* not allowed: try to read from RW directory */ + dic = _tdm_config_load_file(TDM_SYSCONF_PATH, TDM_CONFIG_FILENAME); +#endif + + if (!dic) { + /* try to read from RO directory */ + dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME); + } + + return dic; +} + +INTERN tdm_error +tdm_config_init(void) +{ + if (g_dic) { + TDM_ERR("init failed: twice"); + return TDM_ERROR_OPERATION_FAILED; + } + + if (pthread_mutex_init(&g_dic_lock, NULL)) { + TDM_ERR("mutex init failed: %m"); + return TDM_ERROR_OUT_OF_MEMORY; + } + + g_dic = _tdm_config_load(); + if (!g_dic) { + if (!getenv("TDM_NO_CONFIG")) { + TDM_ERR("Loading config file failed!!"); + pthread_mutex_destroy(&g_dic_lock); + return TDM_ERROR_NONE; + } + } + + TDM_INFO("tdm config init done (%p)", g_dic); + + return TDM_ERROR_NONE; +} + +INTERN void +tdm_config_deinit(void) +{ + if (!g_dic) { + return; + } + + iniparser_freedict(g_dic); + g_dic = NULL; + + /* we don't need to lock/unlock here because we come here + * after tdm_thread has been destroyed + */ + pthread_mutex_destroy(&g_dic_lock); + + TDM_INFO("tdm config deinit done"); +} + +static const char* +_tdm_config_get_string_internal(dictionary *dic, const char *key, const char *default_value) +{ + char *temp = NULL; + const char *result; + + if (default_value) { + temp = strdup(default_value); + if (!temp) { + TDM_ERR("strdup failed: %m"); + return default_value; + } + } + + result = (const char *)iniparser_getstring(dic, key, temp); + if (!result || strlen(result) == 0) { + free(temp); + return default_value; + } + + free(temp); + + return result; +} + +INTERN int +tdm_config_get_int(const char *key, int default_value) +{ + const char *result; + int value; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value); + + if (!g_dic) { + TDM_INFO("%s = %d: default", key, default_value); + return default_value; + } + + pthread_mutex_lock(&g_dic_lock); + result = _tdm_config_get_string_internal(g_dic, key, NULL); + pthread_mutex_unlock(&g_dic_lock); + + if (!result) { + TDM_INFO("%s = %d: no key", key, default_value); + return default_value; + } + + value = (int)strtol(result, NULL, 0); + + TDM_INFO("%s = %d", key, value); + + return value; +} + +INTERN const char* +tdm_config_get_string(const char *key, const char *default_value) +{ + const char *result; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value); + + if (!g_dic) { + TDM_INFO("%s = %s: default", key, default_value); + return default_value; + } + + pthread_mutex_lock(&g_dic_lock); + result = _tdm_config_get_string_internal(g_dic, key, default_value); + pthread_mutex_unlock(&g_dic_lock); + + TDM_INFO("%s = %s", key, result); + + return result; +} + +INTERN tdm_error +tdm_config_set_int(const char *key, int value) +{ + char temp[TDM_NAME_LEN]; + int ret; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!g_dic) { + TDM_INFO("%s = %d set failed", key, value); + return TDM_ERROR_BAD_REQUEST; + } + + snprintf(temp, sizeof temp, "%d", value); + + pthread_mutex_lock(&g_dic_lock); + ret = iniparser_set(g_dic, key, (const char*)temp); + pthread_mutex_unlock(&g_dic_lock); + + TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); + + TDM_INFO("%s = %d set done", key, value); + + return TDM_ERROR_NONE; +} + +INTERN tdm_error +tdm_config_set_string(const char *key, const char *value) +{ + int ret; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!g_dic) { + TDM_INFO("%s = %s set failed", key, value); + return TDM_ERROR_BAD_REQUEST; + } + + pthread_mutex_lock(&g_dic_lock); + ret = iniparser_set(g_dic, key, value); + pthread_mutex_unlock(&g_dic_lock); + + TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); + + TDM_INFO("%s = %s set done", key, value); + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_config.h b/src/tdm_config.h new file mode 100644 index 0000000..b743f93 --- /dev/null +++ b/src/tdm_config.h @@ -0,0 +1,67 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#ifndef _TDM_CONFIG_H_ +#define _TDM_CONFIG_H_ + +#include "tdm_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tdm_common.h" + +/** + * @file tdm_config.h + * @brief The config header file for a frontend library + */ + +tdm_error +tdm_config_init(void); +void +tdm_config_deinit(void); + +tdm_error +tdm_config_set_int(const char *key, int value); +tdm_error +tdm_config_set_string(const char *key, const char *value); + + +#ifdef __cplusplus +} +#endif + +#endif /* _TDM_CONFIG_H_ */ diff --git a/src/tdm_private.h b/src/tdm_private.h index a055105..f7c2a11 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -64,6 +64,7 @@ #include "tdm_macro.h" #include "tdm_helper.h" #include "tdm_thread.h" +#include "tdm_config.h" #ifdef __cplusplus extern "C" { diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index 52e0f61..db70668 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -183,7 +183,6 @@ usage(char *app_name) printf("\t%s\n", usages[t].desc); } printf("\n"); - exit(0); } //////////////////////////////////////////////////////////////////////////////// @@ -316,6 +315,7 @@ struct _tdm_test_server { tdm_display *display; }; +static void destroy(tdm_test_server *data); static void run_test(tdm_test_server *data); static void output_setup(tdm_test_server_output *o); static void layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b); @@ -517,6 +517,7 @@ parse_args(tdm_test_server *data, int argc, char *argv[]) if (argc < 2) { usage(argv[0]); + destroy(data); exit(0); } @@ -597,6 +598,7 @@ parse_args(tdm_test_server *data, int argc, char *argv[]) data->do_vblank = 1; } else { usage(argv[0]); + destroy(data); exit(0); } } -- 2.7.4