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