c614d76ef413a731669725b8fabd7a4fec002686
[framework/appfw/aul-1.git] / launchpad_src / launchpad.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22
23 /*
24  * simple AUL daemon - launchpad 
25  */
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <dlfcn.h>
30 #include <X11/Xlib.h>
31 #include <sys/types.h>
32 #include <signal.h>
33 #include <dirent.h>
34 #include <fcntl.h>
35 #include <stdlib.h>
36 #include <sys/wait.h>
37 #include <poll.h>
38 #include <sys/prctl.h>
39 #include <malloc.h>
40
41 #include "app_sock.h"
42 #include "aul.h"
43
44 #include "config.h"
45
46 #include "menu_db_util.h"
47 #include "simple_util.h"
48 #include "access_control.h"
49 #include "preload.h"
50 #include "perf.h"
51 #include "sigchild.h"
52 #include "aul_util.h"
53
54 #include "heap_dbg.h"
55
56 #include "util_x.h"
57
58 #include "gl.h"
59
60 #include <app-checker.h>
61 #include <sqlite3.h>
62
63 #define _static_ static inline
64 #define POLLFD_MAX 1
65 #define SQLITE_FLUSH_MAX        (1048576)       /* (1024*1024) */
66 #define AUL_POLL_CNT            15
67 #define AUL_PR_NAME                     16
68 #define PATH_APP_ROOT "/opt/apps"
69 #define PATH_DATA "/data"
70 #define SDK_CODE_COVERAGE "CODE_COVERAGE"
71 #define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
72 #define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so"
73
74
75 static char *launchpad_cmdline;
76 static int initialized = 0;
77
78
79 _static_ void __set_oom();
80 _static_ void __set_env(app_info_from_db * menu_info, bundle * kb);
81 _static_ int __prepare_exec(const char *pkg_name,
82                             const char *app_path, app_info_from_db * menu_info,
83                             bundle * kb);
84 _static_ int __fake_launch_app(int cmd, int pid, bundle * kb);
85 _static_ char **__create_argc_argv(bundle * kb, int *margc);
86 _static_ int __normal_fork_exec(int argc, char **argv);
87 _static_ void __real_launch(const char *app_path, bundle * kb);
88 _static_ void __add_history(int caller, int callee, const char *pkgname,
89                                 bundle *b, const char *app_path);
90 static inline int __parser(const char *arg, char *out, int out_size);
91 _static_ void __modify_bundle(bundle * kb, int caller_pid,
92                             app_info_from_db * menu_info, int cmd);
93 _static_ int __child_raise_win_by_x(int pid, void *priv);
94 _static_ int __raise_win_by_x(int pid);
95 _static_ int __send_to_sigkill(int pid);
96 _static_ int __term_app(int pid);
97 _static_ int __resume_app(int pid);
98 _static_ int __app_process_by_pid(int cmd, 
99         const char *pkg_name, struct ucred *cr);
100 _static_ int __nofork_processing(int cmd, int pid, bundle * kb);
101 _static_ void __real_send(int clifd, int ret);
102 _static_ void __send_result_to_caller(int clifd, int ret);
103 _static_ void __launchpad_main_loop(int main_fd);
104 _static_ int __launchpad_pre_init(int argc, char **argv);
105 _static_ int __launchpad_post_init();
106
107 extern ail_error_e ail_db_close(void);
108
109
110
111 _static_ void __set_oom()
112 {
113         char buf[MAX_LOCAL_BUFSZ];
114         FILE *fp;
115
116         /* we should reset oomadj value as default because child 
117         inherits from parent oom_adj*/
118         snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid());
119         fp = fopen(buf, "w");
120         if (fp == NULL)
121                 return;
122         fprintf(fp, "%d", -16);
123         fclose(fp);
124 }
125
126 _static_ void __set_sdk_env(app_info_from_db* menu_info, char* str) {
127         char buf[MAX_LOCAL_BUFSZ];
128         int ret;
129
130         _D("key : %s / value : %s", AUL_K_SDK, str);
131         /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
132         /* GCOV_PREFIX contains the prefix to add to the absolute paths in the object file. */
133         /*              Prefix can be absolute, or relative. The default is no prefix.  */
134         /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
135         /*              to stripoff the hardwired absolute paths. Default value is 0. */
136         if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
137                 snprintf(buf, MAX_LOCAL_BUFSZ, PATH_APP_ROOT"/%s"PATH_DATA, _get_pkgname(menu_info));
138                 ret = setenv("GCOV_PREFIX", buf, 1);
139                 _D("GCOV_PREFIX : %d", ret);
140                 ret = setenv("GCOV_PREFIX_STRIP", "4096", 1);
141                 _D("GCOV_PREFIX_STRIP : %d", ret);
142         } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
143                 ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
144                 _D("LD_PRELOAD : %d", ret);
145         }
146 }
147
148
149 _static_ void __set_env(app_info_from_db * menu_info, bundle * kb)
150 {
151         const char *str;
152         const char **str_array;
153         int len;
154         int i;
155
156         setenv("PKG_NAME", _get_pkgname(menu_info), 1);
157
158         USE_ENGINE("gl")
159
160         str = bundle_get_val(kb, AUL_K_STARTTIME);
161         if (str != NULL)
162                 setenv("APP_START_TIME", str, 1);
163
164         if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
165                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
166                 if(str_array != NULL) {
167                         for (i = 0; i < len; i++) {
168                                 _D("index : [%d]", i);
169                                 __set_sdk_env(menu_info, (char *)str_array[i]);
170                         }
171                 }
172         } else {
173                 str = bundle_get_val(kb, AUL_K_SDK);
174                 if(str != NULL) {
175                         __set_sdk_env(menu_info, (char *)str);
176                 }
177         }
178 }
179
180 _static_ int __prepare_exec(const char *pkg_name,
181                             const char *app_path, app_info_from_db * menu_info,
182                             bundle * kb)
183 {
184         char *file_name;
185         char process_name[AUL_PR_NAME];
186
187         /* Set new session ID & new process group ID*/
188         /* In linux, child can set new session ID without check permission */
189         /* TODO : should be add to check permission in the kernel*/
190         setsid();
191
192         /* SET OOM*/
193         __set_oom();
194
195         /* SET SMACK LABEL */
196         __set_smack((char *)app_path);
197
198         /* SET DAC*/
199         if (__set_dac(pkg_name) < 0) {
200                 _D("fail to set DAC - check your package's credential\n");
201                 return -1;
202         }
203         /* SET DUMPABLE - for coredump*/
204         prctl(PR_SET_DUMPABLE, 1);
205
206         /* SET PROCESS NAME*/
207         if (app_path == NULL) {
208                 _D("app_path should not be NULL - check menu db");
209                 return -1;
210         }
211         file_name = strrchr(app_path, '/') + 1;
212         if (file_name == NULL) {
213                 _D("can't locate file name to execute");
214                 return -1;
215         }
216         memset(process_name, '\0', AUL_PR_NAME);
217         snprintf(process_name, AUL_PR_NAME, "%s", file_name);
218         prctl(PR_SET_NAME, process_name);
219
220         /* SET ENVIROMENT*/
221         __set_env(menu_info, kb);
222
223         return 0;
224 }
225
226 _static_ int __fake_launch_app(int cmd, int pid, bundle * kb)
227 {
228         int datalen;
229         int ret;
230         bundle_raw *kb_data;
231
232         bundle_encode(kb, &kb_data, &datalen);
233         if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
234                 _E("error request fake launch - error code = %d", ret);
235         free(kb_data);
236         return ret;
237 }
238
239 _static_ char **__create_argc_argv(bundle * kb, int *margc)
240 {
241         char **argv;
242         int argc;
243
244         argc = bundle_export_to_argv(kb, &argv);
245
246         *margc = argc;
247         return argv;
248 }
249
250 _static_ int __normal_fork_exec(int argc, char **argv)
251 {
252         _D("start real fork and exec\n");
253
254         if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
255                 if (errno == EACCES)
256                         _E("such a file is no executable - %s", argv[0]);
257                 else
258                         _E("unknown executable error - %s", argv[0]);
259                 return -1;
260         }
261         /* never reach*/
262         return 0;
263 }
264
265 _static_ void __real_launch(const char *app_path, bundle * kb)
266 {
267         int app_argc;
268         char **app_argv;
269         int i;
270
271         app_argv = __create_argc_argv(kb, &app_argc);
272         app_argv[0] = strdup(app_path);
273
274         for (i = 0; i < app_argc; i++)
275                 _D("input argument %d : %s##", i, app_argv[i]);
276
277         PERF("setup argument done");
278         _E("lock up test log(no error) : setup argument done");
279
280         /* Temporary log: launch time checking */
281         LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
282
283         __preload_exec(app_argc, app_argv);
284
285         __normal_fork_exec(app_argc, app_argv);
286 }
287
288 _static_ void __add_history(int caller, int callee, const char *pkgname, 
289                                 bundle *b, const char *app_path)
290 {
291         struct history_data *hd;
292         bundle_raw *kb_data;
293         int len;
294
295         _D("***** HISTORY *****\n");
296         _D("%d ==> %d(%s) \n", caller, callee, pkgname);
297         _D("*******************\n");
298
299         if (b) {
300                 bundle_encode(b, (bundle_raw **)&kb_data, &len);
301                 hd = (struct history_data *)malloc(sizeof(char) * (len+1029));
302
303                 strncpy(hd->pkg_name, pkgname, MAX_PACKAGE_STR_SIZE-1);
304                 strncpy(hd->app_path, app_path, MAX_PACKAGE_APP_PATH_SIZE-1);
305                 hd->len = len;
306                 memcpy(hd->data, kb_data, len);
307
308                 __app_send_raw(AUL_UTIL_PID, ADD_HISTORY, (unsigned char *)hd,
309                         hd->len+1029);
310                 free(kb_data);
311                 free(hd);
312         } else {
313                 hd = (struct history_data *)malloc(sizeof(char) * 1029);
314
315                 strncpy(hd->pkg_name, pkgname, MAX_PACKAGE_STR_SIZE-1);
316                 strncpy(hd->app_path, app_path, MAX_PACKAGE_APP_PATH_SIZE-1);
317                 hd->len = 0;
318
319                 __app_send_raw(AUL_UTIL_PID, ADD_HISTORY, (unsigned char *)hd,
320                         1029);
321                 free(hd);
322         }
323
324         return;
325 }
326
327
328 /*
329  * Parsing original app path to retrieve default bundle
330  *
331  * -1 : Invalid sequence
332  * -2 : Buffer overflow
333  *
334  */
335 static inline int __parser(const char *arg, char *out, int out_size)
336 {
337         register int i;
338         int state = 1;
339         char *start_out = out;
340
341         if (arg == NULL || out == NULL) {
342                 /* Handles null buffer*/
343                 return 0;
344         }
345
346         for (i = 0; out_size > 1; i++) {
347                 switch (state) {
348                 case 1:
349                         switch (arg[i]) {
350                         case ' ':
351                         case '\t':
352                                 state = 5;
353                                 break;
354                         case '\0':
355                                 state = 7;
356                                 break;
357                         case '\"':
358                                 state = 2;
359                                 break;
360                         case '\\':
361                                 state = 4;
362                                 break;
363                         default:
364                                 *out = arg[i];
365                                 out++;
366                                 out_size--;
367                                 break;
368                         }
369                         break;
370                 case 2: /* escape start*/
371                         switch (arg[i]) {
372                         case '\0':
373                                 state = 6;
374                                 break;
375                         case '\"':
376                                 state = 1;
377                                 break;
378                         default:
379                                 *out = arg[i];
380                                 out++;
381                                 out_size--;
382                                 break;
383                         }
384                         break;
385                 case 4: /* character escape*/
386                         if (arg[i] == '\0') {
387                                 state = 6;
388                         } else {
389                                 *out = arg[i];
390                                 out++;
391                                 out_size--;
392                                 state = 1;
393                         }
394                         break;
395                 case 5: /* token*/
396                         if (out != start_out) {
397                                 *out = '\0';
398                                 out_size--;
399                                 return i;
400                         }
401                         i--;
402                         state = 1;
403                         break;
404                 case 6:
405                         return -1;      /* error*/
406                 case 7: /* terminate*/
407                         *out = '\0';
408                         out_size--;
409                         return 0;
410                 default:
411                         state = 6;
412                         break;  /* error*/
413                 }
414         }
415
416         if (out_size == 1) {
417                 *out = '\0';
418         }
419         /* Buffer overflow*/
420         return -2;
421 }
422
423 _static_ void __modify_bundle(bundle * kb, int caller_pid,
424                             app_info_from_db * menu_info, int cmd)
425 {
426         char tmp_pid[MAX_PID_STR_BUFSZ];
427
428         snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", caller_pid);
429         bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
430         bundle_del(kb, AUL_K_PKG_NAME);
431         if (cmd == APP_START_RES)
432                 bundle_add(kb, AUL_K_WAIT_RESULT, "1");
433
434         /* Parse app_path to retrieve default bundle*/
435         if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_RESUME) {
436                 char *ptr;
437                 char exe[MAX_PATH_LEN];
438                 int flag;
439
440                 ptr = _get_original_app_path(menu_info);
441
442                 flag = __parser(ptr, exe, sizeof(exe));
443                 if (flag > 0) {
444                         char key[256];
445                         char value[256];
446
447                         ptr += flag;
448                         _D("parsing app_path: EXEC - %s\n", exe);
449
450                         do {
451                                 flag = __parser(ptr, key, sizeof(key));
452                                 if (flag <= 0)
453                                         break;
454                                 ptr += flag;
455
456                                 flag = __parser(ptr, value, sizeof(value));
457                                 if (flag < 0)
458                                         break;
459                                 ptr += flag;
460
461                                 /*bundle_del(kb, key);*/
462                                 bundle_add(kb, key, value);
463                         } while (flag > 0);
464                 } else if (flag == 0) {
465                         _D("parsing app_path: No arguments\n");
466                 } else {
467                         _D("parsing app_path: Invalid argument\n");
468                 }
469         }
470 }
471
472 _static_ int __child_raise_win_by_x(int pid, void *priv)
473 {
474         return x_util_raise_win(pid);
475 }
476
477 _static_ int __raise_win_by_x(int pid)
478 {
479         int pgid;
480         if (x_util_raise_win(pid) == 0)
481                 return 0;
482
483         /* support app launched by shell script*/
484         pgid = getpgid(pid);
485         _D("X raise failed. try to find first child & raise it - c:%d p:%d\n",
486            pgid, pid);
487
488         if (pgid <= 1)
489                 return -1;
490         if (__proc_iter_pgid(pgid, __child_raise_win_by_x, NULL) < 0)
491                 return -1;
492
493         return 0;
494 }
495
496 _static_ int __send_to_sigkill(int pid)
497 {
498         int pgid;
499
500         pgid = getpgid(pid);
501         if (pgid <= 1)
502                 return -1;
503
504         if (killpg(pgid, SIGKILL) < 0)
505                 return -1;
506
507         return 0;
508 }
509
510 _static_ int __term_app(int pid)
511 {
512         int dummy;
513         if (__app_send_raw
514             (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
515                 _D("terminate packet send error - use SIGKILL");
516                 if (__send_to_sigkill(pid) < 0) {
517                         _E("fail to killing - %d\n", pid);
518                         return -1;
519                 }
520         }
521         _D("term done\n");
522         return 0;
523 }
524
525 _static_ int __resume_app(int pid)
526 {
527         int dummy;
528         int ret;
529         if ((ret =
530              __app_send_raw(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy,
531                             sizeof(int))) < 0) {
532                 if (ret == -EAGAIN)
533                         _E("resume packet timeout error");
534                 else {
535                         _D("resume packet send error - use raise win");
536                         if (__raise_win_by_x(pid) < 0) {
537                                 _E("raise failed - %d resume fail\n", pid);
538                                 _E("we will term the app - %d\n", pid);
539                                 __send_to_sigkill(pid);
540                                 ret = -1;
541                         } else
542                                 ret = 0;
543                 }
544         }
545         _D("resume done\n");
546         return ret;
547 }
548
549 static int __get_caller_pid(bundle *kb)
550 {
551         const char *pid_str;
552         int pid;
553
554         pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
555         if(pid_str)
556                 goto end;
557
558         pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
559         if (pid_str == NULL)
560                 return -1;
561
562 end:
563         pid = atoi(pid_str);
564         if (pid <= 1)
565                 return -1;
566
567         return pid;
568 }
569
570 _static_ int __foward_cmd(int cmd, bundle *kb, int cr_pid)
571 {
572         int pid;
573         char tmp_pid[MAX_PID_STR_BUFSZ];
574         int datalen;
575         bundle_raw *kb_data;
576         int res;
577
578         if ((pid = __get_caller_pid(kb)) < 0)
579                         return AUL_R_ERROR;
580
581         snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
582
583         bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
584
585         bundle_encode(kb, &kb_data, &datalen);
586         if ((res = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
587                 res = AUL_R_ERROR;
588
589         free(kb_data);
590
591         return res;
592 }
593
594 _static_ int __app_process_by_pid(int cmd, 
595         const char *pkg_name, struct ucred *cr)
596 {
597         int pid;
598         int ret = -1;
599
600         if (pkg_name == NULL)
601                 return -1;
602
603         if ((cr->uid != 0) && (cr->uid != INHOUSE_UID)) {
604                 _E("reject by security rule, your uid is %u\n", cr->uid);
605                 return -1;
606         }
607
608         pid = atoi(pkg_name);
609         if (pid <= 1) {
610                 _E("invalid pid");
611                 return -1;
612         }
613
614         switch (cmd) {
615         case APP_RESUME_BY_PID:
616                 ret = __resume_app(pid);
617                 break;
618         case APP_TERM_BY_PID:
619                 ret = __term_app(pid);
620                 break;
621         case APP_KILL_BY_PID:
622                 if ((ret = __send_to_sigkill(pid)) < 0)
623                         _E("fail to killing - %d\n", pid);
624         }
625
626         return ret;
627 }
628
629 _static_ int __nofork_processing(int cmd, int pid, bundle * kb)
630 {
631         int ret = -1;
632         switch (cmd) {
633         case APP_RESUME:
634                 _D("resume app's pid : %d\n", pid);
635                 if ((ret = __resume_app(pid)) < 0)
636                         _E("__resume_app failed. error code = %d", ret);
637                 PERF("resume app done");
638                 break;
639
640         case APP_START:
641         case APP_START_RES:
642                 _D("fake launch pid : %d\n", pid);
643                 if ((ret = __fake_launch_app(cmd, pid, kb)) < 0)
644                         _E("fake_launch failed. error code = %d", ret);
645                 PERF("fake launch done");
646                 break;
647         }
648         return ret;
649 }
650
651 _static_ void __real_send(int clifd, int ret)
652 {
653         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
654                 if (errno == EPIPE) {
655                         _E("send failed due to EPIPE.\n");
656                 }
657                 _E("send fail to client");
658         }
659
660         close(clifd);
661 }
662
663 _static_ void __send_result_to_caller(int clifd, int ret)
664 {
665         char *cmdline;
666         int wait_count;
667         int cmdline_changed = 0;
668         int cmdline_exist = 0;
669
670         if (clifd == -1)
671                 return;
672
673         if (ret <= 1) {
674                 __real_send(clifd, ret);
675                 return;
676         }
677         /* check normally was launched?*/
678         wait_count = 1;
679         do {
680                 cmdline = __proc_get_cmdline_bypid(ret);
681                 if (cmdline == NULL) {
682                         _E("error founded when being launched with %d", ret);
683
684                 } else if (strcmp(cmdline, launchpad_cmdline)) {
685                         free(cmdline);
686                         cmdline_changed = 1;
687                         break;
688                 } else {
689                         cmdline_exist = 1;
690                         free(cmdline);
691                 }
692
693                 _D("-- now wait to change cmdline --");
694                 usleep(50 * 1000);      /* 50ms sleep*/
695                 wait_count++;
696         } while (wait_count <= 10);     /* max 50*10ms will be sleep*/
697
698         if ((!cmdline_exist) && (!cmdline_changed)) {
699                 __real_send(clifd, -1); /* abnormally launched*/
700                 return;
701         }
702
703         if (!cmdline_changed)
704                 _E("process launched, but cmdline not changed");
705
706         __real_send(clifd, ret);
707         return;
708 }
709
710 _static_ void __launchpad_main_loop(int main_fd)
711 {
712         bundle *kb = NULL;
713         app_pkt_t *pkt = NULL;
714         app_info_from_db *menu_info = NULL;
715
716         const char *pkg_name = NULL;
717         const char *app_path = NULL;
718         int pid = -1;
719         int clifd = -1;
720         struct ucred cr;
721
722         char sock_path[UNIX_PATH_MAX] = {0,};
723
724         pkt = __app_recv_raw(main_fd, &clifd, &cr);
725         if (!pkt) {
726                 _D("packet is NULL");
727                 goto end;
728         }
729
730         kb = bundle_decode(pkt->data, pkt->len);
731         if (!kb) {
732                 _D("bundle decode error");
733                 goto end;
734         }
735
736         INIT_PERF(kb);
737         PERF("packet processing start");
738
739         if (pkt->cmd == APP_RESULT || pkt->cmd == APP_CANCEL) {
740                 pid = __foward_cmd(pkt->cmd, kb, cr.pid);
741                 goto end;
742         }
743
744         pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
745         _D("pkg name : %s\n", pkg_name);
746
747         if (pkt->cmd == APP_TERM_BY_PID || pkt->cmd == APP_RESUME_BY_PID ||
748             pkt->cmd == APP_KILL_BY_PID) {
749                 pid = __app_process_by_pid(pkt->cmd, pkg_name, &cr);
750                 goto end;
751         }
752
753         menu_info = _get_app_info_from_db_by_pkgname(pkg_name);
754         if (menu_info == NULL) {
755                 _D("such pkg no found");
756                 goto end;
757         }
758
759         app_path = _get_app_path(menu_info);
760         if(app_path == NULL) {
761                 _E("app_path is NULL");
762                 goto end;
763         }
764         if (app_path[0] != '/') {
765                 _D("app_path is not absolute path");
766                 goto end;
767         }
768
769         __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
770         pkg_name = _get_pkgname(menu_info);
771
772         PERF("get package information & modify bundle done");
773
774         if (_is_app_multi_inst(menu_info) == 0)
775                 pid = __proc_iter_cmdline(NULL, (void *)app_path);
776
777         PERF("find pid by searching proc file system done");
778
779         if (pid > 0) {
780                 int ret;
781
782                 if (cr.pid == pid) {
783                         _D("caller process & callee process is same.[%s:%d]",
784                            pkg_name, pid);
785                         pid = -ELOCALLAUNCH_ID;
786                 } else if ((ret = __nofork_processing(pkt->cmd, pid, kb)) < 0)
787                         pid = ret;
788         } else {
789                 pid = fork();
790                 if (pid == 0) {
791                         PERF("fork done");
792                         _E("lock up test log(no error) : fork done");
793
794                         close(clifd);
795                         close(main_fd);
796                         ail_db_close();
797                         __signal_unset_sigchld();
798                         __signal_fini();
799
800                         snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, getpid());
801                         unlink(sock_path);
802
803                         PERF("prepare exec - first done");
804                         _E("lock up test log(no error) : prepare exec - first done");
805
806                         if (__prepare_exec(pkg_name, app_path,
807                                            menu_info, kb) < 0) {
808                                 _E("preparing work fail to launch - "
809                                    "can not launch %s\n", pkg_name);
810                                 exit(-1);
811                         }
812
813                         PERF("prepare exec - second done");
814                         _E("lock up test log(no error) : prepare exec - second done");
815
816                         __real_launch(app_path, kb);
817
818                         exit(-1);
819                 }
820                 _D("==> real launch pid : %d %s\n", pid, app_path);
821         }
822
823  end:
824         __send_result_to_caller(clifd, pid);
825
826         if (pid > 0) {
827                 int ret;
828                 ret = ac_check_launch_privilege(pkg_name, menu_info->pkg_type, pid);
829                 _D("ac_check_launch_privilege : %d", ret);
830                 switch (pkt->cmd) {
831                 case APP_RESUME:
832                         __add_history(cr.pid, pid, pkg_name, NULL, app_path);
833                         break;
834                 case APP_START:
835                 case APP_START_RES:
836                         __add_history(cr.pid, pid, pkg_name, kb, app_path);
837                         break;
838                 default:
839                         _D("no launch case");
840                 }
841         }
842
843         if (menu_info != NULL)
844                 _free_app_info_from_db(menu_info);
845
846         if (kb != NULL)
847                 bundle_free(kb);
848         if (pkt != NULL)
849                 free(pkt);
850
851         /* Active Flusing for Daemon */
852         if (initialized > AUL_POLL_CNT) {
853                 sqlite3_release_memory(SQLITE_FLUSH_MAX);
854                 malloc_trim(0);
855                 initialized = 1;
856         }
857
858 }
859
860 _static_ int __launchpad_pre_init(int argc, char **argv)
861 {
862         int fd;
863
864         /* signal init*/
865         __signal_init();
866
867         /* dac init*/
868         __dac_init();
869
870         /* get my(launchpad) command line*/
871         launchpad_cmdline = __proc_get_cmdline_bypid(getpid());
872         if (launchpad_cmdline == NULL) {
873                 _E("launchpad cmdline fail to get");
874                 return -1;
875         }
876         _D("launchpad cmdline = %s", launchpad_cmdline);
877
878         /* create launchpad sock        */
879         fd = __create_server_sock(LAUNCHPAD_PID);
880         if (fd < 0) {
881                 _E("server sock error");
882                 return -1;
883         }
884
885         __preload_init(argc, argv);
886
887         return fd;
888 }
889
890 _static_ int __launchpad_post_init()
891 {
892         /* Setting this as a global variable to keep track 
893         of launchpad poll cnt */
894         /* static int initialized = 0;*/
895
896         if (initialized) {
897                 initialized++;
898                 return 0;
899         }
900
901         preinit_init();
902         if (__signal_set_sigchld() < 0)
903                 return -1;
904
905         initialized++;
906
907         return 0;
908 }
909
910 int main(int argc, char **argv)
911 {
912         int main_fd;
913         struct pollfd pfds[POLLFD_MAX];
914         int i;
915
916         /* init without concerning X & EFL*/
917         main_fd = __launchpad_pre_init(argc, argv);
918         if (main_fd < 0) {
919                 _E("launchpad pre init failed");
920                 exit(-1);
921         }
922
923         pfds[0].fd = main_fd;
924         pfds[0].events = POLLIN;
925         pfds[0].revents = 0;
926
927         while (1) {
928                 if (poll(pfds, POLLFD_MAX, -1) < 0)
929                         continue;
930
931                 /* init with concerning X & EFL (because of booting 
932                 sequence problem)*/
933                 if (__launchpad_post_init() < 0) {
934                         _E("launcpad post init failed");
935                         exit(-1);
936                 }
937
938                 for (i = 0; i < POLLFD_MAX; i++) {
939                         if ((pfds[i].revents & POLLIN) != 0) {
940                                 __launchpad_main_loop(pfds[i].fd);
941                         }
942                 }
943         }
944 }
945