Initialize Tizen 2.3
[framework/appfw/aul-1.git] / src / simple_util.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <errno.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <linux/un.h>
34 #include "simple_util.h"
35
36 #define BINSH_NAME      "/bin/sh"
37 #define BINSH_SIZE      7
38 #define VALGRIND_NAME   "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
39 #define VALGRIND_SIZE   51
40 #define BASH_NAME       "/bin/bash"
41 #define BASH_SIZE       9
42 #define OPROFILE_NAME   "/usr/bin/oprofile_command"
43 #define OPROFILE_SIZE   25
44 #define OPTION_VALGRIND_NAME    "valgrind"
45 #define OPTION_VALGRIND_SIZE    8
46
47
48 #define PROC_STAT_GID_POS       5
49
50
51 static inline int __read_proc(const char *path, char *buf, int size);
52 static inline int __find_pid_by_cmdline(const char *dname,
53                                       const char *cmdline, void *priv);
54 static inline int __get_pgid_from_stat(int pid);
55
56
57 static inline int __read_proc(const char *path, char *buf, int size)
58 {
59         int fd;
60         int ret;
61
62         if (buf == NULL || path == NULL)
63                 return -1;
64
65         fd = open(path, O_RDONLY);
66         if (fd < 0)
67                 return -1;
68
69         ret = read(fd, buf, size - 1);
70         if (ret <= 0) {
71                 close(fd);
72                 return -1;
73         } else
74                 buf[ret] = 0;
75
76         close(fd);
77
78         return ret;
79 }
80
81 static inline int __find_pid_by_cmdline(const char *dname,
82                                       const char *cmdline, void *priv)
83 {
84         char *apppath;
85         int pid = 0;
86
87         apppath = (char *)priv;
88         if (strncmp(cmdline, apppath, MAX_LOCAL_BUFSZ-1) == 0) {
89                 pid = atoi(dname);
90                 if (pid != getpgid(pid))
91                         pid = 0;
92         }
93
94         return pid;
95 }
96
97 int __proc_iter_cmdline(
98         int (*iterfunc)(const char *dname, const char *cmdline, void *priv),
99                     void *priv)
100 {
101         DIR *dp;
102         struct dirent *dentry;
103         int pid;
104         int ret;
105         char buf[MAX_LOCAL_BUFSZ];
106
107         dp = opendir("/proc");
108         if (dp == NULL) {
109                 return -1;
110         }
111
112         if (iterfunc == NULL)
113                 iterfunc = __find_pid_by_cmdline;
114
115         while ((dentry = readdir(dp)) != NULL) {
116                 if (!isdigit(dentry->d_name[0]))
117                         continue;
118
119                 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
120                 ret = __read_proc(buf, buf, sizeof(buf));
121                 if (ret <= 0)
122                         continue;
123
124                 /* support app launched by shell script*/
125                 if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
126                         pid =
127                             iterfunc(dentry->d_name, &buf[BINSH_SIZE + 1],
128                                      priv);
129                 else
130                         pid = iterfunc(dentry->d_name, buf, priv);
131
132                 if (pid > 0) {
133                         closedir(dp);
134                         return pid;
135                 }
136         }
137
138         closedir(dp);
139         return -1;
140 }
141
142 char *__proc_get_cmdline_bypid(int pid)
143 {
144 #define MAX_CMD_BUFSZ 1024
145
146         char buf[MAX_CMD_BUFSZ];
147         int ret;
148
149         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
150         ret = __read_proc(buf, buf, sizeof(buf));
151         if (ret <= 0)
152                 return NULL;
153
154         /* support app launched by shell script*/
155         if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0) {
156                 return strdup(&buf[BINSH_SIZE + 1]);
157         }
158         else if (strncmp(buf, VALGRIND_NAME, VALGRIND_SIZE) == 0) {
159                 char* ptr = buf;
160
161                 // buf comes with double null-terminated string
162                 while (1) {
163                         while (*ptr) {
164                                 ptr++;
165                         }
166                         ptr++;
167
168                         if (*ptr == NULL)
169                                 break;
170
171                         // ignore trailing "--"
172                         if (strncmp(ptr, "-", 1) != 0)
173                                 break;
174                 };
175
176                 return strdup(ptr);
177         }
178         else if (strncmp(buf, BASH_NAME, BASH_SIZE) == 0) {
179                 if (strncmp(&buf[BASH_SIZE + 1], OPROFILE_NAME, OPROFILE_SIZE) == 0) {
180                         if (strncmp(&buf[BASH_SIZE + OPROFILE_SIZE + 2], OPTION_VALGRIND_NAME, OPTION_VALGRIND_SIZE) == 0) {
181                                 return strdup(&buf[BASH_SIZE + OPROFILE_SIZE + OPTION_VALGRIND_SIZE + 3]);
182                         }
183                 }
184         }
185
186         return strdup(buf);
187 }
188
189 static inline int __get_pgid_from_stat(int pid)
190 {
191         char buf[MAX_LOCAL_BUFSZ];
192         char *str;
193         int ret;
194         int i;
195         int count = 0;
196
197         if (pid <= 1)
198                 return -1;
199
200         snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
201         ret = __read_proc(buf, buf, sizeof(buf));
202         if (ret < 0)
203                 return -1;
204
205         for (i = 0; i < (ret - 1); i++) {
206                 if (buf[i] == ' ') {
207                         count++;
208                         if (count == PROC_STAT_GID_POS - 1)
209                                 str = &(buf[i + 1]);
210                         else if (count == PROC_STAT_GID_POS) {
211                                 buf[i] = 0;
212                                 break;
213                         }
214                 }
215         }
216
217         if (count == PROC_STAT_GID_POS)
218                 pid = atoi(str);
219         else
220                 pid = -1;
221
222         return pid;
223 }
224
225 int __proc_iter_pgid(int pgid, int (*iterfunc) (int pid, void *priv),
226                      void *priv)
227 {
228         DIR *dp;
229         struct dirent *dentry;
230         int _pgid;
231         int ret = -1;
232
233         dp = opendir("/proc");
234         if (dp == NULL) {
235                 return -1;
236         }
237
238         while ((dentry = readdir(dp)) != NULL) {
239                 if (!isdigit(dentry->d_name[0]))
240                         continue;
241
242                 _pgid = __get_pgid_from_stat(atoi(dentry->d_name));
243                 if (pgid == _pgid) {
244                         ret = iterfunc(atoi(dentry->d_name), priv);
245                         if (ret >= 0)
246                                 break;
247                 }
248         }
249
250         closedir(dp);
251         return ret;
252 }
253
254 void __trm_app_info_send_socket(char *write_buf)
255 {
256         const char trm_socket_for_app_info[] = "/dev/socket/app_info";
257         int socket_fd = 0;
258         int ret = 0;
259         struct sockaddr_un addr;
260
261         _D("__trm_app_info_send_socket");
262
263         if (access(trm_socket_for_app_info, F_OK) != 0) {
264                 _E("access");
265                 goto trm_end;
266         }
267
268         socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
269         if (socket_fd < 0) {
270                 _E("socket");
271                 goto trm_end;
272         }
273
274         memset(&addr, 0, sizeof(addr));
275         snprintf(addr.sun_path, UNIX_PATH_MAX, "%s", trm_socket_for_app_info);
276         addr.sun_family = AF_LOCAL;
277
278         ret = connect(socket_fd, (struct sockaddr *) &addr ,sizeof(sa_family_t) + strlen(trm_socket_for_app_info) );
279         if (ret != 0) {
280                 close(socket_fd);
281                 goto trm_end;
282         }
283
284         ret = send(socket_fd, write_buf, strlen(write_buf), MSG_DONTWAIT | MSG_NOSIGNAL);
285         if (ret < 0)
286                 _E("Unable to send data. Error is %s\n",strerror(errno));
287         else
288                 _D("send");
289
290         close(socket_fd);
291 trm_end:
292         return;
293 }
294