You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2010/01/04 16:01:01 UTC

svn commit: r895655 - in /commons/sandbox/runtime/trunk/src/main/native: include/acr_exec.h os/unix/exec.c os/unix/uutils.c test/testsuite.c

Author: mturk
Date: Mon Jan  4 15:01:01 2010
New Revision: 895655

URL: http://svn.apache.org/viewvc?rev=895655&view=rev
Log:
Add timeout to the exec

Modified:
    commons/sandbox/runtime/trunk/src/main/native/include/acr_exec.h
    commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c
    commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c
    commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_exec.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_exec.h?rev=895655&r1=895654&r2=895655&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_exec.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_exec.h Mon Jan  4 15:01:01 2010
@@ -81,7 +81,7 @@
  * @return Exit reason.
  */
 ACR_DECLARE(int) ACR_ExecShellCmd(acr_exec_t *exe, const acr_pchar_t *cmdline,
-                                  const acr_pchar_t *const *envp);
+                                  acr_pchar_t *const *envp);
 
 /**
  * Execute shell script file.
@@ -94,7 +94,7 @@
  */
 ACR_DECLARE(int) ACR_ExecShellScript(acr_exec_t *ep, const acr_pchar_t *file,
                                      const acr_pchar_t *const *argv,
-                                     const acr_pchar_t *const *envp);
+                                     acr_pchar_t *const *envp);
 
 /**
  * Get executed program output stream.
@@ -118,6 +118,13 @@
                                    const void *data, size_t len);
 
 /**
+ * Set execution timeout.
+ * @param exe The executable object
+ * @param timeout Timeout value.
+ */
+ACR_DECLARE(void) ACR_ExecTimeoutSet(acr_exec_t *exe, acr_time_t timeout);
+
+/**
  * Free allocated executable object resources.
  * @param exe The executable object
  */

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c?rev=895655&r1=895654&r2=895655&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/exec.c Mon Jan  4 15:01:01 2010
@@ -38,6 +38,9 @@
 extern int pipepair(int pd[2], int flags);
 extern int nullpipe(int flags, int fd);
 
+#define PROC_TIMEOUT_STEP   100
+#define PROC_BUFFER_SIZE    512
+
 #define PIPE_STDINP         0
 #define PIPE_STDINP_RDS     0
 #define PIPE_STDINP_WRS     1
@@ -73,13 +76,15 @@
     ep->flags   = flags;
 
     if (flags & ACR_PROC_HAS_STDOUT) {
-        if (!acr_sbuf_new(&ep->sout, NULL, 512, ACR_SBUF_AUTOEXTEND)) {
+        if (!acr_sbuf_new(&ep->sout, NULL, PROC_BUFFER_SIZE,
+                          ACR_SBUF_AUTOEXTEND)) {
             rc = ACR_GET_OS_ERROR();
             goto cleanup;
         }
     }
     if (flags & ACR_PROC_HAS_STDERR) {
-        if (!acr_sbuf_new(&ep->serr, NULL, 512, ACR_SBUF_AUTOEXTEND)) {
+        if (!acr_sbuf_new(&ep->serr, NULL, PROC_BUFFER_SIZE,
+                          ACR_SBUF_AUTOEXTEND)) {
             rc = ACR_GET_OS_ERROR();
             goto cleanup;
         }
@@ -97,7 +102,7 @@
 
 static int do_exec(acr_exec_t *ep, const char *cmdline,
                    char **argv,
-                   const char *const *envp)
+                   char *const *envp)
 {
     pid_t  pid;
     ssize_t rd;
@@ -191,6 +196,7 @@
         }
         i_close(&pipes[PIPE_STDOUT_WRS]);
         i_close(&pipes[PIPE_STDERR_WRS]);
+        i_close(&pipes[PIPE_SIGNAL_WRS]);
         if (argv == NULL)
             argv = (char **)args;
         if (envp)
@@ -217,7 +223,8 @@
         int    running   = ep->flags & (ACR_PROC_HAS_STDOUT | ACR_PROC_HAS_STDERR);
         pid_t  child     = pid;
         const char *inpp = (const char *)ep->data.iov_base;
-
+        int    polltime  = ep->timeout > 0 ? PROC_TIMEOUT_STEP : -1;
+        acr_time_t endat = 0;
         /* Close parent side of pipes
          */
         i_close(&pipes[PIPE_STDINP_RDS]);
@@ -225,10 +232,12 @@
         i_close(&pipes[PIPE_STDERR_WRS]);
         i_close(&pipes[PIPE_SIGNAL_WRS]);
 
+        if (ep->timeout > 0)
+            endat = ACR_TimeNow() + ep->timeout;
         /* Handshake with the child process.
          * If the read is sucessful it means that
          * either init or execv inside child failed.
-         */
+         */        
         rd = r_read(pipes[PIPE_SIGNAL_RDS], &info, sizeof(info));
         i_close(&pipes[PIPE_SIGNAL_RDS]);
         if (rd == sizeof(info)) {
@@ -260,11 +269,20 @@
             if (npipes) {
                 i = 0;
                 do {
-                    rc = poll(ps, npipes, -1);
+                    rc = poll(ps, npipes, polltime);
                 } while (rc == -1 && errno == EINTR);
-                if (rc < 1)
+                if (rc < 1) {
+                    if (polltime == -1 || rc == -1)
+                        break;
+                    /* No events fired within a second
+                     */
+                    if (ACR_TimeNow() < endat)
+                        continue;
+                    /* Send SIGTERM to the child
+                     */
+                    kill(pid, 9);
                     break;
-
+                }
                 if (pipes[PIPE_STDINP_WRS] != -1 && ps[i].revents) {
                     if (ps[i].revents & POLLOUT) {
                         ssize_t wr;
@@ -383,14 +401,14 @@
 }
 
 ACR_DECLARE(int) ACR_ExecShellCmd(acr_exec_t *ep, const char *cmdline,
-                                  const char *const *envp)
+                                  char *const *envp)
 {
     return do_exec(ep, cmdline, NULL, envp);
 }
 
 ACR_DECLARE(int) ACR_ExecShellScript(acr_exec_t *ep, const char *fname,
                                      const char *const *argv,
-                                     const char *const *envp)
+                                     char *const *envp)
 {
     int    rc;
     char **args = NULL;
@@ -433,6 +451,12 @@
     return ACR_EINVAL;
 }
 
+ACR_DECLARE(void) ACR_ExecTimeoutSet(acr_exec_t *e, acr_time_t timeout)
+{
+    if (e)
+        e->timeout = timeout;
+}
+
 ACR_DECLARE(void) ACR_ExecFree(acr_exec_t *e)
 {
     if (e) {

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c?rev=895655&r1=895654&r2=895655&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c Mon Jan  4 15:01:01 2010
@@ -211,6 +211,9 @@
 int acr_nonblock(int fd, int on)
 {
     int rc = 0;
+
+    if (fd == -1)
+        return ACR_EBADF;
 #ifdef O_NONBLOCK
     /* Use non-blocking I/O
      */
@@ -237,16 +240,19 @@
 int acr_cloexec(int fd)
 {
     int rc = 0;
+
+    if (fd == -1)
+        return ACR_EBADF;
 #ifdef FD_CLOEXEC
     /* Close on exec
      */
     int mode, forg;
-    if ((mode = fcntl(fd, F_GETFL, 0)) == -1) {
+    if ((mode = fcntl(fd, F_GETFD, 0)) == -1) {
         return ACR_GET_OS_ERROR();
     }
     forg = mode;
     mode |= FD_CLOEXEC;
-    if (forg != mode && fcntl(fd, F_SETFL, mode) == -1) {
+    if (forg != mode && fcntl(fd, F_SETFD, mode) == -1) {
         return ACR_GET_OS_ERROR();
     }
 #else

Modified: commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c?rev=895655&r1=895654&r2=895655&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c Mon Jan  4 15:01:01 2010
@@ -575,6 +575,7 @@
         return ACR_EINVAL;
     }
     exe = ACR_ExecNew(ACR_PROC_HAS_STDOUT);
+    ACR_ExecTimeoutSet(exe, ACR_USEC_PER_SEC * 2);
     rc = ACR_ExecShellCmd(exe, argv[0], NULL);
 
     fprintf(stdout, "[STDOUT]:\n%s", ACR_ExecStream(exe, 1));