tizen 2.4 release accepted/tizen/2.4/mobile/20151029.033953 submit/tizen_2.4/20151028.063852 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:31:12 +0000 (16:31 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:31:12 +0000 (16:31 +0900)
18 files changed:
CMakeLists.txt [changed mode: 0644->0755]
launchpad.manifest
native/launchpad_native.c [deleted file]
native/native_preload.h [deleted file]
packaging/launchpad-native-preload-list.txt [deleted file]
packaging/launchpad-native.service [deleted file]
packaging/launchpad-process-pool.service
packaging/launchpad.spec
packaging/preload_list.txt [new file with mode: 0644]
process_pool/config.h [new file with mode: 0644]
process_pool/launchpad.c [changed mode: 0644->0755]
process_pool/launchpad_loader.c [new file with mode: 0644]
process_pool/preload.h [new file with mode: 0644]
process_pool/process_pool.c
process_pool/process_pool.h
process_pool/process_pool_preload.h
process_pool/sigchild.h [new file with mode: 0644]
process_pool/smack_util.c

old mode 100644 (file)
new mode 100755 (executable)
index ad5dc07..a74e5db
@@ -3,6 +3,9 @@ SET (this_target launchpad)
 
 INCLUDE(FindPkgConfig)
 PKG_CHECK_MODULES(${this_target} REQUIRED
+       gobject-2.0
+       gio-2.0
+       glib-2.0
        aul
        dlog
        ecore
@@ -11,6 +14,8 @@ PKG_CHECK_MODULES(${this_target} REQUIRED
        deviced
        elementary
        libsystemd-daemon
+       dbus-glib-1
+       vconf
        )
 
 FOREACH(flag ${${this_target}_CFLAGS})
@@ -19,7 +24,7 @@ ENDFOREACH(flag)
 
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -D_FILE_OFFSET_BITS=64")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I/usr/include/aul/launch -I/usr/include/aul/launchpad")
@@ -42,6 +47,26 @@ ADD_DEFINITIONS("-D_APPFW_FEATURE_PROCESS_POOL")
 IF(_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING)
        ADD_DEFINITIONS("-D_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING")
 ENDIF(_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING)
+IF(_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING)
+       ADD_DEFINITIONS("-D_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING")
+ENDIF(_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING)
+
+SET(LAUNCHPAD_LOADER "launchpad-loader")
+SET(${LAUNCHPAD_LOADER}_SOURCE_FILES
+       process_pool/launchpad_loader.c
+       process_pool/process_pool.c
+       process_pool/smack_util.c
+       )
+ADD_EXECUTABLE(${LAUNCHPAD_LOADER} ${${LAUNCHPAD_LOADER}_SOURCE_FILES})
+
+TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} aul)
+TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} "-ldl")
+TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} ${${this_target}_LDFLAGS} "-pie")
+
+SET_TARGET_PROPERTIES(${LAUNCHPAD_LOADER}
+       PROPERTIES SKIP_BUILD_RPATH TRUE
+       ) # remove rpath option that is automatically generated by cmake.
+INSTALL(TARGETS ${LAUNCHPAD_LOADER} DESTINATION bin)
 
 SET(LAUNCHPAD_PROCESS_POOL "launchpad-process-pool")
 
@@ -52,38 +77,15 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES
        )
 ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES})
 
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} aul_mods launchpad_common)
+TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} aul_mods)
 TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} aul)
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} "-ldl -pie")
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} ${${this_target}_LDFLAGS})
+TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} ${${this_target}_LDFLAGS} "-pie")
 
 SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL}
        PROPERTIES SKIP_BUILD_RPATH TRUE
        ) # remove rpath option that is automatically generated by cmake.
 
 INSTALL(TARGETS ${LAUNCHPAD_PROCESS_POOL} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/preload_list.txt DESTINATION share/aul)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/launchpad-process-pool-preload-list.txt DESTINATION share/aul)
 ENDIF(_APPFW_FEATURE_PROCESS_POOL)
-
-IF(_APPFW_FEATURE_NATIVE_LAUNCHPAD)
-ADD_DEFINITIONS("-D_APPFW_FEATURE_NATIVE_LAUNCHPAD")
-
-SET(LAUNCHPAD_NATIVE "launchpad-native")
-
-SET(${LAUNCHPAD_NATIVE}_SOURCE_FILES
-       native/launchpad_native.c
-       )
-ADD_EXECUTABLE(${LAUNCHPAD_NATIVE} ${${LAUNCHPAD_NATIVE}_SOURCE_FILES})
-
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_NATIVE} aul_mods launchpad_common)
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_NATIVE} aul)
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_NATIVE} "-ldl")
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_NATIVE} ${${this_target}_LDFLAGS})
-
-SET_TARGET_PROPERTIES(${LAUNCHPAD_NATIVE}
-       PROPERTIES SKIP_BUILD_RPATH TRUE
-       ) # remove rpath option that is automatically generated by cmake.
-
-INSTALL(TARGETS ${LAUNCHPAD_NATIVE} DESTINATION bin)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/launchpad-native-preload-list.txt DESTINATION share/aul)
-ENDIF(_APPFW_FEATURE_NATIVE_LAUNCHPAD)
index 4302722..fe5b8fc 100644 (file)
@@ -9,7 +9,15 @@
                        <smack request="sound_server" type="rwx"/>
                        <smack request="system::homedir" type="rwxat"/>
                        <smack request="pulseaudio" type="rwxat"/>
+                       <smack request="xorg" type="rw"/>
+                       <smack request="dbus" type="rwxa"/>
+                       <smack request="isf" type="rwx"/>
+                       <smack request="device::sys_logging" type="w"/>
                </request>
+               <permit>
+                       <smack permit="dbus" type="rwxa"/>
+                       <smack permit="xorg" type="rwx"/>
+               </permit>
        </define>
        <request>
                <domain name="launchpad"/>
diff --git a/native/launchpad_native.c b/native/launchpad_native.c
deleted file mode 100644 (file)
index f9409e6..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <X11/Xlib.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <poll.h>
-#include <sys/prctl.h>
-#include <malloc.h>
-#include <sys/resource.h>
-
-#include "app_sock.h"
-#include "aul.h"
-
-#include "config.h"
-
-#include "menu_db_util.h"
-#include "simple_util.h"
-#include "access_control.h"
-#include "preload.h"
-#include "preexec.h"
-#include "perf.h"
-#include "sigchild.h"
-#include "aul_util.h"
-
-#include "heap_dbg.h"
-
-#include "util_x.h"
-
-#include "gl.h"
-
-#include <sqlite3.h>
-
-#include "native_preload.h"
-
-#define _static_ static inline
-#define POLLFD_MAX 1
-#define SQLITE_FLUSH_MAX       (1048576)       /* (1024*1024) */
-#define AUL_POLL_CNT           15
-#define AUL_PR_NAME                    16
-
-
-static char *launchpad_cmdline;
-static char *__appid = NULL;
-static int initialized = 0;
-
-_static_ void __set_env(app_info_from_db * menu_info, bundle * kb);
-_static_ int __prepare_exec(const char *pkg_name,
-                           const char *app_path, app_info_from_db * menu_info,
-                           bundle * kb);
-_static_ int __fake_launch_app(int cmd, int pid, bundle * kb);
-_static_ char **__create_argc_argv(bundle * kb, int *margc);
-_static_ int __normal_fork_exec(int argc, char **argv);
-_static_ void __real_launch(const char *app_path, bundle * kb);
-static inline int __parser(const char *arg, char *out, int out_size);
-_static_ void __modify_bundle(bundle * kb, int caller_pid,
-                           app_info_from_db * menu_info, int cmd);
-_static_ int __child_raise_win_by_x(int pid, void *priv);
-_static_ int __raise_win_by_x(int pid);
-_static_ int __send_to_sigkill(int pid);
-_static_ int __term_app(int pid);
-_static_ int __resume_app(int pid);
-_static_ int __real_send(int clifd, int ret);
-_static_ void __send_result_to_caller(int clifd, int ret);
-_static_ void __launchpad_main_loop(int main_fd);
-_static_ int __launchpad_pre_init(int argc, char **argv);
-_static_ int __launchpad_post_init();
-
-extern ail_error_e ail_db_close(void);
-
-_static_ void __set_env(app_info_from_db * menu_info, bundle * kb)
-{
-       const char *str;
-
-       setenv("PKG_NAME", _get_pkgname(menu_info), 1);
-
-       USE_ENGINE("gl")
-
-       str = bundle_get_val(kb, AUL_K_STARTTIME);
-       if (str != NULL)
-               setenv("APP_START_TIME", str, 1);
-
-       if (menu_info->hwacc != NULL)
-               setenv("HWACC", menu_info->hwacc, 1);
-       if (menu_info->taskmanage != NULL)
-               setenv("TASKMANAGE", menu_info->taskmanage, 1);
-}
-
-_static_ int __prepare_exec(const char *pkg_name,
-                           const char *app_path, app_info_from_db * menu_info,
-                           bundle * kb)
-{
-       char *file_name;
-       char process_name[AUL_PR_NAME];
-       int ret;
-
-       /* Set new session ID & new process group ID*/
-       /* In linux, child can set new session ID without check permission */
-       /* TODO : should be add to check permission in the kernel*/
-       setsid();
-
-       __preexec_run(menu_info->pkg_type, pkg_name, app_path);
-
-       /* SET PRIVILEGES*/
-       SECURE_LOGD("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*/
-       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_ int __fake_launch_app(int cmd, int pid, bundle * kb)
-{
-       int datalen;
-       int ret;
-       bundle_raw *kb_data;
-
-       bundle_encode(kb, &kb_data, &datalen);
-       if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
-               _E("error request fake launch - error code = %d", ret);
-       free(kb_data);
-       return ret;
-}
-
-_static_ char **__create_argc_argv(bundle * kb, int *margc)
-{
-       char **argv;
-       int argc;
-
-       argc = bundle_export_to_argv(kb, &argv);
-
-       *margc = argc;
-       return argv;
-}
-
-_static_ int __normal_fork_exec(int argc, char **argv)
-{
-       _D("start real fork and exec\n");
-
-#ifdef _APPFW_FEATURE_PRIORITY_CHANGE
-       int res = setpriority(PRIO_PROCESS, 0, 0);
-       if (res == -1)
-       {
-               SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)",
-                               getpid(), errno, strerror(errno));
-       }
-#endif
-       if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
-               if (errno == EACCES)
-                       _E("such a file is no executable - %s", argv[0]);
-               else
-                       _E("unknown executable error - %s", argv[0]);
-               return -1;
-       }
-       /* never reach*/
-       return 0;
-}
-
-_static_ void __real_launch(const char *app_path, bundle * kb)
-{
-       int app_argc;
-       char **app_argv;
-       int i;
-
-       app_argv = __create_argc_argv(kb, &app_argc);
-       app_argv[0] = strdup(app_path);
-
-       for (i = 0; i < app_argc; i++) {
-               if( (i%2) == 1)
-                       continue;
-               SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
-       }
-
-       PERF("setup argument done");
-
-       /* Temporary log: launch time checking */
-       SECURE_LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
-
-       __preload_exec(app_argc, app_argv);
-
-       __normal_fork_exec(app_argc, app_argv);
-}
-
-
-/*
- * Parsing original app path to retrieve default bundle
- *
- * -1 : Invalid sequence
- * -2 : Buffer overflow
- *
- */
-static inline int __parser(const char *arg, char *out, int out_size)
-{
-       register int i;
-       int state = 1;
-       char *start_out = out;
-
-       if (arg == NULL || out == NULL) {
-               /* Handles null buffer*/
-               return 0;
-       }
-
-       for (i = 0; out_size > 1; i++) {
-               switch (state) {
-               case 1:
-                       switch (arg[i]) {
-                       case ' ':
-                       case '\t':
-                               state = 5;
-                               break;
-                       case '\0':
-                               state = 7;
-                               break;
-                       case '\"':
-                               state = 2;
-                               break;
-                       case '\\':
-                               state = 4;
-                               break;
-                       default:
-                               *out = arg[i];
-                               out++;
-                               out_size--;
-                               break;
-                       }
-                       break;
-               case 2: /* escape start*/
-                       switch (arg[i]) {
-                       case '\0':
-                               state = 6;
-                               break;
-                       case '\"':
-                               state = 1;
-                               break;
-                       default:
-                               *out = arg[i];
-                               out++;
-                               out_size--;
-                               break;
-                       }
-                       break;
-               case 4: /* character escape*/
-                       if (arg[i] == '\0') {
-                               state = 6;
-                       } else {
-                               *out = arg[i];
-                               out++;
-                               out_size--;
-                               state = 1;
-                       }
-                       break;
-               case 5: /* token*/
-                       if (out != start_out) {
-                               *out = '\0';
-                               out_size--;
-                               return i;
-                       }
-                       i--;
-                       state = 1;
-                       break;
-               case 6:
-                       return -1;      /* error*/
-               case 7: /* terminate*/
-                       *out = '\0';
-                       out_size--;
-                       return 0;
-               default:
-                       state = 6;
-                       break;  /* error*/
-               }
-       }
-
-       if (out_size == 1) {
-               *out = '\0';
-       }
-       /* Buffer overflow*/
-       return -2;
-}
-
-_static_ void __modify_bundle(bundle * kb, int caller_pid,
-                           app_info_from_db * menu_info, int cmd)
-{
-       bundle_del(kb, AUL_K_PKG_NAME);
-       bundle_del(kb, AUL_K_EXEC);
-       bundle_del(kb, AUL_K_PACKAGETYPE);
-       bundle_del(kb, AUL_K_HWACC);
-       bundle_del(kb, AUL_K_TASKMANAGE);
-
-       /* Parse app_path to retrieve default bundle*/
-       if (cmd == APP_START
-               || cmd == APP_START_RES
-               || cmd == APP_START_ASYNC
-#ifdef _APPFW_FEATURE_MULTI_INSTANCE
-               || cmd == APP_START_MULTI_INSTANCE
-#endif
-               || cmd == APP_OPEN
-               || cmd == APP_RESUME
-               ) {
-               char *ptr;
-               char exe[MAX_PATH_LEN];
-               int flag;
-
-               ptr = _get_original_app_path(menu_info);
-
-               flag = __parser(ptr, exe, sizeof(exe));
-               if (flag > 0) {
-                       char key[256];
-                       char value[256];
-
-                       ptr += flag;
-                       SECURE_LOGD("parsing app_path: EXEC - %s\n", exe);
-
-                       do {
-                               flag = __parser(ptr, key, sizeof(key));
-                               if (flag <= 0)
-                                       break;
-                               ptr += flag;
-
-                               flag = __parser(ptr, value, sizeof(value));
-                               if (flag < 0)
-                                       break;
-                               ptr += flag;
-
-                               /*bundle_del(kb, key);*/
-                               bundle_add(kb, key, value);
-                       } while (flag > 0);
-               } else if (flag == 0) {
-                       _D("parsing app_path: No arguments\n");
-               } else {
-                       _D("parsing app_path: Invalid argument\n");
-               }
-       }
-}
-
-_static_ int __child_raise_win_by_x(int pid, void *priv)
-{
-       return x_util_raise_win(pid);
-}
-
-_static_ int __raise_win_by_x(int pid)
-{
-       int pgid;
-       if (x_util_raise_win(pid) == 0)
-               return 0;
-
-       /* support app launched by shell script*/
-       pgid = getpgid(pid);
-       _D("X raise failed. try to find first child & raise it - c:%d p:%d\n",
-          pgid, pid);
-
-       if (pgid <= 1)
-               return -1;
-       if (__proc_iter_pgid(pgid, __child_raise_win_by_x, NULL) < 0)
-               return -1;
-
-       return 0;
-}
-
-_static_ int __send_to_sigkill(int pid)
-{
-       int pgid;
-
-       pgid = getpgid(pid);
-       if (pgid <= 1)
-               return -1;
-
-       if (killpg(pgid, SIGKILL) < 0)
-               return -1;
-
-       return 0;
-}
-
-_static_ int __term_app(int pid)
-{
-       int dummy;
-       if (__app_send_raw
-           (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
-               _D("terminate packet send error - use SIGKILL");
-               if (__send_to_sigkill(pid) < 0) {
-                       _E("fail to killing - %d\n", pid);
-                       return -1;
-               }
-       }
-       _D("term done\n");
-       return 0;
-}
-
-_static_ int __resume_app(int pid)
-{
-       int dummy;
-       int ret;
-       if ((ret =
-            __app_send_raw(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy,
-                           sizeof(int))) < 0) {
-               if (ret == -EAGAIN)
-                       _E("resume packet timeout error");
-               else {
-                       _D("resume packet send error - use raise win");
-                       if (__raise_win_by_x(pid) < 0) {
-                               _E("raise failed - %d resume fail\n", pid);
-                               _E("we will term the app - %d\n", pid);
-                               __send_to_sigkill(pid);
-                               ret = -1;
-                       } else
-                               ret = 0;
-               }
-       }
-       _D("resume done\n");
-       return ret;
-}
-
-static int __get_caller_pid(bundle *kb)
-{
-       const char *pid_str;
-       int pid;
-
-       pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
-       if(pid_str)
-               goto end;
-
-       pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
-       if (pid_str == NULL)
-               return -1;
-
-end:
-       pid = atoi(pid_str);
-       if (pid <= 1)
-               return -1;
-
-       return pid;
-}
-
-_static_ int __foward_cmd(int cmd, bundle *kb, int cr_pid)
-{
-       int pid;
-       char tmp_pid[MAX_PID_STR_BUFSZ];
-       int datalen;
-       bundle_raw *kb_data;
-       int res;
-
-       if ((pid = __get_caller_pid(kb)) < 0)
-                       return AUL_R_ERROR;
-
-       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
-
-       bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
-
-       bundle_encode(kb, &kb_data, &datalen);
-       if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
-               res = AUL_R_ERROR;
-
-       free(kb_data);
-
-       return res;
-}
-
-_static_ int __real_send(int clifd, int ret)
-{
-       if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
-               if (errno == EPIPE) {
-                       _E("send failed due to EPIPE.\n");
-                       close(clifd);
-                       return -1;
-               }
-               _E("send fail to client");
-       }
-
-       close(clifd);
-       return 0;
-}
-
-_static_ void __send_result_to_caller(int clifd, int ret)
-{
-       char *cmdline;
-       int wait_count;
-       int cmdline_changed = 0;
-       int cmdline_exist = 0;
-       int r;
-
-       if (clifd == -1)
-               return;
-
-       if (ret <= 1) {
-               __real_send(clifd, ret);
-               return;
-       }
-       /* check normally was launched?*/
-       wait_count = 1;
-       do {
-               cmdline = __proc_get_cmdline_bypid(ret);
-               if (cmdline == NULL) {
-                       _E("error founded when being launched with %d", ret);
-
-               } else if (strcmp(cmdline, launchpad_cmdline)) {
-                       free(cmdline);
-                       cmdline_changed = 1;
-                       break;
-               } else {
-                       cmdline_exist = 1;
-                       free(cmdline);
-               }
-
-               _D("-- now wait to change cmdline --");
-               usleep(100 * 1000);     /* 50ms sleep*/
-               wait_count++;
-       } while (wait_count <= 20);     /* max 100*20ms will be sleep*/
-
-       if ((!cmdline_exist) && (!cmdline_changed)) {
-               __real_send(clifd, -1); /* abnormally launched*/
-               return;
-       }
-
-       if (!cmdline_changed)
-               _E("process launched, but cmdline not changed");
-
-       if(__real_send(clifd, ret) < 0) {
-               r = kill(ret, SIGKILL);
-               if (r == -1)
-                       _E("send SIGKILL: %s", strerror(errno));
-       }
-
-       return;
-}
-
-static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
-                                                       const char *pkgname, bundle *kb)
-{
-       app_info_from_db *menu_info;
-
-       menu_info = calloc(1, sizeof(app_info_from_db));
-       if (menu_info == NULL) {
-               return NULL;
-       }
-
-       menu_info->pkg_name = strdup(pkgname);
-       menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
-       if (menu_info->app_path != NULL)
-               menu_info->original_app_path = strdup(menu_info->app_path);
-       menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
-       menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
-       menu_info->taskmanage = strdup(bundle_get_val(kb, AUL_K_TASKMANAGE));
-
-       if (!_get_app_path(menu_info)) {
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       return menu_info;
-}
-
-static void __release_appid_at_exit(void)
-{
-       if (__appid != NULL) {
-               free(__appid);
-       }
-}
-
-_static_ void __launchpad_main_loop(int main_fd)
-{
-       bundle *kb = NULL;
-       app_pkt_t *pkt = NULL;
-       app_info_from_db *menu_info = NULL;
-
-       const char *pkg_name = NULL;
-       const char *app_path = NULL;
-       int pid = -1;
-       int clifd = -1;
-       struct ucred cr;
-       int is_real_launch = 0;
-
-       char sock_path[UNIX_PATH_MAX] = {0,};
-
-       pkt = __app_recv_raw(main_fd, &clifd, &cr);
-       if (!pkt) {
-               _D("packet is NULL");
-               goto end;
-       }
-
-       kb = bundle_decode(pkt->data, pkt->len);
-       if (!kb) {
-               _D("bundle decode error");
-               goto end;
-       }
-
-       INIT_PERF(kb);
-       PERF("packet processing start");
-
-       pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
-       SECURE_LOGD("pkg name : %s\n", pkg_name);
-
-       menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
-       if (menu_info == NULL) {
-               _D("such pkg no found");
-               goto end;
-       }
-
-       app_path = _get_app_path(menu_info);
-       if(app_path == NULL) {
-               _E("app_path is NULL");
-               goto end;
-       }
-       if (app_path[0] != '/') {
-               _D("app_path is not absolute path");
-               goto end;
-       }
-
-       __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
-       pkg_name = _get_pkgname(menu_info);
-
-       PERF("get package information & modify bundle done");
-
-       {
-               pid = fork();
-               if (pid == 0) {
-                       PERF("fork done");
-                       _D("lock up test log(no error) : fork done");
-
-                       close(clifd);
-                       close(main_fd);
-                       __signal_unset_sigchld();
-                       __signal_fini();
-
-                       snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, getpid());
-                       unlink(sock_path);
-
-                       PERF("prepare exec - first done");
-                       _D("lock up test log(no error) : prepare exec - first done");
-
-                       __appid = strdup(pkg_name);
-                       aul_set_preinit_appid(__appid);
-                       atexit(__release_appid_at_exit);
-
-                       if (__prepare_exec(pkg_name, app_path,
-                                          menu_info, kb) < 0) {
-                               SECURE_LOGE("preparing work fail to launch - "
-                                  "can not launch %s\n", pkg_name);
-                               exit(-1);
-                       }
-
-                       PERF("prepare exec - second done");
-                       _D("lock up test log(no error) : prepare exec - second done");
-
-                       __real_launch(app_path, kb);
-
-                       exit(-1);
-               }
-               SECURE_LOGD("==> real launch pid : %d %s\n", pid, app_path);
-               is_real_launch = 1;
-       }
-
- end:
-       __send_result_to_caller(clifd, pid);
-
-       if (pid > 0) {
-               if (is_real_launch) {
-                       /*TODO: retry*/
-                       __signal_block_sigchld();
-                       __send_app_launch_signal(pid);
-                       __signal_unblock_sigchld();
-               }
-       }
-
-       if (menu_info != NULL)
-               _free_app_info_from_db(menu_info);
-
-       if (kb != NULL)
-               bundle_free(kb);
-       if (pkt != NULL)
-               free(pkt);
-
-       /* Active Flusing for Daemon */
-       if (initialized > AUL_POLL_CNT) {
-               sqlite3_release_memory(SQLITE_FLUSH_MAX);
-               malloc_trim(0);
-               initialized = 1;
-       }
-
-}
-
-_static_ int __launchpad_pre_init(int argc, char **argv)
-{
-       int fd;
-
-       /* signal init*/
-       __signal_init();
-
-       /* get my(launchpad) command line*/
-       launchpad_cmdline = __proc_get_cmdline_bypid(getpid());
-       if (launchpad_cmdline == NULL) {
-               _E("launchpad cmdline fail to get");
-               return -1;
-       }
-       _D("launchpad cmdline = %s", launchpad_cmdline);
-
-       /* create launchpad sock        */
-       fd = __create_server_sock(NATIVE_LAUNCHPAD_PID);
-       if (fd < 0) {
-               _E("server sock error");
-               return -1;
-       }
-
-       __preload_init(argc, argv);
-
-       __preload_init_for_native();
-
-       __preexec_init(argc, argv);
-
-       return fd;
-}
-
-_static_ int __launchpad_post_init()
-{
-       /* Setting this as a global variable to keep track
-       of launchpad poll cnt */
-       /* static int initialized = 0;*/
-
-       if (initialized) {
-               initialized++;
-               return 0;
-       }
-
-       if (__signal_set_sigchld() < 0)
-               return -1;
-
-       initialized++;
-
-       return 0;
-}
-
-int main(int argc, char **argv)
-{
-       int main_fd;
-       struct pollfd pfds[POLLFD_MAX];
-       int i;
-
-       /* init without concerning X & EFL*/
-       main_fd = __launchpad_pre_init(argc, argv);
-       if (main_fd < 0) {
-               _E("launchpad pre init failed");
-               exit(-1);
-       }
-
-       pfds[0].fd = main_fd;
-       pfds[0].events = POLLIN;
-       pfds[0].revents = 0;
-
-#ifdef _APPFW_FEATURE_PRIORITY_CHANGE
-       int res = setpriority(PRIO_PROCESS, 0, -12);
-       if (res == -1)
-       {
-               SECURE_LOGE("Setting process (%d) priority to -12 failed, errno: %d (%s)",
-                               getpid(), errno, strerror(errno));
-       }
-#endif
-       while (1) {
-               if (poll(pfds, POLLFD_MAX, -1) < 0)
-                       continue;
-
-               /* init with concerning X & EFL (because of booting
-               sequence problem)*/
-               if (__launchpad_post_init() < 0) {
-                       _E("launcpad post init failed");
-                       exit(-1);
-               }
-
-               for (i = 0; i < POLLFD_MAX; i++) {
-                       if ((pfds[i].revents & POLLIN) != 0) {
-                               __launchpad_main_loop(pfds[i].fd);
-                       }
-               }
-       }
-}
-
diff --git a/native/native_preload.h b/native/native_preload.h
deleted file mode 100644 (file)
index 965457c..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2014 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 __NATIVE_PRELOAD_H__
-#define __NATIVE_PRELOAD_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dlfcn.h>
-
-#define NATIVE_PRELOAD_FILE SHARE_PREFIX"/launchpad-native-preload-list.txt"
-
-static int g_dlopen_size = 5;
-static int g_dlopen_count = 0;
-static void** g_dlopen_handle_list = NULL;
-
-static inline int __preload_save_dlopen_handle(void *handle)
-{
-    if (!handle) {
-        return 1;
-    }
-    if (g_dlopen_count == g_dlopen_size || !g_dlopen_handle_list) {
-        void** tmp =
-            realloc(g_dlopen_handle_list, 2 * g_dlopen_size * sizeof(void *));
-        if (NULL == tmp) {
-            _E("out of memory\n");
-            dlclose(handle);
-            return 1;
-        }
-        g_dlopen_size *= 2;
-        g_dlopen_handle_list = tmp;
-    }
-    g_dlopen_handle_list[g_dlopen_count++] = handle;
-    return 0;
-}
-
-static inline void __preload_fini_for_native(void)
-{
-    int i = 0;
-    if (!g_dlopen_handle_list) {
-        return;
-    }
-    for (i = 0; i < g_dlopen_count; ++i)
-    {
-        void *handle = g_dlopen_handle_list[i];
-        if (handle) {
-            if (0 != dlclose(handle)) {
-                _E("dlclose failed\n");
-            }
-        }
-    }
-    free(g_dlopen_handle_list);
-    g_dlopen_handle_list = NULL;
-    g_dlopen_size = 5;
-    g_dlopen_count = 0;
-}
-
-static inline void __preload_init_for_native(void)
-{
-    if (atexit(__preload_fini_for_native) != 0) {
-        _E("Cannot register atexit callback. Libraries will not be unloaded");
-    }
-
-       void *handle = NULL;
-       char soname[MAX_LOCAL_BUFSZ] = { 0, };
-       FILE *preload_list = NULL;
-
-       preload_list = fopen(NATIVE_PRELOAD_FILE, "rt");
-       if (preload_list == NULL) {
-               _E("no preload\n");
-               return;
-       }
-
-       while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) {
-        size_t len = strnlen(soname, MAX_LOCAL_BUFSZ);
-        if (len > 0) {
-            soname[len - 1] = '\0';
-        }
-               handle = dlopen((const char *) soname, RTLD_NOW);
-               if (handle == NULL) {
-            _E("dlopen(\"%s\") was failed!", soname);
-            continue;
-        }
-
-        if (__preload_save_dlopen_handle(handle) != 0) {
-            _E("Cannot save handle, no more preloads");
-            break;
-        }
-        _D("preload %s# - handle : %x\n", soname, handle);
-       }
-
-       fclose(preload_list);
-}
-
-#endif //__NATIVE_PRELOAD_H__
diff --git a/packaging/launchpad-native-preload-list.txt b/packaging/launchpad-native-preload-list.txt
deleted file mode 100644 (file)
index bb21d5e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/usr/lib/osp/libosp-appfw.so.1
-/usr/lib/osp/libosp-uifw.so.1
-/usr/lib/samsung-private/libsamsung-ui.so.1
-/usr/lib/libmirage.so
-/usr/lib/libchart-framework.so
-/usr/lib/samsung-private/libsamsung-media.so.1
-/usr/lib/samsung-private/libsamsung-net.so.1
-/usr/lib/samsung-private/libsamsung-messaging.so.1
-/usr/lib/osp/libosp-media.so.1
-/usr/lib/osp/libosp-messaging.so.1
-/usr/lib/samsung-private/libsamsung-shell.so.1
-/usr/lib/samsung-private/libsamsung-social.so.1
-/usr/lib/osp/libosp-shell.so.1
-/usr/lib/osp/libosp-wifi.so.1
-/usr/lib/osp/libosp-social.so.1
-/usr/lib/osp/libosp-content.so.1
-/usr/lib/samsung-private/libsamsung-content.so.1
-/usr/lib/osp/libosp-image.so.1
-/usr/lib/osp/libosp-net.so.1
diff --git a/packaging/launchpad-native.service b/packaging/launchpad-native.service
deleted file mode 100644 (file)
index 2ac3288..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Start native launchpad daemon
-After=dbus.service vconf-setup.service ac.service
-
-[Service]
-EnvironmentFile=/run/tizen-mobile-env
-ExecStart=/usr/bin/launchpad-native "                                                                                                                                                                                                         "
-TimeoutStopSec=3s
-Restart=always
-RestartSec=0
-
-[Install]
-WantedBy=graphical.target
index bccc8cb..b00d498 100644 (file)
@@ -1,6 +1,7 @@
 [Unit]
 Description=Start process-pool launchpad daemon
-After=dbus.service vconf-setup.service ac.service
+Requires=xorg.service tizen-generate-env.service
+After=dbus.service vconf-setup.service ac.service xorg.service tizen-generate-env.service
 
 [Service]
 EnvironmentFile=/run/tizen-mobile-env
@@ -10,4 +11,4 @@ Restart=always
 RestartSec=0
 
 [Install]
-WantedBy=graphical.target
+WantedBy=multi-user.target
index d225114..5488e9f 100644 (file)
@@ -1,12 +1,11 @@
 Name:       launchpad
 Summary:    Launchpad for launching applications
-Version:    0.0.20
+Version:    0.2.3.14
 Release:    1
 Group:      Application Framework/Daemons
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 Source101:  launchpad-process-pool.service
-Source102:  launchpad-native.service
 
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(dbus-glib-1)
@@ -14,14 +13,16 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgconfig(ecore)
 BuildRequires:  pkgconfig(bundle)
 BuildRequires:  pkgconfig(dlog)
-BuildRequires:  pkgconfig(ail)
 BuildRequires:  pkgconfig(libprivilege-control)
 BuildRequires:  pkgconfig(libsmack)
+BuildRequires:  pkgconfig(gobject-2.0)
+BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(deviced)
 BuildRequires:  pkgconfig(libsystemd-daemon)
 BuildRequires:  pkgconfig(elementary)
 BuildRequires:  pkgconfig(eina)
+BuildRequires:  pkgconfig(vconf)
 BuildRequires:  aul-devel
 
 Requires: aul
@@ -31,17 +32,29 @@ Requires(postun): /sbin/ldconfig
 Requires(postun): /usr/bin/systemctl
 Requires(preun): /usr/bin/systemctl
 
-%define feature_appfw_process_pool 1
-
+%define appfw_feature_process_pool 1
 %if "%{?tizen_profile_name}" == "wearable"
 %define appfw_feature_process_pool_common 1
-%define appfw_feature_hw_rendering 0
-%elseif "%{?tizen_profile_name}" == "mobile"
-%define appfw_feature_process_pool_common 0
+%define appfw_feature_sw_rendering 1
+%define appfw_feature_hw_rendering 1
+%else
+%if "%{?tizen_profile_name}" == "mobile"
+%define appfw_feature_process_pool_common 1
+%define appfw_feature_sw_rendering 1
+%define appfw_feature_hw_rendering 1
+%else
+%if "%{?tizen_profile_name}" == "tv"
+%define appfw_feature_process_pool_common 1
+%define appfw_feature_sw_rendering 1
+%define appfw_feature_hw_rendering 1
+%else
+%define appfw_feature_process_pool_common 1
+%define appfw_feature_sw_rendering 1
 %define appfw_feature_hw_rendering 1
 %endif
-%define appfw_feature_priority_change 1
-%define appfw_feature_native_launchpad 0
+%endif
+%endif
+%define appfw_feature_priority_change 0
 
 %description
 Launchpad for launching applications
@@ -63,48 +76,41 @@ export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
 export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
 export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
 %endif
-%if 0%{?feature_appfw_process_pool}
+%if 0%{?appfw_feature_process_pool}
 _APPFW_FEATURE_PROCESS_POOL=ON
  %if 0%{?appfw_feature_process_pool_common}
- _APPFW_FEATURE_PROCESS_POOL_COMMON=ON
- %else
 %if 0%{?appfw_feature_hw_rendering}
 _APPFW_FEATURE_PROCESS_POOL_COMMON=ON
+ %endif
+ %if 0%{?appfw_feature_hw_rendering}
   _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING=ON
-  %endif
+ %endif
+ %if 0%{?appfw_feature_sw_rendering}
+  _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING=ON
  %endif
 %endif
 %if 0%{?appfw_feature_priority_change}
 _APPFW_FEATURE_PRIORITY_CHANGE=ON
 %endif
-%if 0%{?appfw_feature_native_launchpad}
-_APPFW_FEATURE_NATIVE_LAUNCHPAD=ON
-%endif
 
 cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \
        -D_APPFW_FEATURE_PROCESS_POOL:BOOL=${_APPFW_FEATURE_PROCESS_POOL} \
        -D_APPFW_FEATURE_PROCESS_POOL_COMMON:BOOL=${_APPFW_FEATURE_PROCESS_POOL_COMMON} \
+       -D_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING:BOOL=${_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING} \
        -D_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING:BOOL=${_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING} \
-       -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE} \
-       -D_APPFW_FEATURE_NATIVE_LAUNCHPAD:BOOL=${_APPFW_FEATURE_NATIVE_LAUNCHPAD}
+       -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE}
 
 make %{?jobs:-j%jobs}
 
 %install
 rm -rf %{buildroot}
-%if 0%{?feature_appfw_process_pool} || 0%{?appfw_feature_native_launchpad}
+%if 0%{?appfw_feature_process_pool}
 %make_install
 %endif
 
-%if 0%{?feature_appfw_process_pool}
-mkdir -p %{buildroot}%{_libdir}/systemd/system/graphical.target.wants
+%if 0%{?appfw_feature_process_pool}
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
 install -m0644 %SOURCE101 %{buildroot}%{_libdir}/systemd/system/launchpad-process-pool.service
-ln -s ../launchpad-process-pool.service %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/launchpad-process-pool.service
-%endif
-
-%if 0%{?appfw_feature_native_launchpad}
-mkdir -p %{buildroot}%{_libdir}/systemd/system/graphical.target.wants
-install -m0644 %SOURCE102 %{buildroot}%{_libdir}/systemd/system/launchpad-native.service
-ln -s ../launchpad-native.service %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/launchpad-native.service
+ln -s ../launchpad-process-pool.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/launchpad-process-pool.service
 %endif
 
 mkdir -p %{buildroot}/usr/share/license
@@ -115,15 +121,11 @@ cp %{_builddir}/%{name}-%{version}/LICENSE  %{buildroot}/usr/share/license/%{nam
 %files
 %manifest launchpad.manifest
 %{_prefix}/share/license/%{name}
-%if 0%{?feature_appfw_process_pool}
-%{_bindir}/launchpad-process-pool
+%if 0%{?appfw_feature_process_pool}
+%attr(0700,root,root) %{_bindir}/launchpad-process-pool
+%attr(0700,root,root) %{_bindir}/launchpad-loader
+%{_prefix}/share/aul/preload_list.txt
 %{_prefix}/share/aul/launchpad-process-pool-preload-list.txt
 %{_libdir}/systemd/system/launchpad-process-pool.service
-%{_libdir}/systemd/system/graphical.target.wants/launchpad-process-pool.service
-%endif
-%if 0%{?appfw_feature_native_launchpad}
-%{_bindir}/launchpad-native
-%{_prefix}/share/aul/launchpad-native-preload-list.txt
-%{_libdir}/systemd/system/launchpad-native.service
-%{_libdir}/systemd/system/graphical.target.wants/launchpad-native.service
+%{_libdir}/systemd/system/multi-user.target.wants/launchpad-process-pool.service
 %endif
diff --git a/packaging/preload_list.txt b/packaging/preload_list.txt
new file mode 100644 (file)
index 0000000..3ccda07
--- /dev/null
@@ -0,0 +1,4 @@
+/usr/lib/libappcore-efl.so.1
+/usr/lib/libappcore-common.so.1
+/usr/lib/libcapi-appfw-application.so.0
+/usr/lib/ecore/immodules/libisf-imf-module.so
diff --git a/process_pool/config.h b/process_pool/config.h
new file mode 100644 (file)
index 0000000..ecbe306
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+#define LAUNCHPAD_LOG
+#define DAC_ACTIVATE
+#define PRELOAD_ACTIVATE
+#define PREEXEC_ACTIVATE
+/*#define PERF_ACTIVATE*/
old mode 100644 (file)
new mode 100755 (executable)
index a7cdfc2..6b19d55
  * limitations under the License.
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <dlfcn.h>
 #include <poll.h>
+#include <stdlib.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
-#define __USE_GNU
 #include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <malloc.h>
 
 #include <sqlite3.h>
 
 #include <aul.h>
 #include <Elementary.h>
 #include <Ecore.h>
+#include <bundle_internal.h>
 
-#include <config.h> //should be included first
+#include "config.h" //should be included first
 
 //including aul/launch
 #include <access_control.h>
 #include <perf.h>
 #include <simple_util.h>
 
-//including aul/launchpad
-#include <gl.h>
-#include <heap_dbg.h>
-#include <preexec.h>
-#include <preload.h>
-#include <sigchild.h>
-#include <util_x.h>
+#include "sigchild.h"
 
 #include "process_pool.h"
-#include "process_pool_preload.h"
 
 #include "smack_util.h"
 
 #define _static_ static inline
 #define SQLITE_FLUSH_MAX       (1048576)       /* (1024*1024) */
 #define AUL_POLL_CNT           15
-#define AUL_PR_NAME                    16
 
 #define EXEC_CANDIDATE_EXPIRED 5
+#define EXEC_CANDIDATE_WAIT 1
 #define DIFF(a,b) (((a)>(b))?(a)-(b):(b)-(a))
-#define LOWEST_PRIO 20
 #define CANDIDATE_NONE 0
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
- #ifndef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
- #define MAX_LAUNCHPAD_TYPE_NUM 1
- #else
- #define MAX_LAUNCHPAD_TYPE_NUM 2
- #endif
-#else //_APPFW_FEATURE_PROCESS_POOL_COMMON
-#define MAX_LAUNCHPAD_TYPE_NUM 1
-#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
 
 typedef struct
 {
@@ -77,10 +65,8 @@ typedef struct
        int last_exec_time;
 } candidate;
 
-static char *launchpad_cmdline;
-static char *__appid = NULL;
 static int initialized = 0;
-static candidate __candidate[MAX_LAUNCHPAD_TYPE_NUM] =
+static candidate __candidate[LAUNCHPAD_TYPE_MAX] =
 {
        { CANDIDATE_NONE, -1, 0 },
        { CANDIDATE_NONE, -1, 0 }
@@ -89,26 +75,13 @@ const char* const HOME = "HOME";
 const char* const APP_HOME_PATH = "/opt/home/app";
 const char* const ROOT_HOME_PATH = "/opt/home/root";
 
-_static_ void __set_env(app_info_from_db *menu_info, bundle *kb);
-_static_ int __prepare_exec(const char *pkg_name,
-                               const char *app_path, app_info_from_db * menu_info,
-                               bundle * kb);
-_static_ int __fake_launch_app(int cmd, int pid, bundle * kb);
-_static_ char **__create_argc_argv(bundle *kb, int *margc);
-_static_ int __normal_fork_exec(int argc, char **argv);
-_static_ void __real_launch(const char *app_path, bundle * kb);
 _static_ int __candidate_process_real_launch(int candidate_fd, app_pkt_t *pkt);
 static inline int __parser(const char *arg, char *out, int out_size);
 _static_ void __modify_bundle(bundle * kb, int caller_pid,
                                app_info_from_db * menu_info, int cmd);
-_static_ int __child_raise_win_by_x(int pid, void *priv);
-_static_ int __raise_win_by_x(int pid);
-_static_ int __send_to_sigkill(int pid);
-_static_ int __term_app(int pid);
-_static_ int __resume_app(int pid);
 _static_ int __real_send(int clifd, int ret);
-_static_ void __send_result_to_caller(int clifd, int ret);
-_static_ void __prepare_candidate_process(int type, int launchpad_fd, int pool_fd, int client_fd);
+_static_ void __send_result_to_caller(int clifd, int ret, const char* app_path);
+_static_ void __prepare_candidate_process(int type);
 _static_ void __launchpad_main_loop(int launchpad_fd, int *pool_fd);
 _static_ int __launchpad_pre_init(int argc, char **argv);
 _static_ int __launchpad_post_init();
@@ -116,140 +89,6 @@ _static_ int __launchpad_post_init();
 static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
                                                        const char *pkgname, bundle *kb);
 
-_static_ void __set_env(app_info_from_db * menu_info, bundle * kb)
-{
-       const char *str;
-
-       setenv("PKG_NAME", _get_pkgname(menu_info), 1);
-
-       USE_ENGINE("gl")
-
-       str = bundle_get_val(kb, AUL_K_STARTTIME);
-       if (str != NULL)
-               setenv("APP_START_TIME", str, 1);
-
-       if (menu_info->hwacc != NULL)
-               setenv("HWACC", menu_info->hwacc, 1);
-       if (menu_info->taskmanage != NULL)
-               setenv("TASKMANAGE", menu_info->taskmanage, 1);
-}
-
-_static_ int __prepare_exec(const char *pkg_name,
-                               const char *app_path, app_info_from_db * menu_info,
-                               bundle * kb)
-{
-       char *file_name;
-       char process_name[AUL_PR_NAME];
-       int ret;
-
-       /* Set new session ID & new process group ID*/
-       /* In linux, child can set new session ID without check permission */
-       /* TODO : should be add to check permission in the kernel*/
-       setsid();
-
-       __preexec_run(menu_info->pkg_type, pkg_name, app_path);
-
-       /* SET PRIVILEGES*/
-       SECURE_LOGD("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*/
-       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_ int __fake_launch_app(int cmd, int pid, bundle * kb)
-{
-       int datalen;
-       int ret;
-       bundle_raw *kb_data;
-
-       bundle_encode(kb, &kb_data, &datalen);
-       if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
-               _E("error request fake launch - error code = %d", ret);
-       free(kb_data);
-       return ret;
-}
-
-_static_ char **__create_argc_argv(bundle * kb, int *margc)
-{
-       char **argv;
-       int argc;
-
-       argc = bundle_export_to_argv(kb, &argv);
-
-       *margc = argc;
-       return argv;
-}
-
-_static_ int __normal_fork_exec(int argc, char **argv)
-{
-       _D("start real fork and exec\n");
-
-#ifdef _APPFW_FEATURE_PRIORITY_CHANGE
-       int res = setpriority(PRIO_PROCESS, 0, 0);
-       if (res == -1)
-       {
-               SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)",
-                               getpid(), errno, strerror(errno));
-       }
-#endif
-       if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
-               if (errno == EACCES)
-                       _E("such a file is no executable - %s", argv[0]);
-               else
-                       _E("unknown executable error - %s", argv[0]);
-               return -1;
-       }
-       /* never reach*/
-       return 0;
-}
-
-_static_ void __real_launch(const char *app_path, bundle * kb)
-{
-       int app_argc;
-       char **app_argv;
-       int i;
-
-       app_argv = __create_argc_argv(kb, &app_argc);
-       app_argv[0] = strdup(app_path);
-
-       for (i = 0; i < app_argc; i++) {
-               if( (i%2) == 1)
-                       continue;
-               SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
-       }
-
-       PERF("setup argument done");
-
-       /* Temporary log: launch time checking */
-       LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
-
-       __preload_exec(app_argc, app_argv);
-
-       __normal_fork_exec(app_argc, app_argv);
-}
-
 _static_ int __candidate_process_real_launch(int candidate_fd, app_pkt_t *pkt)
 {
        return __send_pkt_raw_data(candidate_fd, pkt);
@@ -343,9 +182,9 @@ static inline int __parser(const char *arg, char *out, int out_size)
                }
        }
 
-       if (out_size == 1) {
+       if (out_size == 1)
                *out = '\0';
-       }
+
        /* Buffer overflow*/
        return -2;
 }
@@ -393,136 +232,13 @@ _static_ void __modify_bundle(bundle * kb, int caller_pid,
                                /*bundle_del(kb, key);*/
                                bundle_add(kb, key, value);
                        } while (flag > 0);
-               } else if (flag == 0) {
+               } else if (flag == 0)
                        _D("parsing app_path: No arguments\n");
-               } else {
+               else
                        _D("parsing app_path: Invalid argument\n");
-               }
        }
 }
 
-_static_ int __child_raise_win_by_x(int pid, void *priv)
-{
-       return x_util_raise_win(pid);
-}
-
-_static_ int __raise_win_by_x(int pid)
-{
-       int pgid;
-       if (x_util_raise_win(pid) == 0)
-               return 0;
-
-       /* support app launched by shell script*/
-       pgid = getpgid(pid);
-       _D("X raise failed. try to find first child & raise it - c:%d p:%d\n",
-          pgid, pid);
-
-       if (pgid <= 1)
-               return -1;
-       if (__proc_iter_pgid(pgid, __child_raise_win_by_x, NULL) < 0)
-               return -1;
-
-       return 0;
-}
-
-_static_ int __send_to_sigkill(int pid)
-{
-       int pgid;
-
-       pgid = getpgid(pid);
-       if (pgid <= 1)
-               return -1;
-
-       if (killpg(pgid, SIGKILL) < 0)
-               return -1;
-
-       return 0;
-}
-
-_static_ int __term_app(int pid)
-{
-       int dummy;
-       if (__app_send_raw
-               (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
-               _D("terminate packet send error - use SIGKILL");
-               if (__send_to_sigkill(pid) < 0) {
-                       _E("fail to killing - %d\n", pid);
-                       return -1;
-               }
-       }
-       _D("term done\n");
-       return 0;
-}
-
-_static_ int __resume_app(int pid)
-{
-       int dummy;
-       int ret;
-       if ((ret =
-                __app_send_raw(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy,
-                               sizeof(int))) < 0) {
-               if (ret == -EAGAIN)
-                       _E("resume packet timeout error");
-               else {
-                       _D("resume packet send error - use raise win");
-                       if (__raise_win_by_x(pid) < 0) {
-                               _E("raise failed - %d resume fail\n", pid);
-                               _E("we will term the app - %d\n", pid);
-                               __send_to_sigkill(pid);
-                               ret = -1;
-                       } else
-                               ret = 0;
-               }
-       }
-       _D("resume done\n");
-       return ret;
-}
-
-static int __get_caller_pid(bundle *kb)
-{
-       const char *pid_str;
-       int pid;
-
-       pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
-       if(pid_str)
-               goto end;
-
-       pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
-       if (pid_str == NULL)
-               return -1;
-
-end:
-       pid = atoi(pid_str);
-       if (pid <= 1)
-               return -1;
-
-       return pid;
-}
-
-_static_ int __foward_cmd(int cmd, bundle *kb, int cr_pid)
-{
-       int pid;
-       char tmp_pid[MAX_PID_STR_BUFSZ];
-       int datalen;
-       bundle_raw *kb_data;
-       int res;
-
-       if ((pid = __get_caller_pid(kb)) < 0)
-                       return AUL_R_ERROR;
-
-       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
-
-       bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
-
-       bundle_encode(kb, &kb_data, &datalen);
-       if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
-               res = AUL_R_ERROR;
-
-       free(kb_data);
-
-       return res;
-}
-
 _static_ int __real_send(int clifd, int ret)
 {
        if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
@@ -538,7 +254,7 @@ _static_ int __real_send(int clifd, int ret)
        return 0;
 }
 
-_static_ void __send_result_to_caller(int clifd, int ret)
+_static_ void __send_result_to_caller(int clifd, int ret, const char* app_path)
 {
        char *cmdline;
        int wait_count;
@@ -546,10 +262,13 @@ _static_ void __send_result_to_caller(int clifd, int ret)
        int cmdline_exist = 0;
        int r;
 
+       _W("Check app launching");
+
        if (clifd == -1)
                return;
 
        if (ret <= 1) {
+               _E("launching failed");
                __real_send(clifd, ret);
                return;
        }
@@ -559,20 +278,30 @@ _static_ void __send_result_to_caller(int clifd, int ret)
                cmdline = __proc_get_cmdline_bypid(ret);
                if (cmdline == NULL) {
                        _E("error founded when being launched with %d", ret);
-
-               } else if (strcmp(cmdline, launchpad_cmdline)) {
+                       if (cmdline_exist || cmdline_changed) {
+                               _E("The app process might be terminated while we are wating %d", ret);
+                               break;
+                       }
+               } else if (strcmp(cmdline, app_path) == 0) {
+                       /* Check app main loop is prepared or not */
+                       _D("-- now wait app mainloop creation --");
                        free(cmdline);
                        cmdline_changed = 1;
-                       break;
+
+                       char sock_path[UNIX_PATH_MAX] = { 0, };
+                       snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, ret);
+                       if (access(sock_path, F_OK) == 0)
+                               break;
+
                } else {
+                       _D("-- now wait cmdline changing --");
                        cmdline_exist = 1;
                        free(cmdline);
                }
-
-               _D("-- now wait to change cmdline --");
-               usleep(100 * 1000);     /* 50ms sleep*/
+               usleep(100 * 1000);     /* 100ms sleep*/
                wait_count++;
-       } while (wait_count <= 20);     /* max 100*20ms will be sleep*/
+
+       } while (wait_count <= 50);     /* max 100*50ms will be sleep*/
 
        if ((!cmdline_exist) && (!cmdline_changed)) {
                __real_send(clifd, -1); /* abnormally launched*/
@@ -591,386 +320,114 @@ _static_ void __send_result_to_caller(int clifd, int ret)
        return;
 }
 
-_static_ int __candidate_process_prepare_exec(const char *pkg_name,
-                                                       const char *app_path, app_info_from_db *menu_info,
-                                                       bundle *kb, int type)
+_static_ void __prepare_candidate_process(int type)
 {
-       const char *file_name = NULL;
-       char process_name[AUL_PR_NAME] = { 0, };
-       int ret = 0;
-
-       if (set_app_smack_label(app_path, type) != 0)
-       {
-               _E("set_app_smack_label() failed");
-       }
-
-       /* 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;
-       }
-
-       //XXX: Check CAP_MAC_ADMIN
-#if 0
-       /* SET INHERIT BIT FOR CAP_MAC_ADMIN TO WHOLE THREAD */
-       EXECUTE_ON_WHOLE_THREAD(__set_inherit_bit_for_CAP_MAC_ADMIN, SIGUSR1);
-#endif
+       int pid;
 
-       /* SET PROCESS NAME*/
-       if (app_path == NULL) {
-               _D("app_path should not be NULL - check menu db");
-               return -1;
-       }
+       __candidate[type].last_exec_time = time(NULL);
 
-       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);
+       pid = fork();
 
-       /* SET ENVIROMENT*/
-       __set_env(menu_info, kb);
+       if (pid == 0) { /* child */
+               char type_str[2] = {0,};
 
-       return 0;
-}
+               /* execute with very long (1024 bytes) argument in order to prevent argv overflow caused by dlopen */
+               char *argv[] = {"/usr/bin/launchpad-loader", NULL,
+"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ", NULL};
+               __signal_unblock_sigchld();
 
-static bundle *_s_bundle = NULL;
-static void __at_exit_to_release_bundle()
-{
-       if (_s_bundle) {
-               bundle_free(_s_bundle);
-               _s_bundle = NULL;
-       }
-}
+               type_str[0] = '0' + type;
+               argv[1] = type_str;
+               if (execv(argv[0], argv) < 0)
+                       _E("Failed to prepare candidate_process");
+               else
+                       _D("Succeeded to prepare candidate_process");
 
-static void __release_appid_at_exit(void)
-{
-       if (__appid != NULL) {
-               free(__appid);
+               exit(-1);
        }
 }
 
-_static_ void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, char* out_app_path, int* out_argc, char ***out_argv)
+static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
+                       const char *pkgname, bundle *kb)
 {
-       bundle *kb = NULL;
-       app_info_from_db *menu_info = NULL;
-
-       const char *pkg_name = NULL;
-       const char *app_path = NULL;
-       const char *launchpad_type = NULL;
-       int type = 0;
-
-       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);
-
-       pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
-       menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
-       if (menu_info == NULL) {
-               _D("such pkg no found");
-               exit(-1);
-       }
-
-       launchpad_type = bundle_get_val(kb, AUL_K_LAUNCHPAD_TYPE);
-       if (launchpad_type == NULL)
-       {
-               _E("Invalid launchpad type");
-               exit(-1);
-       }
-       type = atoi(launchpad_type);
-       SECURE_LOGD("pkg name : %s, launchpad type: %d", pkg_name, 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);
-       pkg_name = _get_pkgname(menu_info);
-       SECURE_LOGD("pkg name : %s", pkg_name);
-
-       __appid = strdup(pkg_name);
-       aul_set_preinit_appid(__appid);
-       atexit(__release_appid_at_exit);
-
-       __candidate_process_prepare_exec(pkg_name, app_path, menu_info, kb, type);
-
-       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);
+       app_info_from_db *menu_info;
+       const char *ptr = NULL;
 
-               *out_argv = __create_argc_argv(kb, out_argc);
-               (*out_argv)[0] = out_app_path;
+       menu_info = calloc(1, sizeof(app_info_from_db));
+       if (menu_info == NULL)
+               return NULL;
 
-               for (i = 0; i < *out_argc; i++)
-               {
-                       SECURE_LOGD("input argument %d : %s##", i, (*out_argv)[i]);
-               }
-       }
-       else
-       {
-               exit(-1);
-       }
+       menu_info->pkg_name = strdup(pkgname);
+       ptr = bundle_get_val(kb, AUL_K_EXEC);
+       if (ptr)
+               menu_info->app_path = strdup(ptr);
+       if (menu_info->app_path != NULL)
+               menu_info->original_app_path = strdup(menu_info->app_path);
+       ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE);
+       if (ptr)
+               menu_info->pkg_type = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_HWACC);
+       if (ptr)
+               menu_info->hwacc = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_TASKMANAGE);
+       if (ptr)
+               menu_info->taskmanage = strdup(ptr);
 
-       if (menu_info != NULL) {
+       if (!_get_app_path(menu_info)) {
                _free_app_info_from_db(menu_info);
+               return NULL;
        }
+
+       return menu_info;
 }
 
-static Eina_Bool __candidate_proces_fd_handler(void* data, Ecore_Fd_Handler *handler)
+_static_ void __sleep_safe(time_t sec)
 {
-       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 == NULL) {
-                               _E("[candidate] out of memory");
-                               close(fd);
-                               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("[candidate] 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);
-                       SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", g_argv[0], g_argc);
-                       free(pkt);
+       struct timespec delay, remain;
+       delay.tv_sec = sec;
+       delay.tv_nsec = 0;
+       remain.tv_sec = 0;
+       remain.tv_nsec = 0;
+
+       while (nanosleep(&delay, &remain)) {
+               if (errno == EINTR) {
+                       delay.tv_sec = remain.tv_sec;
+                       delay.tv_nsec = remain.tv_nsec;
+               }
+               else {
+                       _D("nanosleep() failed, errno: %d (%s)", errno, strerror(errno));
+                       break;
                }
-               ecore_main_loop_quit();
-               _D("[candidate] ecore main loop quit");
        }
-
-       return ECORE_CALLBACK_CANCEL;
 }
 
-_static_ void __prepare_candidate_process(int type, int launchpad_fd, int pool_fd, int client_fd)
+static int __send_launchpad_loader(int type, app_pkt_t *pkt, const char *app_path, int clifd)
 {
-       int pid;
-
-       if (type == 1)
-       {
-               __candidate[TYPE1].last_exec_time = time(NULL);
-       }
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
-#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-       else if (type == 2)
-       {
-               __candidate[TYPE2].last_exec_time = time(NULL);
-       }
-#endif
-#endif
-
-       pid = fork();
-
-       if (pid == 0) // child
-       {
-               int res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO);
-               if (res == -1)
-               {
-                       SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)",
-                                       getpid(), LOWEST_PRIO, errno, strerror(errno));
-               }
-               _D("[candidate] Another candidate process was forked.");
-
-               //temp - this requires some optimization.
-               sleep(1);
-               _D("sleeping 1 sec...");
-
-               /* Set new session ID & new process group ID*/
-               /* In linux, child can set new session ID without check permission */
-               /* TODO : should be add to check permission in the kernel*/
-               setsid();
-
-               if (launchpad_fd != -1)
-               {
-                       close(launchpad_fd);
-               }
-               if (pool_fd != -1)
-               {
-                       close(pool_fd);
-               }
-               if (client_fd != -1)
-               {
-                       close(client_fd);
-               }
-
-               __signal_unset_sigchld();
-               __signal_fini();
-
-#if 0
-               if (set_SIGUSR1_handler() != 0)
-               {
-                       _E("Setting signal hanlder failed.");
-                       exit(-1);
-               }
-#endif
-
-               /* SET PR_SET_KEEPCAPS */
-               if (prctl(PR_SET_KEEPCAPS, 1) < 0)
-               {
-                       _E("prctl(PR_SET_KEEPCAPS) failed.");
-               }
-
-               /* SET DUMPABLE - for coredump*/
-               prctl(PR_SET_DUMPABLE, 1);
-
-               {
-                       int client_fd = __connect_to_launchpad(type);
-                       if (client_fd == -1)
-                       {
-                               _D("Connecting to candidate process was failed.");
-                               exit(-1);
-                       }
-
-                       // Temporarily change HOME path to app
-                       // This change is needed for getting elementary profile
-                       // /opt/home/app/.elementary/config/mobile/base.cfg
-                       setenv(HOME, APP_HOME_PATH, 1);
-                       _D("[candidate] elm_init()");
-                       elm_init(g_argc, g_argv);
-                       setenv(HOME, ROOT_HOME_PATH, 1);
-
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
- #ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-                       if (type == 2)
-                       {
-                               elm_config_preferred_engine_set("opengl_x11");
-                       }
- #endif
-                       Evas_Object* win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC);
-                       aul_set_preinit_window(win);
-
-                       Evas_Object* bg = elm_bg_add(win);
-                       evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-                       elm_win_resize_object_add(win, bg);
-
-                       aul_set_preinit_background(bg);
-
-                       Evas_Object* conform = elm_conformant_add(win);
-                       aul_set_preinit_conformant(conform);
-#else //_APPFW_FEATURE_PROCESS_POOL_COMMON
-                       Eina_Bool is_exist = edje_file_group_exists("/usr/share/elementary/themes/tizen-2.3-wearable-HVGA.edj", "*");
-                       if(!is_exist)
-                               _D("edje_file_group_exists return false");
-#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
-
-                       Ecore_Fd_Handler* fd_handler = ecore_main_fd_handler_add(client_fd,
-                                                                                  (Ecore_Fd_Handler_Flags)(ECORE_FD_READ|ECORE_FD_ERROR),
-                                                                                  __candidate_proces_fd_handler, NULL, NULL, NULL);
-                       if (fd_handler == NULL)
-                       {
-                               _D("fd_handler is NULL");
-                               exit(-1);
-                       }
-
-                       res = setpriority(PRIO_PGRP, 0, 0);
-                       if (res == -1)
-                       {
-                               SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)",
-                                               getpid(), errno, strerror(errno));
-                       }
-
-                       _D("[candidate] ecore main loop begin");
-                       ecore_main_loop_begin();
+       char sock_path[UNIX_PATH_MAX] = { 0, };
+       int pid = -1;
 
-                       void *handle = NULL;
-                       int (*dl_main) (int, char **);
+       snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, __candidate[type].pid);
+       unlink(sock_path);
 
-                       SECURE_LOGD("[candidate] Launch real application (%s)", g_argv[0]);
-                       handle = dlopen(g_argv[0], RTLD_LAZY | RTLD_GLOBAL);
-                       if (handle == NULL)
-                       {
-                               _E("dlopen failed (%s).", dlerror());
-                               exit(-1);
-                       }
-                       dlerror();
+       __candidate_process_real_launch(__candidate[type].send_fd, pkt);
+       SECURE_LOGD("Request to candidate process, pid: %d, bin path: %s", __candidate[type].pid, app_path);
 
-                       dl_main = dlsym(handle, "main");
-                       if (dl_main != NULL)
-                       {
-                               dl_main(g_argc, g_argv);
-                       }
-                       else
-                       {
-                               _E("dlsym not founded. bad preloaded app - check fpie pie");
-                       }
+       pid = __candidate[type].pid;
+       close(__candidate[type].send_fd);
 
-                       exit(0);
-               }
-       }
-}
+       __candidate[type].pid = CANDIDATE_NONE;
+       __candidate[type].send_fd = -1;
 
-static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
-                                                       const char *pkgname, bundle *kb)
-{
-       app_info_from_db *menu_info;
+       /* Temporary log: launch time checking */
+       //SECURE_LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
 
-       menu_info = calloc(1, sizeof(app_info_from_db));
-       if (menu_info == NULL) {
-               return NULL;
-       }
+       __send_result_to_caller(clifd, pid, app_path); //to AMD
 
-       menu_info->pkg_name = strdup(pkgname);
-       menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
-       if (menu_info->app_path != NULL)
-               menu_info->original_app_path = strdup(menu_info->app_path);
-       menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
-       menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
-       menu_info->taskmanage = strdup(bundle_get_val(kb, AUL_K_TASKMANAGE));
+       __sleep_safe(1); //1 sec
+       __prepare_candidate_process(type);
 
-       if (!_get_app_path(menu_info)) {
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       return menu_info;
+       _D("Prepare another candidate process");
+       return pid;
 }
 
 _static_ void __launchpad_main_loop(int launchpad_fd, int *pool_fd)
@@ -980,24 +437,23 @@ _static_ void __launchpad_main_loop(int launchpad_fd, int *pool_fd)
        app_info_from_db *menu_info = NULL;
 
        const char *pkg_name = NULL;
+       const char *internal_pool = NULL;
        const char *app_path = NULL;
-       const char *launchpad_type = NULL;
        int pid = -1;
        int clifd = -1;
        struct ucred cr;
        int is_real_launch = 0;
-       char sock_path[UNIX_PATH_MAX] = {0,};
        int type = -1;
 
        pkt = __app_recv_raw(launchpad_fd, &clifd, &cr);
        if (!pkt) {
-               _D("packet is NULL");
+               _E("packet is NULL");
                goto end;
        }
 
        kb = bundle_decode(pkt->data, pkt->len);
        if (!kb) {
-               _D("bundle decode error");
+               _E("bundle decode error");
                goto end;
        }
 
@@ -1009,7 +465,7 @@ _static_ void __launchpad_main_loop(int launchpad_fd, int *pool_fd)
 
        menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
        if (menu_info == NULL) {
-               _D("such pkg no found");
+               _E("such pkg no found");
                goto end;
        }
 
@@ -1019,125 +475,76 @@ _static_ void __launchpad_main_loop(int launchpad_fd, int *pool_fd)
                goto end;
        }
        if (app_path[0] != '/') {
-               _D("app_path is not absolute path");
+               _E("app_path is not absolute path");
                goto end;
        }
 
-       launchpad_type = bundle_get_val(kb, AUL_K_LAUNCHPAD_TYPE);
-       if (launchpad_type == NULL)
-       {
-               _E("[launchpad] invalid launchpad type");
+       if (menu_info->hwacc == NULL) {
+               _E("[launchpad] Failed to find H/W acceleration type");
+               goto end;
+       }
+
+       internal_pool = bundle_get_val(kb, AUL_K_EXEC);
+       SECURE_LOGD("exec : %s\n", internal_pool);
+       internal_pool = bundle_get_val(kb, AUL_K_INTERNAL_POOL);
+       SECURE_LOGD("internal pool : %s\n", internal_pool);
+       SECURE_LOGD("hwacc : %s\n", menu_info->hwacc);
+       type = __get_launchpad_type(internal_pool, menu_info->hwacc);
+       if (type < 0) {
+               _E("failed to get launchpad type");
                goto end;
        }
-       type = atoi(launchpad_type);
-       _D("[launchpad] launchpad type: %d", type);
 
        __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
        pkg_name = _get_pkgname(menu_info);
+       if (pkg_name == NULL){
+               _E("unable to get pkg_name from menu_info");
+               goto end;
+       }
 
        PERF("get package information & modify bundle done");
 
-       if ((type == 1 && __candidate[TYPE1].pid != CANDIDATE_NONE)
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
- #ifndef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-               )
- #else
-               || (type == 2 && __candidate[TYPE2].pid != CANDIDATE_NONE))
- #endif
-#else //_APPFW_FEATURE_PROCESS_POOL_COMMON
-               )
-#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
+       if ((type >= 0) && (type < LAUNCHPAD_TYPE_MAX) && (__candidate[type].pid != CANDIDATE_NONE)
+               && (DIFF(__candidate[type].last_exec_time, time(NULL)) > EXEC_CANDIDATE_WAIT))
        {
-               int i = type - 1;
-               snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, __candidate[i].pid);
-               unlink(sock_path);
-
-               __candidate_process_real_launch(__candidate[i].send_fd, pkt);
-               _D("Request real launch to candidate_process.");
-
-               pid = __candidate[i].pid;
+               _W("Launch on type-based process-pool");
+               pid = __send_launchpad_loader(type, pkt, app_path, clifd);
                is_real_launch = 1;
-               close(__candidate[i].send_fd);
-
-               __candidate[i].pid = CANDIDATE_NONE;
-               __candidate[i].send_fd = -1;
-
-               /* Temporary log: launch time checking */
-               //LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
-
-               __prepare_candidate_process(type, launchpad_fd, pool_fd[type - 1], clifd);
-
-               SECURE_LOGD("Prepare candidate process, pid: %d, bin path: %s\n", pid, app_path);
        }
-       else
+       else if ((__candidate[LAUNCHPAD_TYPE_COMMON].pid != CANDIDATE_NONE)
+               && (DIFF(__candidate[LAUNCHPAD_TYPE_COMMON].last_exec_time, time(NULL)) > EXEC_CANDIDATE_WAIT))
        {
-               // legacy approach
-               pid = fork();
-
-               if (pid == 0)
-               {
-                       PERF("fork done");
-                       _E("lock up test log(no error) : fork done");
-
-                       close(clifd);
-                       close(launchpad_fd);
-                       __signal_unset_sigchld();
-                       __signal_fini();
-
-                       snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, getpid());
-                       unlink(sock_path);
-
-                       PERF("prepare exec - first done");
-                       _E("lock up test log(no error) : prepare exec - first done");
-
-                       if (__prepare_exec(pkg_name, app_path, menu_info, kb) < 0)
-                       {
-                               SECURE_LOGE("preparing work fail to launch - "
-                                  "can not launch %s\n", pkg_name);
-                               exit(-1);
-                       }
-
-                       PERF("prepare exec - second done");
-                       _E("lock up test log(no error) : prepare exec - second done");
-
-                       __real_launch(app_path, kb);
-
-                       exit(-1);
-               }
-               _D("==> real launch pid : %d %s\n", pid, app_path);
+               _W("Launch on common type process-pool");
+               pid = __send_launchpad_loader(LAUNCHPAD_TYPE_COMMON, pkt, app_path, clifd);
                is_real_launch = 1;
        }
+       else
+       {
+               // legacy logic(fork & exec) will be done in AMD
+               _W("Candidate is not prepared, enter legacy logic");
+               __send_result_to_caller(clifd, -ENOLAUNCHPAD, app_path);
+       }
+       clifd = -1;
+
 end:
-       __send_result_to_caller(clifd, pid);
+       if (clifd != -1)
+               close(clifd);
 
-       if (pid > 0)
-       {
+       if (pid > 0) {
                if (is_real_launch)
-               {
-                       /*TODO: retry*/
-                       __signal_block_sigchld();
                        __send_app_launch_signal(pid);
-                       __signal_unblock_sigchld();
-               }
        }
 
        if (menu_info != NULL)
-       {
                _free_app_info_from_db(menu_info);
-       }
 
        if (kb != NULL)
-       {
                bundle_free(kb);
-       }
        if (pkt != NULL)
-       {
                free(pkt);
-       }
 
        /* Active Flusing for Daemon */
-       if (initialized > AUL_POLL_CNT)
-       {
+       if (initialized > AUL_POLL_CNT) {
                sqlite3_release_memory(SQLITE_FLUSH_MAX);
                malloc_trim(0);
                initialized = 1;
@@ -1151,28 +558,13 @@ _static_ int __launchpad_pre_init(int argc, char **argv)
        /* signal init*/
        __signal_init();
 
-       /* get my(launchpad) command line*/
-       launchpad_cmdline = __proc_get_cmdline_bypid(getpid());
-       if (launchpad_cmdline == NULL) {
-               _E("launchpad cmdline fail to get");
-               return -1;
-       }
-       _D("launchpad cmdline: %s", launchpad_cmdline);
-
        /* create launchpad sock */
        fd = __create_server_sock(PROCESS_POOL_LAUNCHPAD_PID);
-       if (fd < 0)
-       {
+       if (fd < 0) {
                _E("server sock error");
                return -1;
        }
 
-       __preload_init(argc, argv);
-
-       __preload_init_for_process_pool();
-
-//     __preexec_init(argc, argv);
-
        return fd;
 }
 
@@ -1182,17 +574,11 @@ _static_ int __launchpad_post_init()
        of launchpad poll cnt */
        /* static int initialized = 0;*/
 
-       if (initialized)
-       {
+       if (initialized) {
                ++initialized;
                return 0;
        }
 
-       if (__signal_set_sigchld() < 0)
-       {
-               return -1;
-       }
-
        ++initialized;
 
        return 0;
@@ -1202,31 +588,23 @@ int main(int argc, char **argv)
 {
        enum {
                LAUNCH_PAD = 0,
-               POOL_TYPE1,
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
-#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-               POOL_TYPE2,
-#endif
-#endif
-               CANDIDATE_TYPE1,
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
-#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-               CANDIDATE_TYPE2,
-#endif
-#endif
-               POLLFD_MAX
+               POOL_TYPE = 1,
+               CANDIDATE_TYPE = LAUNCHPAD_TYPE_MAX + 1,
+               SIGCHLD_FD = LAUNCHPAD_TYPE_MAX * 2 + 1,
+               POLLFD_MAX = LAUNCHPAD_TYPE_MAX * 2 + 2
        };
        int launchpad_fd = -1;
-       int pool_fd[MAX_LAUNCHPAD_TYPE_NUM] =
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
- #ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-       { -1, -1 };
- #else
-       { -1 };
- #endif
-#else //_APPFW_FEATURE_PROCESS_POOL_COMMON
-       { -1 };
-#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
+       int sigchld_fd = -1;
+       int pool_fd[LAUNCHPAD_TYPE_MAX] = {
+               -1
+#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+               ,-1
+#endif // _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+#ifdef _APPFW_FEATURE_PROCESS_POOL_COMMON
+               ,-1
+#endif // _APPFW_FEATURE_PROCESS_POOL_COMMON
+               };
+
        struct pollfd pfds[POLLFD_MAX];
        int i;
 
@@ -1234,50 +612,50 @@ int main(int argc, char **argv)
 
        /* init without concerning X & EFL*/
        launchpad_fd = __launchpad_pre_init(argc, argv);
-       if (launchpad_fd < 0)
-       {
+       if (launchpad_fd < 0) {
                _E("launchpad pre init failed");
                exit(-1);
        }
-       pfds[LAUNCH_PAD].fd      = launchpad_fd;
+       pfds[LAUNCH_PAD].fd      = launchpad_fd;
        pfds[LAUNCH_PAD].events  = POLLIN;
        pfds[LAUNCH_PAD].revents = 0;
 
-       for (i = 0; i < MAX_LAUNCHPAD_TYPE_NUM; ++i)
-       {
-               pool_fd[i] = __listen_candidate_process(i + 1);
-               if (pool_fd[i] == -1)
-               {
-                       _E("[launchpad] Listening the socket to the type%d candidate process failed.", i + 1);
+       for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) {
+               pool_fd[i] = __listen_candidate_process(i);
+               if (pool_fd[i] == -1) {
+                       _E("[launchpad] Listening the socket to the type %d candidate process failed.", i);
                        goto error;
                }
-               pfds[POOL_TYPE1 + i].fd          = pool_fd[i];
-               pfds[POOL_TYPE1 + i].events  = POLLIN;
-               pfds[POOL_TYPE1 + i].revents = 0;
+               pfds[POOL_TYPE + i].fd   = pool_fd[i];
+               pfds[POOL_TYPE + i].events  = POLLIN;
+               pfds[POOL_TYPE + i].revents = 0;
+       }
+
+       sigchld_fd = __signal_get_sigchld_fd();
+       if (sigchld_fd == -1) {
+               _E("failed to get sigchld fd");
+               goto error;
        }
+       pfds[SIGCHLD_FD].fd = sigchld_fd;
+       pfds[SIGCHLD_FD].events = POLLIN;
+       pfds[SIGCHLD_FD].revents = 0;
 
 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
        int res = setpriority(PRIO_PROCESS, 0, -12);
-       if (res == -1)
-       {
+       if (res == -1) {
                SECURE_LOGE("Setting process (%d) priority to -12 failed, errno: %d (%s)",
                                getpid(), errno, strerror(errno));
        }
 #endif
-       while (1)
-       {
-               for (i = 0; i < MAX_LAUNCHPAD_TYPE_NUM; ++i)
-               {
-                       if (__candidate[i].pid == CANDIDATE_NONE)
-                       {
-                               pfds[CANDIDATE_TYPE1 + i].fd      = -1;
-                               pfds[CANDIDATE_TYPE1 + i].events  = 0;
-                               pfds[CANDIDATE_TYPE1 + i].revents = 0;
+       while (1) {
+               for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) {
+                       if (__candidate[i].pid == CANDIDATE_NONE) {
+                               pfds[CANDIDATE_TYPE + i].fd       = -1;
+                               pfds[CANDIDATE_TYPE + i].events  = 0;
+                               pfds[CANDIDATE_TYPE + i].revents = 0;
 
                                if (DIFF(__candidate[i].last_exec_time, time(NULL)) > EXEC_CANDIDATE_EXPIRED)
-                               {
-                                       __prepare_candidate_process(i + 1, launchpad_fd, pool_fd[i], -1);
-                               }
+                                       __prepare_candidate_process(i);
                        }
                }
 
@@ -1285,74 +663,78 @@ int main(int argc, char **argv)
                        continue;
 
                _D("pfds[LAUNCH_PAD].revent  : 0x%x", pfds[LAUNCH_PAD].revents) ;
-               _D("pfds[POOL_TYPE1].revents : 0x%x", pfds[POOL_TYPE1].revents) ;
-               _D("pfds[CANDIDATE_TYPE1].revents : 0x%x", pfds[CANDIDATE_TYPE1].revents) ;
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
-#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-               _D("pfds[POOL_TYPE2].revents : 0x%x", pfds[POOL_TYPE2].revents) ;
-               _D("pfds[CANDIDATE_TYPE2].revents : 0x%x", pfds[CANDIDATE_TYPE2].revents);
-#endif
-#endif
+               for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) {
+                       _D("pfds[POOL_TYPE + %d].revents : 0x%x", i, pfds[POOL_TYPE + i].revents) ;
+                       _D("pfds[CANDIDATE_TYPE + %d].revents : 0x%x", i, pfds[CANDIDATE_TYPE + i].revents);
+               }
+
                /* init with concerning X & EFL (because of booting
                * sequence problem)*/
-               if (__launchpad_post_init() < 0)
-               {
+               if (__launchpad_post_init() < 0) {
                        _E("launcpad post init failed");
                        goto error;
                }
 
-               if ((pfds[LAUNCH_PAD].revents & POLLIN) != 0)
-               {
+               if ((pfds[SIGCHLD_FD].revents & POLLIN) != 0) {
+                       struct signalfd_siginfo siginfo;
+                       ssize_t s;
+
+                       do {
+                               s = read(pfds[SIGCHLD_FD].fd, &siginfo, sizeof(struct signalfd_siginfo));
+                               if (s == 0)
+                                       break;
+
+                               if (s != sizeof(struct signalfd_siginfo)) {
+                                       _E("error reading sigchld info");
+                                       break;
+                               }
+                               __launchpad_process_sigchld(&siginfo);
+                       } while (s > 0);
+               }
+
+               if ((pfds[LAUNCH_PAD].revents & POLLIN) != 0) {
                        _D("pfds[LAUNCH_PAD].revents & POLLIN");
                        __launchpad_main_loop(pfds[LAUNCH_PAD].fd, pool_fd);
                }
 
-               for (i = 0; i < MAX_LAUNCHPAD_TYPE_NUM; ++i)
-               {
-                       if ((pfds[POOL_TYPE1 + i].revents & POLLIN) != 0)
-                       {
+               for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) {
+                       if ((pfds[POOL_TYPE + i].revents & POLLIN) != 0) {
                                int server_fd, client_fd;
                                int client_pid;
 
-                               server_fd = pfds[POOL_TYPE1 + i].fd;
+                               server_fd = pfds[POOL_TYPE + i].fd;
 
-                               _D("pfds[POOL_TYPE%d].revents & POLLIN", i + 1);
+                               _D("pfds[POOL_TYPE + %d].revents & POLLIN", i);
 
-                               if (__candidate[i].pid == CANDIDATE_NONE)
-                               {
+                               if (__candidate[i].pid == CANDIDATE_NONE) {
                                        __accept_candidate_process(server_fd, &client_fd, &client_pid);
 
                                        __candidate[i].pid = client_pid;
                                        __candidate[i].send_fd = client_fd;
 
-                                       pfds[CANDIDATE_TYPE1 + i].fd      = client_fd;
-                                       pfds[CANDIDATE_TYPE1 + i].events  = POLLIN | POLLHUP;
-                                       pfds[CANDIDATE_TYPE1 + i].revents = 0;
+                                       pfds[CANDIDATE_TYPE + i].fd       = client_fd;
+                                       pfds[CANDIDATE_TYPE + i].events  = POLLIN | POLLHUP;
+                                       pfds[CANDIDATE_TYPE + i].revents = 0;
 
-                                       SECURE_LOGD("Type%d candidate process was connected, pid: %d", i + 1, __candidate[i].pid);
-                               }
-                               else
-                               {
+                                       SECURE_LOGD("Type %d candidate process was connected, pid: %d", i, __candidate[i].pid);
+                               } else {
                                        __refuse_candidate_process(server_fd);
                                        _E("Refused candidate process connection");
                                }
                        }
 
-                       if ((pfds[CANDIDATE_TYPE1 + i].revents & (POLLHUP | POLLNVAL)) != 0)
-                       {
-                               SECURE_LOGD("pfds[CANDIDATE_TYPE%d].revents & (POLLHUP|POLLNVAL), pid: %d", i + 1, __candidate[i].pid);
+                       if ((pfds[CANDIDATE_TYPE + i].revents & (POLLHUP | POLLNVAL)) != 0) {
+                               SECURE_LOGD("pfds[CANDIDATE_TYPE + %d].revents & (POLLHUP|POLLNVAL), pid: %d", i, __candidate[i].pid);
 
-                               if (pfds[CANDIDATE_TYPE1 + i].fd > -1)
-                               {
-                                       close(pfds[CANDIDATE_TYPE1 + i].fd);
-                               }
+                               if (pfds[CANDIDATE_TYPE + i].fd > -1)
+                                       close(pfds[CANDIDATE_TYPE + i].fd);
 
                                __candidate[i].pid = CANDIDATE_NONE;
                                __candidate[i].send_fd = -1;
 
-                               pfds[CANDIDATE_TYPE1 + i].fd      = -1;
-                               pfds[CANDIDATE_TYPE1 + i].events  = 0;
-                               pfds[CANDIDATE_TYPE1 + i].revents = 0;
+                               pfds[CANDIDATE_TYPE + i].fd       = -1;
+                               pfds[CANDIDATE_TYPE + i].events  = 0;
+                               pfds[CANDIDATE_TYPE + i].revents = 0;
                        }
                }
        }
@@ -1361,20 +743,13 @@ int main(int argc, char **argv)
 
 error:
        if (launchpad_fd != -1)
-       {
                close(launchpad_fd);
-       }
 
-       for (i = 0; i < MAX_LAUNCHPAD_TYPE_NUM; ++i)
-       {
+       for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) {
                if (pool_fd[i] != -1)
-               {
                        close(pool_fd[i]);
-               }
                if (__candidate[i].send_fd != -1)
-               {
                        close(__candidate[i].send_fd);
-               }
        }
 
        return -1;
diff --git a/process_pool/launchpad_loader.c b/process_pool/launchpad_loader.c
new file mode 100644 (file)
index 0000000..3d28cd9
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <dlfcn.h>
+#include <poll.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <sqlite3.h>
+
+#include <aul.h>
+#include <Elementary.h>
+#include <Ecore.h>
+#include <bundle_internal.h>
+
+#include "config.h" //should be included first
+
+//including aul/launch
+#include <access_control.h>
+#include <app_sock.h>
+#include <menu_db_util.h>
+#include <perf.h>
+#include <simple_util.h>
+
+#include "preload.h"
+
+#include "process_pool.h"
+#include "process_pool_preload.h"
+#include "preexec.h"
+
+#include "smack_util.h"
+
+#define AUL_PR_NAME                    16
+
+#define LOWEST_PRIO 20
+
+static char *__appid = NULL;
+static char *__pkgid = NULL;
+
+const char* const HOME = "HOME";
+const char* const APP_HOME_PATH = "/opt/home/app";
+const char* const ROOT_HOME_PATH = "/opt/home/root";
+#define APP_UID 5000
+#define ROOT_UID 0
+
+static inline void __set_uid(uid_t uid);
+static inline void __set_env(app_info_from_db *menu_info, bundle *kb);
+static inline char **__create_argc_argv(bundle *kb, int *margc);
+static inline int __parser(const char *arg, char *out, int out_size);
+static inline void __modify_bundle(bundle * kb, int caller_pid,
+                               app_info_from_db * menu_info, int cmd);
+
+static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
+                       const char *pkgname, bundle *kb);
+
+static inline void __init_group(uid_t uid)
+{
+       int res;
+       struct passwd *pw;
+
+       pw = getpwuid(uid);
+       if (!pw) {
+               _E("failed to get pw from uid: %d: %s", uid, strerror(errno));
+               return;
+       }
+
+       res = initgroups(pw->pw_name, pw->pw_gid);
+       if (res == -1)
+               _E("failed to initgroups for uid: %d: %s", uid, strerror(errno));
+}
+
+static inline void __set_uid(uid_t uid)
+{
+       int res;
+
+       if (uid != ROOT_UID)
+               __init_group(uid);
+
+       res = setresuid(uid, uid, ROOT_UID);
+       if (res == -1) {
+               _E("failed to set user id to %d: %s", uid, strerror(errno));
+               return;
+       }
+
+       if (uid == ROOT_UID)
+               __init_group(uid);
+}
+
+static inline void __set_env(app_info_from_db * menu_info, bundle * kb)
+{
+       const char *str;
+
+       setenv("PKG_NAME", _get_pkgname(menu_info), 1);
+
+       str = bundle_get_val(kb, AUL_K_STARTTIME);
+       if (str != NULL)
+               setenv("APP_START_TIME", str, 1);
+
+       if (menu_info->hwacc != NULL)
+               setenv("HWACC", menu_info->hwacc, 1);
+       if (menu_info->taskmanage != NULL)
+               setenv("TASKMANAGE", menu_info->taskmanage, 1);
+}
+
+static inline char **__create_argc_argv(bundle * kb, int *margc)
+{
+       char **argv;
+       int argc;
+
+       argc = bundle_export_to_argv(kb, &argv);
+
+       *margc = argc;
+       return argv;
+}
+
+/*
+ * Parsing original app path to retrieve default bundle
+ *
+ * -1 : Invalid sequence
+ * -2 : Buffer overflow
+ *
+ */
+static inline int __parser(const char *arg, char *out, int out_size)
+{
+       register int i;
+       int state = 1;
+       char *start_out = out;
+
+       if (arg == NULL || out == NULL) {
+               /* Handles null buffer*/
+               return 0;
+       }
+
+       for (i = 0; out_size > 1; i++) {
+               switch (state) {
+               case 1:
+                       switch (arg[i]) {
+                       case ' ':
+                       case '\t':
+                               state = 5;
+                               break;
+                       case '\0':
+                               state = 7;
+                               break;
+                       case '\"':
+                               state = 2;
+                               break;
+                       case '\\':
+                               state = 4;
+                               break;
+                       default:
+                               *out = arg[i];
+                               out++;
+                               out_size--;
+                               break;
+                       }
+                       break;
+               case 2: /* escape start*/
+                       switch (arg[i]) {
+                       case '\0':
+                               state = 6;
+                               break;
+                       case '\"':
+                               state = 1;
+                               break;
+                       default:
+                               *out = arg[i];
+                               out++;
+                               out_size--;
+                               break;
+                       }
+                       break;
+               case 4: /* character escape*/
+                       if (arg[i] == '\0') {
+                               state = 6;
+                       } else {
+                               *out = arg[i];
+                               out++;
+                               out_size--;
+                               state = 1;
+                       }
+                       break;
+               case 5: /* token*/
+                       if (out != start_out) {
+                               *out = '\0';
+                               out_size--;
+                               return i;
+                       }
+                       i--;
+                       state = 1;
+                       break;
+               case 6:
+                       return -1;      /* error*/
+               case 7: /* terminate*/
+                       *out = '\0';
+                       out_size--;
+                       return 0;
+               default:
+                       state = 6;
+                       break;  /* error*/
+               }
+       }
+
+       if (out_size == 1)
+               *out = '\0';
+
+       /* Buffer overflow*/
+       return -2;
+}
+
+static inline void __modify_bundle(bundle * kb, int caller_pid,
+                       app_info_from_db * menu_info, int cmd)
+{
+       bundle_del(kb, AUL_K_PKG_NAME);
+       bundle_del(kb, AUL_K_EXEC);
+       bundle_del(kb, AUL_K_PACKAGETYPE);
+       bundle_del(kb, AUL_K_HWACC);
+       bundle_del(kb, AUL_K_TASKMANAGE);
+       bundle_del(kb, AUL_K_PKGID);
+
+       /* Parse app_path to retrieve default bundle*/
+       if (cmd == APP_START
+               || cmd == APP_START_RES
+               || cmd == APP_OPEN
+               || cmd == APP_RESUME
+               ) {
+               char *ptr;
+               char exe[MAX_PATH_LEN];
+               int flag;
+
+               ptr = _get_original_app_path(menu_info);
+
+               flag = __parser(ptr, exe, sizeof(exe));
+               if (flag > 0) {
+                       char key[256];
+                       char value[256];
+
+                       ptr += flag;
+                       SECURE_LOGD("parsing app_path: EXEC - %s\n", exe);
+
+                       do {
+                               flag = __parser(ptr, key, sizeof(key));
+                               if (flag <= 0)
+                                       break;
+                               ptr += flag;
+
+                               flag = __parser(ptr, value, sizeof(value));
+                               if (flag < 0)
+                                       break;
+                               ptr += flag;
+
+                               /*bundle_del(kb, key);*/
+                               bundle_add(kb, key, value);
+                       } while (flag > 0);
+               } else if (flag == 0)
+                       _D("parsing app_path: No arguments\n");
+               else
+                       _D("parsing app_path: Invalid argument\n");
+       }
+}
+
+static inline 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;
+
+       if (set_app_smack_label(app_path, type) != 0)
+               _E("set_app_smack_label() failed");
+
+       __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 bundle *_s_bundle = NULL;
+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 inline 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_PKG_NAME);
+       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) {
+                       SECURE_LOGE("Setting process (%d) priority to -10 failed, errno: %d (%s)",
+                               getpid(), errno, strerror(errno));
+               }
+       }
+       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)) {
+                       SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)",
+                               app_path, errno, strerror(errno));
+               }
+               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);
+
+       /* recover to root to process privileged operations */
+       __set_uid(ROOT_UID);
+
+       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 app_info_from_db *_get_app_info_from_bundle_by_pkgname(
+                       const char *pkgname, bundle *kb)
+{
+       app_info_from_db *menu_info;
+       const char *ptr = NULL;
+
+       menu_info = calloc(1, sizeof(app_info_from_db));
+       if (menu_info == NULL)
+               return NULL;
+
+       menu_info->pkg_name = strdup(pkgname);
+       ptr = bundle_get_val(kb, AUL_K_EXEC);
+       if (ptr)
+               menu_info->app_path = strdup(ptr);
+       if (menu_info->app_path != NULL)
+               menu_info->original_app_path = strdup(menu_info->app_path);
+       ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE);
+       if (ptr)
+               menu_info->pkg_type = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_HWACC);
+       if (ptr)
+               menu_info->hwacc = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_TASKMANAGE);
+       if (ptr)
+               menu_info->taskmanage = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_PKGID);
+       if (ptr)
+               menu_info->pkg_id= strdup(ptr);
+
+       if (!_get_app_path(menu_info)) {
+               _free_app_info_from_db(menu_info);
+               return NULL;
+       }
+
+       return menu_info;
+}
+
+int main(int argc, char **argv)
+{
+       static int type = LAUNCHPAD_TYPE_UNSUPPORTED;
+       int elm_init_cnt = 0;
+       Ecore_Fd_Handler *fd_handler = NULL;
+       void *handle = NULL;
+       int (*dl_main)(int, char **);
+       int client_fd;
+       int res;
+
+       if (argc < 2) {
+               _E("too few argument.");
+               return -1;
+       }
+
+       type = argv[1][0] - '0';
+       if (type < 0 || type >= LAUNCHPAD_TYPE_MAX) {
+               _E("invalid argument. (type: %d)", type);
+               return -1;
+       }
+
+       //temp - this requires some optimization.
+       sleep(1);
+       _D("sleeping 1 sec...");
+
+       __preload_init(argc, argv);
+       __preload_init_for_process_pool();
+       __preexec_init(argc, argv);
+
+       res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO);
+       if (res == -1) {
+               SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)",
+                               getpid(), LOWEST_PRIO, errno, strerror(errno));
+       }
+       _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 */
+       /* TODO : should be add to check permission in the kernel*/
+       setsid();
+
+       client_fd = __connect_to_launchpad(type);
+       if (client_fd == -1) {
+               _D("Connecting to candidate process was failed.");
+               return -1;
+       }
+
+       {
+               /* dummy code for hacking dbus setuid issue. */
+               DBusError err;
+               dbus_error_init(&err);
+               DBusConnection *tmp_con = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+               dbus_connection_set_exit_on_disconnect(tmp_con, FALSE);
+               dbus_connection_close(tmp_con);
+               dbus_connection_unref(tmp_con);
+       }
+
+       /* elementary related initialization is needed to be run as the app user */
+       __set_uid(APP_UID);
+
+       /* Temporarily change HOME path to app
+          This change is needed for getting elementary profile
+          /opt/home/app/.elementary/config/mobile/base.cfg */
+       setenv(HOME, APP_HOME_PATH, 1);
+
+       elm_init_cnt = elm_init(g_argc, g_argv);
+       _D("[candidate] elm init, returned: %d", elm_init_cnt);
+
+#ifdef _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING
+       if (type == LAUNCHPAD_TYPE_SW) {
+               elm_config_accel_preference_set("none");
+       }
+#endif // _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING
+#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+       if (type == LAUNCHPAD_TYPE_HW) {
+               elm_config_accel_preference_set("hw");
+       }
+#endif // _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+#ifdef _APPFW_FEATURE_PROCESS_POOL_COMMON
+       if (type != LAUNCHPAD_TYPE_COMMON)
+#endif // _APPFW_FEATURE_PROCESS_POOL_COMMON
+       {
+               Evas_Object *win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC);
+               if (win) {
+                       aul_set_preinit_window(win);
+
+                       Evas_Object *bg = elm_bg_add(win);
+                       if (bg) {
+                               evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                               elm_win_resize_object_add(win, bg);
+                               aul_set_preinit_background(bg);
+                       } else {
+                               _E("[candidate] elm_bg_add() failed");
+                       }
+
+                       Evas_Object *conform = elm_conformant_add(win);
+                       if (conform) {
+                               evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                               elm_win_resize_object_add(win, conform);
+                               aul_set_preinit_conformant(conform);
+                       } else {
+                               _E("elm_conformant_add() failed");
+                       }
+               } else {
+                       _E("[candidate] elm_win_add() failed");
+               }
+       }
+#ifdef _APPFW_FEATURE_PROCESS_POOL_COMMON
+       else {
+               char *theme = elm_theme_list_item_path_get(
+                       eina_list_data_get(elm_theme_list_get(NULL)), NULL);
+               Eina_Bool is_exist = edje_file_group_exists(theme, "*");
+               if (!is_exist)
+                       _D("theme path: %s", theme);
+
+               if (theme)
+                       free(theme);
+       }
+#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
+
+       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");
+
+       /* recover to root to process privileged operations */
+       __set_uid(ROOT_UID);
+
+       res = setpriority(PRIO_PGRP, 0, 0);
+       if (res == -1) {
+               SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)",
+                       getpid(), errno, strerror(errno));
+       }
+
+       /* set uid to app again to finish elementary related initialization in the main loop */
+       __set_uid(APP_UID);
+
+       _D("[candidate] ecore main loop begin");
+       ecore_main_loop_begin();
+
+       SECURE_LOGD("[candidate] Launch real application (%s)", g_argv[0]);
+       handle = dlopen(g_argv[0], RTLD_LAZY | RTLD_GLOBAL);
+       if (handle == NULL) {
+               _E("dlopen failed(%s). Please complile with -fPIE and link with -pie flag", dlerror());
+               goto do_exec;
+       }
+
+       dlerror();
+
+       dl_main = dlsym(handle, "main");
+       if (dl_main != NULL)
+               res = dl_main(g_argc, g_argv);
+       else {
+               _E("dlsym not founded(%s). Please export 'main' function", dlerror());
+               dlclose(handle);
+               goto do_exec;
+       }
+
+       dlclose(handle);
+       return res;
+
+do_exec:
+       if (access(g_argv[0], F_OK | R_OK)) {
+               SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)",
+                       g_argv[0], errno, strerror(errno));
+       } else {
+               SECURE_LOGD("[candidate] Exec application (%s)", g_argv[0]);
+               if (execv(g_argv[0], g_argv) < 0) {
+                       SECURE_LOGE("execv() failed for file: \"%s\", error: %d (%s)",
+                               g_argv[0], errno, strerror(errno));
+               }
+       }
+       return -1;
+}
diff --git a/process_pool/preload.h b/process_pool/preload.h
new file mode 100644 (file)
index 0000000..f9f719b
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+#ifdef PRELOAD_ACTIVATE
+
+#include <dlfcn.h>
+#define PRELOAD_FILE SHARE_PREFIX"/preload_list.txt"
+
+#define EFL_PREINIT_FUNC       "elm_quicklaunch_init"
+#define EFL_SHUTDOWN_FUNC      "elm_quicklaunch_shutdown"
+
+static int preload_initialized = 0;
+static int g_argc;
+static char **g_argv;
+static int max_cmdline_size = 0;
+
+static int (*dl_einit) () = NULL;
+static int (*dl_efini) () = NULL;
+
+static inline void __preload_init(int argc, char **argv)
+{
+       void *handle = NULL;
+       char soname[MAX_LOCAL_BUFSZ];
+       FILE *preload_list;
+       int (*func)() = NULL;
+       int i;
+
+       g_argc = argc;
+       g_argv = argv;
+       for (i = 0; i < argc; i++) {
+               max_cmdline_size += (strlen(argv[i]) + 1);
+       }
+       _D("max_cmdline_size = %d", max_cmdline_size);
+
+       preload_list = fopen(PRELOAD_FILE, "rt");
+       if (preload_list == NULL) {
+               _E("no preload\n");
+               return;
+       }
+
+       while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) {
+               soname[strlen(soname) - 1] = 0;
+               handle = dlopen((const char *) soname, RTLD_NOW);
+               if (handle == NULL)
+                       continue;
+               _D("preload %s# - handle : %x\n", soname, handle);
+
+               func = dlsym(handle, EFL_PREINIT_FUNC);
+               if (func != NULL) {
+                       _D("get pre-initialization function\n");
+                       dl_einit = func;
+                       func = dlsym(handle, EFL_SHUTDOWN_FUNC);
+                       if (func != NULL) {
+                               _D("get shutdown function\n");
+                               dl_efini = func;
+                       }
+               }
+       }
+
+       fclose(preload_list);
+       preload_initialized = 1;
+}
+
+static inline int preinit_init()
+{
+       if (dl_einit != NULL)
+               dl_einit(0, NULL);
+       _D("pre-initialzation on");
+       return 0;
+}
+
+static inline int preinit_fini()
+{
+       if (dl_efini != NULL)
+               dl_efini();
+       _D("pre-initialization off");
+       return 0;
+}
+
+/* TODO : how to set cmdline gracefully ?? */
+static inline int __change_cmdline(char *cmdline)
+{
+       if (strlen(cmdline) > max_cmdline_size + 1) {
+               _E("cmdline exceed max size : %d", max_cmdline_size);
+               return -1;
+       }
+
+       memset(g_argv[0], '\0', max_cmdline_size);
+       snprintf(g_argv[0], max_cmdline_size, "%s", cmdline);
+
+       return 0;
+}
+
+static inline void __preload_exec(int argc, char **argv)
+{
+       void *handle = NULL;
+       int (*dl_main) (int, char **);
+       char *error = NULL;
+
+       if (!preload_initialized)
+               return;
+
+       handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL);
+       if (handle == NULL) {
+               _E("dlopen(\"%s\") failed", argv[0]);
+               if ((error = dlerror()) != NULL) {
+                       _E("dlopen error: %s", error);
+               }
+               return;
+       }
+
+       dlerror();
+
+       dl_main = dlsym(handle, "main");
+       if (dl_main != NULL) {
+               if (__change_cmdline(argv[0]) < 0) {
+                       _E("change cmdline fail");
+                       dlclose(handle);
+                       return;
+               }
+
+#ifdef _APPFW_FEATURE_PRIORITY_CHANGE
+               int res = setpriority(PRIO_PROCESS, 0, 0);
+               if (res == -1)
+               {
+                       SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)",
+                                       getpid(), errno, strerror(errno));
+               }
+#endif
+               dl_main(argc, argv);
+       } else {
+               _E("dlsym not founded. bad preloaded app - check fpie pie");
+               if ((error = dlerror()) != NULL) {
+                       _E("dlsym error: %s", error);
+               }
+               dlclose(handle);
+               return;
+       }
+
+       exit(0);
+}
+
+#else
+
+static inline void __preload_init();
+static inline void __preload_exec(int argc, char **argv);
+
+#endif
+
index 7e62150..6b7ed0b 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include "process_pool.h"
 
 #define TMP_PATH "/tmp"
-#define LAUNCHPAD_TYPE1 ".launchpad-type1"
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
- #ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
- #define LAUNCHPAD_TYPE2 ".launchpad-type2"
- #endif
-#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
+#define LAUNCHPAD_TYPE ".launchpad-type"
+
 #define MAX_PENDING_CONNECTIONS 10
 #define CONNECT_RETRY_TIME 100 * 1000
 #define CONNECT_RETRY_COUNT 3
@@ -47,28 +44,14 @@ int __listen_candidate_process(int type)
 
        memset(&addr, 0x00, sizeof(struct sockaddr_un));
        addr.sun_family = AF_UNIX;
-       if (type == 1)
-       {
-               snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, LAUNCHPAD_TYPE1);
-       }
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
-#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-       else if (type == 2)
-       {
-               snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, LAUNCHPAD_TYPE2);
-       }
-#endif
-#endif
+       snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s%d", TMP_PATH, LAUNCHPAD_TYPE, type);
+
        listen_fds = sd_listen_fds(0);
-       if (listen_fds < 0)
-       {
+       if (listen_fds < 0) {
                _E("Invalid systemd environment");
                return -1;
-       }
-       else if (listen_fds > 0)
-       {
-               for (i = 0; i < listen_fds; i++)
-               {
+       } else if (listen_fds > 0) {
+               for (i = 0; i < listen_fds; i++) {
                        fd = SD_LISTEN_FDS_START + i;
                        if (sd_is_socket_unix(fd, SOCK_STREAM, 1, addr.sun_path, 0))
                                return fd;
@@ -78,8 +61,7 @@ int __listen_candidate_process(int type)
        }
 
        fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (fd < 0)
-       {
+       if (fd < 0) {
                _E("Socket error");
                goto error;
        }
@@ -87,22 +69,19 @@ int __listen_candidate_process(int type)
        unlink(addr.sun_path);
 
        _D("bind to %s", addr.sun_path);
-       if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
-       {
+       if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                _E("bind error");
                goto error;
        }
 
        _D("chmod %s", addr.sun_path);
-       if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0)
-       {
+       if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
                _E("chmod error");
                goto error;
        }
 
        _D("listen to %s", addr.sun_path);
-       if (listen(fd, MAX_PENDING_CONNECTIONS) == -1)
-       {
+       if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) {
                _E("listen error");
                goto error;
        }
@@ -112,9 +91,7 @@ int __listen_candidate_process(int type)
 
 error:
        if (fd != -1)
-       {
                close(fd);
-       }
 
        return -1;
 }
@@ -130,31 +107,18 @@ int __connect_to_launchpad(int type)
        _D("[launchpad] enter, type: %d", type);
 
        fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (fd < 0)
-       {
+       if (fd < 0) {
                _E("socket error");
                goto error;
        }
 
        memset(&addr, 0x00, sizeof(struct sockaddr_un));
        addr.sun_family = AF_UNIX;
-       if (type == 1)
-       {
-               snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, LAUNCHPAD_TYPE1);
-       }
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
-#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-       else if (type == 2)
-       {
-               snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, LAUNCHPAD_TYPE2);
-       }
-#endif
-#endif
+       snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s%d", TMP_PATH, LAUNCHPAD_TYPE, type);
+
        _D("connect to %s", addr.sun_path);
-       while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
-       {
-               if (errno != ETIMEDOUT || retry <= 0)
-               {
+       while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+               if (errno != ETIMEDOUT || retry <= 0) {
                        _E("connect error : %d", errno);
                        goto error;
                }
@@ -167,8 +131,7 @@ int __connect_to_launchpad(int type)
        send_ret = send(fd, &client_pid, sizeof(client_pid), 0);
        _D("send(%d) : %d", client_pid, send_ret);
 
-       if (send_ret == -1)
-       {
+       if (send_ret == -1) {
                _E("send error");
                goto error;
        }
@@ -178,9 +141,7 @@ int __connect_to_launchpad(int type)
 
 error:
        if (fd != -1)
-       {
                close(fd);
-       }
 
        return -1;
 }
@@ -189,24 +150,21 @@ int __accept_candidate_process(int server_fd, int* out_client_fd, int* out_clien
 {
        int client_fd = -1, client_pid = 0, recv_ret = 0;
 
-       if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL)
-       {
+       if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL) {
                _E("arguments error!");
                goto error;
        }
 
        client_fd = accept(server_fd, NULL, NULL);
 
-       if (client_fd == -1)
-       {
+       if (client_fd == -1) {
                _E("accept error!");
                goto error;
        }
 
        recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL);
 
-       if (recv_ret == -1)
-       {
+       if (recv_ret == -1) {
                _E("recv error!");
                goto error;
        }
@@ -218,9 +176,7 @@ int __accept_candidate_process(int server_fd, int* out_client_fd, int* out_clien
 
 error:
        if (client_fd != -1)
-       {
                close(client_fd);
-       }
 
        return -1;
 }
@@ -229,15 +185,13 @@ void __refuse_candidate_process(int server_fd)
 {
        int client_fd = -1;
 
-       if (server_fd == -1)
-       {
+       if (server_fd == -1) {
                _E("arguments error!");
                goto error;
        }
 
        client_fd = accept(server_fd, NULL, NULL);
-       if (client_fd == -1)
-       {
+       if (client_fd == -1) {
                _E("accept error!");
                goto error;
        }
@@ -254,8 +208,7 @@ int __send_pkt_raw_data(int client_fd, app_pkt_t *pkt)
        int send_ret = 0;
        int pkt_size = 0;
 
-       if (client_fd == -1 || pkt == NULL)
-       {
+       if (client_fd == -1 || pkt == NULL) {
                _E("arguments error!");
                goto error;
        }
@@ -265,13 +218,10 @@ int __send_pkt_raw_data(int client_fd, app_pkt_t *pkt)
        send_ret = send(client_fd, pkt, pkt_size, 0);
        _D("send(%d) : %d / %d", client_fd, send_ret, pkt_size);
 
-       if (send_ret == -1)
-       {
+       if (send_ret == -1) {
                _E("send error!");
                goto error;
-       }
-       else if (send_ret != pkt_size)
-       {
+       } else if (send_ret != pkt_size) {
                _E("send byte fail!");
                goto error;
        }
index a6a2c53..1e04aef 100644 (file)
 #ifdef __cplusplus
 extern "C"
 {
-#endif //__cplusplus
+#endif /* __cplusplus */
 
 #include <app_sock.h>
-
-static const int TYPE1 = 0;
-#ifndef _APPFW_FEATURE_PROCESS_POOL_COMMON
- #ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
-static const int TYPE2 = 1;
- #endif
-#endif //_APPFW_FEATURE_PROCESS_POOL_COMMON
+#include <vconf.h>
 
 int  __listen_candidate_process(int type);
 int  __connect_to_launchpad(int type);
@@ -37,8 +31,74 @@ int  __accept_candidate_process(int server_fd, int* out_client_fd, int* out_clie
 void __refuse_candidate_process(int server_fd);
 int  __send_pkt_raw_data(int client_fd, app_pkt_t* pkt);
 
+enum LAUNCHPAD_TYPE {
+       LAUNCHPAD_TYPE_UNSUPPORTED = -1,
+#ifdef _APPFW_FEATURE_PROCESS_POOL_COMMON
+       LAUNCHPAD_TYPE_COMMON,
+#endif /* _APPFW_FEATURE_PROCESS_POOL_COMMON */
+#ifdef _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING
+       LAUNCHPAD_TYPE_SW,
+#endif /* _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING */
+#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+       LAUNCHPAD_TYPE_HW,
+#endif /* _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING */
+       LAUNCHPAD_TYPE_MAX
+};
+
+static inline int __get_launchpad_type(const char* internal_pool, const char* hwacc)
+{
+#if defined(_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING) || defined(_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING)
+       if (internal_pool && strncmp(internal_pool, "true", 4) == 0 && hwacc) {
+#ifdef _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING
+               if (strncmp(hwacc, "NOT_USE", 7) == 0) {
+                       _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW);
+                       return LAUNCHPAD_TYPE_SW;
+               }
+#endif /* _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING */
+#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+               if (strncmp(hwacc, "USE", 3) == 0) {
+                       _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW);
+                       return LAUNCHPAD_TYPE_HW;
+               }
+#endif /* _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING */
+
+               if (strncmp(hwacc, "SYS", 3) == 0) {
+                       int r;
+                       int sys_hwacc = -1;
+
+                       r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &sys_hwacc);
+                       if (r != VCONF_OK)
+                               _E("failed to get vconf int: %s", VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
+
+                       SECURE_LOGD("sys hwacc: %d", sys_hwacc);
+
+#ifdef _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING
+                       if (sys_hwacc == SETTING_HW_ACCELERATION_ON) {
+                               _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW);
+                               return LAUNCHPAD_TYPE_HW;
+                       }
+#endif /* _APPFW_FEATURE_PROCESS_POOL_HW_RENDERING */
+#ifdef _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING
+                       if (sys_hwacc == SETTING_HW_ACCELERATION_OFF) {
+                               _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW);
+                               return LAUNCHPAD_TYPE_SW;
+                       }
+#endif /* _APPFW_FEATURE_PROCESS_POOL_SW_RENDERING */
+               }
+       }
+#endif /* defined(_APPFW_FEATURE_PROCESS_POOL_SW_RENDERING) || defined(_APPFW_FEATURE_PROCESS_POOL_HW_RENDERING) */
+
+#ifdef _APPFW_FEATURE_PROCESS_POOL_COMMON
+       _D("[launchpad] launchpad type: COMMON(%d)", LAUNCHPAD_TYPE_COMMON);
+       return LAUNCHPAD_TYPE_COMMON;
+#else /* _APPFW_FEATURE_PROCESS_POOL_COMMON */
+       _D("[launchpad] unsupported launchpad type, use legacy way");
+       return LAUNCHPAD_TYPE_UNSUPPORTED;
+#endif /* _APPFW_FEATURE_PROCESS_POOL_COMMON */
+}
+
 #ifdef __cplusplus
 }
-#endif //__cplusplus
+#endif /* __cplusplus */
 
-#endif //__PROCESS_POOL_H_
+#endif /* __PROCESS_POOL_H_ */
index 1fbd55f..4c77185 100644 (file)
@@ -30,50 +30,47 @@ static void** g_dlopen_handle_list = NULL;
 
 static inline int __preload_save_dlopen_handle(void *handle)
 {
-    if (!handle) {
-        return 1;
-    }
-    if (g_dlopen_count == g_dlopen_size || !g_dlopen_handle_list) {
-        void** tmp =
-            realloc(g_dlopen_handle_list, 2 * g_dlopen_size * sizeof(void *));
-        if (NULL == tmp) {
-            _E("out of memory\n");
-            dlclose(handle);
-            return 1;
-        }
-        g_dlopen_size *= 2;
-        g_dlopen_handle_list = tmp;
-    }
-    g_dlopen_handle_list[g_dlopen_count++] = handle;
-    return 0;
+       if (!handle)
+               return 1;
+
+       if (g_dlopen_count == g_dlopen_size || !g_dlopen_handle_list) {
+               void** tmp =
+                       realloc(g_dlopen_handle_list, 2 * g_dlopen_size * sizeof(void *));
+               if (NULL == tmp) {
+                       _E("out of memory\n");
+                       dlclose(handle);
+                       return 1;
+               }
+               g_dlopen_size *= 2;
+               g_dlopen_handle_list = tmp;
+       }
+       g_dlopen_handle_list[g_dlopen_count++] = handle;
+       return 0;
 }
 
 static inline void __preload_fini_for_process_pool(void)
 {
-    int i = 0;
-    if (!g_dlopen_handle_list) {
-        return;
-    }
-    for (i = 0; i < g_dlopen_count; ++i)
-    {
-        void *handle = g_dlopen_handle_list[i];
-        if (handle) {
-            if (0 != dlclose(handle)) {
-                _E("dlclose failed\n");
-            }
-        }
-    }
-    free(g_dlopen_handle_list);
-    g_dlopen_handle_list = NULL;
-    g_dlopen_size = 5;
-    g_dlopen_count = 0;
+       int i = 0;
+       if (!g_dlopen_handle_list)
+               return;
+
+       for (i = 0; i < g_dlopen_count; ++i) {
+               void *handle = g_dlopen_handle_list[i];
+               if (handle) {
+                       if (0 != dlclose(handle))
+                               _E("dlclose failed\n");
+               }
+       }
+       free(g_dlopen_handle_list);
+       g_dlopen_handle_list = NULL;
+       g_dlopen_size = 5;
+       g_dlopen_count = 0;
 }
 
 static inline void __preload_init_for_process_pool(void)
 {
-    if (atexit(__preload_fini_for_process_pool) != 0) {
-        _E("Cannot register atexit callback. Libraries will not be unloaded");
-    }
+       if (atexit(__preload_fini_for_process_pool) != 0)
+               _E("Cannot register atexit callback. Libraries will not be unloaded");
 
        void *handle = NULL;
        char soname[MAX_LOCAL_BUFSZ] = { 0, };
@@ -86,21 +83,21 @@ static inline void __preload_init_for_process_pool(void)
        }
 
        while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) {
-        size_t len = strnlen(soname, MAX_LOCAL_BUFSZ);
-        if (len > 0) {
-            soname[len - 1] = '\0';
-        }
+               size_t len = strnlen(soname, MAX_LOCAL_BUFSZ);
+               if (len > 0)
+                       soname[len - 1] = '\0';
+
                handle = dlopen((const char *) soname, RTLD_NOW);
                if (handle == NULL) {
-            _E("dlopen(\"%s\") was failed!", soname);
-            continue;
-        }
-
-        if (__preload_save_dlopen_handle(handle) != 0) {
-            _E("Cannot save handle, no more preloads");
-            break;
-        }
-        _D("preload %s# - handle : %x\n", soname, handle);
+                       _E("dlopen(\"%s\") was failed!", soname);
+                       continue;
+               }
+
+               if (__preload_save_dlopen_handle(handle) != 0) {
+                       _E("Cannot save handle, no more preloads");
+                       break;
+               }
+               _D("preload %s# - handle : %x\n", soname, handle);
        }
 
        fclose(preload_list);
diff --git a/process_pool/sigchild.h b/process_pool/sigchild.h
new file mode 100644 (file)
index 0000000..b7e0538
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+#include <pthread.h>
+#include <sys/signalfd.h>
+#include <signal.h>
+#include "app_signal.h"
+
+sigset_t oldmask;
+
+static inline void __socket_garbage_collector()
+{
+       DIR *dp;
+       struct dirent *dentry;
+       char tmp[MAX_LOCAL_BUFSZ];
+
+       dp = opendir(AUL_SOCK_PREFIX);
+       if (dp == NULL)
+               return;
+
+       while ((dentry = readdir(dp)) != NULL) {
+               if (!isdigit(dentry->d_name[0]))
+                       continue;
+
+               snprintf(tmp, MAX_LOCAL_BUFSZ, "/proc/%s", dentry->d_name);
+               if (access(tmp, F_OK) < 0) {    /* Flawfinder: ignore */
+                       snprintf(tmp, MAX_LOCAL_BUFSZ, "%s/%s", AUL_SOCK_PREFIX,
+                                dentry->d_name);
+                       unlink(tmp);
+                       continue;
+               }
+       }
+       closedir(dp);
+}
+
+static inline int __send_app_dead_signal(int dead_pid)
+{
+       DBusConnection *bus;
+       DBusMessage *message;
+       DBusError error;
+
+       dbus_error_init(&error);
+       dbus_threads_init_default();
+       bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+       if (!bus) {
+               _E("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free(&error);
+               return -1;
+       }
+
+       message = dbus_message_new_signal(AUL_DBUS_PATH,
+                                         AUL_DBUS_SIGNAL_INTERFACE,
+                                         AUL_DBUS_APPDEAD_SIGNAL);
+
+       if (dbus_message_append_args(message,
+                                    DBUS_TYPE_UINT32, &dead_pid,
+                                    DBUS_TYPE_INVALID) == FALSE) {
+               _E("Failed to load data error");
+               return -1;
+       }
+
+       if (dbus_connection_send(bus, message, NULL) == FALSE) {
+               _E("dbus send error");
+               return -1;
+       }
+
+       dbus_connection_flush(bus);
+       dbus_connection_close(bus);
+       dbus_message_unref(message);
+
+       _D("send dead signal done\n");
+
+       return 0;
+}
+
+static inline int __send_app_launch_signal(int launch_pid)
+{
+       DBusConnection *bus;
+       DBusMessage *message;
+       DBusError error;
+
+       dbus_error_init(&error);
+       dbus_threads_init_default();
+       bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+       if (!bus) {
+               _E("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free(&error);
+               return -1;
+       }
+
+       message = dbus_message_new_signal(AUL_DBUS_PATH,
+                                         AUL_DBUS_SIGNAL_INTERFACE,
+                                         AUL_DBUS_APPLAUNCH_SIGNAL);
+
+       if (dbus_message_append_args(message,
+                                    DBUS_TYPE_UINT32, &launch_pid,
+                                    DBUS_TYPE_INVALID) == FALSE) {
+               _E("Failed to load data error");
+               return -1;
+       }
+
+       if (dbus_connection_send(bus, message, NULL) == FALSE) {
+               _E("dbus send error");
+               return -1;
+       }
+
+       dbus_connection_flush(bus);
+       dbus_connection_close(bus);
+       dbus_message_unref(message);
+
+       _D("send launch signal done\n");
+
+       return 0;
+}
+
+static int __sigchild_action(void *data)
+{
+       pid_t dead_pid;
+       int ret;
+
+       dead_pid = (pid_t) data;
+       _I("dead_pid(%d)", dead_pid);
+       if (dead_pid <= 0)
+               goto end;
+
+       ret = __send_app_dead_signal(dead_pid);
+
+       _I("__send_app_dead_signal(%d)", ret);
+
+ end:
+       return 0;
+}
+
+static void __launchpad_process_sigchld(struct signalfd_siginfo *info)
+{
+       int status;
+       pid_t child_pid;
+       pid_t child_pgid;
+
+       child_pgid = getpgid(info->ssi_pid);
+       _I("dead_pid = %d pgid = %d", info->ssi_pid, child_pgid);
+
+       while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
+               if (child_pid == child_pgid)
+                       killpg(child_pgid, SIGKILL);
+               __sigchild_action((void *)child_pid);
+       }
+
+       _I("after __sigchild_action");
+
+       return;
+}
+
+static inline int __signal_init(void)
+{
+       int i;
+       for (i = 0; i < _NSIG; i++) {
+               switch (i) {
+                       /* controlled by sys-assert package*/
+               case SIGQUIT:
+               case SIGILL:
+               case SIGABRT:
+               case SIGBUS:
+               case SIGFPE:
+               case SIGSEGV:
+               case SIGPIPE:
+                       break;
+               default:
+                       signal(i, SIG_DFL);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static inline int __signal_get_sigchld_fd(void)
+{
+       sigset_t mask;
+       int sfd;
+
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGCHLD);
+
+       if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
+               _E("failed to sigprocmask");
+
+       sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
+       if (sfd == -1) {
+               _E("failed to create signalfd for SIGCHLD");
+               return -1;
+       }
+
+       return sfd;
+}
+
+static inline int __signal_unblock_sigchld(void)
+{
+       if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
+               _E("SIG_SETMASK error");
+               return -1;
+       }
+
+       _D("SIGCHLD unblocked");
+       return 0;
+}
+
+static inline int __signal_fini(void)
+{
+#ifndef PRELOAD_ACTIVATE
+       int i;
+       for (i = 0; i < _NSIG; i++)
+               signal(i, SIG_DFL);
+#endif
+       return 0;
+}
+
index 2342556..bff094e 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define _GNU_SOURCE
 #include <unistd.h>
 #include <sys/syscall.h>
 #include <stdio.h>
 #include <sys/smack.h>
 #include <dirent.h>
 #include <assert.h>
+#include <errno.h>
 
 #include <simple_util.h>
 
+#include "process_pool.h"
 #include "smack_util.h"
 
-#define SMACK_LABEL_LEN        255
-#define FILE_MAX_LEN           1024
-#define MAX_RETRY_CNT          1000
-#define UID_ROOT               0
+#define SMACK_LABEL_LEN        255
+#define FILE_MAX_LEN 1024
+#define MAX_RETRY_CNT 1000
+#define UID_ROOT 0
 
 static char s_smack_label[SMACK_LABEL_LEN + 1] = {0,};
 static int signal_cnt = 0;
+static struct sigaction old_act;
 
-static int
-smack_set_label_for_tid(const char *label)
+static int smack_set_label_for_tid(const char *label)
 {
        int len, fd, ret;
        char curren_path[FILE_MAX_LEN + 1] = {0,};
 
        len = strnlen(label, SMACK_LABEL_LEN + 1);
-
        if (len > SMACK_LABEL_LEN)
-       {
                return -1;
-       }
 
-       snprintf(curren_path, sizeof(curren_path), "/proc/%d/attr/current", (int)syscall(SYS_gettid));
+       snprintf(curren_path, sizeof(curren_path), "/proc/%d/attr/current",
+               (int)syscall(SYS_gettid));
        fd = open(curren_path, O_WRONLY);
-       if (fd < 0)
-       {
-               _E("open() failed. path: %s, errno: %d (%s)", curren_path, errno, strerror(errno));
+       if (fd < 0) {
+               _E("open() failed. path: %s, errno: %d (%s)",
+                       curren_path, errno, strerror(errno));
                return -1;
        }
 
@@ -66,117 +67,94 @@ smack_set_label_for_tid(const char *label)
        return (ret < 0) ? -1 : 0;
 }
 
-static void
-SIGUSR1_handler(int signo)
+static void SIGUSR1_handler(int signo)
 {
        if (smack_set_label_for_tid(s_smack_label) != 0)
-       {
                _E("smack_set_label_for_tid() failed!");
-       }
 
        SECURE_LOGD("tid: %d, signo: %d", (int)syscall(SYS_gettid), signo);
        ++signal_cnt;
 }
 
-static int
-set_SIGUSR1_handler()
+static int set_SIGUSR1_handler(void)
 {
-#if 1
-       if (signal(SIGUSR1, SIGUSR1_handler) == SIG_ERR)
-       {
-               _E("signal(SIGUSR1) failed.");
-               return -1;
-       }
-#else
-       struct sigaction usr_action;
-       sigset_t usr_mask;
+       struct sigaction new_act;
 
-       sigemptyset(&usr_mask);
-       usr_action.sa_handler = SIGUSR1_handler;
-       usr_action.sa_mask = usr_mask;
-       usr_action.sa_flags = 0;
+       sigemptyset(&new_act.sa_mask);
+       new_act.sa_handler = SIGUSR1_handler;
+       new_act.sa_flags = SA_RESTART;
 
-       if (sigaction(SIGUSR1, &usr_action, NULL) != 0)
-       {
+       if (sigaction(SIGUSR1, &new_act, &old_act) == -1) {
                _E("sigaction(SIGUSR1) failed.");
                return -1;
        }
-#endif
+
        return 0;
 }
 
-static int
-set_SIGUSR1_to_default()
+static int set_SIGUSR1_to_default(void)
 {
-       if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
-       {
-               _E("signal(SIGUSR1, SIG_ERR) failed!");
+       if (sigaction(SIGUSR1, &old_act, NULL) == -1) {
+               _E("sigaction(SIGUSR1) failed.");
                return -1;
        }
 
        return 0;
 }
 
-static int
-send_SIGUSR1_to_threads()
+static int send_SIGUSR1_to_threads(void)
 {
        int ret;
        DIR *dir;
        struct dirent entry, *result;
        char proc_self_task_path[FILE_MAX_LEN + 1] = {0, };
        int main_tid = (int)syscall(SYS_gettid);
+       int thr_cnt = 0;
 
        sprintf(proc_self_task_path, "/proc/self/task");
 
        dir = opendir(proc_self_task_path);
-       if (dir)
-       {
+       if (dir) {
                for (ret = readdir_r(dir, &entry, &result);
                                result != NULL && ret == 0;
-                               ret = readdir_r(dir, &entry, &result))
-               {
+                               ret = readdir_r(dir, &entry, &result)) {
                        if (strncmp(entry.d_name, ".", 2) == 0 ||
                                strncmp(entry.d_name, "..", 3) == 0)
-                       {
                                continue;
-                       }
 
                        int tid = atoi(entry.d_name);
-                       if (main_tid != tid)
-                       {
-                               SECURE_LOGD("Sending SIGUSR1 signal to the thread (%d).", tid);
-                               if (syscall(SYS_tkill, tid, SIGUSR1) != 0)
-                               {
-                                       _E("tkill(%d, SIGUSR1) failed.", tid);
+                       if (main_tid != tid) {
+                               SECURE_LOGD("SIGUSR1 signal to the sub-thread (%d) is sent.", tid);
+                               if (syscall(SYS_tkill, tid, SIGUSR1) != 0) {
+                                       _E("Sending SIGUSR1 singnal to sub-thread (%d) failed.", tid);
                                        closedir(dir);
                                        return -1;
                                }
+                               ++thr_cnt;
                        }
                }
 
                closedir(dir);
-       }
-       else
-       {
+       } else {
                _E("opendir(/proc/self/task) failed!");
                return -1;
        }
 
-       return 0;
+       return thr_cnt;
 }
 
-int
-set_app_smack_label(const char* app_path, int type)
+int set_app_smack_label(const char* app_path, int type)
 {
-       if (UID_ROOT != getuid() || app_path == NULL)
-       {
+       int thr_cnt = 0; // except main thread
+       int i = 0;
+
+       if (UID_ROOT != getuid() || app_path == NULL) {
                _E("parameter error!");
                return -1;
        }
 
        // set SIGUSR1 signal handler
-       if (set_SIGUSR1_handler() != 0)
-       {
+       if (set_SIGUSR1_handler() != 0) {
                _E("Setting signal hanlder failed.");
                return -1;
        }
@@ -184,57 +162,47 @@ set_app_smack_label(const char* app_path, int type)
        // get smack label from app_path
        char *smack_label = NULL;
 
-       if (smack_lgetlabel(app_path, &smack_label, SMACK_LABEL_EXEC) != 0)
-       {
+       if (smack_lgetlabel(app_path, &smack_label, SMACK_LABEL_EXEC) != 0) {
                _E("smack_lgetlabel() failed!");
-               goto error;
+               goto end;
        }
 
-       if (smack_label)
-       {
+       if (smack_label) {
                strncpy(s_smack_label, smack_label, sizeof(s_smack_label));
                s_smack_label[SMACK_LABEL_LEN] = '\0';
 
                free(smack_label);
                smack_label = NULL;
-       }
-       else
-       {
+       } else {
                _E("smack_label is NULL!");
                strcpy(s_smack_label, "");
        }
 
-       if (type == 2)
-       {
-               signal_cnt = 0;
+       signal_cnt = 0;
 
-               if (send_SIGUSR1_to_threads() != 0)
-               {
-                       _E("Sending SIGUSR1 singnal to sub-threads failed.");
-                       goto error;
-               }
+       thr_cnt = send_SIGUSR1_to_threads();
+       if (thr_cnt < 0)
+               goto end;
+       else if (thr_cnt == 0) {
+               set_SIGUSR1_to_default();
+               return 0;
+       }
 
-               // wait for labeling on each tasks
-               int i = 0;
-               for (i = 0; signal_cnt < (type - 1) && i < MAX_RETRY_CNT; ++i)
-               {
-                       usleep(1000); // 1 ms
-               }
+       // wait for labeling on each tasks.
+       for (i = 0; signal_cnt < thr_cnt && i < MAX_RETRY_CNT; ++i)
+               usleep(1000); // 1 ms
 
-               if (i == MAX_RETRY_CNT)
-               {
-                       _E("Thread subject label update failed.");
-               }
+       if (i == MAX_RETRY_CNT)
+               _E("Thread subject label update failed.");
 
-               _D("signal count: %d, launchpad type: %d", signal_cnt, type);
-       }
+       _D("signal count: %d, launchpad type: %d", signal_cnt, type);
 
-       // set SIGUSR1 signal defualt handler
+       // set SIGUSR1 signal default handler
        set_SIGUSR1_to_default();
 
        return 0;
 
-error:
+end:
        set_SIGUSR1_to_default();
 
        return -1;