add library for making launchpad-loader 35/51735/4 accepted/tizen/mobile/20151116.074826 accepted/tizen/tv/20151116.074843 accepted/tizen/wearable/20151116.074850 submit/tizen/20151116.052223
authorJunghoon, Park <jh9216.park@samsung.com>
Fri, 13 Nov 2015 08:45:35 +0000 (17:45 +0900)
committerJunghoon, Park <jh9216.park@samsung.com>
Mon, 16 Nov 2015 02:42:35 +0000 (11:42 +0900)
Change-Id: Ic929c89fa1f8b77172846423a1658009b142a99e
Signed-off-by: Junghoon, Park <jh9216.park@samsung.com>
CMakeLists.txt
inc/launchpad.h [new file with mode: 0644]
inc/launchpad_common.h
launchpad.pc.in [new file with mode: 0644]
packaging/launchpad.spec
src/launchpad.c
src/launchpad_lib.c [new file with mode: 0644]
src/launchpad_loader.c

index 867449e89abb3e1ef985e6d9637c24ca24bbddde..0eccf724de905b5e685f6b6e0edf9f126a2d4d7f 100755 (executable)
@@ -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 (file)
index 0000000..37d50ed
--- /dev/null
@@ -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__ */
+
index e677be7354fe66d3b5213fb40d0520a64f11d115..0934a0ce3346329ba2494ee107c1f3e37818e2e4 100644 (file)
@@ -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 (file)
index 0000000..a3da8bf
--- /dev/null
@@ -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
index 73fad0eb09223933567163a1dcf591dea5555b0d..8d87f02c1ffa94edb3868a43ad976fd8fffa7e8a 100644 (file)
@@ -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
index 09d20aaf508669cb5ecf34ed9cc22d6520a80cff..0d5e7425b0290d8b8ce7747de84c60a1e6873ca2 100755 (executable)
@@ -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 (file)
index 0000000..c22cd3a
--- /dev/null
@@ -0,0 +1,382 @@
+#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();
+}
+
+
index b755989d4239a8d016da32737d9501973e956e14..8f081c71562d107c0289dd661004f8ffa1803921 100644 (file)
 #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)
 {
@@ -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);
 }