IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 15868


Ignore:
Timestamp:
Dec 16, 2007, 12:25:44 PM (18 years ago)
Author:
eugene
Message:

re-write to use fork,exec,waitpid to catch timeouts

File:
1 edited

Legend:

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

    r2598 r15868  
    33int shell (int argc, char **argv) {
    44 
    5   int i, status;
    6   char line[2048], tmp[1024];
     5  int i, pid;
     6  int exit_status;
     7  int wait_status;
     8  int result;
     9  char **args;
    710
    8   bzero (tmp, 1024);
    9   bzero (line, 2048);
     11  ALLOCATE (args, char *, argc);
     12  for (i = 1; i < argc; i++) {
     13    args[i-1] = argv[i];
     14  }
     15  args[i-1] = NULL;
    1016
    11   for (i = 1; i < argc; i++) {
    12     sprintf (tmp, "%s ", argv[i]);
    13     strcat (line, tmp);
     17  // use execvp to enable a timeout on the system call
     18  pid = fork ();
     19  if (!pid) { /* must be child process */
     20    execvp (args[0], args);
     21    exit (1);
     22  }
     23  free (args);
     24 
     25  // wait for process to finish or timeout
     26  for (i = 0; i < 200; i++) {
     27    result = waitpid (pid, &wait_status, WNOHANG);
     28    switch (result) {
     29      case -1:   // error on waitpid
     30        switch (errno) {
     31          case ECHILD:
     32            gprint (GP_ERR, "unknown PID, not a child process: %d\n", pid);
     33            return (FALSE);
     34          default:
     35            gprint (GP_ERR, "unexpected response to waitpid: %d\n", result);
     36            abort();
     37        }
     38        break;
     39
     40      case 0:   // child not yet exited
     41        usleep (10000);
     42        continue;
     43
     44      default:
     45        if (result != pid) {
     46          gprint (GP_ERR, "waitpid error: mis-matched PID (%d vs %d).  programming error\n", result, pid);
     47          abort();
     48        }
     49        if (WIFEXITED(wait_status)) {
     50          exit_status = WEXITSTATUS(wait_status);
     51          if (exit_status) {
     52            return FALSE;
     53          } else {
     54            return TRUE;
     55          }
     56        }
     57        if (WIFSIGNALED(wait_status)) {
     58          gprint (GP_ERR, "job %d exited on signal %d\n", pid, WTERMSIG(wait_status));
     59          return (FALSE);
     60        }
     61        if (WIFSTOPPED(wait_status)) {
     62          gprint (GP_ERR, "waitpid returns 'stopped' programming error\n");
     63          abort();
     64        }
     65    }
    1466  }
    1567
    16   strcat (line, "\n");
    17   status = system (line);
    18 
    19   if (status) {
    20     return (FALSE);
    21   } else {
    22     return (TRUE);
    23   }
     68  gprint (GP_ERR, "timeout on %d\n", pid);
     69  return (FALSE);
    2470}
    2571
Note: See TracChangeset for help on using the changeset viewer.