device-node: Replace system() with the combination of fork/exec 20/30020/1
authorjy910.yun <jy910.yun@samsung.com>
Fri, 7 Nov 2014 09:11:10 +0000 (18:11 +0900)
committerjy910.yun <jy910.yun@samsung.com>
Fri, 7 Nov 2014 09:11:10 +0000 (18:11 +0900)
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>
devices/extcon.c

index 42a41d17a5374adce95d7a546598720c333143f4..dc79e2e8fefd49f35d96bd17c64fb069e52107a8 100644 (file)
 
 
 #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;
        }