4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 * simple AUL daemon - launchpad
30 #include <sys/types.h>
37 #include <sys/prctl.h>
45 #include "menu_db_util.h"
46 #include "simple_util.h"
47 #include "access_control.h"
59 #include <sys/smack.h>
60 #include "fileutils.h"
62 #define _static_ static inline
64 #define SQLITE_FLUSH_MAX (1048576) /* (1024*1024) */
65 #define AUL_POLL_CNT 15
66 #define AUL_PR_NAME 16
68 #define PATH_TMP "/tmp"
69 #define PATH_DATA "/data"
71 #define SDK_CODE_COVERAGE "CODE_COVERAGE"
72 #define SDK_DEBUG "DEBUG"
73 #define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
74 #define SDK_UNIT_TEST "UNIT_TEST"
75 #define SDK_VALGRIND "VALGRIND"
77 /* DLP is short for debug-launchpad */
78 #define DLP_K_DEBUG_ARG "__DLP_DEBUG_ARG__"
79 #define DLP_K_UNIT_TEST_ARG "__DLP_UNIT_TEST_ARG__"
80 #define DLP_K_VALGRIND_ARG "__DLP_VALGRIND_ARG__"
82 #define PATH_GDBSERVER "/home/developer/sdk_tools/gdbserver/gdbserver"
83 #define PATH_VALGRIND "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
84 #define PATH_DA_SO "/usr/lib/da_probe_osp.so"
85 #define PATH_NATIVE_APP "/opt/apps/"
87 #define OPT_VALGRIND_LOGFILE "--log-file="
88 #define OPT_VALGRIND_LOGFILE_FIXED "--log-file=/tmp/valgrind_result.txt"
89 #define PATH_VALGRIND_LOGFILE "/tmp/valgrind_result.txt"
90 #define OPT_VALGRIND_XMLFILE "--xml-file="
91 #define OPT_VALGRIND_XMLFILE_FIXED "--xml-file=/tmp/valgrind_result.xml"
92 #define PATH_VALGRIND_XMLFILE "/tmp/valgrind_result.xml"
94 #define POLL_VALGRIND_LOGFILE 0x00000001
95 #define POLL_VALGRIND_XMLFILE 0x00000002
97 static char *launchpad_cmdline;
98 static int initialized = 0;
100 static int poll_outputfile = 0;
103 void __set_env(app_info_from_db * menu_info, bundle * kb);
104 int __prepare_exec(const char *pkg_name,
105 const char *app_path, app_info_from_db * menu_info,
107 int __fake_launch_app(int cmd, int pid, bundle * kb);
108 char **__create_argc_argv(bundle * kb, int *margc, const char *app_path);
109 int __normal_fork_exec(int argc, char **argv);
110 void __real_launch(const char *app_path, bundle * kb);
111 static inline int __parser(const char *arg, char *out, int out_size);
112 void __modify_bundle(bundle * kb, int caller_pid,
113 app_info_from_db * menu_info, int cmd);
114 int __send_to_sigkill(int pid);
115 int __term_app(int pid);
116 void __real_send(int clifd, int ret);
117 void __send_result_to_caller(int clifd, int ret);
118 void __launchpad_main_loop(int main_fd);
119 int __launchpad_pre_init(int argc, char **argv);
120 int __launchpad_post_init();
122 extern ail_error_e ail_db_close(void);
128 char buf[MAX_LOCAL_BUFSZ];
131 /* we should reset oomadj value as default because child
132 inherits from parent oom_adj*/
133 snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid());
134 fp = fopen(buf, "w");
137 fprintf(fp, "%d", -16);
141 void __set_sdk_env(app_info_from_db* menu_info, char* str) {
142 char buf_pkgname[MAX_LOCAL_BUFSZ];
143 char buf[MAX_LOCAL_BUFSZ];
146 _D("key : %s / value : %s", AUL_K_SDK, str);
147 /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
148 /* GCOV_PREFIX contains the prefix to add to the absolute paths */
149 /* in the object file. Prefix can be absolute, or relative.*/
150 /* The default is no prefix. */
151 /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
152 /* to stripoff the hardwired absolute paths. Default value is 0. */
153 if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
154 strncpy(buf_pkgname,_get_pkgname(menu_info),MAX_LOCAL_BUFSZ-1);
155 buf_pkgname[MAX_LOCAL_BUFSZ-1]='\0';
156 snprintf(buf, MAX_LOCAL_BUFSZ, PATH_TMP"/%s"PATH_DATA
157 , strtok(buf_pkgname,"."));
158 ret = setenv("GCOV_PREFIX", buf, 1);
159 _D("GCOV_PREFIX : %d", ret);
160 ret = setenv("GCOV_PREFIX_STRIP", "0", 1);
161 _D("GCOV_PREFIX_STRIP : %d", ret);
162 } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
163 ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
164 _D("LD_PRELOAD : %d", ret);
169 void __set_env(app_info_from_db * menu_info, bundle * kb)
172 const char **str_array;
176 setenv("PKG_NAME", _get_pkgname(menu_info), 1);
180 str = bundle_get_val(kb, AUL_K_STARTTIME);
182 setenv("APP_START_TIME", str, 1);
184 if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
185 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
186 if(str_array != NULL) {
187 for (i = 0; i < len; i++) {
188 _D("index : [%d]", i);
189 __set_sdk_env(menu_info, (char *)str_array[i]);
193 str = bundle_get_val(kb, AUL_K_SDK);
195 __set_sdk_env(menu_info, (char *)str);
198 if (menu_info->hwacc != NULL)
199 setenv("HWACC", menu_info->hwacc, 1);
202 int __prepare_exec(const char *pkg_name,
203 const char *app_path, app_info_from_db * menu_info,
207 char process_name[AUL_PR_NAME];
210 /* Set new session ID & new process group ID*/
211 /* In linux, child can set new session ID without check permission */
212 /* TODO : should be add to check permission in the kernel*/
215 __preexec_run(menu_info->pkg_type, pkg_name, app_path);
221 if(bundle_get_val(kb, AUL_K_PRIVACY_APPID) == NULL) {
222 _D("pkg_name : %s / pkg_type : %s / app_path : %s ", pkg_name
223 , menu_info->pkg_type, app_path);
224 if ((ret = __set_access(pkg_name, menu_info->pkg_type
227 _D("fail to set privileges - check your package's credential : %d\n"
232 /* SET DUMPABLE - for coredump*/
233 prctl(PR_SET_DUMPABLE, 1);
235 /* SET PROCESS NAME*/
236 if (app_path == NULL) {
237 _D("app_path should not be NULL - check menu db");
240 file_name = strrchr(app_path, '/') + 1;
241 if (file_name == NULL) {
242 _D("can't locate file name to execute");
245 memset(process_name, '\0', AUL_PR_NAME);
246 snprintf(process_name, AUL_PR_NAME, "%s", file_name);
247 prctl(PR_SET_NAME, process_name);
250 __set_env(menu_info, kb);
255 int __fake_launch_app(int cmd, int pid, bundle * kb)
261 bundle_encode(kb, &kb_data, &datalen);
262 if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
263 _E("error request fake launch - error code = %d", ret);
268 char** __add_arg(bundle * kb, char **argv, int *margc, const char *key)
270 const char *str = NULL;
271 const char **str_array = NULL;
274 char ** new_argv = NULL;
276 if(bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
277 str_array = bundle_get_str_array(kb, key, &len);
279 str = bundle_get_val(kb, key);
285 if(str_array != NULL) {
286 if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
287 || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
289 new_argv = (char **) realloc(argv
290 , sizeof(char *) * (*margc+len+2));
292 _E("realloc fail (key = %s)", key);
295 for(i=*margc+len+1; i-(len+1)>=0; i--) {
296 new_argv[i] = new_argv[i-(len+1)];
298 // need to add new_argv[0]
299 for(i=0; i<len; i++) {
300 new_argv[1+i] = strdup(str_array[i]);
302 len++; /* gdbserver or valgrind */
303 _D("uid : %d", getuid());
304 _D("euid : %d", geteuid());
305 _D("gid : %d", getgid());
306 _D("egid : %d", getegid());
308 new_argv = (char **) realloc(argv
309 , sizeof(char *) * (*margc+len+1));
311 _E("realloc fail (key = %s)", key);
314 for(i=0; i<len; i++) {
315 new_argv[*margc+i] = strdup(str_array[i]);
318 new_argv[*margc+len] = NULL;
321 if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
322 || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
324 new_argv = (char **) realloc(argv
325 , sizeof(char *) * (*margc+2));
327 _E("realloc fail (key = %s)", key);
330 for(i=*margc+1; i-1>=0; i--) {
331 new_argv[i] = new_argv[i-1];
333 // need to add new_argv[0]
338 if(new_argv==NULL) return argv;
342 char **__create_argc_argv(bundle * kb, int *margc, const char *app_path)
345 char **new_argv = NULL;
348 const char *str = NULL;
349 const char **str_array = NULL;
353 argc = bundle_export_to_argv(kb, &argv);
355 for(i=1; i<argc; i++) {
356 argv[i] = strdup(argv[i]);
358 argv[0] = strdup(app_path);
360 _E("bundle_export_to_argv error");
364 if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
365 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
367 str = bundle_get_val(kb, AUL_K_SDK);
373 if(str_array == NULL) {
378 for (i = 0; i < len; i++) {
379 if(str_array[i] == NULL) break;
380 _D("index : [%d]", i);
382 if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
384 char buf[MAX_LOCAL_BUFSZ];
385 if (argv[0]) free(argv[0]);
386 sprintf(buf,"%s.exe",app_path);
387 argv[0] = strdup(buf);
388 new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
389 new_argv[0] = strdup(PATH_GDBSERVER);
392 else if (strncmp(str_array[i], SDK_VALGRIND
393 , strlen(str_array[i])) == 0)
395 new_argv = __add_arg(kb, argv, &argc
396 , DLP_K_VALGRIND_ARG);
397 new_argv[0] = strdup(PATH_VALGRIND);
400 else if (strncmp(str_array[i], SDK_UNIT_TEST
401 , strlen(str_array[i])) == 0)
403 new_argv = __add_arg(kb, argv, &argc
404 , DLP_K_UNIT_TEST_ARG);
409 if(new_argv==NULL) return argv;
413 int __normal_fork_exec(int argc, char **argv)
415 _D("start real fork and exec\n");
417 if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
418 if (errno == EACCES) {
419 _E("such a file is no executable - %s", argv[0]);
421 _E("unknown executable error - %s", argv[0]);
429 void __real_launch(const char *app_path, bundle * kb)
435 app_argv = __create_argc_argv(kb, &app_argc, app_path);
437 for (i = 0; i < app_argc; i++)
438 _D("input argument %d : %s##", i, app_argv[i]);
440 PERF("setup argument done");
441 _D("lock up test log(no error) : setup argument done");
443 /* Temporary log: launch time checking */
444 LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
446 __normal_fork_exec(app_argc, app_argv);
448 for(i=0; i<app_argc; i++) {
449 if(app_argv[i]) free(app_argv[i]);
456 * Parsing original app path to retrieve default bundle
458 * -1 : Invalid sequence
459 * -2 : Buffer overflow
462 static inline int __parser(const char *arg, char *out, int out_size)
466 char *start_out = out;
468 if (arg == NULL || out == NULL) {
469 /* Handles null buffer*/
473 for (i = 0; out_size > 1; i++) {
497 case 2: /* escape start*/
512 case 4: /* character escape*/
513 if (arg[i] == '\0') {
523 if (out != start_out) {
532 return -1; /* error*/
533 case 7: /* terminate*/
550 void __modify_bundle(bundle * kb, int caller_pid,
551 app_info_from_db * menu_info, int cmd)
553 bundle_del(kb, AUL_K_PKG_NAME);
554 bundle_del(kb, AUL_K_EXEC);
555 bundle_del(kb, AUL_K_PACKAGETYPE);
556 bundle_del(kb, AUL_K_HWACC);
558 /* Parse app_path to retrieve default bundle*/
559 if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN
560 || cmd == APP_RESUME)
563 char exe[MAX_PATH_LEN];
566 ptr = _get_original_app_path(menu_info);
568 flag = __parser(ptr, exe, sizeof(exe));
574 _D("parsing app_path: EXEC - %s\n", exe);
577 flag = __parser(ptr, key, sizeof(key));
582 flag = __parser(ptr, value, sizeof(value));
587 /*bundle_del(kb, key);*/
588 bundle_add(kb, key, value);
590 } else if (flag == 0) {
591 _D("parsing app_path: No arguments\n");
593 _D("parsing app_path: Invalid argument\n");
598 int __send_to_sigkill(int pid)
606 if (killpg(pgid, SIGKILL) < 0)
612 int __term_app(int pid)
616 (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
617 _D("terminate packet send error - use SIGKILL");
618 if (__send_to_sigkill(pid) < 0) {
619 _E("fail to killing - %d\n", pid);
627 static int __get_caller_pid(bundle *kb)
632 pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
636 pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
648 int __foward_cmd(int cmd, bundle *kb, int cr_pid)
651 char tmp_pid[MAX_PID_STR_BUFSZ];
656 if ((pid = __get_caller_pid(kb)) < 0)
659 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
661 bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
663 bundle_encode(kb, &kb_data, &datalen);
664 if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
672 void __real_send(int clifd, int ret)
674 if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
675 if (errno == EPIPE) {
676 _E("send failed due to EPIPE.\n");
678 _E("send fail to client");
684 void __send_result_to_caller(int clifd, int ret)
688 int cmdline_changed = 0;
689 int cmdline_exist = 0;
695 __real_send(clifd, ret);
698 /* check normally was launched?*/
701 cmdline = __proc_get_cmdline_bypid(ret);
702 if (cmdline == NULL) {
703 _E("error founded when being launched with %d", ret);
705 } else if (strcmp(cmdline, launchpad_cmdline)) {
714 _D("-- now wait to change cmdline --");
715 usleep(50 * 1000); /* 50ms sleep*/
717 } while (wait_count <= 20); /* max 50*20ms will be sleep*/
719 if ((!cmdline_exist) && (!cmdline_changed)) {
720 _E("abnormally launched");
721 __real_send(clifd, -1); /* abnormally launched*/
725 if (!cmdline_changed)
726 _E("process launched, but cmdline not changed");
728 __real_send(clifd, ret);
732 static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
733 const char *pkgname, bundle *kb)
735 app_info_from_db *menu_info;
737 menu_info = calloc(1, sizeof(app_info_from_db));
738 if (menu_info == NULL) {
742 menu_info->pkg_name = strdup(pkgname);
743 menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
744 if (menu_info->app_path != NULL)
745 menu_info->original_app_path = strdup(menu_info->app_path);
746 menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
747 menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
749 if (!_get_app_path(menu_info)) {
750 _free_app_info_from_db(menu_info);
760 int get_native_appid(const char* app_path, char** appid) {
761 int rc = smack_lgetlabel(app_path, appid, SMACK_LABEL_ACCESS);
763 if (rc != 0 || *appid == NULL) {
764 _E("smack_lgetlabel fail");
768 if (strlen(*appid) != APPID_LEN) {
769 _E("wrong native appid : %s", *appid);
773 if (strlen(app_path) < sizeof(PATH_NATIVE_APP)+APPID_LEN-1) {
774 _E("wrong native app_path : %s", app_path);
777 else if ( strncmp(app_path, PATH_NATIVE_APP, sizeof(PATH_NATIVE_APP)-1)
778 || strncmp(&app_path[sizeof(PATH_NATIVE_APP)-1]
779 , *appid,APPID_LEN) )
781 _E("wrong native app_path : %s", app_path);
785 _D("get_appid return : %s", *appid);
789 int apply_smack_rules(const char* subject, const char* object
790 , const char* access_type)
792 struct smack_accesses *rules = NULL;
794 _D("apply_smack_rules : %s %s %s", subject, object, access_type);
796 if (smack_accesses_new(&rules)) {
797 _E("smack_accesses_new fail");
801 if (smack_accesses_add(rules, subject, object, access_type)) {
802 smack_accesses_free(rules);
803 _E("smack_accesses_add fail");
807 if (smack_accesses_apply(rules)) {
808 smack_accesses_free(rules);
809 _E("smack_accesses_apply fail");
813 smack_accesses_free(rules);
818 int __prepare_valgrind_outputfile(bundle *kb)
820 const char *str = NULL;
821 const char **str_array = NULL;
825 if(bundle_get_type(kb, DLP_K_VALGRIND_ARG) & BUNDLE_TYPE_ARRAY) {
826 str_array = bundle_get_str_array(kb, DLP_K_VALGRIND_ARG, &len);
828 str = bundle_get_val(kb, DLP_K_VALGRIND_ARG);
834 if(str_array == NULL) return 0;
836 for (i = 0; i < len; i++) {
837 if(str_array[i] == NULL) break;
838 /* valgrind log file option */
839 if (strncmp(str_array[i], OPT_VALGRIND_LOGFILE
840 , strlen(OPT_VALGRIND_LOGFILE)) == 0)
842 if(strncmp(str_array[i], OPT_VALGRIND_LOGFILE_FIXED
843 , strlen(str_array[i])))
845 _E("wrong valgrind option(%s). It should be %s"
847 , OPT_VALGRIND_LOGFILE_FIXED);
850 poll_outputfile |= POLL_VALGRIND_LOGFILE;
851 if(remove(PATH_VALGRIND_LOGFILE)){
852 _D("cannot remove %s"
853 , PATH_VALGRIND_LOGFILE);
857 /* valgrind xml file option */
858 else if (strncmp(str_array[i], OPT_VALGRIND_XMLFILE
859 , strlen(OPT_VALGRIND_XMLFILE)) == 0)
861 if(strncmp(str_array[i], OPT_VALGRIND_XMLFILE_FIXED
862 , strlen(str_array[i])))
864 _E("wrong valgrind option(%s). It should be %s"
866 , OPT_VALGRIND_XMLFILE_FIXED);
869 poll_outputfile |= POLL_VALGRIND_XMLFILE;
870 if(remove(PATH_VALGRIND_XMLFILE)){
871 _D("cannot remove %s"
872 , PATH_VALGRIND_XMLFILE);
880 int __prepare_fork(bundle *kb, char *appid)
882 const char *str = NULL;
883 const char **str_array = NULL;
888 if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
889 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
891 str = bundle_get_val(kb, AUL_K_SDK);
897 if(str_array == NULL) return 0;
899 for (i = 0; i < len; i++) {
900 if(str_array[i] == NULL) break;
902 if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
904 if(apply_smack_rules("sdbd",appid,"w")) {
905 _E("unable to set sdbd rules");
909 // FIXME: set gdbfolder to 755 also
910 if(dlp_chmod(PATH_GDBSERVER
911 , S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP
915 _D("unable to set 755 to %s", PATH_GDBSERVER);
919 else if (strncmp(str_array[i], SDK_VALGRIND
920 , strlen(str_array[i])) == 0)
922 if (__prepare_valgrind_outputfile(kb)) return 1;
928 /* chmod and chsmack to read file without root privilege */
929 void __chmod_chsmack_toread(const char * path)
932 if(dlp_chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 0))
934 _E("unable to set 644 to %s", path);
936 _D("set 644 to %s", path);
940 if(smack_setlabel(path, "*", SMACK_LABEL_ACCESS))
942 _E("failed chsmack -a \"*\" %s", path);
944 _D("chsmack -a \"*\" %s", path);
950 /* waiting for creating outputfile by child process */
951 void __waiting_outputfile()
954 while(poll_outputfile && wait_count<10) {
955 /* valgrind log file */
956 if( (poll_outputfile & POLL_VALGRIND_LOGFILE)
957 && (access(PATH_VALGRIND_LOGFILE,F_OK)==0) )
959 __chmod_chsmack_toread(PATH_VALGRIND_LOGFILE);
960 poll_outputfile &= ~POLL_VALGRIND_LOGFILE;
963 /* valgrind xml file */
964 if( (poll_outputfile & POLL_VALGRIND_XMLFILE)
965 && (access(PATH_VALGRIND_XMLFILE,F_OK)==0) )
967 __chmod_chsmack_toread(PATH_VALGRIND_XMLFILE);
968 poll_outputfile &= ~POLL_VALGRIND_XMLFILE;
971 if(poll_outputfile) {
972 _D("-- now wait for creating the file --");
973 usleep(50 * 1000); /* 50ms sleep*/
978 if(wait_count==10) _E("faild to waiting");
982 int __stdout_stderr_redirection(int defpid)
984 char defpath[UNIX_PATH_MAX];
988 snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/1", defpid);
989 deffd = open(defpath,O_WRONLY);
991 _E("opening caller(%d) stdout failed due to %s"
992 , defpid, strerror(errno));
1000 snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/2", defpid);
1001 deffd = open(defpath,O_WRONLY);
1003 _E("opening caller(%d) stderr failed due to %s"
1004 , defpid,strerror(errno));
1014 void __launchpad_main_loop(int main_fd)
1017 app_pkt_t *pkt = NULL;
1018 app_info_from_db *menu_info = NULL;
1020 const char *pkg_name = NULL;
1021 const char *app_path = NULL;
1025 int is_real_launch = 0;
1027 char sock_path[UNIX_PATH_MAX] = {0,};
1028 char * appid = NULL;
1030 pkt = __app_recv_raw(main_fd, &clifd, &cr);
1032 _D("packet is NULL");
1036 kb = bundle_decode(pkt->data, pkt->len);
1038 _D("bundle decode error");
1043 PERF("packet processing start");
1045 pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
1046 _D("pkg name : %s\n", pkg_name);
1048 menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
1049 if (menu_info == NULL) {
1050 _D("such pkg no found");
1054 app_path = _get_app_path(menu_info);
1055 if(app_path == NULL) {
1056 _E("app_path is NULL");
1059 if (app_path[0] != '/') {
1060 _D("app_path is not absolute path");
1065 int rc = get_native_appid(app_path,&appid);
1066 if(rc!=0 || appid==NULL) {
1067 _E("unable to get native appid");
1068 if(appid) free(appid);
1073 __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
1074 pkg_name = _get_pkgname(menu_info);
1076 PERF("get package information & modify bundle done");
1078 if(__prepare_fork(kb,appid)) goto end;
1083 _D("lock up test log(no error) : fork done");
1087 __signal_unset_sigchld();
1090 snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX
1094 if(__stdout_stderr_redirection(__get_caller_pid(kb))) {
1095 _E("__stdout_stderr_redirection fail");
1098 PERF("prepare exec - first done");
1099 _D("lock up test log(no error) : prepare exec - first done");
1101 if (__prepare_exec(pkg_name, app_path,
1102 menu_info, kb) < 0) {
1103 _E("preparing work fail to launch - "
1104 "can not launch %s\n", pkg_name);
1108 PERF("prepare exec - second done");
1109 _D("lock up test log(no error) : prepare exec - second done");
1111 __real_launch(app_path, kb);
1116 _D("==> real launch pid : %d %s\n", pid, app_path);
1120 __send_result_to_caller(clifd, pid);
1123 if (is_real_launch) {
1125 __signal_block_sigchld();
1126 __send_app_launch_signal(pid);
1127 __signal_unblock_sigchld();
1131 if (menu_info != NULL)
1132 _free_app_info_from_db(menu_info);
1141 /* Active Flusing for Daemon */
1142 if (initialized > AUL_POLL_CNT) {
1143 sqlite3_release_memory(SQLITE_FLUSH_MAX);
1148 if(poll_outputfile) __waiting_outputfile();
1151 int __launchpad_pre_init(int argc, char **argv)
1158 /* get my(launchpad) command line*/
1159 launchpad_cmdline = __proc_get_cmdline_bypid(getpid());
1160 if (launchpad_cmdline == NULL) {
1161 _E("launchpad cmdline fail to get");
1164 _D("launchpad cmdline = %s", launchpad_cmdline);
1166 /* create launchpad sock */
1167 fd = __create_server_sock(DEBUG_LAUNCHPAD_PID);
1169 _E("server sock error");
1173 __preload_init(argc, argv);
1175 __preexec_init(argc, argv);
1180 int __launchpad_post_init()
1182 /* Setting this as a global variable to keep track
1183 of launchpad poll cnt */
1184 /* static int initialized = 0;*/
1191 if (__signal_set_sigchld() < 0)
1199 int main(int argc, char **argv)
1202 struct pollfd pfds[POLLFD_MAX];
1205 /* init without concerning X & EFL*/
1206 main_fd = __launchpad_pre_init(argc, argv);
1208 _E("launchpad pre init failed");
1212 pfds[0].fd = main_fd;
1213 pfds[0].events = POLLIN;
1214 pfds[0].revents = 0;
1217 if (poll(pfds, POLLFD_MAX, -1) < 0)
1220 /* init with concerning X & EFL (because of booting
1222 if (__launchpad_post_init() < 0) {
1223 _E("launcpad post init failed");
1227 for (i = 0; i < POLLFD_MAX; i++) {
1228 if ((pfds[i].revents & POLLIN) != 0) {
1229 __launchpad_main_loop(pfds[i].fd);