tizen 2.3 release
[framework/system/deviced.git] / src / core / common.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdbool.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <fcntl.h>
28 #include <signal.h>
29 #include <dirent.h>
30 #include <ctype.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <errno.h>
34 #include <poll.h>
35 #include <mntent.h>
36 #include "log.h"
37
38 #define PERMANENT_DIR           "/tmp/permanent"
39 #define VIP_DIR                 "/tmp/vip"
40 #define BUFF_MAX 255
41
42 /**
43  * Opens "/proc/$pid/oom_score_adj" file for w/r;
44  * Return: FILE pointer or NULL
45  */
46 FILE * open_proc_oom_score_adj_file(int pid, const char *mode)
47 {
48         char buf[32];
49         FILE *fp;
50
51         snprintf(buf, sizeof(buf), "/proc/%d/oom_score_adj", pid);
52         fp = fopen(buf, mode);
53         return fp;
54 }
55
56 int get_exec_pid(const char *execpath)
57 {
58         DIR *dp;
59         struct dirent *dentry;
60         int pid = -1, fd;
61         int ret;
62         char buf[PATH_MAX];
63         char buf2[PATH_MAX];
64
65         dp = opendir("/proc");
66         if (!dp) {
67                 _E("FAIL: open /proc");
68                 return -1;
69         }
70
71         while ((dentry = readdir(dp)) != NULL) {
72                 if (!isdigit(dentry->d_name[0]))
73                         continue;
74
75                 pid = atoi(dentry->d_name);
76
77                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
78                 fd = open(buf, O_RDONLY);
79                 if (fd < 0)
80                         continue;
81                 ret = read(fd, buf2, PATH_MAX);
82                 close(fd);
83
84                 if (ret < 0 || ret >= PATH_MAX)
85                         continue;
86
87                 buf2[ret] = '\0';
88
89                 if (!strcmp(buf2, execpath)) {
90                         closedir(dp);
91                         return pid;
92                 }
93         }
94
95         errno = ESRCH;
96         closedir(dp);
97         return -1;
98 }
99
100 int get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
101 {
102         int fd, ret;
103         char buf[PATH_MAX + 1];
104         char *filename;
105
106         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
107         fd = open(buf, O_RDONLY);
108         if (fd < 0) {
109                 errno = ESRCH;
110                 return -1;
111         }
112
113         ret = read(fd, buf, PATH_MAX);
114         close(fd);
115         buf[PATH_MAX] = '\0';
116
117         filename = strrchr(buf, '/');
118         if (filename == NULL)
119                 filename = buf;
120         else
121                 filename = filename + 1;
122
123         if (cmdline_size < strlen(filename) + 1) {
124                 errno = EOVERFLOW;
125                 return -1;
126         }
127
128         strncpy(cmdline, filename, cmdline_size - 1);
129         cmdline[cmdline_size - 1] = '\0';
130         return 0;
131 }
132
133 int is_vip(int pid)
134 {
135         if (pid < 1)
136                 return -1;
137
138         char buf[PATH_MAX];
139
140         snprintf(buf, PATH_MAX, "%s/%d", VIP_DIR, pid);
141
142         if (access(buf, R_OK) == 0)
143                 return 1;
144         else
145                 return 0;
146 }
147
148 static int remove_dir_internal(int fd)
149 {
150         DIR *dir;
151         struct dirent *de;
152         int subfd, ret = 0;
153
154         dir = fdopendir(fd);
155         if (!dir)
156                 return -1;
157         while ((de = readdir(dir))) {
158                 if (de->d_type == DT_DIR) {
159                         if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
160                                 continue;
161                         subfd = openat(fd, de->d_name, O_RDONLY | O_DIRECTORY);
162                         if (subfd < 0) {
163                                 _SE("Couldn't openat %s: %s\n", de->d_name, strerror(errno));
164                                 ret = -1;
165                                 continue;
166                         }
167                         if (remove_dir_internal(subfd)) {
168                                 ret = -1;
169                         }
170                         close(subfd);
171                         if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
172                                 _SE("Couldn't unlinkat %s: %s\n", de->d_name, strerror(errno));
173                                 ret = -1;
174                         }
175                 } else {
176                         if (unlinkat(fd, de->d_name, 0) < 0) {
177                                 _SE("Couldn't unlinkat %s: %s\n", de->d_name, strerror(errno));
178                                 ret = -1;
179                         }
180                 }
181         }
182         closedir(dir);
183         return ret;
184 }
185
186 int remove_dir(char *path, int del_dir)
187 {
188         int fd, ret = 0;
189
190         if (!path)
191                 return -1;
192         fd = open(path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
193         if (fd < 0) {
194                 _SE("Couldn't opendir %s: %s\n", path, strerror(errno));
195                 return -errno;
196         }
197         ret = remove_dir_internal(fd);
198         close(fd);
199
200         if (del_dir) {
201                 if (rmdir(path)) {
202                         _SE("Couldn't rmdir %s: %s\n", path, strerror(errno));
203                         ret = -1;
204                 }
205         }
206         return ret;
207 }
208
209 /*
210  * Helper function
211  * - Read from sysfs entry
212  * - Write to sysfs entry
213  */
214 static int sys_read_buf(char *file, char *buf)
215 {
216         int fd;
217         int r;
218         int ret = 0;
219
220         fd = open(file, O_RDONLY);
221         if (fd == -1)
222                 return -ENOENT;
223
224         r = read(fd, buf, BUFF_MAX);
225         if ((r >= 0) && (r < BUFF_MAX))
226                 buf[r] = '\0';
227         else
228                 ret = -EIO;
229
230         close(fd);
231
232         return ret;
233 }
234
235 static int sys_write_buf(char *file, char *buf)
236 {
237         int fd;
238         int r;
239         int ret = 0;
240
241         fd = open(file, O_WRONLY);
242         if (fd == -1)
243                 return -ENOENT;
244
245         r = write(fd, buf, strlen(buf));
246         if (r < 0)
247                 ret = -EIO;
248
249         close(fd);
250
251         return ret;
252 }
253
254 int sys_get_int(char *fname, int *val)
255 {
256         char buf[BUFF_MAX];
257         int ret = 0;
258
259         if (sys_read_buf(fname, buf) == 0) {
260                 *val = atoi(buf);
261         } else {
262                 *val = -1;
263                 ret = -EIO;
264         }
265
266         return ret;
267 }
268
269 int sys_set_int(char *fname, int val)
270 {
271         char buf[BUFF_MAX];
272         int ret = 0;
273
274         snprintf(buf, sizeof(buf), "%d", val);
275
276         if (sys_write_buf(fname, buf) != 0)
277                 ret = -EIO;
278
279         return ret;
280 }
281
282 int sys_get_str(char *fname, char *str)
283 {
284         char buf[BUFF_MAX] = {0};
285
286         if (sys_read_buf(fname, buf) == 0) {
287                 strncpy(str, buf, strlen(buf));
288                 return 0;
289         }
290
291         return -1;
292 }
293
294 int sys_set_str(char *fname, char *val)
295 {
296         int r = -1;
297
298         if (val != NULL) {
299                 if (sys_write_buf(fname, val) == 0)
300                         r = 0;
301         }
302
303         return r;
304 }
305
306 int terminate_process(char* partition, bool force)
307 {
308         const char *argv[7] = {"/sbin/fuser", "-m", "-k", "-S", NULL, NULL, NULL};
309         int argc;
310
311         if (force)
312                 argv[4] = "-SIGKILL";
313         else
314                 argv[4] = "-SIGTERM";
315         argv[5] = partition;
316         argc = sizeof(argv) / sizeof(argv[0]);
317         return run_child(argc, argv);
318 }
319
320 int mount_check(const char* path)
321 {
322         int ret = false;
323         struct mntent* mnt;
324         const char* table = "/etc/mtab";
325         FILE* fp;
326
327         fp = setmntent(table, "r");
328         if (!fp)
329                 return ret;
330         while (mnt=getmntent(fp)) {
331                 if (!strcmp(mnt->mnt_dir, path)) {
332                         ret = true;
333                         break;
334                 }
335         }
336         endmntent(fp);
337         return ret;
338 }
339
340 void print_time(const char *prefix)
341 {
342         struct timeval tv;
343         struct tm *tm;
344         gettimeofday(&tv, NULL);
345         tm = localtime(&(tv.tv_sec));
346         _D("%s --> %d:%02d:%02d %d",
347                         prefix, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
348 }