Remove unnecessary macro
[platform/core/appfw/debug-launchpad.git] / src / 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 <stdio.h>
20 #include <stdlib.h>
21 #include <stdbool.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <sys/xattr.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29 #include <errno.h>
30 #include <dirent.h>
31 #include <unistd.h>
32 #include <bundle.h>
33 #include <bundle_internal.h>
34 #include <systemd/sd-daemon.h>
35
36 #include "common.h"
37 #include "debug_util.h"
38 #include "defs.h"
39
40 #define MAX_PATH_LEN 1024
41 #define MAX_CMD_BUFSZ 1024
42 #define PATH_TMP "/tmp"
43 #define PATH_DATA "/data"
44 #define AUL_PKT_HEADER_SIZE (sizeof(int) + sizeof(int) + sizeof(int))
45
46 static void __set_sock_option(int fd, int cli)
47 {
48         int size;
49         struct timeval tv = { 5, 200 * 1000 };  /* 5.2 sec */
50
51         size = AUL_SOCK_MAXBUFF;
52         setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
53         setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
54         if (cli)
55                 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
56 }
57
58 static int __create_sock_activation(void)
59 {
60         int listen_fds;
61
62         listen_fds = sd_listen_fds(0);
63         if (listen_fds == 1)
64                 return SD_LISTEN_FDS_START;
65         else if (listen_fds > 1)
66                 _E("Too many file descriptors received.");
67         else
68                 _E("There is no socket stream");
69
70         return -1;
71 }
72
73 static int __create_server_socket(bool is_app)
74 {
75         struct sockaddr_un saddr;
76         int fd;
77         int ret;
78
79         if (is_app)
80                 fd = socket(AF_UNIX, SOCK_STREAM, 0);
81         else
82                 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
83         /* support above version 2.6.27 */
84         if (fd < 0) {
85                 if (errno == EINVAL) {
86                         fd = socket(AF_UNIX, SOCK_STREAM, 0);
87                         if (fd < 0) {
88                                 _E("second chance - socket create error");
89                                 return -1;
90                         }
91                 } else {
92                         _E("socket error");
93                         return -1;
94                 }
95         }
96
97         memset(&saddr, 0, sizeof(saddr));
98         saddr.sun_family = AF_UNIX;
99
100         if (is_app) {
101                 snprintf(saddr.sun_path, sizeof(saddr.sun_path),
102                                 "%s/apps/%d/%d",
103                                 SOCKET_PATH, getuid(), getpid());
104                 ret = mkdir(saddr.sun_path, 0700);
105                 if (ret != 0) {
106                         if (errno == EEXIST) {
107                                 if (access(saddr.sun_path, R_OK) != 0) {
108                                         _E("Failed to access %s directory - %d",
109                                                         saddr.sun_path, errno);
110                                         close(fd);
111                                         return -1;
112                                 }
113                         } else {
114                                 _E("Failed to create %s directory - %d",
115                                                 saddr.sun_path, errno);
116                                 close(fd);
117                                 return -1;
118                         }
119                 }
120                 snprintf(saddr.sun_path, sizeof(saddr.sun_path),
121                                 "%s/apps/%d/%d/.app-sock",
122                                 SOCKET_PATH, getuid(), getpid());
123         } else {
124                 snprintf(saddr.sun_path, sizeof(saddr.sun_path),
125                                 "%s/daemons/%d/.debug-launchpad-sock",
126                                 SOCKET_PATH, getuid());
127         }
128         unlink(saddr.sun_path);
129
130         if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
131                 _E("bind error");
132                 close(fd);
133                 return -1;
134         }
135
136         if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
137                 /* Flawfinder: ignore */
138                 _E("Failed to change the socket permission");
139                 close(fd);
140                 return -1;
141         }
142
143         __set_sock_option(fd, 0);
144
145         if (listen(fd, 128) == -1) {
146                 _E("listen error");
147                 close(fd);
148                 return -1;
149         }
150
151         return fd;
152 }
153
154 int _create_server_sock(void)
155 {
156         int fd = -1;
157
158         fd = __create_sock_activation();
159         if (fd < 0) {
160                 fd = __create_server_socket(false);
161                 if (fd < 0) {
162                         _E("server sock error %d", fd);
163                         return -1;
164                 }
165         }
166
167         return fd;
168 }
169
170 app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr)
171 {
172         int len;
173         int ret;
174         struct sockaddr_un aul_addr = {0, };
175         int sun_size;
176         app_pkt_t *pkt = NULL;
177         int cl = sizeof(struct ucred);
178         unsigned char buf[AUL_SOCK_MAXBUFF];
179         int cmd;
180         int datalen;
181         int opt;
182
183         sun_size = sizeof(struct sockaddr_un);
184
185         *clifd = accept(fd, (struct sockaddr *)&aul_addr,
186                         (socklen_t *)&sun_size);
187         if (*clifd == -1) {
188                 if (errno != EINTR)
189                         _E("accept error");
190                 return NULL;
191         }
192
193         if (getsockopt(*clifd, SOL_SOCKET, SO_PEERCRED, cr,
194                                 (socklen_t *)&cl) < 0) {
195                 _E("peer information error");
196                 close(*clifd);
197                 return NULL;
198         }
199
200         __set_sock_option(*clifd, 1);
201
202 retry_recv:
203         /* receive header(cmd, datalen) */
204         len = recv(*clifd, buf, AUL_PKT_HEADER_SIZE, 0);
205         if (len < 0)
206                 if (errno == EINTR)
207                         goto retry_recv;
208
209         if (len < AUL_PKT_HEADER_SIZE) {
210                 _E("recv error");
211                 close(*clifd);
212                 return NULL;
213         }
214         memcpy(&cmd, buf, sizeof(int));
215         memcpy(&datalen, buf + sizeof(int), sizeof(int));
216         memcpy(&opt, buf + sizeof(int) + sizeof(int), sizeof(int));
217
218         /* allocate for a null byte */
219         pkt = (app_pkt_t *)calloc(1, AUL_PKT_HEADER_SIZE + datalen + 1);
220         if (pkt == NULL) {
221                 close(*clifd);
222                 return NULL;
223         }
224         pkt->cmd = cmd;
225         pkt->len = datalen;
226         pkt->opt = opt;
227
228         len = 0;
229         while (len != pkt->len) {
230                 ret = recv(*clifd, pkt->data + len, pkt->len - len, 0);
231                 if (ret < 0) {
232                         _E("recv error %d %d", len, pkt->len);
233                         free(pkt);
234                         close(*clifd);
235                         return NULL;
236                 }
237                 len += ret;
238                 _D("recv len %d %d", len, pkt->len);
239         }
240
241         return pkt;
242 }
243
244 static char *__appinfo_get_app_path(appinfo_t *appinfo)
245 {
246         int i = 0;
247         int path_len = -1;
248         char *tmp_app_path;
249
250         if (appinfo == NULL || appinfo->app_path == NULL)
251                 return NULL;
252
253         while (appinfo->app_path[i] != 0) {
254                 if (appinfo->app_path[i] == ' '
255                                 || appinfo->app_path[i] == '\t') {
256                         path_len = i;
257                         break;
258                 }
259
260                 i++;
261         }
262
263         if (path_len == 0) {
264                 free(appinfo->app_path);
265                 appinfo->app_path = NULL;
266         } else if (path_len > 0) {
267                 tmp_app_path = (char *)malloc(sizeof(char) * (path_len + 1));
268                 if (tmp_app_path == NULL)
269                         return NULL;
270
271                 snprintf(tmp_app_path, path_len + 1, "%s", appinfo->app_path);
272                 free(appinfo->app_path);
273                 appinfo->app_path = tmp_app_path;
274         }
275
276         return appinfo->app_path;
277 }
278
279 appinfo_t *_appinfo_create(bundle *kb)
280 {
281         appinfo_t *appinfo;
282         const char *ptr;
283
284         appinfo = (appinfo_t *)calloc(1, sizeof(appinfo_t));
285         if (appinfo == NULL)
286                 return NULL;
287
288         ptr = bundle_get_val(kb, AUL_K_APPID);
289         if (ptr)
290                 appinfo->appid = strdup(ptr);
291         ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE);
292         if (ptr)
293                 appinfo->pkg_type = strdup(ptr);
294         ptr = bundle_get_val(kb, AUL_K_HWACC);
295         if (ptr)
296                 appinfo->hwacc = strdup(ptr);
297         ptr = bundle_get_val(kb, AUL_K_PKGID);
298         if (ptr)
299                 appinfo->debug_appid = strdup(ptr);
300         ptr = bundle_get_val(kb, AUL_K_TASKMANAGE);
301         if (ptr)
302                 appinfo->taskmanage = strdup(ptr);
303         ptr = bundle_get_val(kb, AUL_K_COMP_TYPE);
304         if (ptr)
305                 appinfo->comp_type = strdup(ptr);
306         ptr = bundle_get_val(kb, AUL_K_PKGID);
307         if (ptr)
308                 appinfo->pkgid = strdup(ptr);
309         ptr = bundle_get_val(kb, AUL_K_EXEC);
310         if (ptr)
311                 appinfo->app_path = strdup(ptr);
312         if (appinfo->app_path)
313                 appinfo->original_app_path = strdup(appinfo->app_path);
314
315         if (__appinfo_get_app_path(appinfo) == NULL) {
316                 _appinfo_free(appinfo);
317                 return NULL;
318         }
319
320         return appinfo;
321 }
322
323 void _appinfo_free(appinfo_t *appinfo)
324 {
325         if (appinfo == NULL)
326                 return;
327
328         if (appinfo->appid)
329                 free(appinfo->appid);
330         if (appinfo->app_path)
331                 free(appinfo->app_path);
332         if (appinfo->original_app_path)
333                 free(appinfo->original_app_path);
334         if (appinfo->pkg_type)
335                 free(appinfo->pkg_type);
336         if (appinfo->hwacc)
337                 free(appinfo->hwacc);
338         if (appinfo->taskmanage)
339                 free(appinfo->taskmanage);
340         if (appinfo->debug_appid)
341                 free(appinfo->debug_appid);
342         if (appinfo->comp_type)
343                 free(appinfo->comp_type);
344         if (appinfo->pkgid)
345                 free(appinfo->pkgid);
346
347         free(appinfo);
348 }
349
350 static int __parse_app_path(const char *arg, char *out, int out_size)
351 {
352         register int i;
353         int state = 1;
354         char *start_out = out;
355
356         if (arg == NULL || out == NULL)
357                 return 0;
358
359         for (i = 0; out_size > 1; i++) {
360                 switch (state) {
361                 case 1:
362                         switch (arg[i]) {
363                         case ' ':
364                         case '\t':
365                                 state = 5;
366                                 break;
367                         case '\0':
368                                 state = 7;
369                                 break;
370                         case '\"':
371                                 state = 2;
372                                 break;
373                         case '\\':
374                                 state = 4;
375                                 break;
376                         default:
377                                 *out = arg[i];
378                                 out++;
379                                 out_size--;
380                                 break;
381                         }
382                         break;
383                 case 2: /* escape start */
384                         switch (arg[i]) {
385                         case '\0':
386                                 state = 6;
387                                 break;
388                         case '\"':
389                                 state = 1;
390                                 break;
391                         default:
392                                 *out = arg[i];
393                                 out++;
394                                 out_size--;
395                                 break;
396                         }
397                         break;
398                 case 4: /* character escape */
399                         if (arg[i] == '\0')
400                                 state = 6;
401                         else {
402                                 *out = arg[i];
403                                 out++;
404                                 out_size--;
405                                 state = 1;
406                         }
407                         break;
408                 case 5: /* token */
409                         if (out != start_out) {
410                                 *out = '\0';
411                                 out_size--;
412                                 return i;
413                         }
414                         i--;
415                         state = 1;
416                         break;
417                 case 6:
418                         return -1;  /* error */
419                 case 7: /* terminate */
420                         *out = '\0';
421                         out_size--;
422                         return 0;
423                 default:
424                         state = 6;
425                         break;  /* error */
426                 }
427         }
428
429         if (out_size == 1)
430                 *out = '\0';
431
432         /* Buffer overflow*/
433         return -2;
434 }
435
436 void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *appinfo, int cmd)
437 {
438         char *ptr;
439         char exe[MAX_PATH_LEN];
440         int flag;
441         char key[256];
442         char value[256];
443
444         bundle_del(kb, AUL_K_APPID);
445         bundle_del(kb, AUL_K_EXEC);
446         bundle_del(kb, AUL_K_PACKAGETYPE);
447         bundle_del(kb, AUL_K_HWACC);
448         bundle_del(kb, AUL_K_PKGID);
449         bundle_del(kb, AUL_K_TASKMANAGE);
450         bundle_del(kb, AUL_K_COMP_TYPE);
451
452         /* Parse app_path to retrieve default bundle */
453         if (cmd == PAD_CMD_LAUNCH) {
454                 ptr = appinfo->original_app_path;
455                 flag = __parse_app_path(ptr, exe, sizeof(exe));
456                 if (flag > 0) {
457                         ptr += flag;
458                         SECURE_LOGD("parsing app_path: EXEC - %s", exe);
459
460                         do {
461                                 flag = __parse_app_path(ptr, key, sizeof(key));
462                                 if (flag <= 0)
463                                         break;
464                                 ptr += flag;
465
466                                 flag = __parse_app_path(ptr, value,
467                                                 sizeof(value));
468                                 if (flag < 0)
469                                         break;
470                                 ptr += flag;
471
472                                 /* bundle_del(kb, key); */
473                                 bundle_add(kb, key, value);
474                         } while (flag > 0);
475                 } else if (flag == 0) {
476                         _D("parsing app_path: No arguments");
477                 } else {
478                         _D("parsing app_path: Invalid argument");
479                 }
480
481         }
482 }
483
484 static char *__get_libdir(const char *path)
485 {
486         char *path_dup;
487         char buf[PATH_MAX];
488         char *ptr;
489
490         path_dup = strdup(path);
491         if (path_dup == NULL)
492                 return NULL;
493
494         ptr = strrchr(path_dup, '/');
495         if (ptr == NULL)
496                 return NULL;
497
498         *ptr = '\0';
499
500         snprintf(buf, sizeof(buf), "%s/../lib/", path_dup);
501         free(path_dup);
502
503         if (access(buf, F_OK) == -1)
504                 return NULL;
505
506         return strdup(buf);
507 }
508
509 static void __set_sdk_env(const char *appid, const char *value)
510 {
511         char buf[MAX_LOCAL_BUFSZ];
512         char *token = NULL;
513
514         _D("key: %s / value: %s", AUL_K_SDK, value);
515         /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
516         /* GCOV_PREFIX contains the prefix to add to the absolute paths */
517         /*      in the object file. Prefix can be absolute, or relative.*/
518         /*      The default is no prefix.  */
519         /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
520         /*      to stripoff the hardwired absolute paths. Default value is 0. */
521         if (strncmp(value, SDK_CODE_COVERAGE, strlen(value)) == 0) {
522                 token = strrchr(appid, '.');
523                 if (token == NULL)
524                         return;
525                 token++;
526
527                 snprintf(buf, sizeof(buf), PATH_TMP"/%s"PATH_DATA, token);
528                 setenv("GCOV_PREFIX", buf, 1);
529                 setenv("GCOV_PREFIX_STRIP", "0", 1);
530         }
531 }
532
533 void _set_env(appinfo_t *appinfo, bundle *kb)
534 {
535         const char *str;
536         const char **str_array = NULL;
537         int len = 0;
538         int i;
539         char *libdir;
540
541         setenv("PKG_NAME", appinfo->appid, 1);
542
543         str = bundle_get_val(kb, AUL_K_STARTTIME);
544         if (str)
545                 setenv("APP_START_TIME", str, 1);
546         if (appinfo->hwacc)
547                 setenv("HWACC", appinfo->hwacc, 1);
548         if (appinfo->taskmanage)
549                 setenv("TASKMANAGE", appinfo->taskmanage, 1);
550         if (appinfo->appid)
551                 setenv("AUL_APPID", appinfo->appid, 1);
552         if (appinfo->pkgid)
553                 setenv("AUL_PKGID", appinfo->pkgid, 1);
554
555         str = bundle_get_val(kb, AUL_K_WAYLAND_DISPLAY);
556         if (str)
557                 setenv("WAYLAND_DISPLAY", str, 1);
558
559         str = bundle_get_val(kb, AUL_K_WAYLAND_WORKING_DIR);
560         if (str)
561                 setenv("XDG_RUNTIME_DIR", str, 1);
562
563         str = bundle_get_val(kb, AUL_K_API_VERSION);
564         if (str)
565                 setenv("TIZEN_API_VERSION", str, 1);
566
567         str = bundle_get_val(kb, AUL_K_ROOT_PATH);
568         if (str)
569                 setenv("AUL_ROOT_PATH", str, 1);
570
571         libdir = __get_libdir(appinfo->app_path);
572         if (libdir) {
573                 setenv("LD_LIBRARY_PATH", libdir, 1);
574                 free(libdir);
575         }
576
577         if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
578                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
579         } else {
580                 str = bundle_get_val(kb, AUL_K_SDK);
581                 if (str) {
582                         str_array = &str;
583                         len = 1;
584                 }
585         }
586
587         for (i = 0; i < len; i++)
588                 __set_sdk_env(appinfo->appid, str_array[i]);
589 }
590
591 static char **__add_arg(bundle *kb, char **argv, int *margc, const char *key)
592 {
593         const char *str = NULL;
594         const char **str_array = NULL;
595         int len = 0;
596         int i;
597         char **new_argv = NULL;
598
599         if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
600                 str_array = bundle_get_str_array(kb, key, &len);
601         } else {
602                 str = bundle_get_val(kb, key);
603                 if (str) {
604                         str_array = &str;
605                         len = 1;
606                 }
607         }
608
609         if (str_array) {
610                 if (strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
611                         || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
612                         new_argv = (char **)realloc(argv,
613                                         sizeof(char *) * (*margc + len + 2));
614                         if (new_argv == NULL) {
615                                 _E("Failed to realloc (key: %s)", key);
616                                 exit(-1);
617                         }
618
619                         for (i = *margc + len + 1; i - (len + 1) >= 0; i--)
620                                 new_argv[i] = new_argv[i - (len + 1)];
621
622                         /* need to add new_argv[0] */
623                         for (i = 0; i < len; i++)
624                                 new_argv[1 + i] = strdup(str_array[i]);
625
626                         len++; /* gdbserver or valgrind */
627                 } else if (strncmp(key, DLP_K_ATTACH_ARG, strlen(key)) == 0) {
628                         new_argv = (char **)malloc((len + 2) * sizeof(char *));
629                         if (new_argv == NULL) {
630                                 _E("Failed to malloc (key: %s)", key);
631                                 exit(-1);
632                         }
633
634                         for (i = 0; i < len; i++)
635                                 new_argv[1 + i] = strdup(str_array[i]);
636
637                         *margc = 0;
638                         len = len + 1;
639                 } else {
640                         new_argv = (char **)realloc(argv,
641                                         sizeof(char *) * (*margc + len + 1));
642                         if (new_argv == NULL) {
643                                 _E("Failed to realloc (key: %s)", key);
644                                 exit(-1);
645                         }
646
647                         for (i = 0; i < len; i++)
648                                 new_argv[*margc + i] = strdup(str_array[i]);
649                 }
650
651                 new_argv[*margc + len] = NULL;
652                 *margc += len;
653         } else {
654                 if (strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
655                         || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
656                         new_argv = (char **)realloc(argv,
657                                         sizeof(char *) * (*margc + 2));
658                         if (new_argv == NULL) {
659                                 _E("Failed to realloc (key: %s)", key);
660                                 exit(-1);
661                         }
662
663                         for (i = *margc + 1; i - 1 >= 0; i--)
664                                 new_argv[i] = new_argv[i - 1];
665
666                         /* need to add new_argv[0] */
667                         (*margc)++;
668                 }
669         }
670
671         if (new_argv == NULL)
672                 return argv;
673
674         return new_argv;
675 }
676
677 char **_create_argc_argv(bundle *kb, int *margc, const char *app_path)
678 {
679         char **argv = NULL;
680         char **new_argv = NULL;
681         int argc;
682         int i;
683         char buf[MAX_LOCAL_BUFSZ];
684         const char *str;
685         const char **str_array = NULL;
686         int len = 0;
687         const char *path;
688
689         argc = bundle_export_to_argv(kb, &argv);
690         if (argv) {
691                 argv[0] = strdup(app_path);
692         } else {
693                 _E("bundle_export_to_argv() is failed.");
694                 return NULL;
695         }
696
697         if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
698                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
699         } else {
700                 str = bundle_get_val(kb, AUL_K_SDK);
701                 if (str) {
702                         str_array = &str;
703                         len = 1;
704                 }
705         }
706
707         for (i = 0; i < len; i++) {
708                 if (str_array[i] == NULL)
709                         break;
710
711                 if (strncmp(str_array[i], SDK_DEBUG,
712                                         strlen(str_array[i])) == 0) {
713                         if (argv[0])
714                                 free(argv[0]);
715                         snprintf(buf, sizeof(buf), "%s.exe", app_path);
716                         /* this code is added  */
717                         /* because core app don't have '.exe' excutable */
718                         /* if '.exe' not exist then use app_path */
719                         if (access(buf, F_OK) != 0)
720                                 argv[0] = strdup(app_path);
721                         else
722                                 argv[0] = strdup(buf);
723
724                         path = bundle_get_val(kb, DLP_K_GDBSERVER_PATH);
725                         if (path == NULL) {
726                                 _E("Failed to get gdbserver path");
727                                 if (argv[0])
728                                         free(argv[0]);
729                                 bundle_free_exported_argv(argc, &argv);
730                                 *margc = 0;
731                                 return NULL;
732                         }
733                         new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
734                         new_argv[0] = strdup(path);
735                         argv = new_argv;
736                 } else if (strncmp(str_array[i], SDK_VALGRIND,
737                                         strlen(str_array[i])) == 0) {
738                         path = bundle_get_val(kb, DLP_K_VALGRIND_PATH);
739                         if (path == NULL) {
740                                 _E("Failed to get valgrind path");
741                                 if (argv[0])
742                                         free(argv[0]);
743                                 bundle_free_exported_argv(argc, &argv);
744                                 *margc = 0;
745                                 return NULL;
746                         }
747                         new_argv = __add_arg(kb, argv, &argc,
748                                         DLP_K_VALGRIND_ARG);
749                         new_argv[0] = strdup(path);
750                         argv = new_argv;
751                 } else if (strncmp(str_array[i], SDK_UNIT_TEST,
752                                         strlen(str_array[i])) == 0) {
753                         new_argv = __add_arg(kb, argv, &argc,
754                                         DLP_K_UNIT_TEST_ARG);
755                         argv = new_argv;
756                 } else if (strncmp(str_array[i], SDK_ATTACH,
757                                         strlen(str_array[i])) == 0) {
758                         if (argv[0])
759                                 free(argv[0]);
760                         bundle_free_exported_argv(argc, &argv);
761                         *margc = 0;
762                         path = bundle_get_val(kb, DLP_K_GDBSERVER_PATH);
763                         if (path == NULL) {
764                                 _E("Failed to get gdbserver path");
765                                 return NULL;
766                         }
767                         new_argv = __add_arg(kb, argv, &argc, DLP_K_ATTACH_ARG);
768                         new_argv[0] = strdup(path);
769                         argv = new_argv;
770                 }
771         }
772
773         *margc = argc;
774
775         return argv;
776 }
777
778 static int __delete_dir(const char *path)
779 {
780         DIR *dp;
781         struct dirent dentry;
782         struct dirent *result = NULL;
783         char buf[PATH_MAX];
784         struct stat statbuf;
785         int ret;
786
787         if (path == NULL)
788                 return -1;
789
790         dp = opendir(path);
791         if (dp == NULL)
792                 return -1;
793
794         while (readdir_r(dp, &dentry, &result) == 0 && result) {
795                 if (!strcmp(dentry.d_name, ".") || !strcmp(dentry.d_name, ".."))
796                         continue;
797
798                 snprintf(buf, sizeof(buf), "%s/%s", path, dentry.d_name);
799                 ret = stat(buf, &statbuf);
800                 if (ret == 0) {
801                         if (S_ISDIR(statbuf.st_mode))
802                                 __delete_dir(buf);
803                         else
804                                 unlink(buf);
805                 }
806         }
807
808         rmdir(path);
809         closedir(dp);
810
811         return 0;
812 }
813
814 int _delete_sock_path(int pid, uid_t uid)
815 {
816         char path[PATH_MAX];
817
818         snprintf(path, sizeof(path), "/run/aul/apps/%d/%d", uid, pid);
819         if (access(path, F_OK) == 0)
820                 __delete_dir(path);
821
822         if (access(path, F_OK) == 0)
823                 return -1;
824
825         return 0;
826 }
827
828 int _close_all_fds(void)
829 {
830         DIR *dp;
831         struct dirent dentry;
832         struct dirent *result = NULL;
833         int fd;
834         int max_fd;
835
836         dp = opendir("/proc/self/fd");
837         if (dp == NULL) {
838                 /* fallback */
839                 max_fd = sysconf(_SC_OPEN_MAX);
840                 for (fd = 3; fd < max_fd; fd++)
841                         close(fd);
842
843                 return 0;
844         }
845
846         while (readdir_r(dp, &dentry, &result) == 0 && result) {
847                 if (!isdigit(dentry.d_name[0]))
848                         continue;
849
850                 fd = atoi(dentry.d_name);
851                 if (fd < 3)
852                         continue;
853
854                 if (fd == dirfd(dp))
855                         continue;
856
857                 close(fd);
858         }
859         closedir(dp);
860
861         return 0;
862 }
863