#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) {
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;
}