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