From: Junghoon, Park Date: Fri, 13 Nov 2015 08:45:35 +0000 (+0900) Subject: add library for making launchpad-loader X-Git-Tag: submit/tizen/20151116.052223^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad1a35219f47af9788b1a9ed0477215604b25a39;p=platform%2Fcore%2Fappfw%2Flaunchpad.git add library for making launchpad-loader Change-Id: Ic929c89fa1f8b77172846423a1658009b142a99e Signed-off-by: Junghoon, Park --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 867449e8..0eccf724 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) SET (this_target_pool launchpad_pool) SET (this_target_loader launchpad_loader) +SET (this_target_lib launchpad) +SET (VERSION_MAJOR 0) INCLUDE(FindPkgConfig) PKG_CHECK_MODULES(${this_target_pool} REQUIRED @@ -29,6 +31,17 @@ FOREACH(flag ${${this_target_loader}_CFLAGS}) SET(EXTRA_CFLAGS_loader "${EXTRA_CFLAGS_loader} ${flag}") ENDFOREACH(flag) +PKG_CHECK_MODULES(${this_target_lib} REQUIRED + dlog + bundle + aul + security-manager + ) + +FOREACH(flag ${${this_target_lib}_CFLAGS}) + SET(EXTRA_CFLAGS_lib "${EXTRA_CFLAGS_lib} ${flag}") +ENDFOREACH(flag) + SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -Wl,-zdefs" ) SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fvisibility=hidden") SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fPIE") @@ -37,6 +50,7 @@ SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -D_FILE_OFFSET_BITS=64") SET(EXTRA_CFLAGS_pool "${EXTRA_CFLAGS_pool} ${EXTRA_CFLAGS_common}") SET(EXTRA_CFLAGS_loader "${EXTRA_CFLAGS_loader} ${EXTRA_CFLAGS_common}") +SET(EXTRA_CFLAGS_lib "${EXTRA_CFLAGS_lib} ${EXTRA_CFLAGS_common}") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") SET(CMAKE_C_FLAGS_RELEASE "-O2") @@ -55,10 +69,12 @@ ADD_DEFINITIONS("-DPREEXEC_ACTIVATE") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc) +# launchpad-loader SET(LAUNCHPAD_LOADER "launchpad-loader") SET(${LAUNCHPAD_LOADER}_SOURCE_FILES src/launchpad_loader.c src/launchpad_common.c + src/launchpad_lib.c ) ADD_EXECUTABLE(${LAUNCHPAD_LOADER} ${${LAUNCHPAD_LOADER}_SOURCE_FILES}) @@ -70,8 +86,8 @@ SET_TARGET_PROPERTIES(${LAUNCHPAD_LOADER} ) # remove rpath option that is automatically generated by cmake. INSTALL(TARGETS ${LAUNCHPAD_LOADER} DESTINATION bin) +# launchpad-process-pool SET(LAUNCHPAD_PROCESS_POOL "launchpad-process-pool") - SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES src/launchpad.c src/launchpad_common.c @@ -87,3 +103,20 @@ SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL} INSTALL(TARGETS ${LAUNCHPAD_PROCESS_POOL} DESTINATION bin) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/launchpad-process-pool-preload-list.txt DESTINATION share/aul) +# liblaunchpad +SET(LAUNCHPAD_LIB "launchpad") +ADD_LIBRARY(${LAUNCHPAD_LIB} SHARED + src/launchpad_lib.c + src/launchpad_common.c + ) +SET_TARGET_PROPERTIES(${LAUNCHPAD_LIB} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${LAUNCHPAD_LIB} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${LAUNCHPAD_LIB} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_lib}) +TARGET_LINK_LIBRARIES(${LAUNCHPAD_LIB} ${${this_target_lib}_LDFLAGS} "-ldl") +INSTALL(TARGETS ${LAUNCHPAD_LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/inc/launchpad.h DESTINATION include/launchpad) +CONFIGURE_FILE(launchpad.pc.in launchpad.pc @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/launchpad.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + + + diff --git a/inc/launchpad.h b/inc/launchpad.h new file mode 100644 index 00000000..37d50ed0 --- /dev/null +++ b/inc/launchpad.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 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. + */ + +#ifndef __LAUNCHPAD_H__ +#define __LAUNCHPAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*loader_create_cb)(int argc, char **argv, int type, void *user_data); +typedef int (*loader_launch_cb)(int argc, char **argv, const char *app_path, + const char *appid, const char *pkgid, const char *pkg_type, void *user_data); +typedef int (*loader_terminate_cb)(int argc, char **argv, void *user_data); + +typedef void (*loader_receiver_cb)(int fd); +typedef void (*loader_loop_begin_cb)(void *user_data); +typedef void (*loader_loop_quit_cb)(void *user_data); +typedef void (*loader_add_fd_cb)(void *user_data, int fd, loader_receiver_cb receiver); +typedef void (*loader_remove_fd_cb)(void *user_data, int fd); + +typedef struct { + loader_create_cb create; + loader_launch_cb launch; + loader_terminate_cb terminate; +} loader_lifecycle_callback_s; + +typedef struct { + loader_loop_begin_cb loop_begin; + loader_loop_quit_cb loop_quit; + loader_add_fd_cb add_fd; + loader_remove_fd_cb remove_fd; +} loader_adapter_s; + +enum LAUNCHPAD_TYPE { + LAUNCHPAD_TYPE_UNSUPPORTED = -1, + LAUNCHPAD_TYPE_COMMON, + LAUNCHPAD_TYPE_SW, + LAUNCHPAD_TYPE_HW, + LAUNCHPAD_TYPE_MAX +}; + +int launchpad_loader_main(int argc, char **argv, loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, void *user_data); + + +#ifdef __cplusplus +} +#endif + +#endif /* __LAUNCHPAD_H__ */ + diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index e677be73..0934a0ce 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -65,14 +65,6 @@ typedef struct _app_pkt_t { unsigned char data[1]; } app_pkt_t; -enum LAUNCHPAD_TYPE { - LAUNCHPAD_TYPE_UNSUPPORTED = -1, - LAUNCHPAD_TYPE_COMMON, - LAUNCHPAD_TYPE_SW, - LAUNCHPAD_TYPE_HW, - LAUNCHPAD_TYPE_MAX -}; - char *_proc_get_cmdline_bypid(int pid); app_info_from_db *_get_app_info_from_bundle_by_pkgname(const char *pkgname, bundle *kb); void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd); diff --git a/launchpad.pc.in b/launchpad.pc.in new file mode 100644 index 00000000..a3da8bfa --- /dev/null +++ b/launchpad.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=/usr +exec_prefix=@EXEC_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: liblaunchpad +Description: launchpad library for making other types of loader +Version: @VERSION@ +Requires: bundle dlog aul +Libs: -L${libdir} -llaunchpad +Cflags: -I${includedir} -I${includedir}/launchpad diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 73fad0eb..8d87f02c 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -52,10 +52,10 @@ export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" _APPFW_FEATURE_PRIORITY_CHANGE=ON %endif -cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \ - -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE} - -make %{?jobs:-j%jobs} +%cmake -DVERSION=%{version} \ + -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE} \ + . +%__make %{?_smp_mflags} %install rm -rf %{buildroot} @@ -83,4 +83,9 @@ cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{nam %{_unitdir_user}/default.target.wants/launchpad-process-pool.service %caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/launchpad-process-pool %caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/launchpad-loader +%attr(0644,root,root) %{_libdir}/liblaunchpad.so.* +%files devel +%{_includedir}/launchpad/*.h +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc diff --git a/src/launchpad.c b/src/launchpad.c index 09d20aaf..0d5e7425 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -34,6 +34,7 @@ #include "launchpad_common.h" #include "sigchild.h" #include "key.h" +#include "launchpad.h" #define AUL_PR_NAME 16 #define AUL_POLL_CNT 15 diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c new file mode 100644 index 00000000..c22cd3a4 --- /dev/null +++ b/src/launchpad_lib.c @@ -0,0 +1,382 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "launchpad_common.h" +#include "launchpad.h" +#include "preexec.h" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#define AUL_PR_NAME 16 +#define LOWEST_PRIO 20 + +static loader_lifecycle_callback_s *__loader_callbacks; +static loader_adapter_s *__loader_adapter; +static void *__loader_user_data; +static int __argc; +static char **__argv; +static bundle *__bundle; +static char *__appid; +static char *__pkgid; +static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED; + +static void __at_exit_to_release_bundle() +{ + if (__bundle) { + bundle_free(__bundle); + __bundle = NULL; + } +} + +static void __release_appid_at_exit(void) +{ + if (__appid != NULL) { + free(__appid); + } + if (__pkgid != NULL) { + free(__pkgid); + } +} + +static int __set_access(const char* appId, const char* pkg_type, + const char* app_path) +{ + return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1; +} + +static int __prepare_exec(const char *appid, const char *app_path, + const char *pkg_type, int type) +{ + const char *file_name = NULL; + char process_name[AUL_PR_NAME] = { 0, }; + int ret = 0; + + __preexec_run(pkg_type, appid, app_path); + + /* SET PRIVILEGES*/ + SECURE_LOGD("[candidata] appid : %s / pkg_type : %s / app_path : %s", + appid, pkg_type, app_path); + if ((ret = __set_access(appid, pkg_type, app_path)) < 0) { + _D("fail to set privileges - check your package's credential : %d\n", ret); + return -1; + } + + /* + * SET DUMPABLE - for coredump + * This dumpable flag should be set after calling perm_app_set_privilege() + */ + prctl(PR_SET_DUMPABLE, 1); + + /* SET PROCESS NAME*/ + if (app_path == NULL) { + _D("app_path should not be NULL - check menu db"); + return -1; + } + + file_name = strrchr(app_path, '/') + 1; + if (file_name == NULL) { + _D("can't locate file name to execute"); + return -1; + } + memset(process_name, '\0', AUL_PR_NAME); + snprintf(process_name, AUL_PR_NAME, "%s", file_name); + prctl(PR_SET_NAME, process_name); + + return 0; +} + +static int __default_launch_cb(bundle *kb, const char *appid, + const char *app_path, const char *pkg_type, int loader_type) +{ +#ifdef _APPFW_FEATURE_PRIORITY_CHANGE + const char *high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY); + _D("high_priority: %s", high_priority); + + if (strncmp(high_priority, "true", 4) == 0) { + int res = setpriority(PRIO_PROCESS, 0, -10); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to -10 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } + } + bundle_del(kb, AUL_K_HIGHPRIORITY); +#endif + + if (__prepare_exec(appid, app_path, pkg_type, loader_type) < 0) { + _E("__candidate_process_prepare_exec() failed"); + if (access(app_path, F_OK | R_OK)) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", + app_path, errno, strerror_r(errno, err_str, sizeof(err_str))); + } + exit(-1); + } + + return 0; +} + +static int __candidate_process_launchpad_main_loop(app_pkt_t* pkt, + char* out_app_path, int* out_argc, char ***out_argv, int type) +{ + bundle *kb = NULL; + app_info_from_db *menu_info = NULL; + const char *app_id = NULL; + const char *app_path = NULL; + const char *pkg_id = NULL; + int tmp_argc = 0; + char **tmp_argv = NULL; + int ret = -1; + + kb = bundle_decode(pkt->data, pkt->len); + if (!kb) { + _E("bundle decode error"); + exit(-1); + } + + if (__bundle != NULL) + bundle_free(__bundle); + + __bundle = kb; + atexit(__at_exit_to_release_bundle); + + app_id = bundle_get_val(kb, AUL_K_APPID); + if (app_id == NULL) { + _E("Unable to get app_id"); + exit(-1); + } + + menu_info = _get_app_info_from_bundle_by_pkgname(app_id, kb); + if (menu_info == NULL) { + _D("such pkg no found"); + exit(-1); + } + + if (type < 0) { + _E("Invalid launchpad type: %d", type); + exit(-1); + } + + SECURE_LOGD("app id: %s, launchpad type: %d", app_id, type); + + app_path = _get_app_path(menu_info); + if (app_path == NULL) { + _E("app_path is NULL"); + exit(-1); + } + + if (app_path[0] != '/') { + _E("app_path is not absolute path"); + exit(-1); + } + + _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); + + app_id = _get_pkgname(menu_info); + if (app_id == NULL) { + _E("unable to get app_id from menu_info"); + exit(-1); + } + SECURE_LOGD("app id: %s", app_id); + __appid = strdup(app_id); + if (__appid == NULL) { + _E("Out of memory"); + exit(-1); + } + aul_set_preinit_appid(__appid); + + pkg_id = _get_pkgid(menu_info); + if (pkg_id == NULL) { + _E("unable to get pkg_id from menu_info"); + exit(-1); + } + SECURE_LOGD("pkg id: %s", pkg_id); + + __pkgid = strdup(pkg_id); + if (__pkgid == NULL) { + _E("Out of memory"); + exit(-1); + } + aul_set_preinit_pkgid(__pkgid); + atexit(__release_appid_at_exit); + + tmp_argv = _create_argc_argv(kb, &tmp_argc); + + __default_launch_cb(kb, __appid, app_path, menu_info->pkg_type, type); + + if (__loader_callbacks->launch) { + ret = __loader_callbacks->launch(tmp_argc, tmp_argv, app_path, __appid, __pkgid, + menu_info->pkg_type, __loader_user_data); + } + + /* SET ENVIROMENT*/ + _set_env(menu_info, kb); + + if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) { + int i = 0; + + memset(out_app_path, '\0', strlen(out_app_path)); + sprintf(out_app_path, "%s", app_path); + + *out_argv = tmp_argv; + *out_argc = tmp_argc; + (*out_argv)[0] = out_app_path; + + for (i = 0; i < *out_argc; i++) + SECURE_LOGD("input argument %d : %s##", i, (*out_argv)[i]); + } else + exit(-1); + + if (menu_info != NULL) + _free_app_info_from_db(menu_info); + + return ret; +} + +static void __receiver_cb(int fd) +{ + _D("[candidate] ECORE_FD_READ"); + app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if (!pkt) { + _D("[candidate] out of memory1"); + exit(-1); + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + int ret = -1; + int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); + + if (recv_ret == -1) { + _D("[condidate] recv error!"); + close(fd); + free(pkt); + exit(-1); + } + _D("[candidate] recv_ret: %d, pkt->len: %d", recv_ret, pkt->len); + + __loader_adapter->remove_fd(__loader_user_data, fd); + ret = __candidate_process_launchpad_main_loop(pkt, __argv[0], &__argc, &__argv, + __loader_type); + SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", __argv[0], + __argc); + close(fd); + free(pkt); + + if (ret >= 0) { + __loader_adapter->loop_quit(__loader_user_data); + _D("[candidate] ecore main loop quit"); + } +} + +static int __before_loop(int argc, char **argv) +{ + int client_fd; + int ret = -1; + + client_fd = _connect_to_launchpad(__loader_type); + if (client_fd == -1) { + _D("Connecting to candidate process was failed."); + return -1; + } + +#ifdef _APPFW_FEATURE_BOOST_PRIORITY + int res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); + + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)", + getpid(), LOWEST_PRIO, errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + __preexec_init(argc, argv); + if (__loader_callbacks->create) { + __loader_callbacks->create(argc, argv, __loader_type, __loader_user_data); + __loader_adapter->add_fd(__loader_user_data, client_fd, __receiver_cb); + ret = 0; + } + +#ifdef _APPFW_FEATURE_BOOST_PRIORITY + res = setpriority(PRIO_PGRP, 0, 0); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + return ret; +} + +static int __after_loop(void) +{ + if (__loader_callbacks->terminate) { + return __loader_callbacks->terminate(__argc, __argv, __loader_user_data); + } + return -1; +} + + +API int launchpad_loader_main(int argc, char **argv, + loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, + void *user_data) +{ + if (argc < 2) { + _E("too few argument."); + return -1; + } + + __loader_type = argv[1][0] - '0'; + if (__loader_type < 0 || __loader_type >= LAUNCHPAD_TYPE_MAX) { + _E("invalid argument. (type: %d)", __loader_type); + return -1; + } + + if (callbacks == NULL) { + _E("invalid argument. callback is null"); + return -1; + } + + if (adapter == NULL) { + _E("invalid argument. adapter is null"); + return -1; + } + + if (adapter->loop_begin == NULL || adapter->loop_quit == NULL + || adapter->add_fd == NULL || adapter->remove_fd == NULL) { + _E("invalid argument. adapter callback is null"); + return -1; + } + + __loader_callbacks = callbacks; + __loader_adapter = adapter; + __loader_user_data = user_data; + __argc = argc; + __argv = argv; + + //temp - this requires some optimization. + sleep(1); + _D("sleeping 1 sec..."); + + if (__before_loop(argc, argv) != 0) + return -1; + + _D("[candidate] ecore main loop begin"); + __loader_adapter->loop_begin(__loader_user_data); + + return __after_loop(); +} + + diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index b755989d..8f081c71 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -17,282 +17,21 @@ #define _GNU_SOURCE #include #include -#include #include -#include #include #include -#include -#include #include -#include #include -#include #include #include "menu_db_util.h" #include "launchpad_common.h" #include "preload.h" #include "process_pool_preload.h" -#include "preexec.h" +#include "launchpad.h" - -#define AUL_PR_NAME 16 -#define LOWEST_PRIO 20 - -static char *__appid; -static char *__pkgid; -static bundle *_s_bundle; - -static int __set_access(const char* appId, const char* pkg_type, - const char* app_path) -{ - return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1; -} - -static int __candidate_process_prepare_exec(const char *pkg_name, - const char *app_path, app_info_from_db *menu_info, - bundle *kb, int type) -{ - const char *file_name = NULL; - char process_name[AUL_PR_NAME] = { 0, }; - int ret = 0; - - __preexec_run(menu_info->pkg_type, pkg_name, app_path); - - /* SET PRIVILEGES*/ - SECURE_LOGD("[candidata] pkg_name : %s / pkg_type : %s / app_path : %s", - pkg_name, menu_info->pkg_type, app_path); - if ((ret = __set_access(pkg_name, menu_info->pkg_type, app_path)) < 0) { - _D("fail to set privileges - check your package's credential : %d\n", ret); - return -1; - } - - /* - * SET DUMPABLE - for coredump - * This dumpable flag should be set after calling perm_app_set_privilege() - */ - prctl(PR_SET_DUMPABLE, 1); - - /* SET PROCESS NAME*/ - if (app_path == NULL) { - _D("app_path should not be NULL - check menu db"); - return -1; - } - - file_name = strrchr(app_path, '/') + 1; - if (file_name == NULL) { - _D("can't locate file name to execute"); - return -1; - } - memset(process_name, '\0', AUL_PR_NAME); - snprintf(process_name, AUL_PR_NAME, "%s", file_name); - prctl(PR_SET_NAME, process_name); - - /* SET ENVIROMENT*/ - _set_env(menu_info, kb); - - return 0; -} - -static void __at_exit_to_release_bundle() -{ - if (_s_bundle) { - bundle_free(_s_bundle); - _s_bundle = NULL; - } -} - -static void __release_appid_at_exit(void) -{ - if (__appid != NULL) { - free(__appid); - } - if (__pkgid != NULL) { - free(__pkgid); - } -} - -static void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, - char* out_app_path, int* out_argc, char ***out_argv, - int type) -{ - bundle *kb = NULL; - app_info_from_db *menu_info = NULL; - - const char *app_id = NULL; - const char *app_path = NULL; - const char *pkg_id = NULL; - - kb = bundle_decode(pkt->data, pkt->len); - if (!kb) { - _E("bundle decode error"); - exit(-1); - } - - if (_s_bundle != NULL) - bundle_free(_s_bundle); - - _s_bundle = kb; - atexit(__at_exit_to_release_bundle); - - app_id = bundle_get_val(kb, AUL_K_APPID); - if (app_id == NULL) { - _E("Unable to get app_id"); - exit(-1); - } - - menu_info = _get_app_info_from_bundle_by_pkgname(app_id, kb); - if (menu_info == NULL) { - _D("such pkg no found"); - exit(-1); - } - - if (type < 0) { - _E("Invalid launchpad type: %d", type); - exit(-1); - } - - SECURE_LOGD("app id: %s, launchpad type: %d", app_id, type); - - app_path = _get_app_path(menu_info); - if (app_path == NULL) { - _E("app_path is NULL"); - exit(-1); - } - - if (app_path[0] != '/') { - _E("app_path is not absolute path"); - exit(-1); - } - - _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); - - // caching appid - app_id = _get_pkgname(menu_info); - if (app_id == NULL) { - _E("unable to get app_id from menu_info"); - exit(-1); - } - SECURE_LOGD("app id: %s", app_id); - __appid = strdup(app_id); - if (__appid == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_appid(__appid); - - // caching pkgid - pkg_id = _get_pkgid(menu_info); - if (pkg_id == NULL) { - _E("unable to get pkg_id from menu_info"); - exit(-1); - } - SECURE_LOGD("pkg id: %s", pkg_id); - - __pkgid = strdup(pkg_id); - if (__pkgid == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_pkgid(__pkgid); - - atexit(__release_appid_at_exit); - -#ifdef _APPFW_FEATURE_PRIORITY_CHANGE - const char *high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY); - _D("high_priority: %s", high_priority); - - if (strncmp(high_priority, "true", 4) == 0) { - int res = setpriority(PRIO_PROCESS, 0, -10); - if (res == -1) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("Setting process (%d) priority to -10 failed, errno: %d (%s)", - getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); - } - } - bundle_del(kb, AUL_K_HIGHPRIORITY); -#endif - - if (__candidate_process_prepare_exec(app_id, app_path, menu_info, kb, - type) < 0) { - _E("__candidate_process_prepare_exec() failed"); - if (access(app_path, F_OK | R_OK)) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", - app_path, errno, strerror_r(errno, err_str, sizeof(err_str))); - } - exit(-1); - } - - if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) { - int i = 0; - - memset(out_app_path, '\0', strlen(out_app_path)); - sprintf(out_app_path, "%s", app_path); - - *out_argv = _create_argc_argv(kb, out_argc); - (*out_argv)[0] = out_app_path; - - for (i = 0; i < *out_argc; i++) - SECURE_LOGD("input argument %d : %s##", i, (*out_argv)[i]); - } else - exit(-1); - - if (menu_info != NULL) - _free_app_info_from_db(menu_info); -} - -static Eina_Bool __candidate_proces_fd_handler(void* data, - Ecore_Fd_Handler *handler) -{ - int type = data ? *((int *)data) : LAUNCHPAD_TYPE_UNSUPPORTED; - int fd = ecore_main_fd_handler_fd_get(handler); - - if (fd == -1) { - _D("[candidate] ECORE_FD_GET"); - exit(-1); - } - - if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) { - _D("[candidate] ECORE_FD_ERROR"); - close(fd); - exit(-1); - } - - if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) { - _D("[candidate] ECORE_FD_READ"); - app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); - if (!pkt) { - _D("[candidate] out of memory1"); - exit(-1); - } - memset(pkt, 0, AUL_SOCK_MAXBUFF); - - int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); - close(fd); - if (recv_ret == -1) { - _D("[condidate] recv error!"); - free(pkt); - exit(-1); - } - _D("[candidate] recv_ret: %d, pkt->len: %d", recv_ret, pkt->len); - - ecore_main_fd_handler_del(handler); - - __candidate_process_launchpad_main_loop(pkt, g_argv[0], &g_argc, &g_argv, type); - SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", g_argv[0], - g_argc); - free(pkt); - - ecore_main_loop_quit(); - _D("[candidate] ecore main loop quit"); - } - - return ECORE_CALLBACK_CANCEL; -} +static Ecore_Fd_Handler *__fd_handler; +static loader_receiver_cb __receiver; static void __init_window(void) { @@ -334,26 +73,12 @@ static void __init_theme(void) free(theme); } -static int __before_loop(int type, int argc, char **argv) +static void __loader_create_cb(int argc, char **argv, int type, void *user_data) { int elm_init_cnt = 0; - Ecore_Fd_Handler *fd_handler = NULL; - int client_fd; __preload_init(argc, argv); __preload_init_for_process_pool(); - __preexec_init(argc, argv); - -#ifdef _APPFW_FEATURE_BOOST_PRIORITY - res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); - if (res == -1) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)", - getpid(), LOWEST_PRIO, errno, strerror_r(errno, err_str, sizeof(err_str))); - } -#endif - _D("[candidate] Another candidate process was forked."); /* Set new session ID & new process group ID*/ /* In linux, child can set new session ID without check permission */ @@ -363,12 +88,6 @@ static int __before_loop(int type, int argc, char **argv) /* SET OOM*/ _set_oom(); - client_fd = _connect_to_launchpad(type); - if (client_fd == -1) { - _D("Connecting to candidate process was failed."); - return -1; - } - elm_init_cnt = elm_init(g_argc, g_argv); _D("[candidate] elm init, returned: %d", elm_init_cnt); @@ -387,36 +106,22 @@ static int __before_loop(int type, int argc, char **argv) __init_theme(); break; } +} - fd_handler = ecore_main_fd_handler_add(client_fd, - (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), - __candidate_proces_fd_handler, &type, NULL, NULL); - if (fd_handler == NULL) { - _D("fd_handler is NULL"); - return -1; - } - - _D("[candidate] ecore handler add"); -#ifdef _APPFW_FEATURE_BOOST_PRIORITY - res = setpriority(PRIO_PGRP, 0, 0); - if (res == -1) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)", - getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); - } -#endif +static int __loader_launch_cb(int argc, char **argv, const char *app_path, + const char *appid, const char *pkgid, const char *pkg_type, void *user_data) +{ return 0; } -static int __after_loop(void) +static int __loader_terminate_cb(int argc, char **argv, void *user_data) { void *handle = NULL; int res; int (*dl_main)(int, char **); - SECURE_LOGD("[candidate] Launch real application (%s)", g_argv[0]); - handle = dlopen(g_argv[0], RTLD_LAZY | RTLD_GLOBAL); + SECURE_LOGD("[candidate] Launch real application (%s)", argv[0]); + handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL); if (handle == NULL) { _E("dlopen failed(%s). Please complile with -fPIE and link with -pie flag", dlerror()); @@ -427,7 +132,7 @@ static int __after_loop(void) dl_main = dlsym(handle, "main"); if (dl_main != NULL) - res = dl_main(g_argc, g_argv); + res = dl_main(argc, argv); else { _E("dlsym not founded(%s). Please export 'main' function", dlerror()); dlclose(handle); @@ -438,48 +143,96 @@ static int __after_loop(void) return res; do_exec: - if (access(g_argv[0], F_OK | R_OK)) { + if (access(argv[0], F_OK | R_OK)) { char err_str[MAX_LOCAL_BUFSZ] = { 0, }; SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", - g_argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); + argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); } else { SECURE_LOGD("[candidate] Exec application (%s)", g_argv[0]); - if (execv(g_argv[0], g_argv) < 0) { + if (execv(argv[0], argv) < 0) { char err_str[MAX_LOCAL_BUFSZ] = { 0, }; SECURE_LOGE("execv() failed for file: \"%s\", error: %d (%s)", - g_argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); + argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); } } return -1; + } -int main(int argc, char **argv) +static Eina_Bool __process_fd_handler(void* data, Ecore_Fd_Handler *handler) { - static int type = LAUNCHPAD_TYPE_UNSUPPORTED; + int fd = ecore_main_fd_handler_fd_get(handler); - if (argc < 2) { - _E("too few argument."); - return -1; + if (fd == -1) { + _D("[candidate] ECORE_FD_GET"); + exit(-1); } - type = argv[1][0] - '0'; - if (type < 0 || type >= LAUNCHPAD_TYPE_MAX) { - _E("invalid argument. (type: %d)", type); - return -1; + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) { + _D("[candidate] ECORE_FD_ERROR"); + close(fd); + exit(-1); } - //temp - this requires some optimization. - sleep(1); - _D("sleeping 1 sec..."); + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) { + if (__receiver) + __receiver(fd); + } - if (__before_loop(type, argc, argv) != 0) - return -1; + return ECORE_CALLBACK_CANCEL; +} - _D("[candidate] ecore main loop begin"); +static void __adapter_loop_begin(void *user_data) +{ ecore_main_loop_begin(); +} + +static void __adapter_loop_quit(void *user_data) +{ + ecore_main_loop_quit(); +} - return __after_loop(); +static void __adapter_add_fd(void *user_data, int fd, + loader_receiver_cb receiver) +{ + __fd_handler = ecore_main_fd_handler_add(fd, + (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), + __process_fd_handler, NULL, NULL, NULL); + if (__fd_handler == NULL) { + _D("fd_handler is NULL"); + close(fd); + exit(-1); + } + + __receiver = receiver; +} + +static void __adapter_remove_fd(void *user_data, int fd) +{ + if (__fd_handler) { + ecore_main_fd_handler_del(__fd_handler); + __fd_handler = NULL; + __receiver = NULL; + } +} + +int main(int argc, char **argv) +{ + loader_lifecycle_callback_s callbacks = { + .create = __loader_create_cb, + .launch = __loader_launch_cb, + .terminate = __loader_terminate_cb + }; + + loader_adapter_s adapter = { + .loop_begin = __adapter_loop_begin, + .loop_quit = __adapter_loop_quit, + .add_fd = __adapter_add_fd, + .remove_fd = __adapter_remove_fd + }; + + return launchpad_loader_main(argc, argv, &callbacks, &adapter, NULL); }