diff options
author | jy910.yun <jy910.yun@samsung.com> | 2014-11-07 18:11:10 +0900 |
---|---|---|
committer | jy910.yun <jy910.yun@samsung.com> | 2014-11-07 18:11:10 +0900 |
commit | 3c3a64225c9c0d8f218bf1976eff5f22cbb22e17 (patch) | |
tree | 78f61542ac36f4fcaab59016a49ab733b1b573da | |
parent | dab55ee02cbae6318ff69494a4977adae8c6d245 (diff) | |
download | libdevice-node-3c3a64225c9c0d8f218bf1976eff5f22cbb22e17.tar.gz libdevice-node-3c3a64225c9c0d8f218bf1976eff5f22cbb22e17.tar.bz2 libdevice-node-3c3a64225c9c0d8f218bf1976eff5f22cbb22e17.zip |
device-node: Replace system() with the combination of fork/exec
As per man page, it cautions against using system() in a program.
It can make a problem like a ruin of system intergrity
by strange values for some environment variables.
Change-Id: I5d77931c3fbb5fd1851219aaf8e8578d8ed9d255
Signed-off-by: jy910.yun <jy910.yun@samsung.com>
-rw-r--r-- | devices/extcon.c | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/devices/extcon.c b/devices/extcon.c index 42a41d1..dc79e2e 100644 --- a/devices/extcon.c +++ b/devices/extcon.c @@ -17,8 +17,83 @@ #include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/wait.h> #include "device-internal.h" +static int parent(pid_t pid) +{ + int status; + + /* wait for child */ + if (waitpid(pid, &status, 0) != -1) { + /* terminated normally */ + if (WIFEXITED(status)) { + _I("%d terminated by exit(%d)", pid, WEXITSTATUS(status)); + return WEXITSTATUS(status); + } else if (WIFSIGNALED(status)) { + _I("%d terminated by signal %d", pid, WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + _I("%d stopped by signal %d", pid, WSTOPSIG(status)); + } + } else { + _I("%d waitpid() failed : %s", pid, strerror(errno)); + } + + return -EAGAIN; +} + +static void child(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_save_blenv(const char *extcon_path, const char *val) +{ + pid_t pid; + struct sigaction act, oldact; + int r = -1; + const char *extcon_argv[4] = {"/usr/bin/save_blenv", NULL, NULL, NULL}; + + if (!extcon_path || !val) + return -EINVAL; + + extcon_argv[1] = extcon_path; + extcon_argv[2] = val; + + /* 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(extcon_argv); + } else + r = parent(pid); + + if (sigaction(SIGCHLD, &oldact, NULL) < 0) + _E("failed to restore sigaction"); + + return r; +} + static int extcon_get_prop(int prop, int *val) { switch (prop) { @@ -58,18 +133,18 @@ static int extcon_set_prop(int prop, int val) r = PLUGIN_SET(uart_path)(val); if (r == 0) { if (val == PATH_CP) - system("/usr/bin/save_blenv uartpath CP"); + r = run_save_blenv("uartpath", "CP"); else - system("/usr/bin/save_blenv uartpath AP"); + r = run_save_blenv("uartpath", "AP"); } return r; case PROP_EXTCON_USB_PATH: r = PLUGIN_SET(usb_path)(val); if (r == 0) { if (val == PATH_CP) - system("/usr/bin/save_blenv usbpath CP"); + r = run_save_blenv("usbpath", "CP"); else - system("/usr/bin/save_blenv usbpath AP"); + r = run_save_blenv("usbpath", "AP"); } return r; } |