IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 8, 2008, 11:30:34 AM (18 years ago)
Author:
eugene
Message:

better timeout handling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/cmd.basic/shell.c

    r16466 r16895  
    11# include "basic.h"
     2# define DTIME(A,B) ((A.tv_sec - B.tv_sec) + 1e-6*(A.tv_usec - B.tv_usec))
    23
    34static char *defshell = "/bin/sh";
     
    910int shell (int argc, char **argv) {
    1011 
    11   int i, pid;
     12  int i, pid, N;
    1213  int exit_status;
    1314  int wait_status;
    1415  int result, length;
    1516  char **args, *shell;
     17  struct timeval start, now;
     18  float timeout;
     19
     20  timeout = 0;
     21  if ((N = get_argument (argc, argv, "-timeout"))) {
     22    remove_argument (N, &argc, argv);
     23    timeout = atof(argv[N]);
     24    remove_argument (N, &argc, argv);
     25  }
    1626
    1727  shell = getenv ("SHELL");
     
    3949  // send the commands to the shell specified in the env variable SHELL, or else /bin/sh
    4050
     51  gettimeofday (&start, NULL);
     52
    4153  // use execvp to enable a timeout on the system call
    4254  pid = fork ();
     
    4961 
    5062  // wait for process to finish or timeout
    51   for (i = 0; i < 200; i++) {
     63  // loop forever if desired, but catch C-C and stop the process on interrupt
     64  interrupt = FALSE;
     65  while (!interrupt) {
    5266    result = waitpid (pid, &wait_status, WNOHANG);
    5367    switch (result) {
     
    6579      case 0:   // child not yet exited
    6680        usleep (10000);
     81        if (timeout > 0.0) {
     82          gettimeofday (&now, NULL);
     83          if (DTIME(now, start) > timeout) {
     84            gprint (GP_ERR, "timeout on %s (pid %d)\n", argv[1], pid);
     85            return (FALSE);
     86          }
     87        }
    6788        continue;
    6889
     
    90111    }
    91112  }
     113  gprint (GP_ERR, "caught interrupt, killing %s (%d)\n", argv[1], pid);
    92114
    93   gprint (GP_ERR, "timeout on %d\n", pid);
     115  // user hit interrupt: kill the process and return
     116  kill (pid, SIGKILL);
     117  result = 0;
     118  for (i = 0; (i < 10) && (result == 0); i++) {
     119    usleep (10000);  // wait for job to exit
     120    result = waitpid (pid, &wait_status, WNOHANG);
     121  }
     122  if (!result) {
     123    gprint (GP_ERR, "trouble killing %s (pid %d)\n", argv[1], pid);
     124  } else {
     125    gprint (GP_ERR, "killed %s (pid %d)\n", argv[1], pid);
     126  }
     127
    94128  return (FALSE);
    95129}
    96 
Note: See TracChangeset for help on using the changeset viewer.