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
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")
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")
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})
) # 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
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)
+
+
+
--- /dev/null
+/*
+ * 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__ */
+
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);
--- /dev/null
+# 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
_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}
%{_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
#include "launchpad_common.h"
#include "sigchild.h"
#include "key.h"
+#include "launchpad.h"
#define AUL_PR_NAME 16
#define AUL_POLL_CNT 15
--- /dev/null
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/prctl.h>
+#include <bundle_internal.h>
+#include <aul.h>
+#include <security-manager.h>
+
+#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();
+}
+
+
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
-#include <poll.h>
#include <sys/prctl.h>
-#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
-#include <grp.h>
-#include <pwd.h>
#include <Elementary.h>
-#include <Ecore.h>
#include <bundle_internal.h>
-#include <security-manager.h>
#include <aul.h>
#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)
{
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 */
/* 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);
__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());
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);
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);
}