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