fixed smack define related build error
[framework/appfw/debug-launchpad.git] / src / simple_util.c
1 /*
2  *  debug-launchpad
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <dirent.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include "simple_util.h"
31
32 #define BINSH_NAME      "/bin/sh"
33 #define BINSH_SIZE      7
34
35 #define PROC_STAT_GID_POS       5
36
37
38 static inline int __read_proc(const char *path, char *buf, int size);
39 static inline int __find_pid_by_cmdline(const char *dname,
40                                       const char *cmdline, void *priv);
41 static inline int __get_pgid_from_stat(int pid);
42
43
44 static inline int __read_proc(const char *path, char *buf, int size)
45 {
46         int fd;
47         int ret;
48
49         if (buf == NULL || path == NULL)
50                 return -1;
51
52         fd = open(path, O_RDONLY);
53         if (fd < 0)
54                 return -1;
55
56         ret = read(fd, buf, size - 1);
57         if (ret <= 0) {
58                 close(fd);
59                 return -1;
60         } else
61                 buf[ret] = 0;
62
63         close(fd);
64
65         return ret;
66 }
67
68 static inline int __find_pid_by_cmdline(const char *dname,
69                                       const char *cmdline, void *priv)
70 {
71         char *apppath;
72         int pid = 0;
73
74         apppath = (char *)priv;
75         if (strncmp(cmdline, apppath, MAX_LOCAL_BUFSZ-1) == 0) {
76                 pid = atoi(dname);
77                 if (pid != getpgid(pid))
78                         pid = 0;
79         }
80
81         return pid;
82 }
83
84 int __proc_iter_cmdline(
85         int (*iterfunc)(const char *dname, const char *cmdline, void *priv),
86                     void *priv)
87 {
88         DIR *dp;
89         struct dirent *dentry;
90         int pid;
91         int ret;
92         char buf[MAX_LOCAL_BUFSZ];
93
94         dp = opendir("/proc");
95         if (dp == NULL) {
96                 return -1;
97         }
98
99         if (iterfunc == NULL)
100                 iterfunc = __find_pid_by_cmdline;
101
102         while ((dentry = readdir(dp)) != NULL) {
103                 if (!isdigit(dentry->d_name[0]))
104                         continue;
105
106                 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
107                 ret = __read_proc(buf, buf, sizeof(buf));
108                 if (ret <= 0)
109                         continue;
110
111                 /* support app launched by shell script*/
112                 if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
113                         pid =
114                             iterfunc(dentry->d_name, &buf[BINSH_SIZE + 1],
115                                      priv);
116                 else
117                         pid = iterfunc(dentry->d_name, buf, priv);
118
119                 if (pid > 0) {
120                         closedir(dp);
121                         return pid;
122                 }
123         }
124
125         closedir(dp);
126         return -1;
127 }
128
129 char *__proc_get_cmdline_bypid(int pid)
130 {
131         char buf[MAX_LOCAL_BUFSZ];
132         int ret;
133
134         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
135         ret = __read_proc(buf, buf, sizeof(buf));
136         if (ret <= 0)
137                 return NULL;
138
139         /* support app launched by shell script*/
140         if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
141                 return strdup(&buf[BINSH_SIZE + 1]);
142         else
143                 return strdup(buf);
144 }
145
146 static inline int __get_pgid_from_stat(int pid)
147 {
148         char buf[MAX_LOCAL_BUFSZ];
149         char *str;
150         int ret;
151         int i;
152         int count = 0;
153
154         if (pid <= 1)
155                 return -1;
156
157         snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
158         ret = __read_proc(buf, buf, sizeof(buf));
159         if (ret < 0)
160                 return -1;
161
162         for (i = 0; i < (ret - 1); i++) {
163                 if (buf[i] == ' ') {
164                         count++;
165                         if (count == PROC_STAT_GID_POS - 1)
166                                 str = &(buf[i + 1]);
167                         else if (count == PROC_STAT_GID_POS) {
168                                 buf[i] = 0;
169                                 break;
170                         }
171                 }
172         }
173
174         if (count == PROC_STAT_GID_POS)
175                 pid = atoi(str);
176         else
177                 pid = -1;
178
179         return pid;
180 }
181
182 int __proc_iter_pgid(int pgid, int (*iterfunc) (int pid, void *priv),
183                      void *priv)
184 {
185         DIR *dp;
186         struct dirent *dentry;
187         int _pgid;
188         int ret = -1;
189
190         dp = opendir("/proc");
191         if (dp == NULL) {
192                 return -1;
193         }
194
195         while ((dentry = readdir(dp)) != NULL) {
196                 if (!isdigit(dentry->d_name[0]))
197                         continue;
198
199                 _pgid = __get_pgid_from_stat(atoi(dentry->d_name));
200                 if (pgid == _pgid) {
201                         ret = iterfunc(atoi(dentry->d_name), priv);
202                         if (ret >= 0)
203                                 break;
204                 }
205         }
206
207         closedir(dp);
208         return ret;
209 }
210