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