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