Initialize Tizen 2.3
[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 <fcntl.h>
27 #include <signal.h>
28 #include <dirent.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <errno.h>
33 #include <poll.h>
34 #include <mntent.h>
35 #include "log.h"
36
37 #define PERMANENT_DIR           "/tmp/permanent"
38 #define VIP_DIR                 "/tmp/vip"
39 #define BUFF_MAX 255
40
41 /**
42  * Opens "/proc/$pid/oom_score_adj" file for w/r;
43  * Return: FILE pointer or NULL
44  */
45 FILE * open_proc_oom_score_adj_file(int pid, const char *mode)
46 {
47         char buf[32];
48         FILE *fp;
49
50         snprintf(buf, sizeof(buf), "/proc/%d/oom_score_adj", pid);
51         fp = fopen(buf, mode);
52         return fp;
53 }
54
55 int get_exec_pid(const char *execpath)
56 {
57         DIR *dp;
58         struct dirent *dentry;
59         int pid = -1, fd;
60         int ret;
61         char buf[PATH_MAX];
62         char buf2[PATH_MAX];
63
64         dp = opendir("/proc");
65         if (!dp) {
66                 _E("FAIL: open /proc");
67                 return -1;
68         }
69
70         while ((dentry = readdir(dp)) != NULL) {
71                 if (!isdigit(dentry->d_name[0]))
72                         continue;
73
74                 pid = atoi(dentry->d_name);
75
76                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
77                 fd = open(buf, O_RDONLY);
78                 if (fd < 0)
79                         continue;
80                 ret = read(fd, buf2, PATH_MAX);
81                 close(fd);
82
83                 if (ret < 0 || ret >= PATH_MAX)
84                         continue;
85
86                 buf2[ret] = '\0';
87
88                 if (!strcmp(buf2, execpath)) {
89                         closedir(dp);
90                         return pid;
91                 }
92         }
93
94         errno = ESRCH;
95         closedir(dp);
96         return -1;
97 }
98
99 int get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
100 {
101         int fd, ret;
102         char buf[PATH_MAX + 1];
103         char *filename;
104
105         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
106         fd = open(buf, O_RDONLY);
107         if (fd < 0) {
108                 errno = ESRCH;
109                 return -1;
110         }
111
112         ret = read(fd, buf, PATH_MAX);
113         close(fd);
114         buf[PATH_MAX] = '\0';
115
116         filename = strrchr(buf, '/');
117         if (filename == NULL)
118                 filename = buf;
119         else
120                 filename = filename + 1;
121
122         if (cmdline_size < strlen(filename) + 1) {
123                 errno = EOVERFLOW;
124                 return -1;
125         }
126
127         strncpy(cmdline, filename, cmdline_size - 1);
128         cmdline[cmdline_size - 1] = '\0';
129         return 0;
130 }
131
132 int is_vip(int pid)
133 {
134         if (pid < 1)
135                 return -1;
136
137         char buf[PATH_MAX];
138
139         snprintf(buf, PATH_MAX, "%s/%d", VIP_DIR, pid);
140
141         if (access(buf, R_OK) == 0)
142                 return 1;
143         else
144                 return 0;
145 }
146
147 static int remove_dir_internal(int fd)
148 {
149         DIR *dir;
150         struct dirent *de;
151         int subfd, ret = 0;
152
153         dir = fdopendir(fd);
154         if (!dir)
155                 return -1;
156         while ((de = readdir(dir))) {
157                 if (de->d_type == DT_DIR) {
158                         if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
159                                 continue;
160                         subfd = openat(fd, de->d_name, O_RDONLY | O_DIRECTORY);
161                         if (subfd < 0) {
162                                 _SE("Couldn't openat %s: %s\n", de->d_name, strerror(errno));
163                                 ret = -1;
164                                 continue;
165                         }
166                         if (remove_dir_internal(subfd)) {
167                                 ret = -1;
168                         }
169                         close(subfd);
170                         if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
171                                 _SE("Couldn't unlinkat %s: %s\n", de->d_name, strerror(errno));
172                                 ret = -1;
173                         }
174                 } else {
175                         if (unlinkat(fd, de->d_name, 0) < 0) {
176                                 _SE("Couldn't unlinkat %s: %s\n", de->d_name, strerror(errno));
177                                 ret = -1;
178                         }
179                 }
180         }
181         closedir(dir);
182         return ret;
183 }
184
185 int remove_dir(char *path, int del_dir)
186 {
187         int fd, ret = 0;
188
189         if (!path)
190                 return -1;
191         fd = open(path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
192         if (fd < 0) {
193                 _SE("Couldn't opendir %s: %s\n", path, strerror(errno));
194                 return -errno;
195         }
196         ret = remove_dir_internal(fd);
197         close(fd);
198
199         if (del_dir) {
200                 if (rmdir(path)) {
201                         _SE("Couldn't rmdir %s: %s\n", path, strerror(errno));
202                         ret = -1;
203                 }
204         }
205         return ret;
206 }
207
208 /*
209  * Helper function
210  * - Read from sysfs entry
211  * - Write to sysfs entry
212  */
213 static int sys_read_buf(char *file, char *buf)
214 {
215         int fd;
216         int r;
217         int ret = 0;
218
219         fd = open(file, O_RDONLY);
220         if (fd == -1)
221                 return -ENOENT;
222
223         r = read(fd, buf, BUFF_MAX);
224         if ((r >= 0) && (r < BUFF_MAX))
225                 buf[r] = '\0';
226         else
227                 ret = -EIO;
228
229         close(fd);
230
231         return ret;
232 }
233
234 static int sys_write_buf(char *file, char *buf)
235 {
236         int fd;
237         int r;
238         int ret = 0;
239
240         fd = open(file, O_WRONLY);
241         if (fd == -1)
242                 return -ENOENT;
243
244         r = write(fd, buf, strlen(buf));
245         if (r < 0)
246                 ret = -EIO;
247
248         close(fd);
249
250         return ret;
251 }
252
253 int sys_get_int(char *fname, int *val)
254 {
255         char buf[BUFF_MAX];
256         int ret = 0;
257
258         if (sys_read_buf(fname, buf) == 0) {
259                 *val = atoi(buf);
260         } else {
261                 *val = -1;
262                 ret = -EIO;
263         }
264
265         return ret;
266 }
267
268 int sys_set_int(char *fname, int val)
269 {
270         char buf[BUFF_MAX];
271         int ret = 0;
272
273         snprintf(buf, sizeof(buf), "%d", val);
274
275         if (sys_write_buf(fname, buf) != 0)
276                 ret = -EIO;
277
278         return ret;
279 }
280
281 int sys_get_str(char *fname, char *str)
282 {
283         char buf[BUFF_MAX] = {0};
284
285         if (sys_read_buf(fname, buf) == 0) {
286                 strncpy(str, buf, strlen(buf));
287                 return 0;
288         }
289
290         return -1;
291 }
292
293 int sys_set_str(char *fname, char *val)
294 {
295         int r = -1;
296
297         if (val != NULL) {
298                 if (sys_write_buf(fname, val) == 0)
299                         r = 0;
300         }
301
302         return r;
303 }
304
305 int terminate_process(char* partition, bool force)
306 {
307         const char *argv[7] = {"/sbin/fuser", "-m", "-k", "-S", NULL, NULL, NULL};
308         int argc;
309
310         if (force)
311                 argv[4] = "-SIGKILL";
312         else
313                 argv[4] = "-SIGTERM";
314         argv[5] = partition;
315         argc = sizeof(argv) / sizeof(argv[0]);
316         return run_child(argc, argv);
317 }
318
319 int mount_check(const char* path)
320 {
321         int ret = false;
322         struct mntent* mnt;
323         const char* table = "/etc/mtab";
324         FILE* fp;
325
326         fp = setmntent(table, "r");
327         if (!fp)
328                 return ret;
329         while (mnt=getmntent(fp)) {
330                 if (!strcmp(mnt->mnt_dir, path)) {
331                         ret = true;
332                         break;
333                 }
334         }
335         endmntent(fp);
336         return ret;
337 }