Add possibility to launch commands via profctl
authorAleksei Vereshchagin <avereschagin@dev.rtsoft.ru>
Tue, 4 Sep 2018 20:20:21 +0000 (23:20 +0300)
committerAleksei Vereshchagin <avereschagin@dev.rtsoft.ru>
Mon, 10 Sep 2018 14:00:10 +0000 (17:00 +0300)
README.md
profctl.c

index 69c3b7896a673810aa8eed823f971b4d502535dc..f2231d97e93adbb3a6208ceb8ea585b7feb8b282 100644 (file)
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ gbs build -P ... -A ...
 ## Usage
 
 ```
-profctl [options...]
+profctl [options...] [command [args]]
 ```
 
 ### Options
index 352cd764c829b637319393949feedf6fa2ba3d95..7c91f39a82ef48c75c5f492a2b0db8aeb29becf0 100644 (file)
--- a/profctl.c
+++ b/profctl.c
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <sys/xattr.h>
 #include <netinet/in.h>
 #include <fcntl.h>
@@ -38,6 +39,7 @@ static struct termios sterm;
 
 static char *appid = NULL;
 static int app_pid = -1;
+static int cmd_pid = -1;
 static char *pname = NULL;
 static char *ename = NULL;
 static char *oname = NULL;
@@ -224,11 +226,6 @@ static int process_option(int argc, char **argv)
        case 's': statPort = atoi(optarg); break;
        case '?': exit(1);
        default:
-               if (optind != argc)
-               {
-                       log_error("extra argument %s", argv[optind]);
-                       exit(1);
-               }
                return -1;
        }
        return 0;
@@ -249,6 +246,7 @@ static pthread_t SimpleThread(void* (*func)(void *), void *arg)
        return thread;
 }
 
+// TODO: should be refactored: use separated launcher
 static int openFileProcess()
 {
        if (ename == NULL) {
@@ -297,7 +295,9 @@ static int openFileProcess()
                return -1;
        }
 
-       if (pid == 0) { /* Child */
+       if (pid == 0) {
+               /* Child branch */
+
                if (close(pipefd[0]) != 0) {
                         // not critical
                        log_system_error("CHILD close(%d)", pipefd[0]);
@@ -475,7 +475,7 @@ static void *command_loop_thread(void *arg)
                char *buf = NULL;
                int pid;
                int signal = -1;
-               if (is_command(line, "test", &pid, -1, NULL, 0) == 0) {
+               if (is_command(line, "test", &pid, cmd_pid, NULL, 0) == 0) {
                        if (app_pid == -1) {
 #if !TIZEN
                                if (pid == -1) {
@@ -622,6 +622,30 @@ int main(int argc, char **argv)
        }
 #endif /* TIZEN */
 
+       if (optind != argc) {
+               // TODO: should be refactored: use separated launcher
+
+               if (verbose) {
+                       log_message("launch command process %s", argv[optind]);
+               }
+
+               cmd_pid = fork();
+               if (!cmd_pid) {
+                       /* Child branch */
+
+                       // TODO: close unneeded descriptors
+
+                       execv(argv[optind], &argv[optind]);
+                       exit(1);
+               } else if (cmd_pid == -1) {
+                       log_system_error_and_exit("cannot fork command process");
+               } else {
+                       if (verbose) {
+                               log_message("waiting for command process exit (pid=%d)", cmd_pid);
+                       }
+               }
+       }
+
        if (controlPort > 0) {
                control_socket = openPort(controlPort);
                if (control_socket < 0) {
@@ -736,6 +760,17 @@ int main(int argc, char **argv)
                                }
                        }
                }
+               // TODO: should separated launcher to be used for pid control?
+               if (cmd_pid != -1) {
+                       if (waitpid(cmd_pid, NULL, WNOHANG) > 0) {
+                               if (verbose) {
+                                       log_message("command process finished (pid=%d)", cmd_pid);
+                               }
+                               cmd_pid = -1;
+                               global_stop = 1;
+                               break;
+                       }
+               }
                // sleep to reduce CPU usage
                usleep(100 * 1000); // 100 msec
        }
@@ -762,5 +797,48 @@ int main(int argc, char **argv)
                }
        }
 
+       // TODO: should be refactored: move to separated launcher
+       if (cmd_pid != -1) {
+               int result = 0;
+               for (int retry = 0; retry < 10; retry++) {
+                       result = waitpid(cmd_pid, NULL, WNOHANG);
+                       if (result != 0) {
+                               break;
+                       }
+                       usleep(100 * 1000); // 100 ms
+               }
+               if (result == 0) {
+                       if (verbose) {
+                               log_message("kill command process (pid=%d)", cmd_pid);
+                       }
+                       result = send_signal(cmd_pid, SIGINT);
+                       if (result == 0)
+                       {
+                               for (int retry = 0; retry < 10; retry++) {
+                                       result = waitpid(cmd_pid, NULL, WNOHANG);
+                                       if (result != 0) {
+                                               break;
+                                       }
+                                       usleep(100 * 1000); // 100 ms
+                               }
+                               if (result == 0) {
+                                       result = send_signal(cmd_pid, SIGKILL);
+                                       if (result == 0)
+                                       {
+                                               result = waitpid(cmd_pid, NULL, 0);
+                                       }
+                               }
+                       }
+               }
+               if (result > 0) {
+                       if (verbose) {
+                               log_message("command process finished (pid=%d)", cmd_pid);
+                       }
+                       cmd_pid = -1;
+               } else if (result == -1) {
+                       log_system_error("cannot finish command process (pid=%d)", cmd_pid);
+               }
+       }
+
        return 0;
 }