4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <sys/types.h>
37 #include <system_info.h>
38 #include <sys/mount.h>
44 #define APP_ATTR_PATH "/proc/%d/attr/current"
46 int get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
49 char buf[PATH_MAX + 1];
52 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
53 fd = open(buf, O_RDONLY);
59 ret = read(fd, buf, PATH_MAX);
66 filename = strrchr(buf, '/');
70 filename = filename + 1;
72 if (cmdline_size < strlen(filename) + 1) {
77 strncpy(cmdline, filename, cmdline_size - 1);
78 cmdline[cmdline_size - 1] = '\0';
88 ret = get_privilege(pid, attr, sizeof(attr));
90 _E("Failed to get privilege of PID(%d).", pid);
94 len = strlen(attr) + 1;
96 if (!strncmp("System", attr, len))
99 if (!strncmp("User", attr, len))
102 if (!strncmp("System::Privileged", attr, len))
110 * - Read from sysfs entry
111 * - Write to sysfs entry
113 int sys_check_node(char *path)
117 fd = open(path, O_RDONLY);
125 int get_systemd_reboot_param(char *buf, unsigned bufsize)
127 int r = sys_read_buf("/run/systemd/reboot-param", buf, bufsize);
131 if (r > 0 && buf[r - 1] == '\n') {
139 static int terminate_processes_on_partition(const char *partition, bool force)
141 const char *argv[7] = {"/usr/bin/fuser", "-m", "-k", "-s", NULL, NULL, NULL};
145 argv[4] = "-SIGKILL";
147 argv[4] = "-SIGTERM";
150 argc = sizeof(argv) / sizeof(argv[0]);
152 return run_child(argc, argv);
155 int mount_check(const char *path)
159 const char *table = "/etc/mtab";
163 fp = setmntent(table, "r");
167 len = strlen(path) + 1;
172 if (!strncmp(mnt->mnt_dir, path, len)) {
181 static int get_num_processes_on_partition(const char *part_path)
187 int num_processes = 0;
190 ret = asprintf(&cmd, "fuser -m %s | grep -o '[0-9]*'", part_path);
194 printf("cmd=%s\n", cmd);
195 fp = popen(cmd, "r");
200 while (getline(&line, &len, fp) != -1)
206 return num_processes;
209 void umount_partition_by_kill(const char *path, const int max_retry)
212 char *part_path = NULL;
214 int ret = 0, retry = 0;
218 /* if the path is not a mountpoint, do not perform umounting and killing */
219 if (!mount_check(path))
222 ret = asprintf(&cmd, "mount | grep \" on %s \" | awk '{print $1}'", path);
226 fp = popen(cmd, "r");
231 ret = getline(&part_path, &len, fp);
232 if (ret == -1 || !part_path) {
236 } else if (ret > 0 && *(part_path + ret - 1) == '\n') {
237 *(part_path + ret -1) = '\0';
241 umount2(path, MNT_DETACH);
244 /* Kill processes with SIGTERM */
245 terminate_processes_on_partition(part_path, false);
246 usleep((useconds_t)MSEC_TO_USEC(500));
248 /* Kill processes with SIGKILL */
249 terminate_processes_on_partition(part_path, true);
250 usleep((useconds_t)MSEC_TO_USEC(200));
252 remain = get_num_processes_on_partition(part_path);
256 } while (remain > 0 && retry < max_retry);
264 int get_privilege(pid_t pid, char *name, size_t len)
271 snprintf(path, sizeof(path), APP_ATTR_PATH, pid);
273 fp = fopen(path, "r");
277 attr_len = fread(attr, 1, sizeof(attr) - 1, fp);
282 attr[attr_len] = '\0';
284 snprintf(name, len, "%s", attr);
288 #define MODEL_NAME "http://tizen.org/system/model_name"
289 #define MODEL_EMULATOR "Emulator"
291 bool is_emulator(void)
294 char *model_name = NULL;
295 static bool emul = false;
301 ret = system_info_get_platform_string(MODEL_NAME, &model_name);
303 _E("Cannot get model name: %d", ret);
307 if (!strncmp(MODEL_EMULATOR, model_name, strlen(model_name) + 1))
316 int do_mkdir(const char *path, mode_t mode)
326 for (p = 0, s = 0; p < l; p += s + 1) {
327 s = strcspn(path + p, "/");
331 assert(PATH_MAX > p + s + 1);
333 r = snprintf(d, p + s + 1, "%s", path);
338 if (r < 0 && errno != EEXIST)
345 static int do_copy_internal(const char *src, const char *dst, mode_t mode, bool force)
347 _cleanup_close_ int rfd = -1, wfd = -1;
356 r = access(dst, F_OK);
359 else if (errno != ENOENT)
363 wfd = open(dst, O_CREAT | O_WRONLY | O_TRUNC, mode);
367 rfd = open(src, O_RDONLY);
371 while ((red = read(rfd, buf, 1024)) > 0)
372 if (write(wfd, buf, red) != red)
381 int do_copy_force(const char *src, const char *dst)
386 return do_copy_internal(src, dst, 0644, true);
389 int get_command(pid_t pid, char *comm, size_t len)
397 snprintf(path, sizeof(path), "/proc/%d/comm", pid);
399 fp = fopen(path, "r");
401 _E("Failed to open file %s, errno:%d", path, errno);
405 ret = fread(name, 1, sizeof(name) - 1, fp);
410 while (*tmp != '\0') {
419 snprintf(comm, len, "%s", name);