Set the architecture info for Unity app
[platform/core/appfw/launchpad.git] / src / launchpad_common.c
1 /*
2  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE
18
19 #include <string.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/mount.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <sys/xattr.h>
28 #include <errno.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #include <linux/limits.h>
32 #include <unistd.h>
33 #include <tzplatform_config.h>
34 #include <stdio.h>
35 #include <stdbool.h>
36 #include <systemd/sd-journal.h>
37 #include <sys/time.h>
38 #include <sys/resource.h>
39 #include <sys/personality.h>
40
41 #include "launchpad_common.h"
42 #include "key.h"
43
44 #define MAX_PATH_LEN    1024
45 #define MAX_CMD_BUFSZ 1024
46
47 #define MAX_PENDING_CONNECTIONS 10
48 #define CONNECT_RETRY_TIME (100 * 1000)
49 #define CONNECT_RETRY_COUNT 3
50 #define AUL_PKT_HEADER_SIZE (sizeof(int) + sizeof(int) + sizeof(int))
51 #define PATH_AMD_SOCK "/run/aul/daemons/.amd-sock"
52 #define PATH_DEV_NULL "/dev/null"
53
54 static int __read_proc(const char *path, char *buf, int size)
55 {
56         int fd;
57         int ret;
58
59         if (buf == NULL || path == NULL)
60                 return -1;
61
62         fd = open(path, O_RDONLY);
63         if (fd < 0)
64                 return -1;
65
66         ret = read(fd, buf, size - 1);
67         if (ret <= 0) {
68                 close(fd);
69                 return -1;
70         }
71
72         buf[ret] = 0;
73         close(fd);
74
75         return ret;
76 }
77
78 void _get_cpu_idle(unsigned long long *total, unsigned long long *idle)
79 {
80         FILE *fp;
81         int i;
82         unsigned long long sum = 0;
83         unsigned long long val;
84         unsigned long long iv = 0;
85         char buf[4] = { 0, };
86
87         fp = fopen("/proc/stat", "rt");
88
89         if (fp == NULL)
90                 return;
91
92         if (fscanf(fp, "%3s", buf) == -1) {
93                 fclose(fp);
94                 return;
95         }
96
97         for (i = 0; i < 10; i++) {
98                 if (fscanf(fp, "%lld", &val) == -1) {
99                         fclose(fp);
100                         return;
101                 }
102
103                 if (sum + val < sum) {
104                         _E("overflow");
105                         fclose(fp);
106                         return;
107                 }
108
109                 sum += val;
110                 if (i == 3) /* idle */
111                         iv = val;
112         }
113
114         fclose(fp);
115
116         *total = sum;
117         *idle = iv;
118 }
119
120 void _set_sock_option(int fd, int cli)
121 {
122         int size;
123         int flag;
124         struct timeval tv = { 5, 200 * 1000 };  /*  5.2 sec */
125
126         size = AUL_SOCK_MAXBUFF;
127         setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
128         setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
129         if (cli) {
130                 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
131                 flag = fcntl(fd, F_GETFD);
132                 flag |= FD_CLOEXEC;
133                 fcntl(fd, F_SETFD, flag);
134         }
135 }
136
137 static int __parse_app_path(const char *arg, char *out, int out_size)
138 {
139         register int i;
140         int state = 1;
141         char *start_out = out;
142
143         if (arg == NULL || out == NULL) {
144                 /* Handles null buffer*/
145                 return 0;
146         }
147
148         for (i = 0; out_size > 1; i++) {
149                 switch (state) {
150                 case 1:
151                         switch (arg[i]) {
152                         case ' ':
153                         case '\t':
154                                 state = 5;
155                                 break;
156                         case '\0':
157                                 state = 7;
158                                 break;
159                         case '\"':
160                                 state = 2;
161                                 break;
162                         case '\\':
163                                 state = 4;
164                                 break;
165                         default:
166                                 *out = arg[i];
167                                 out++;
168                                 out_size--;
169                                 break;
170                         }
171                         break;
172                 case 2: /* escape start*/
173                         switch (arg[i]) {
174                         case '\0':
175                                 state = 6;
176                                 break;
177                         case '\"':
178                                 state = 1;
179                                 break;
180                         default:
181                                 *out = arg[i];
182                                 out++;
183                                 out_size--;
184                                 break;
185                         }
186                         break;
187                 case 4: /* character escape*/
188                         if (arg[i] == '\0') {
189                                 state = 6;
190                         } else {
191                                 *out = arg[i];
192                                 out++;
193                                 out_size--;
194                                 state = 1;
195                         }
196                         break;
197                 case 5: /* token*/
198                         if (out != start_out) {
199                                 *out = '\0';
200                                 out_size--;
201                                 return i;
202                         }
203                         i--;
204                         state = 1;
205                         break;
206                 case 6:
207                         return -1;  /* error*/
208                 case 7: /* terminate*/
209                         *out = '\0';
210                         out_size--;
211                         return 0;
212                 default:
213                         state = 6;
214                         break;  /* error*/
215                 }
216         }
217
218         if (out_size == 1)
219                 *out = '\0';
220
221         /* Buffer overflow*/
222         return -2;
223 }
224
225 int _send_cmd_to_amd(int cmd)
226 {
227         struct sockaddr_un addr = {0,};
228         int fd;
229         int ret;
230         int retry = CONNECT_RETRY_COUNT;
231         app_pkt_t pkt = {0,};
232
233         fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
234         /*  support above version 2.6.27*/
235         if (fd < 0) {
236                 if (errno == EINVAL) {
237                         fd = socket(AF_UNIX, SOCK_STREAM, 0);
238                         if (fd < 0) {
239                                 _E("second chance - socket create error");
240                                 return -1;
241                         }
242                 } else {
243                         _E("socket error");
244                         return -1;
245                 }
246         }
247
248         addr.sun_family = AF_UNIX;
249         snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", PATH_AMD_SOCK);
250         while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
251                 if (errno != ETIMEDOUT || retry <= 0) {
252                         _E("Failed to connect error(%d)", errno);
253                         close(fd);
254                         return -1;
255                 }
256
257                 usleep(CONNECT_RETRY_TIME);
258                 --retry;
259                 _D("re-connect to %s (%d)", addr.sun_path, retry);
260         }
261
262         pkt.cmd = cmd;
263         ret = send(fd, &pkt, sizeof(app_pkt_t), MSG_NOSIGNAL);
264         if (ret <= 0) {
265                 _E("Failed to send cmd(%d), errno(%d)", cmd, errno);
266                 close(fd);
267                 return -ECOMM;
268         }
269
270         close(fd);
271         return 0;
272 }
273
274 int _create_server_sock(const char *name)
275 {
276         struct sockaddr_un saddr;
277         int fd;
278
279         fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
280         /*  support above version 2.6.27*/
281         if (fd < 0) {
282                 if (errno == EINVAL) {
283                         fd = socket(AF_UNIX, SOCK_STREAM, 0);
284                         if (fd < 0) {
285                                 _E("second chance - socket create error");
286                                 return -1;
287                         }
288                 } else {
289                         _E("socket error");
290                         return -1;
291                 }
292         }
293
294         memset(&saddr, 0, sizeof(saddr));
295         saddr.sun_family = AF_UNIX;
296
297         snprintf(saddr.sun_path, sizeof(saddr.sun_path),
298                         "%s/daemons/%d/%s",
299                         SOCKET_PATH, getuid(), name);
300         unlink(saddr.sun_path);
301
302         if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
303                 _E("bind error");
304                 close(fd);
305                 return -1;
306         }
307
308         _set_sock_option(fd, 0);
309
310         if (listen(fd, 128) == -1) {
311                 _E("listen error");
312                 close(fd);
313                 return -1;
314         }
315
316         return fd;
317 }
318
319 app_pkt_t *_recv_pkt_raw(int fd)
320 {
321         int len;
322         int ret;
323         unsigned char buf[AUL_SOCK_MAXBUFF];
324         app_pkt_t *pkt;
325         int cmd;
326         int datalen;
327         int opt;
328
329 retry_recv:
330         /* receive header(cmd, datalen) */
331         len = recv(fd, buf, AUL_PKT_HEADER_SIZE, 0);
332         if (len < 0)
333                 if (errno == EINTR)
334                         goto retry_recv;
335
336         if (len < AUL_PKT_HEADER_SIZE) {
337                 _E("recv error");
338                 return NULL;
339         }
340         memcpy(&cmd, buf, sizeof(int));
341         memcpy(&datalen, buf + sizeof(int), sizeof(int));
342         memcpy(&opt, buf + sizeof(int) + sizeof(int), sizeof(int));
343
344         /* allocate for a null byte */
345         pkt = (app_pkt_t *)calloc(1, AUL_PKT_HEADER_SIZE + datalen + 1);
346         if (pkt == NULL) {
347                 _E("failed to alloc app_pkt_t");
348                 return NULL;
349         }
350         pkt->cmd = cmd;
351         pkt->len = datalen;
352         pkt->opt = opt;
353
354         len = 0;
355         while (len != pkt->len) {
356                 ret = recv(fd, pkt->data + len, pkt->len - len, 0);
357                 if (ret < 0) {
358                         _E("recv error %d %d", len, pkt->len);
359                         free(pkt);
360                         return NULL;
361                 }
362                 len += ret;
363                 _D("recv len %d %d", len, pkt->len);
364         }
365
366         return pkt;
367 }
368
369 app_pkt_t *_accept_recv_pkt_raw(int fd, int *clifd, struct ucred *cr)
370 {
371         struct sockaddr_un aul_addr = { 0, };
372         int sun_size;
373         app_pkt_t *pkt;
374         int newfd;
375         int cl = sizeof(struct ucred);
376
377         sun_size = sizeof(struct sockaddr_un);
378
379         newfd = accept(fd, (struct sockaddr *)&aul_addr,
380                         (socklen_t *) &sun_size);
381         if (newfd == -1) {
382                 if (errno != EINTR)
383                         _E("accept error");
384                 return NULL;
385         }
386
387         if (getsockopt(newfd, SOL_SOCKET, SO_PEERCRED, cr,
388                         (socklen_t *) &cl) < 0) {
389                 _E("peer information error");
390                 close(newfd);
391                 return NULL;
392         }
393
394         _set_sock_option(newfd, 1);
395
396         pkt = _recv_pkt_raw(newfd);
397         if (pkt == NULL) {
398                 _E("failed to receive pkt from client");
399                 close(newfd);
400                 return NULL;
401         }
402
403         *clifd = newfd;
404         return pkt;
405 }
406
407 int _send_pkt_raw(int client_fd, app_pkt_t *pkt)
408 {
409         int send_ret = 0;
410         int pkt_size = 0;
411         int sent = 0;
412
413         if (client_fd == -1 || pkt == NULL) {
414                 _E("arguments error!");
415                 return -1;
416         }
417
418         pkt_size = AUL_PKT_HEADER_SIZE + pkt->len;
419
420         while (sent != pkt_size) {
421                 send_ret = send(client_fd, (char *)pkt + sent,
422                                 pkt_size - sent, MSG_NOSIGNAL);
423                 if (send_ret == -1) {
424                         _E("send error! (%d)", errno);
425                         return -1;
426                 }
427
428                 sent += send_ret;
429                 _D("send(%d: ret: %d) : %d / %d",
430                         client_fd, send_ret, sent, pkt_size);
431         }
432
433         return 0;
434 }
435
436 appinfo_t *_appinfo_create(bundle *kb)
437 {
438         appinfo_t *menu_info;
439         const char *ptr = NULL;
440
441         menu_info = calloc(1, sizeof(appinfo_t));
442         if (menu_info == NULL)
443                 return NULL;
444
445         ptr = bundle_get_val(kb, AUL_K_APPID);
446         if (ptr)
447                 menu_info->appid = strdup(ptr);
448         ptr = bundle_get_val(kb, AUL_K_EXEC);
449         if (ptr)
450                 menu_info->app_path = strdup(ptr);
451         if (menu_info->app_path != NULL)
452                 menu_info->original_app_path = strdup(menu_info->app_path);
453         ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE);
454         if (ptr)
455                 menu_info->pkg_type = strdup(ptr);
456         ptr = bundle_get_val(kb, AUL_K_APP_TYPE);
457         if (ptr)
458                 menu_info->app_type = strdup(ptr);
459         ptr = bundle_get_val(kb, AUL_K_HWACC);
460         if (ptr)
461                 menu_info->hwacc = strdup(ptr);
462         ptr = bundle_get_val(kb, AUL_K_TASKMANAGE);
463         if (ptr)
464                 menu_info->taskmanage = strdup(ptr);
465         ptr = bundle_get_val(kb, AUL_K_PKGID);
466         if (ptr)
467                 menu_info->pkgid = strdup(ptr);
468         ptr = bundle_get_val(kb, AUL_K_COMP_TYPE);
469         if (ptr)
470                 menu_info->comp_type = strdup(ptr);
471         ptr = bundle_get_val(kb, AUL_K_INTERNAL_POOL);
472         if (ptr)
473                 menu_info->internal_pool = strdup(ptr);
474         ptr = bundle_get_val(kb, AUL_K_ROOT_PATH);
475         if (ptr)
476                 menu_info->root_path = strdup(ptr);
477
478         ptr = bundle_get_val(kb, AUL_K_LOADER_NAME);
479         if (ptr)
480                 menu_info->loader_name = strdup(ptr);
481
482         if (!_appinfo_get_app_path(menu_info)) {
483                 _appinfo_free(menu_info);
484                 return NULL;
485         }
486
487         return menu_info;
488 }
489
490 char *_appinfo_get_app_path(appinfo_t *menu_info)
491 {
492         int i = 0;
493         int path_len = -1;
494         char *tmp_app_path;
495
496         if (!menu_info || menu_info->app_path == NULL)
497                 return NULL;
498
499         while (menu_info->app_path[i] != 0) {
500                 if (menu_info->app_path[i] == ' '
501                     || menu_info->app_path[i] == '\t') {
502                         path_len = i;
503                         break;
504                 }
505                 i++;
506         }
507
508         if (path_len == 0) {
509                 free(menu_info->app_path);
510                 menu_info->app_path = NULL;
511         } else if (path_len > 0) {
512                 tmp_app_path = malloc(sizeof(char) * (path_len + 1));
513                 if (tmp_app_path == NULL)
514                         return NULL;
515                 snprintf(tmp_app_path, path_len + 1, "%s", menu_info->app_path);
516                 free(menu_info->app_path);
517                 menu_info->app_path = tmp_app_path;
518         }
519
520         return menu_info->app_path;
521 }
522
523 void _appinfo_free(appinfo_t *menu_info)
524 {
525         if (menu_info == NULL)
526                 return;
527
528         if (menu_info->appid != NULL)
529                 free(menu_info->appid);
530         if (menu_info->app_path != NULL)
531                 free(menu_info->app_path);
532         if (menu_info->original_app_path != NULL)
533                 free(menu_info->original_app_path);
534         if (menu_info->pkg_type != NULL)
535                 free(menu_info->pkg_type);
536         if (menu_info->app_type != NULL)
537                 free(menu_info->app_type);
538         if (menu_info->hwacc != NULL)
539                 free(menu_info->hwacc);
540         if (menu_info->taskmanage != NULL)
541                 free(menu_info->taskmanage);
542         if (menu_info->pkgid != NULL)
543                 free(menu_info->pkgid);
544         if (menu_info->comp_type != NULL)
545                 free(menu_info->comp_type);
546         if (menu_info->internal_pool != NULL)
547                 free(menu_info->internal_pool);
548         if (menu_info->root_path != NULL)
549                 free(menu_info->root_path);
550         if (menu_info->loader_name != NULL)
551                 free(menu_info->loader_name);
552
553         free(menu_info);
554 }
555
556 void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *menu_info, int cmd)
557 {
558         char *ptr;
559         char exe[MAX_PATH_LEN];
560         int flag;
561         char key[256];
562         char value[256];
563
564         bundle_del(kb, AUL_K_APPID);
565         bundle_del(kb, AUL_K_EXEC);
566         bundle_del(kb, AUL_K_APP_TYPE);
567         bundle_del(kb, AUL_K_PACKAGETYPE);
568         bundle_del(kb, AUL_K_TASKMANAGE);
569         bundle_del(kb, AUL_K_PKGID);
570         bundle_del(kb, AUL_K_COMP_TYPE);
571
572         /* Parse app_path to retrieve default bundle*/
573         if (cmd == PAD_CMD_LAUNCH) {
574                 ptr = menu_info->original_app_path;
575                 flag = __parse_app_path(ptr, exe, sizeof(exe));
576                 if (flag > 0) {
577                         ptr += flag;
578                         SECURE_LOGD("parsing app_path: EXEC - %s\n", exe);
579
580                         do {
581                                 flag = __parse_app_path(ptr, key, sizeof(key));
582                                 if (flag <= 0)
583                                         break;
584                                 ptr += flag;
585
586                                 flag = __parse_app_path(ptr, value,
587                                                 sizeof(value));
588                                 if (flag < 0)
589                                         break;
590                                 ptr += flag;
591
592                                 /*bundle_del(kb, key);*/
593                                 bundle_add(kb, key, value);
594                         } while (flag > 0);
595                 } else if (flag == 0)
596                         _D("parsing app_path: No arguments\n");
597                 else
598                         _D("parsing app_path: Invalid argument\n");
599         }
600 }
601
602 int _connect_to_launchpad(int type, int id)
603 {
604         struct sockaddr_un addr;
605         int fd = -1;
606         int retry = CONNECT_RETRY_COUNT;
607         int send_ret = -1;
608         int client_pid = getpid();
609
610         _D("[launchpad] enter, type: %d", type);
611
612         fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
613         if (fd < 0) {
614                 _E("socket error");
615                 goto error;
616         }
617
618         memset(&addr, 0x00, sizeof(struct sockaddr_un));
619         addr.sun_family = AF_UNIX;
620         snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d",
621                         SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME,
622                         type, id);
623
624         _D("connect to %s", addr.sun_path);
625         while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
626                 if (errno != ETIMEDOUT || retry <= 0) {
627                         _E("connect error : %d", errno);
628                         goto error;
629                 }
630
631                 usleep(CONNECT_RETRY_TIME);
632                 --retry;
633                 _D("re-connect to %s (%d)", addr.sun_path, retry);
634         }
635
636         send_ret = send(fd, &client_pid, sizeof(client_pid), MSG_NOSIGNAL);
637         _D("send(%d) : %d", client_pid, send_ret);
638
639         if (send_ret == -1) {
640                 _E("send error");
641                 goto error;
642         }
643
644         SECURE_LOGD("[launchpad] done, connect fd: %d", fd);
645         return fd;
646
647 error:
648         if (fd != -1)
649                 close(fd);
650
651         return -1;
652 }
653
654 void _set_env(appinfo_t *menu_info, bundle *kb)
655 {
656         const char *str;
657         char buf[MAX_LOCAL_BUFSZ];
658
659         str = bundle_get_val(kb, AUL_K_STARTTIME);
660         if (str != NULL)
661                 setenv("APP_START_TIME", str, 1);
662
663         if (menu_info->hwacc != NULL)
664                 setenv("HWACC", menu_info->hwacc, 1);
665         if (menu_info->taskmanage != NULL)
666                 setenv("TASKMANAGE", menu_info->taskmanage, 1);
667         if (menu_info->root_path != NULL)
668                 setenv("AUL_ROOT_PATH", menu_info->root_path, 1);
669         if (menu_info->appid != NULL)
670                 setenv("AUL_APPID", menu_info->appid, 1);
671         if (menu_info->pkgid != NULL)
672                 setenv("AUL_PKGID", menu_info->pkgid, 1);
673         if (menu_info->app_type != NULL)
674                 setenv("RUNTIME_TYPE", menu_info->app_type, 1);
675
676         str = bundle_get_val(kb, AUL_K_WAYLAND_DISPLAY);
677         if (str != NULL)
678                 setenv("WAYLAND_DISPLAY", str, 1);
679
680         str = bundle_get_val(kb, AUL_K_WAYLAND_WORKING_DIR);
681         if (str != NULL)
682                 setenv("XDG_RUNTIME_DIR", str, 1);
683
684         str = bundle_get_val(kb, AUL_K_API_VERSION);
685         if (str != NULL)
686                 setenv("TIZEN_API_VERSION", str, 1);
687
688         snprintf(buf, sizeof(buf), "%d", getpid());
689         setenv("AUL_PID", buf, 1);
690
691 #ifdef TIZEN_FEATURE_SET_PERSONALITY_32
692         int res = personality(PER_LINUX32);
693
694         if (res < 0) {
695                 _E("personality() failed,  error: %d (%s)",
696                                 errno, strerror(errno));
697         }
698 #endif
699 }
700
701 char **_create_argc_argv(bundle *kb, int *margc)
702 {
703         char **argv;
704         int argc;
705
706         argc = bundle_export_to_argv(kb, &argv);
707
708         *margc = argc;
709         return argv;
710 }
711
712 char *_get_libdir(const char *path)
713 {
714         char *path_dup;
715         char buf[PATH_MAX];
716         char *ptr;
717
718         if (path == NULL)
719                 return NULL;
720         path_dup = strdup(path);
721         if (path_dup == NULL)
722                 return NULL;
723         ptr = strrchr(path_dup, '/');
724         if (ptr == NULL)
725                 return NULL;
726
727         *ptr = '\0';
728
729         snprintf(buf, sizeof(buf), "%s/../lib/", path_dup);
730         free(path_dup);
731
732         if (access(buf, F_OK) == -1)
733                 return NULL;
734
735         return strdup(buf);
736 }
737
738 int _proc_get_attr_by_pid(int pid, char *buf, int size)
739 {
740         char path[PATH_MAX] = { 0, };
741         int ret;
742
743         snprintf(path, sizeof(path), "/proc/%d/attr/current", pid);
744         ret = __read_proc(path, buf, size);
745         if (ret <= 0)
746                 return -1;
747
748         return 0;
749 }
750
751 static int __delete_dir(const char *path)
752 {
753         DIR *dp;
754         struct dirent *dentry = NULL;
755         char buf[PATH_MAX];
756         struct stat statbuf;
757         int ret;
758
759         if (path == NULL)
760                 return -1;
761
762         dp = opendir(path);
763         if (dp == NULL)
764                 return -1;
765
766         while ((dentry = readdir(dp)) != NULL) {
767                 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
768                         continue;
769
770                 snprintf(buf, sizeof(buf), "%s/%s", path, dentry->d_name);
771                 ret = stat(buf, &statbuf);
772                 if (ret == 0) {
773                         if (S_ISDIR(statbuf.st_mode))
774                                 __delete_dir(buf);
775                         else
776                                 unlink(buf);
777                 }
778         }
779
780         rmdir(path);
781         closedir(dp);
782
783         return 0;
784 }
785
786 int _delete_sock_path(int pid, uid_t uid)
787 {
788         char path[PATH_MAX];
789
790         snprintf(path, sizeof(path), "/run/aul/apps/%d/%d", uid, pid);
791         if (access(path, F_OK) == 0)
792                 __delete_dir(path);
793
794         if (access(path, F_OK) == 0)
795                 return -1;
796
797         return 0;
798 }
799
800 int _close_all_fds(void)
801 {
802         DIR *dp;
803         struct dirent *dentry = NULL;
804         int fd;
805         int max_fd;
806
807         dp = opendir("/proc/self/fd");
808         if (dp == NULL) {
809                 /* fallback */
810                 max_fd = sysconf(_SC_OPEN_MAX);
811                 for (fd = 3; fd < max_fd; fd++)
812                         close(fd);
813
814                 return 0;
815         }
816
817         while ((dentry = readdir(dp)) != NULL) {
818                 if (!isdigit(dentry->d_name[0]))
819                         continue;
820
821                 fd = atoi(dentry->d_name);
822                 if (fd < 3)
823                         continue;
824
825                 if (fd == dirfd(dp))
826                         continue;
827
828                 close(fd);
829         }
830         closedir(dp);
831
832         return 0;
833 }
834
835 int _setup_stdio(const char *ident)
836 {
837         int fd;
838
839         /* stdin */
840         fd = open(PATH_DEV_NULL, O_RDONLY | O_NOCTTY);
841         if (fd < 0) {
842                 _W("Failed to open /dev/null - err(%d)", errno);
843                 return -1;
844         }
845         if (dup2(fd, STDIN_FILENO) < 0) {
846                 _W("Failed to duplicate fd - oldfd(%d), newfd(%d)",
847                                 fd, STDIN_FILENO);
848         }
849         close(fd);
850
851         /* stdout */
852         fd = sd_journal_stream_fd(ident, LOG_INFO, false);
853         if (fd < 0) {
854                 _W("Failed to connect journal socket - err(%d)", errno);
855                 fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
856                 if (fd < 0) {
857                         _W("Failed to open /dev/null - err(%d)", errno);
858                         return -1;
859                 }
860         }
861         if (dup2(fd, STDOUT_FILENO) < 0) {
862                 _W("Failed to duplicate fd - oldfd(%d), newfd(%d)",
863                                 fd, STDOUT_FILENO);
864         }
865         close(fd);
866
867         /* stderr */
868         fd = sd_journal_stream_fd(ident, LOG_INFO, false);
869         if (fd < 0) {
870                 _W("Failed to connect journal socket - err(%d)", errno);
871                 fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
872                 if (fd < 0) {
873                         _W("Failed to open /dev/null - err(%d)", errno);
874                         return -1;
875                 }
876         }
877         if (dup2(fd, STDERR_FILENO) < 0) {
878                 _W("Failed to duplicate fd - oldfd(%d), newfd(%d)",
879                                 fd, STDERR_FILENO);
880         }
881         close(fd);
882
883         return 0;
884 }
885
886 int _set_priority(int prio)
887 {
888         int r;
889
890         r = setpriority(PRIO_PGRP, 0, prio);
891         if (r < 0) {
892                 SECURE_LOGE("Failed to set process(%d) priority(%d) - err(%d)",
893                                 getpid(), prio, errno);
894         }
895
896         return r;
897 }