libsystem: exec: kill child on timeout and add kill signal selectable api
authorWaLyong Cho <walyong.cho@samsung.com>
Tue, 8 Nov 2016 04:24:37 +0000 (13:24 +0900)
committerWaLyong Cho <walyong.cho@samsung.com>
Tue, 8 Nov 2016 05:17:46 +0000 (14:17 +0900)
On timeout, in do_fork_exec_redirect() ordo_fork_exec(), kill the child
process with SIGTERM signal.
And to configure the kill signal add new two api.
- do_fork_exec_kill()
- do_fork_exec_kill_redirect()

Change-Id: I3877881a98ecc1a86b37ce045443b7e85e3569fa
Signed-off-by: WaLyong Cho <walyong.cho@samsung.com>
src/libsystem/exec.c
src/libsystem/libsystem.h

index 272014d..5fb49f4 100644 (file)
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <signal.h>
 
 #include "libsystem.h"
 
-static int wait_child(pid_t pid, int64_t timeout_msec) {
+static int wait_child(pid_t pid, int64_t timeout_msec, int sig) {
         struct timeval start, timeout;
         int status;
 
@@ -62,8 +63,10 @@ static int wait_child(pid_t pid, int64_t timeout_msec) {
 
                 timersub(&current, &start, &delta);
 
-                if (timercmp(&timeout, &delta, <))
+                if (timercmp(&timeout, &delta, <)) {
+                        (void) kill(pid, sig);
                         return -ETIME;
+                }
 
                 usleep(100000);
         }
@@ -71,7 +74,7 @@ static int wait_child(pid_t pid, int64_t timeout_msec) {
         return WEXITSTATUS(status);
 }
 
-int do_fork_exec_redirect(char *const argv[], char * const envp[], int64_t timeout_msec, int fd, int flags) {
+int do_fork_exec_kill_redirect(char *const argv[], char * const envp[], int64_t timeout_msec, int sig, int fd, int flags) {
         pid_t pid;
 
         assert(argv);
@@ -97,12 +100,26 @@ int do_fork_exec_redirect(char *const argv[], char * const envp[], int64_t timeo
                 _exit(EXIT_FAILURE);
         }
 
-        return wait_child(pid, timeout_msec);
+        return wait_child(pid, timeout_msec, sig);
+}
+
+int do_fork_exec_redirect(char *const argv[], char * const envp[], int64_t timeout_msec, int fd, int flags) {
+
+        assert(argv);
+
+        return do_fork_exec_kill_redirect(argv, envp, timeout_msec, SIGTERM, fd, flags);
+}
+
+int do_fork_exec_kill(char *const argv[], char * const envp[], int64_t timeout_msec, int sig) {
+
+        assert(argv);
+
+        return do_fork_exec_kill_redirect(argv, envp, timeout_msec, sig, -1, EXEC_REDIRECT_NONE);
 }
 
 int do_fork_exec(char *const argv[], char * const envp[], int64_t timeout_msec) {
 
         assert(argv);
 
-        return do_fork_exec_redirect(argv, envp, timeout_msec, -1, EXEC_REDIRECT_NONE);
+        return do_fork_exec_kill(argv, envp, timeout_msec, SIGTERM);
 }
index 18220f6..096b849 100644 (file)
@@ -809,12 +809,38 @@ bool mnt_is_mounted(const char *fsname, const char *dir, const char *type, const
  */
 
 /**
- * @brief Traditional fork() and exec() helper.
+ * standard output/error redirect flags
+ */
+enum {
+        /**
+         * Do not redirect standard output/error
+         */
+        EXEC_REDIRECT_NONE      = 0x01 << 0,
+        /**
+         * Redirect standard output only
+         */
+        EXEC_REDIRECT_OUTPUT    = 0x01 << 1,
+        /**
+         * Redirect standard error only
+         */
+        EXEC_REDIRECT_ERROR     = 0x01 << 2,
+        /**
+         * Redirect standard output and error all
+         */
+        EXEC_REDIRECT_ALL       = (EXEC_REDIRECT_OUTPUT | EXEC_REDIRECT_ERROR),
+};
+
+/**
+ * @brief Traditional fork() and exec() helper. If child is not
+ * deactivated within given \p timeout_msec then kill it with given
+ * signal. And additionally redirect child process standard output or
+ * standard error to given fd.
  *
  * @param argv array of pointers to null-terminated strings that
  * represent the argument list available to the new program. The first
  * argument should point to the filename associated with the file
- * being executed. The array of pointers must be terminated by a NULL pointer.
+ * being executed. The array of pointers must be terminated by a NULL
+ * pointer.
  * @param envp specify the environment of the executed program via the
  * argument envp. The envp argument is an array of pointers to
  * null-terminated strings and must be terminated by a NULL pointer.
@@ -825,19 +851,17 @@ bool mnt_is_mounted(const char *fsname, const char *dir, const char *type, const
  * is given parent will wait given milliseconds and expired return
  * -1. If the child is exit within the tiemout millisecond return with
  * child exit code.
+ * @param sig signal to kill the child on timeout.
+ * @param fd file descriptor to redirect child standard output or
+ * error.
+ * @param flags redirect flag. This flags is able to include
+ * EXEC_REDIRECT_OUTPUT or EXEC_REDIRECT_ERROR.
  *
  * @return exit code of child. It is fully depend on the child
  * process. If the child exit with 1 then this function also return 1.
  * Negative errno on error. -ETIME on timer expired.
  */
-int do_fork_exec(char *const argv[], char * const envp[], int64_t timeout_msec);
-
-enum {
-        EXEC_REDIRECT_NONE      = 0x01 << 0,
-        EXEC_REDIRECT_OUTPUT    = 0x01 << 1,
-        EXEC_REDIRECT_ERROR     = 0x01 << 2,
-        EXEC_REDIRECT_ALL       = (EXEC_REDIRECT_OUTPUT | EXEC_REDIRECT_ERROR),
-};
+int do_fork_exec_kill_redirect(char *const argv[], char * const envp[], int64_t timeout_msec, int sig, int fd, int flags);
 
 /**
  * @brief Traditional fork() and exec() helper. And additionally
@@ -859,7 +883,7 @@ enum {
  * child exit code.
  * @param fd file descriptor to redirect child standard output or error.
  * @param flags redirect flag. This flags is able to include
- * #EXEC_REDIRECT_OUTPUT or EXEC_REDIRECT_ERROR.
+ * EXEC_REDIRECT_OUTPUT or EXEC_REDIRECT_ERROR.
  *
  * @return exit code of child. It is fully depend on the child
  * process. If the child exit with 1 then this function also return 1.
@@ -868,6 +892,57 @@ enum {
 int do_fork_exec_redirect(char *const argv[], char * const envp[], int64_t timeout_msec, int fd, int flags);
 
 /**
+ * @brief Traditional fork() and exec() helper. If child is not
+ * deactivated within given \p timeout_msec then kill it with given
+ * signal.
+ *
+ * @param argv array of pointers to null-terminated strings that
+ * represent the argument list available to the new program. The first
+ * argument should point to the filename associated with the file
+ * being executed. The array of pointers must be terminated by a NULL pointer.
+ * @param envp specify the environment of the executed program via the
+ * argument envp. The envp argument is an array of pointers to
+ * null-terminated strings and must be terminated by a NULL pointer.
+ * @param timeout_msec timeout millisecond to prevent infinite
+ * waiting. If negative is given, the parent will not wait the
+ * child. In other word, the parent will return immediately. If 0 is
+ * given, parent will wait the child infinitly. And if positive value
+ * is given parent will wait given milliseconds and expired return
+ * -1. If the child is exit within the tiemout millisecond return with
+ * child exit code.
+ * @param sig signal to kill the child on timeout.
+ *
+ * @return exit code of child. It is fully depend on the child
+ * process. If the child exit with 1 then this function also return 1.
+ * Negative errno on error. -ETIME on timer expired.
+ */
+int do_fork_exec_kill(char *const argv[], char * const envp[], int64_t timeout_msec, int sig);
+
+/**
+ * @brief Traditional fork() and exec() helper.
+ *
+ * @param argv array of pointers to null-terminated strings that
+ * represent the argument list available to the new program. The first
+ * argument should point to the filename associated with the file
+ * being executed. The array of pointers must be terminated by a NULL pointer.
+ * @param envp specify the environment of the executed program via the
+ * argument envp. The envp argument is an array of pointers to
+ * null-terminated strings and must be terminated by a NULL pointer.
+ * @param timeout_msec timeout millisecond to prevent infinite
+ * waiting. If negative is given, the parent will not wait the
+ * child. In other word, the parent will return immediately. If 0 is
+ * given, parent will wait the child infinitly. And if positive value
+ * is given parent will wait given milliseconds and expired return
+ * -1. If the child is exit within the tiemout millisecond return with
+ * child exit code.
+ *
+ * @return exit code of child. It is fully depend on the child
+ * process. If the child exit with 1 then this function also return 1.
+ * Negative errno on error. -ETIME on timer expired.
+ */
+int do_fork_exec(char *const argv[], char * const envp[], int64_t timeout_msec);
+
+/**
  * @}
  */