Adjust coding rules
[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         libdir = __get_libdir(appinfo->app_path);
530         if (libdir) {
531                 setenv("LD_LIBRARY_PATH", libdir, 1);
532                 free(libdir);
533         }
534
535         if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
536                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
537         } else {
538                 str = bundle_get_val(kb, AUL_K_SDK);
539                 if (str) {
540                         str_array = &str;
541                         len = 1;
542                 }
543         }
544
545         for (i = 0; i < len; i++)
546                 __set_sdk_env(appinfo->appid, str_array[i]);
547 }
548
549 static char **__add_arg(bundle *kb, char **argv, int *margc, const char *key)
550 {
551         const char *str = NULL;
552         const char **str_array = NULL;
553         int len = 0;
554         int i;
555         char **new_argv = NULL;
556
557         if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
558                 str_array = bundle_get_str_array(kb, key, &len);
559         } else {
560                 str = bundle_get_val(kb, key);
561                 if (str) {
562                         str_array = &str;
563                         len = 1;
564                 }
565         }
566
567         if (str_array) {
568                 if (strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
569                         || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
570                         new_argv = (char **)realloc(argv,
571                                         sizeof(char *) * (*margc + len + 2));
572                         if (new_argv == NULL) {
573                                 _E("Failed to realloc (key: %s)", key);
574                                 exit(-1);
575                         }
576
577                         for (i = *margc + len + 1; i - (len + 1) >= 0; i--)
578                                 new_argv[i] = new_argv[i - (len + 1)];
579
580                         /* need to add new_argv[0] */
581                         for (i = 0; i < len; i++)
582                                 new_argv[1 + i] = strdup(str_array[i]);
583
584                         len++; /* gdbserver or valgrind */
585                 } else if (strncmp(key, DLP_K_ATTACH_ARG, strlen(key)) == 0) {
586                         new_argv = (char **)malloc((len + 2) * sizeof(char *));
587                         if (new_argv == NULL) {
588                                 _E("Failed to malloc (key: %s)", key);
589                                 exit(-1);
590                         }
591
592                         for (i = 0; i < len; i++)
593                                 new_argv[1 + i] = strdup(str_array[i]);
594
595                         *margc = 0;
596                         len = len + 1;
597                 } else {
598                         new_argv = (char **)realloc(argv,
599                                         sizeof(char *) * (*margc + len + 1));
600                         if (new_argv == NULL) {
601                                 _E("Failed to realloc (key: %s)", key);
602                                 exit(-1);
603                         }
604
605                         for (i = 0; i < len; i++)
606                                 new_argv[*margc + i] = strdup(str_array[i]);
607                 }
608
609                 new_argv[*margc + len] = NULL;
610                 *margc += len;
611         } else {
612                 if (strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
613                         || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
614                         new_argv = (char **)realloc(argv,
615                                         sizeof(char *) * (*margc + 2));
616                         if (new_argv == NULL) {
617                                 _E("Failed to realloc (key: %s)", key);
618                                 exit(-1);
619                         }
620
621                         for (i = *margc + 1; i - 1 >= 0; i--)
622                                 new_argv[i] = new_argv[i - 1];
623
624                         /* need to add new_argv[0] */
625                         (*margc)++;
626                 }
627         }
628
629         if (new_argv == NULL)
630                 return argv;
631
632         return new_argv;
633 }
634
635 char **_create_argc_argv(bundle *kb, int *margc, const char *app_path)
636 {
637         char **argv = NULL;
638         char **new_argv = NULL;
639         int argc;
640         int i;
641         char buf[MAX_LOCAL_BUFSZ];
642         const char *str;
643         const char **str_array = NULL;
644         int len = 0;
645         const char *path;
646
647         argc = bundle_export_to_argv(kb, &argv);
648         if (argv) {
649                 argv[0] = strdup(app_path);
650         } else {
651                 _E("bundle_export_to_argv() is failed.");
652                 return NULL;
653         }
654
655         if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
656                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
657         } else {
658                 str = bundle_get_val(kb, AUL_K_SDK);
659                 if (str) {
660                         str_array = &str;
661                         len = 1;
662                 }
663         }
664
665         for (i = 0; i < len; i++) {
666                 if (str_array[i] == NULL)
667                         break;
668
669                 if (strncmp(str_array[i], SDK_DEBUG,
670                                         strlen(str_array[i])) == 0) {
671                         if (argv[0])
672                                 free(argv[0]);
673                         snprintf(buf, sizeof(buf), "%s.exe", app_path);
674                         /* this code is added because core app don't have '.exe' excutable */
675                         /* if '.exe' not exist then use app_path */
676                         if (access(buf, F_OK) != 0)
677                                 argv[0] = strdup(app_path);
678                         else
679                                 argv[0] = strdup(buf);
680
681                         path = bundle_get_val(kb, DLP_K_GDBSERVER_PATH);
682                         if (path == NULL) {
683                                 _E("Failed to get gdbserver path");
684                                 if (argv[0])
685                                         free(argv[0]);
686                                 bundle_free_exported_argv(argc, &argv);
687                                 *margc = 0;
688                                 return NULL;
689                         }
690                         new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
691                         new_argv[0] = strdup(path);
692                         argv = new_argv;
693                 } else if (strncmp(str_array[i], SDK_VALGRIND,
694                                         strlen(str_array[i])) == 0) {
695                         path = bundle_get_val(kb, DLP_K_VALGRIND_PATH);
696                         if (path == NULL) {
697                                 _E("Failed to get valgrind path");
698                                 if (argv[0])
699                                         free(argv[0]);
700                                 bundle_free_exported_argv(argc, &argv);
701                                 *margc = 0;
702                                 return NULL;
703                         }
704                         new_argv = __add_arg(kb, argv, &argc,
705                                         DLP_K_VALGRIND_ARG);
706                         new_argv[0] = strdup(path);
707                         argv = new_argv;
708                 } else if (strncmp(str_array[i], SDK_UNIT_TEST,
709                                         strlen(str_array[i])) == 0) {
710                         new_argv = __add_arg(kb, argv, &argc,
711                                         DLP_K_UNIT_TEST_ARG);
712                         argv = new_argv;
713                 } else if (strncmp(str_array[i], SDK_ATTACH,
714                                         strlen(str_array[i])) == 0) {
715                         if (argv[0])
716                                 free(argv[0]);
717                         bundle_free_exported_argv(argc, &argv);
718                         *margc = 0;
719                         path = bundle_get_val(kb, DLP_K_GDBSERVER_PATH);
720                         if (path == NULL) {
721                                 _E("Failed to get gdbserver path");
722                                 return NULL;
723                         }
724                         new_argv = __add_arg(kb, argv, &argc, DLP_K_ATTACH_ARG);
725                         new_argv[0] = strdup(path);
726                         argv = new_argv;
727                 }
728         }
729
730         *margc = argc;
731
732         return argv;
733 }
734
735 static int __read_proc(const char *path, char *buf, int size)
736 {
737         int fd;
738         int ret;
739
740         if (buf == NULL || path == NULL)
741                 return -1;
742
743         fd = open(path, O_RDONLY);
744         if (fd < 0)
745                 return -1;
746
747         ret = read(fd, buf, size - 1);
748         if (ret <= 0) {
749                 close(fd);
750                 return -1;
751         }
752
753         buf[ret] = 0;
754         close(fd);
755
756         return ret;
757 }
758
759 int _proc_check_cmdline_bypid(int pid)
760 {
761         char buf[MAX_CMD_BUFSZ];
762         int ret;
763
764         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
765         ret = __read_proc(buf, buf, sizeof(buf));
766         if (ret <= 0)
767                 return -1;
768
769         _D("cmdline: %s", buf);
770
771         return 0;
772 }
773