2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/prctl.h>
21 #include <sys/socket.h>
23 #include <sys/types.h>
28 #include <bundle_internal.h>
29 #include <security-manager.h>
32 #include <systemd/sd-daemon.h>
34 #include <linux/limits.h>
37 #include "launchpad_common.h"
40 #include "launchpad.h"
42 #define AUL_PR_NAME 16
43 #define EXEC_CANDIDATE_EXPIRED 5
44 #define EXEC_CANDIDATE_WAIT 1
45 #define DIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a))
46 #define CANDIDATE_NONE 0
47 #define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock"
48 #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader"
49 #define LOADER_PATH_WRT "/usr/bin/wrt-loader"
62 } candidate_process_context_t;
70 static GList *candidate_slot_list;
71 static candidate_process_context_t* __add_slot(int type, int loader_id, int caller_pid, const char *loader_path);
72 static int __remove_slot(int type, int loader_id);
74 static int __make_loader_id()
76 static int id = PAD_LOADER_ID_DYNAMIC_BASE;
81 static candidate_process_context_t* __find_slot_from_static_type(int type)
83 GList *iter = candidate_slot_list;
85 if (type == LAUNCHPAD_TYPE_DYNAMIC || type == LAUNCHPAD_TYPE_UNSUPPORTED)
89 candidate_process_context_t *cpc = (candidate_process_context_t*)iter->data;
90 if (type == cpc->type)
93 iter = g_list_next(iter);
99 static candidate_process_context_t* __find_slot_from_pid(int pid)
101 GList *iter = candidate_slot_list;
104 candidate_process_context_t *cpc = (candidate_process_context_t*)iter->data;
108 iter = g_list_next(iter);
114 static candidate_process_context_t* __find_slot_from_caller_pid(int caller_pid)
116 GList *iter = candidate_slot_list;
119 candidate_process_context_t *cpc = (candidate_process_context_t*)iter->data;
120 if (caller_pid == cpc->caller_pid)
123 iter = g_list_next(iter);
129 static candidate_process_context_t* __find_slot_from_loader_id(int id)
131 GList *iter = candidate_slot_list;
134 candidate_process_context_t *cpc = (candidate_process_context_t*)iter->data;
135 if (id == cpc->loader_id)
138 iter = g_list_next(iter);
144 static candidate_process_context_t* __find_slot(int type, int loader_id)
146 if (type == LAUNCHPAD_TYPE_DYNAMIC)
147 return __find_slot_from_loader_id(loader_id);
149 return __find_slot_from_static_type(type);
152 static void __kill_process(int pid)
154 char err_str[MAX_LOCAL_BUFSZ] = { 0, };
156 if (kill(pid, SIGKILL) == -1)
157 _E("send SIGKILL: %s", strerror_r(errno, err_str, sizeof(err_str)));
160 static void __refuse_candidate_process(int server_fd)
164 if (server_fd == -1) {
165 _E("arguments error!");
169 client_fd = accept(server_fd, NULL, NULL);
170 if (client_fd == -1) {
176 _D("refuse connection!");
182 static int __accept_candidate_process(int server_fd, int *out_client_fd,
189 if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL) {
190 _E("arguments error!");
194 client_fd = accept(server_fd, NULL, NULL);
196 if (client_fd == -1) {
201 recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL);
203 if (recv_ret == -1) {
208 *out_client_fd = client_fd;
209 *out_client_pid = client_pid;
211 return *out_client_fd;
220 static int __listen_candidate_process(int type, int loader_id)
222 struct sockaddr_un addr;
225 _D("[launchpad] enter, type: %d", type);
227 memset(&addr, 0x00, sizeof(struct sockaddr_un));
228 addr.sun_family = AF_UNIX;
229 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%d/%s%d-%d", SOCKET_PATH, getuid(),
230 LAUNCHPAD_LOADER_SOCKET_NAME, type, loader_id);
232 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
238 unlink(addr.sun_path);
240 _D("bind to %s", addr.sun_path);
241 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
246 _D("chmod %s", addr.sun_path);
247 if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
252 _D("listen to %s", addr.sun_path);
253 if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) {
258 SECURE_LOGD("[launchpad] done, listen fd: %d", fd);
268 static int __set_access(const char* appId, const char* pkg_type,
269 const char* app_path)
271 return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1;
274 static int __get_launchpad_type(const char* internal_pool, const char* hwacc, const char *pkg_type)
279 if (pkg_type && strncmp(pkg_type, "wgt", 3) == 0) {
280 _D("[launchpad] launchpad type: wrt");
281 return LAUNCHPAD_TYPE_WRT;
284 if (internal_pool && strncmp(internal_pool, "true", 4) == 0 && hwacc) {
285 if (strncmp(hwacc, "NOT_USE", 7) == 0) {
286 _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW);
287 return LAUNCHPAD_TYPE_SW;
289 if (strncmp(hwacc, "USE", 3) == 0) {
290 _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW);
291 return LAUNCHPAD_TYPE_HW;
293 if (strncmp(hwacc, "SYS", 3) == 0) {
294 r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &sys_hwacc);
296 _E("failed to get vconf int: %s", VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
298 SECURE_LOGD("sys hwacc: %d", sys_hwacc);
300 if (sys_hwacc == SETTING_HW_ACCELERATION_ON) {
301 _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW);
302 return LAUNCHPAD_TYPE_HW;
303 } else if (sys_hwacc == SETTING_HW_ACCELERATION_OFF) {
304 _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW);
305 return LAUNCHPAD_TYPE_SW;
310 _D("[launchpad] launchpad type: COMMON(%d)", LAUNCHPAD_TYPE_COMMON);
311 return LAUNCHPAD_TYPE_COMMON;
314 static int __get_loader_id(bundle *kb)
318 val = bundle_get_val(kb, AUL_K_LOADER_ID);
320 _E("failed to get loader_id");
327 static int __candidate_process_real_launch(int candidate_fd, app_pkt_t *pkt)
329 return _send_pkt_raw(candidate_fd, pkt);
332 static int __real_send(int clifd, int ret)
334 if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
335 if (errno == EPIPE) {
336 _E("send failed due to EPIPE.\n");
340 _E("send fail to client");
347 static void __send_result_to_caller(int clifd, int ret, const char* app_path)
351 _W("Check app launching");
357 _E("launching failed");
358 __real_send(clifd, ret);
362 cmdline = _proc_get_cmdline_bypid(ret);
363 if (cmdline == NULL) {
364 _E("The app process might be terminated while we are wating %d", ret);
365 __real_send(clifd, -1); /* abnormally launched*/
369 if (__real_send(clifd, ret) < 0)
375 static int __prepare_candidate_process(int type, int loader_id)
378 char type_str[2] = {0, };
379 char loader_id_str[10] = {0, };
380 char *argv[] = {NULL, NULL, NULL, NULL};
381 candidate_process_context_t* cpt = __find_slot(type, loader_id);
386 cpt->last_exec_time = time(NULL);
388 if (pid == 0) { /* child */
389 __signal_unblock_sigchld();
391 type_str[0] = '0' + type;
392 snprintf(loader_id_str, sizeof(loader_id_str), "%d", loader_id);
393 argv[0] = cpt->loader_path;
395 argv[2] = loader_id_str;
396 if (execv(argv[0], argv) < 0)
397 _E("Failed to prepare candidate_process");
399 _D("Succeeded to prepare candidate_process");
409 static gboolean __handle_preparing_candidate_process(gpointer user_data)
411 candidate_process_context_t *cpc = (candidate_process_context_t*)user_data;
413 __prepare_candidate_process(cpc->type, cpc->loader_id);
414 _D("Prepare another candidate process");
416 return G_SOURCE_REMOVE;
419 static int __send_launchpad_loader(candidate_process_context_t *cpc, app_pkt_t *pkt,
420 const char *app_path, int clifd, const char *comp_type)
422 char sock_path[PATH_MAX];
425 snprintf(sock_path, sizeof(sock_path), "/run/user/%d/%d", getuid(),
429 __candidate_process_real_launch(cpc->send_fd, pkt);
430 SECURE_LOGD("Request to candidate process, pid: %d, bin path: %s",
436 cpc->prepared = false;
437 cpc->pid = CANDIDATE_NONE;
439 if (cpc->source > 0) {
440 g_source_remove(cpc->source);
444 if (cpc->timer > 0) {
445 g_source_remove(cpc->timer);
449 __send_result_to_caller(clifd, pid, app_path); /* to AMD */
451 if (strcmp("uiapp", comp_type) == 0)
452 cpc->timer = g_timeout_add(5000, __handle_preparing_candidate_process, cpc);
454 cpc->timer = g_timeout_add(2000, __handle_preparing_candidate_process, cpc);
459 static int __normal_fork_exec(int argc, char **argv)
461 _D("start real fork and exec\n");
463 if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
465 _E("such a file is no executable - %s", argv[0]);
467 _E("unknown executable error - %s", argv[0]);
474 static void __real_launch(const char *app_path, bundle * kb)
480 if (bundle_get_val(kb, AUL_K_DEBUG) != NULL)
481 putenv("TIZEN_DEBUGGING_PORT=1");
483 app_argv = _create_argc_argv(kb, &app_argc);
484 app_argv[0] = strdup(app_path);
486 for (i = 0; i < app_argc; i++) {
489 SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
492 PERF("setup argument done");
493 __normal_fork_exec(app_argc, app_argv);
496 static int __prepare_exec(const char *appId, const char *app_path,
497 appinfo_t *menu_info, bundle * kb)
500 char process_name[AUL_PR_NAME];
503 /* Set new session ID & new process group ID*/
504 /* In linux, child can set new session ID without check permission */
505 /* TODO : should be add to check permission in the kernel*/
509 if (bundle_get_val(kb, AUL_K_PRIVACY_APPID) == NULL) {
510 _D("appId: %s / pkg_type : %s / app_path : %s ", appId, menu_info->pkg_type,
512 if ((ret = __set_access(appId, menu_info->pkg_type, app_path)) != 0) {
513 _D("fail to set privileges - check your package's credential : %d\n", ret);
517 /* SET DUMPABLE - for coredump*/
518 prctl(PR_SET_DUMPABLE, 1);
520 /* SET PROCESS NAME*/
521 if (app_path == NULL) {
522 _D("app_path should not be NULL - check menu db");
525 file_name = strrchr(app_path, '/') + 1;
526 if (file_name == NULL) {
527 _D("can't locate file name to execute");
530 memset(process_name, '\0', AUL_PR_NAME);
531 snprintf(process_name, AUL_PR_NAME, "%s", file_name);
532 prctl(PR_SET_NAME, process_name);
535 _set_env(menu_info, kb);
540 static int __launch_directly(const char *appid, const char *app_path, int clifd,
541 bundle* kb, appinfo_t *menu_info)
543 char sock_path[PATH_MAX];
550 _D("lock up test log(no error) : fork done");
552 __signal_unblock_sigchld();
555 max_fd = sysconf(_SC_OPEN_MAX);
556 for (iter_fd = 3; iter_fd <= max_fd; iter_fd++)
559 snprintf(sock_path, sizeof(sock_path), "/run/user/%d/%d", getuid(), getpid());
562 PERF("prepare exec - first done");
563 _D("lock up test log(no error) : prepare exec - first done");
565 if (__prepare_exec(appid, app_path,
566 menu_info, kb) < 0) {
567 SECURE_LOGE("preparing work fail to launch - "
568 "can not launch %s\n", appid);
572 PERF("prepare exec - second done");
573 _D("lock up test log(no error) : prepare exec - second done");
574 __real_launch(app_path, kb);
578 SECURE_LOGD("==> real launch pid : %d %s\n", pid, app_path);
583 static int __create_sock_activation(void)
587 fds = sd_listen_fds(0);
589 return SD_LISTEN_FDS_START;
591 _E("Too many file descriptors received.\n");
593 _D("There is no socket stream");
598 static int __launchpad_pre_init(int argc, char **argv)
605 /* create launchpad sock */
606 fd = __create_sock_activation();
608 fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_SOCK);
610 _E("server sock error %d", fd);
618 static void __destroy_poll_data(gpointer data)
623 static gboolean __glib_check(GSource *src)
628 fd_list = src->poll_fds;
630 tmp = (GPollFD *) fd_list->data;
631 if ((tmp->revents & (G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_NVAL)))
633 fd_list = fd_list->next;
639 static gboolean __glib_dispatch(GSource *src, GSourceFunc callback,
642 return callback(data);
645 static gboolean __glib_prepare(GSource *src, gint *timeout)
650 static GSourceFuncs funcs = {
651 .prepare = __glib_prepare,
652 .check = __glib_check,
653 .dispatch = __glib_dispatch,
657 static int __poll_fd(int fd, gushort events, GSourceFunc func, int type, int loader_id)
663 src = g_source_new(&funcs, sizeof(GSource));
669 gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
672 g_source_destroy(src);
676 gpollfd->events = events;
679 loader_context_t *lc = malloc(sizeof(loader_context_t));
682 g_source_destroy(src);
686 lc->gpollfd = gpollfd;
688 lc->loader_id = loader_id;
690 g_source_add_poll(src, gpollfd);
691 g_source_set_callback(src, func,
692 (gpointer) lc, __destroy_poll_data);
693 g_source_set_priority(src, G_PRIORITY_DEFAULT);
695 r = g_source_attach(src, NULL);
698 g_source_destroy(src);
705 static gboolean __handle_loader_client_event(gpointer data)
707 loader_context_t *lc = (loader_context_t*) data;
709 int loader_id = lc->loader_id;
710 gushort revents = lc->gpollfd->revents;
712 candidate_process_context_t *cpc = __find_slot(type, loader_id);
715 return G_SOURCE_REMOVE;
717 if (revents & (G_IO_HUP | G_IO_NVAL)) {
718 SECURE_LOGE("Type %d candidate process was (POLLHUP|POLLNVAL), pid: %d", cpc->type,
722 cpc->prepared = false;
723 cpc->pid = CANDIDATE_NONE;
727 g_source_remove(cpc->timer);
729 __prepare_candidate_process(cpc->type, cpc->loader_id);
731 return G_SOURCE_REMOVE;
734 return G_SOURCE_CONTINUE;
737 static gboolean __handle_loader_event(gpointer data)
739 loader_context_t *lc = (loader_context_t*) data;
740 int fd = lc->gpollfd->fd;
742 int loader_id = lc->loader_id;
746 candidate_process_context_t *cpc = __find_slot(type, loader_id);
749 return G_SOURCE_REMOVE;
751 if (!cpc->prepared) {
752 if (__accept_candidate_process(fd, &client_fd, &client_pid) >= 0) {
753 cpc->prepared = true;
754 cpc->send_fd = client_fd;
756 SECURE_LOGD("Type %d candidate process was connected, pid: %d", type,
759 cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP,
760 (GSourceFunc)__handle_loader_client_event, type, loader_id);
765 __refuse_candidate_process(fd);
766 _E("Refused candidate process connection");
769 return G_SOURCE_CONTINUE;
772 static gboolean __handle_sigchild(gpointer data)
774 loader_context_t *lc = (loader_context_t*) data;
775 int fd = lc->gpollfd->fd;
776 struct signalfd_siginfo siginfo;
780 s = read(fd, &siginfo, sizeof(struct signalfd_siginfo));
784 if (s != sizeof(struct signalfd_siginfo)) {
785 _E("error reading sigchld info");
788 __launchpad_process_sigchld(&siginfo);
789 candidate_process_context_t *cpc = __find_slot_from_pid(siginfo.ssi_pid);
792 cpc->prepared = false;
793 __prepare_candidate_process(cpc->type, cpc->loader_id);
796 cpc = __find_slot_from_caller_pid(siginfo.ssi_pid);
798 __remove_slot(LAUNCHPAD_TYPE_DYNAMIC, cpc->loader_id);
799 cpc = __find_slot_from_caller_pid(siginfo.ssi_pid);
804 return G_SOURCE_CONTINUE;
807 static int __dispatch_cmd_visibility(bundle *kb)
809 GList *iter = candidate_slot_list;
811 _W("cmd visibility");
813 candidate_process_context_t *cpc = (candidate_process_context_t*)iter->data;
815 if (cpc->pid == CANDIDATE_NONE) {
816 if (cpc->timer > 0) {
817 g_source_remove(cpc->timer);
820 __prepare_candidate_process(cpc->type, cpc->loader_id);
823 iter = g_list_next(iter);
829 static int __dispatch_cmd_add_loader(bundle *kb)
831 const char *add_slot_str = NULL;
832 const char *caller_pid = NULL;
835 _W("cmd add loader");
836 add_slot_str = bundle_get_val(kb, AUL_K_LOADER_PATH);
837 caller_pid = bundle_get_val(kb, AUL_K_CALLER_PID);
839 if (add_slot_str && caller_pid) {
840 lid = __make_loader_id();
841 candidate_process_context_t *cpc = __add_slot(LAUNCHPAD_TYPE_DYNAMIC, lid, atoi(caller_pid), add_slot_str);
843 cpc->timer = g_timeout_add(2000, __handle_preparing_candidate_process, cpc);
851 static int __dispatch_cmd_remove_loader(bundle *kb)
853 const char *id = bundle_get_val(kb, AUL_K_LOADER_ID);
856 _W("cmd remove loader");
859 if (__remove_slot(LAUNCHPAD_TYPE_DYNAMIC, lid) == 0)
866 static gboolean __handle_launch_event(gpointer data)
868 loader_context_t *lc = (loader_context_t*) data;
869 int fd = lc->gpollfd->fd;
871 app_pkt_t *pkt = NULL;
872 appinfo_t *menu_info = NULL;
873 candidate_process_context_t *cpc;
875 const char *app_path = NULL;
883 pkt = _recv_pkt_raw(fd, &clifd, &cr);
885 _E("packet is NULL");
889 kb = bundle_decode(pkt->data, pkt->len);
891 _E("bundle decode error");
896 case PAD_CMD_VISIBILITY:
897 ret = __dispatch_cmd_visibility(kb);
898 __real_send(clifd, ret);
901 case PAD_CMD_ADD_LOADER:
902 ret = __dispatch_cmd_add_loader(kb);
903 __real_send(clifd, ret);
906 case PAD_CMD_REMOVE_LOADER:
907 ret = __dispatch_cmd_remove_loader(kb);
908 __real_send(clifd, ret);
914 PERF("packet processing start");
916 menu_info = _appinfo_create(kb);
917 if (menu_info == NULL) {
918 _E("such pkg no found");
922 app_path = _appinfo_get_app_path(menu_info);
923 if (app_path == NULL) {
924 _E("app_path is NULL");
927 if (app_path[0] != '/') {
928 _E("app_path is not absolute path");
932 if (menu_info->hwacc == NULL) {
933 _E("[launchpad] Failed to find H/W acceleration type");
937 SECURE_LOGD("exec : %s\n", menu_info->app_path);
938 SECURE_LOGD("comp_type : %s\n", menu_info->comp_type);
939 SECURE_LOGD("internal pool : %s\n", menu_info->internal_pool);
940 SECURE_LOGD("hwacc : %s\n", menu_info->hwacc);
941 SECURE_LOGD("pkg_type : %s\n", menu_info->pkg_type);
943 if ((loader_id = __get_loader_id(kb)) <= PAD_LOADER_ID_STATIC) {
944 type = __get_launchpad_type(menu_info->internal_pool, menu_info->hwacc, menu_info->pkg_type);
946 _E("failed to get launchpad type");
949 loader_id = PAD_LOADER_ID_STATIC;
951 type = LAUNCHPAD_TYPE_DYNAMIC;
954 _modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
955 if (menu_info->appid == NULL) {
956 _E("unable to get appid from menu_info");
960 PERF("get package information & modify bundle done");
962 if (loader_id == PAD_LOADER_ID_DIRECT ||
963 (cpc = __find_slot(type, loader_id)) == NULL) {
964 _W("Launch directly");
965 pid = __launch_directly(menu_info->appid, app_path, clifd, kb, menu_info);
968 _W("Launch %d type process", type);
969 pid = __send_launchpad_loader(cpc, pkt, app_path, clifd, menu_info->comp_type);
970 } else if (cpc->type == LAUNCHPAD_TYPE_SW || cpc->type == LAUNCHPAD_TYPE_HW) {
971 cpc = __find_slot(LAUNCHPAD_TYPE_COMMON, loader_id);
972 if (cpc != NULL && cpc->prepared) {
973 _W("Launch common type process");
974 pid = __send_launchpad_loader(cpc, pkt, app_path, clifd, menu_info->comp_type);
976 _W("Launch directly");
977 pid = __launch_directly(menu_info->appid, app_path, clifd, kb, menu_info);
980 _W("Launch directly");
981 pid = __launch_directly(menu_info->appid, app_path, clifd, kb, menu_info);
985 __send_result_to_caller(clifd, pid, app_path);
992 __send_app_launch_signal_dbus(pid, menu_info->appid);
994 if (menu_info != NULL)
995 _appinfo_free(menu_info);
1002 return G_SOURCE_CONTINUE;
1005 static candidate_process_context_t* __add_slot(int type, int loader_id, int caller_pid, const char *loader_path)
1007 candidate_process_context_t *cpc;
1010 if (__find_slot(type, loader_id) != NULL)
1013 cpc = (candidate_process_context_t*)malloc(sizeof(candidate_process_context_t));
1018 cpc->prepared = false;
1019 cpc->pid = CANDIDATE_NONE;
1020 cpc->caller_pid = caller_pid;
1021 cpc->loader_id = loader_id;
1023 cpc->last_exec_time = 0;
1026 cpc->loader_path = strdup(loader_path);
1028 fd = __listen_candidate_process(cpc->type, cpc->loader_id);
1030 _E("[launchpad] Listening the socket to the type %d candidate process failed.",
1036 if (__poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_loader_event, cpc->type, cpc->loader_id) < 0) {
1042 candidate_slot_list = g_list_append(candidate_slot_list, cpc);
1047 static int __remove_slot(int type, int loader_id)
1050 iter = candidate_slot_list;
1053 candidate_process_context_t *cpc = (candidate_process_context_t*)iter->data;
1055 if (type == cpc->type && loader_id == cpc->loader_id) {
1057 __kill_process(cpc->pid);
1059 g_source_remove(cpc->timer);
1060 if (cpc->source > 0)
1061 g_source_remove(cpc->source);
1063 candidate_slot_list = g_list_remove_link(candidate_slot_list, iter);
1064 free(cpc->loader_path);
1069 iter = g_list_next(iter);
1075 static int __init_launchpad_fd(int argc, char **argv)
1079 fd = __launchpad_pre_init(argc, argv);
1081 _E("launchpad pre init failed");
1085 if (__poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_launch_event, 0, 0) < 0) {
1093 static int __init_sigchild_fd(void)
1097 fd = __signal_get_sigchld_fd();
1099 _E("failed to get sigchld fd");
1103 if (__poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_sigchild, 0, 0) < 0) {
1111 static int __add_default_slots()
1113 if (__add_slot(LAUNCHPAD_TYPE_COMMON, PAD_LOADER_ID_STATIC, 0, LOADER_PATH_DEFAULT) == NULL)
1115 if (__prepare_candidate_process(LAUNCHPAD_TYPE_COMMON, PAD_LOADER_ID_STATIC) != 0)
1118 if (__add_slot(LAUNCHPAD_TYPE_SW, PAD_LOADER_ID_STATIC, 0, LOADER_PATH_DEFAULT) == NULL)
1120 if (__prepare_candidate_process(LAUNCHPAD_TYPE_SW, PAD_LOADER_ID_STATIC) != 0)
1123 if (__add_slot(LAUNCHPAD_TYPE_HW, PAD_LOADER_ID_STATIC, 0, LOADER_PATH_DEFAULT) == NULL)
1125 if (__prepare_candidate_process(LAUNCHPAD_TYPE_HW, PAD_LOADER_ID_STATIC) != 0)
1128 if (access(LOADER_PATH_WRT, F_OK | X_OK) == 0) {
1129 if (__add_slot(LAUNCHPAD_TYPE_WRT, PAD_LOADER_ID_STATIC, 0, LOADER_PATH_WRT) == NULL)
1131 if (__prepare_candidate_process(LAUNCHPAD_TYPE_WRT, PAD_LOADER_ID_STATIC) != 0)
1138 static int __before_loop(int argc, char **argv)
1140 if (__init_sigchild_fd() != 0) {
1141 _E("__init_sigchild_fd() failed");
1145 if (__init_launchpad_fd(argc, argv) != 0) {
1146 _E("__init_launchpad_fd() failed");
1150 if (__add_default_slots() != 0) {
1151 _E("__add_default_slots() failed");
1158 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
1159 static void __set_priority(void)
1161 char err_str[MAX_LOCAL_BUFSZ] = { 0, };
1162 int res = setpriority(PRIO_PROCESS, 0, -12);
1165 SECURE_LOGE("Setting process (%d) priority to -12 failed, errno: %d (%s)",
1166 getpid(), errno, strerror_r(errno, err_str, sizeof(err_str)));
1170 int main(int argc, char **argv)
1172 GMainLoop *mainloop = NULL;
1174 mainloop = g_main_loop_new(NULL, FALSE);
1176 _E("failed to create glib main loop");
1180 if (__before_loop(argc, argv) != 0) {
1181 _E("process-pool Initialization failed!\n");
1185 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
1188 g_main_loop_run(mainloop);