INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
IF(POWER_MODULE STREQUAL on)
- ADD_EXECUTABLE(deviced-shutdown src/power-shutdown/shutdown.c src/shared/common.c src/shared/execute.c)
+ ADD_EXECUTABLE(deviced-shutdown src/power-shutdown/shutdown.c src/shared/common.c)
SET(deviced-shutdown_LDFLAGS ${REQUIRED_PKGS_LDFLAGS})
TARGET_LINK_LIBRARIES(deviced-shutdown ${REQUIRED_PKGS_LDFLAGS} "-lrt -ldl -lm" deviced-common-private)
INSTALL(TARGETS deviced-shutdown DESTINATION /usr/lib/systemd)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/systemd/deviced-request-shutdown-exit.conf
DESTINATION /usr/lib/systemd/system/systemd-exit.service.d)
- ADD_EXECUTABLE(deviced-request-shutdown src/power-command/command.c src/shared/common.c src/shared/execute.c)
+ ADD_EXECUTABLE(deviced-request-shutdown src/power-command/command.c src/shared/common.c)
SET(deviced-request-shutdown_LDFLAGS ${REQUIRED_PKGS_LDFLAGS})
TARGET_LINK_LIBRARIES(deviced-request-shutdown ${REQUIRED_PKGS_LDFLAGS} "-lrt -ldl -lm" deviced-common-private)
INSTALL(TARGETS deviced-request-shutdown DESTINATION /usr/sbin)
* limitations under the License.
*/
+#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/mount.h>
#include <unistd.h>
+#include <mntent.h>
+#include <libsyscommon/common.h>
#include "dd-deviced.h"
#include "core/log.h"
return 0;
}
+static int parent(pid_t pid)
+{
+ int status;
+
+ /* wait for child */
+ if (waitpid(pid, &status, 0) != -1) {
+ /* terminated normally */
+ if (WIFEXITED(status)) {
+ _I("Process(%d) terminated by exit(%d).", pid, WEXITSTATUS(status));
+ return WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status))
+ _I("Process(%d) terminated by signal(%d).", pid, WTERMSIG(status));
+ else if (WIFSTOPPED(status))
+ _I("Process(%d) stopped by signal(%d).", pid, WSTOPSIG(status));
+ } else
+ _I("Process(%d) failed to call waitpid(): %d", pid, errno);
+
+ return -EAGAIN;
+}
+
+static void child(int argc, const char *argv[])
+{
+ int i, r;
+
+ for (i = 0; i < _NSIG; ++i)
+ signal(i, SIG_DFL);
+
+ r = execv(argv[0], (char **)argv);
+ if (r < 0)
+ exit(EXIT_FAILURE);
+}
+
+static int run_child(int argc, const char *argv[])
+{
+ pid_t pid;
+ struct sigaction act, oldact;
+ int r = 0;
+ FILE *fp;
+
+ if (!argv)
+ return -EINVAL;
+
+ fp = fopen(argv[0], "r");
+ if (fp == NULL) {
+ _E("Failed to open '%s': %d", argv[0], errno);
+ return -errno;
+ }
+ fclose(fp);
+
+ /* Use default signal handler */
+ act.sa_handler = SIG_DFL;
+ act.sa_sigaction = NULL;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+
+ if (sigaction(SIGCHLD, &act, &oldact) < 0)
+ return -errno;
+
+ pid = fork();
+ if (pid < 0) {
+ _E("Failed to fork.");
+ r = -errno;
+ } else if (pid == 0) {
+ child(argc, argv);
+ } else
+ r = parent(pid);
+
+ if (sigaction(SIGCHLD, &oldact, NULL) < 0)
+ _E("Failed to restore sigaction.");
+
+ return r;
+}
+
+static int terminate_processes_on_partition(const char *partition, bool force)
+{
+ const char *argv[7] = {"/usr/bin/fuser", "-m", "-k", "-s", NULL, NULL, NULL};
+ int argc;
+
+ if (force)
+ argv[4] = "-SIGKILL";
+ else
+ argv[4] = "-SIGTERM";
+
+ argv[5] = partition;
+ argc = sizeof(argv) / sizeof(argv[0]);
+
+ return run_child(argc, argv);
+}
+
+static int get_num_processes_on_partition(const char *part_path)
+{
+ FILE *fp;
+ char *cmd = NULL;
+ char *line = NULL;
+ size_t len = 0;
+ int num_processes = 0;
+ int ret = 0;
+
+ ret = asprintf(&cmd, "fuser -m %s | grep -o '[0-9]*'", part_path);
+ if (ret < 0)
+ return -1;
+
+ printf("cmd=%s\n", cmd);
+ fp = popen(cmd, "r");
+ free(cmd);
+ if (fp == NULL)
+ return -1;
+
+ while (getline(&line, &len, fp) != -1)
+ num_processes++;
+
+ free(line);
+ pclose(fp);
+
+ return num_processes;
+}
+
+static void umount_partition_by_kill(const char *path, const int max_retry)
+{
+ FILE *fp;
+ char *part_path = NULL;
+ size_t len = 0;
+ int ret = 0, retry = 0;
+ int remain;
+ char *cmd = NULL;
+
+ /* if the path is not a mountpoint, do not perform umounting and killing */
+ if (!syscommon_is_mounted(path))
+ return;
+
+ ret = asprintf(&cmd, "mount | grep \" on %s \" | awk '{print $1}'", path);
+ if (ret < 0)
+ return;
+
+ fp = popen(cmd, "r");
+ free(cmd);
+ if (!fp)
+ return;
+
+ ret = getline(&part_path, &len, fp);
+ if (ret == -1 || !part_path) {
+ pclose(fp);
+ free(part_path);
+ return;
+ } else if (ret > 0 && *(part_path + ret - 1) == '\n') {
+ *(part_path + ret -1) = '\0';
+ }
+
+ sync();
+ umount2(path, MNT_DETACH);
+
+ do {
+ /* Kill processes with SIGTERM */
+ terminate_processes_on_partition(part_path, false);
+ usleep((useconds_t)MSEC_TO_USEC(500));
+
+ /* Kill processes with SIGKILL */
+ terminate_processes_on_partition(part_path, true);
+ usleep((useconds_t)MSEC_TO_USEC(200));
+
+ remain = get_num_processes_on_partition(part_path);
+
+ retry++;
+
+ } while (remain > 0 && retry < max_retry);
+ sync();
+
+ free(part_path);
+ pclose(fp);
+ return;
+}
+
+
static void umount_partitions(void)
{
umount_partition_by_kill(UMOUNT_RW_PATH_USER, MAX_UMOUNT_KILL_RETRY);
#include <stdarg.h>
#include <errno.h>
#include <poll.h>
-#include <mntent.h>
#include <system_info.h>
-#include <sys/mount.h>
-#include <libsyscommon/common.h>
#include "log.h"
#include "common.h"
return r;
}
-static int terminate_processes_on_partition(const char *partition, bool force)
-{
- const char *argv[7] = {"/usr/bin/fuser", "-m", "-k", "-s", NULL, NULL, NULL};
- int argc;
-
- if (force)
- argv[4] = "-SIGKILL";
- else
- argv[4] = "-SIGTERM";
-
- argv[5] = partition;
- argc = sizeof(argv) / sizeof(argv[0]);
-
- return run_child(argc, argv);
-}
-
-static int get_num_processes_on_partition(const char *part_path)
-{
- FILE *fp;
- char *cmd = NULL;
- char *line = NULL;
- size_t len = 0;
- int num_processes = 0;
- int ret = 0;
-
- ret = asprintf(&cmd, "fuser -m %s | grep -o '[0-9]*'", part_path);
- if (ret < 0)
- return -1;
-
- printf("cmd=%s\n", cmd);
- fp = popen(cmd, "r");
- free(cmd);
- if (fp == NULL)
- return -1;
-
- while (getline(&line, &len, fp) != -1)
- num_processes++;
-
- free(line);
- pclose(fp);
-
- return num_processes;
-}
-
-void umount_partition_by_kill(const char *path, const int max_retry)
-{
- FILE *fp;
- char *part_path = NULL;
- size_t len = 0;
- int ret = 0, retry = 0;
- int remain;
- char *cmd = NULL;
-
- /* if the path is not a mountpoint, do not perform umounting and killing */
- if (!syscommon_is_mounted(path))
- return;
-
- ret = asprintf(&cmd, "mount | grep \" on %s \" | awk '{print $1}'", path);
- if (ret < 0)
- return;
-
- fp = popen(cmd, "r");
- free(cmd);
- if (!fp)
- return;
-
- ret = getline(&part_path, &len, fp);
- if (ret == -1 || !part_path) {
- pclose(fp);
- free(part_path);
- return;
- } else if (ret > 0 && *(part_path + ret - 1) == '\n') {
- *(part_path + ret -1) = '\0';
- }
-
- sync();
- umount2(path, MNT_DETACH);
-
- do {
- /* Kill processes with SIGTERM */
- terminate_processes_on_partition(part_path, false);
- usleep((useconds_t)MSEC_TO_USEC(500));
-
- /* Kill processes with SIGKILL */
- terminate_processes_on_partition(part_path, true);
- usleep((useconds_t)MSEC_TO_USEC(200));
-
- remain = get_num_processes_on_partition(part_path);
-
- retry++;
-
- } while (remain > 0 && retry < max_retry);
- sync();
-
- free(part_path);
- pclose(fp);
- return;
-}
-
#define MODEL_NAME "http://tizen.org/system/model_name"
#define MODEL_EMULATOR "Emulator"
#define _cleanup_fclose_ _cleanup_(__cleanup_fclose_func)
#endif
-int run_child(int argc, const char *argv[]);
int get_systemd_reboot_param(char *buf, unsigned bufsize);
-void umount_partition_by_kill(const char *path, const int max_retry);
bool is_emulator(void);
int do_mkdir(const char *path, mode_t mode);
int do_copy_force(const char *src, const char *dst);
+++ /dev/null
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <limits.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-
-#include "log.h"
-
-static int parent(pid_t pid)
-{
- int status;
-
- /* wait for child */
- if (waitpid(pid, &status, 0) != -1) {
- /* terminated normally */
- if (WIFEXITED(status)) {
- _I("Process(%d) terminated by exit(%d).", pid, WEXITSTATUS(status));
- return WEXITSTATUS(status);
- } else if (WIFSIGNALED(status))
- _I("Process(%d) terminated by signal(%d).", pid, WTERMSIG(status));
- else if (WIFSTOPPED(status))
- _I("Process(%d) stopped by signal(%d).", pid, WSTOPSIG(status));
- } else
- _I("Process(%d) failed to call waitpid(): %d", pid, errno);
-
- return -EAGAIN;
-}
-
-static void child(int argc, const char *argv[])
-{
- int i, r;
-
- for (i = 0; i < _NSIG; ++i)
- signal(i, SIG_DFL);
-
- r = execv(argv[0], (char **)argv);
- if (r < 0)
- exit(EXIT_FAILURE);
-}
-
-int run_child(int argc, const char *argv[])
-{
- pid_t pid;
- struct sigaction act, oldact;
- int r = 0;
- FILE *fp;
-
- if (!argv)
- return -EINVAL;
-
- fp = fopen(argv[0], "r");
- if (fp == NULL) {
- _E("Failed to open '%s': %d", argv[0], errno);
- return -errno;
- }
- fclose(fp);
-
- /* Use default signal handler */
- act.sa_handler = SIG_DFL;
- act.sa_sigaction = NULL;
- act.sa_flags = 0;
- sigemptyset(&act.sa_mask);
-
- if (sigaction(SIGCHLD, &act, &oldact) < 0)
- return -errno;
-
- pid = fork();
- if (pid < 0) {
- _E("Failed to fork.");
- r = -errno;
- } else if (pid == 0) {
- child(argc, argv);
- } else
- r = parent(pid);
-
- if (sigaction(SIGCHLD, &oldact, NULL) < 0)
- _E("Failed to restore sigaction.");
-
- return r;
-}