summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjy910.yun <jy910.yun@samsung.com>2014-11-07 18:11:10 +0900
committerjy910.yun <jy910.yun@samsung.com>2014-11-07 18:11:10 +0900
commit3c3a64225c9c0d8f218bf1976eff5f22cbb22e17 (patch)
tree78f61542ac36f4fcaab59016a49ab733b1b573da
parentdab55ee02cbae6318ff69494a4977adae8c6d245 (diff)
downloadlibdevice-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.c83
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;
}