Ejemplo n.º 1
0
void rktio_reap_processes(rktio_t *rktio)
{
  if (rktio->need_to_check_children) {
    rktio->need_to_check_children = 0;
    check_child_done(rktio, 0);
  }
}
Ejemplo n.º 2
0
rktio_status_t *rktio_process_status(rktio_t *rktio, rktio_process_t *sp)
{
  int going = 0, status = 0;
  rktio_status_t *result;

#if defined(RKTIO_SYSTEM_UNIX)
# if defined(CENTRALIZED_SIGCHILD)
  if (sp->done) {
    status = sp->status;
  } else {
    if (!centralized_get_child_status(sp->pid, sp->in_group, 1, &status)) {
      going = 1;
    } else {
      sp->done = 1;
      sp->status = status;
      centralized_ended_child();
    }
  }
# else
  System_Child *sc = (System_Child *)sp->handle;
  check_child_done(rktio, sp->pid);

  if (sc->done) {
    status = sc->status;
  } else
   going = 1;
# endif
#else
# ifdef RKTIO_SYSTEM_WINDOWS
  DWORD w;
  if (sp->handle) {
    if (GetExitCodeProcess((HANDLE)sp->handle, &w)) {
      collect_process_time(rktio, w, sp);
      if (w == STILL_ACTIVE)
        going = 1;
      else
        status = w;
    } else {
      get_windows_error();
      return NULL;
    }
  } else
    status = -1;
# endif
#endif

  result = malloc(sizeof(rktio_status_t));
  result->running = going;
  result->result = (going ? 0 : status);
  return result;
}
Ejemplo n.º 3
0
int rktio_poll_process_done(rktio_t *rktio, rktio_process_t *sp)
{
#if defined(RKTIO_SYSTEM_UNIX)
# if defined(CENTRALIZED_SIGCHILD)
  {
    int status;
    if (!sp->done) {
      if (centralized_get_child_status(sp->pid, sp->in_group, 1, &status)) {
        sp->done = 1;
        sp->status = status;
        centralized_ended_child();
        return 1;
      }
      return 0;
    }
    else
      return RKTIO_PROCESS_DONE;
  }
# else
  {
    System_Child *sc;
    sc = (System_Child *)sp->handle;
    /* Check specific pid, in case the child has its own group
       (either given by us or given to itself): */
    check_child_done(rktio, sp->pid);
    return sc->done;
  }
# endif
#endif
#ifdef RKTIO_SYSTEM_WINDOWS
  {
    HANDLE sci = (HANDLE)sp->handle;
    DWORD w;
    if (sci) {
      if (GetExitCodeProcess(sci, &w)) {
        collect_process_time(rktio, w, sp);
        return (w != STILL_ACTIVE);
      } else
        return RKTIO_PROCESS_DONE;
    } else
      return RKTIO_PROCESS_DONE;

    get_windows_error();

    return RKTIO_PROCESS_ERROR;
  }
#endif
}
Ejemplo n.º 4
0
static int do_subprocess_kill(rktio_t *rktio, rktio_process_t *sp, int as_kill)
{
#if defined(RKTIO_SYSTEM_UNIX)
# if defined(CENTRALIZED_SIGCHILD)
  {
    int status;

    if (sp->done)
      return 1;

    centralized_wait_suspend();

    /* Don't allow group checking, because we don't want to wait
       on a group if we haven't already: */
    if (centralized_get_child_status(sp->pid, 0, 0, &status)) {
      sp->status = status;
      sp->done = 1;
      centralized_wait_resume();
      centralized_ended_child();
      return 1;
    }
  }
# else
  {
    System_Child *sc = (System_Child *)sp->handle;

    /* Don't pass sp->pid, because we don't want to wait
       on a group if we haven't already: */
    check_child_done(rktio, 0);
    if (sc->done)
      return 1;
  }
# define centralized_wait_resume() /* empty */
# endif

  while (1) {

    if (sp->is_group) {
      if (!killpg(sp->pid, as_kill ? SIGKILL : SIGINT)) {
        centralized_wait_resume();
        return 1;
      }
    } else {
      if (!kill(sp->pid, as_kill ? SIGKILL : SIGINT)) {
        centralized_wait_resume();
        return 1;
      }
    }
    
    if (errno != EINTR)
      break;
    /* Otherwise we were interrupted. Try `kill' again. */
  }

  get_posix_error();

  centralized_wait_resume();

  return 0;
#endif
#if defined(RKTIO_SYSTEM_WINDOWS)  
  if (as_kill || sp->is_group) {
    DWORD w;

    if (!sp->handle)
      return 1;

    if (!as_kill) {
      /* must be for a group; we don't care whether the
         original process is still running */
      if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, sp->pid))
        return 1;
    } else if (GetExitCodeProcess((HANDLE)sp->handle, &w)) {
      collect_process_time(rktio, w, sp);
      if (w != STILL_ACTIVE)
        return 1;
      if (TerminateProcess((HANDLE)sp->handle, 1))
        return 1;
    }
    get_windows_error();

    return 0;
  } else
    return 1;
#endif
}
Ejemplo n.º 5
0
static void check_child_done(rktio_t *rktio, pid_t pid)
{
  pid_t result, check_pid;
  int status, is_unused;
  System_Child *sc, *prev;
  void **unused = (void **)unused_pids, **unused_prev = NULL;

  if (pid && rktio->need_to_check_children) {
    rktio->need_to_check_children = 0;
    check_child_done(rktio, 0);
  }
  
  if (rktio->system_children) {
    do {
      if (!pid && unused) {
        check_pid = (pid_t)(intptr_t)unused[0];
        is_unused = 1;
      } else {
        check_pid = pid;
        is_unused = 0;
      }

      do {
        result = waitpid(check_pid, &status, WNOHANG);
      } while ((result == -1) && (errno == EINTR));

      if (result > 0) {
        if (is_unused) {
          /* done with an inaccessible group id */
          void *next;
          next = (void **)unused[1];
          if (unused_prev)
            unused_prev[1] = unused[1];
          else
            unused_pids = unused[1];
          free(unused);
          unused = (void **)next;
        }

        status = extract_child_status(status);

        prev = NULL;
        for (sc = rktio->system_children; sc; prev = sc, sc = sc->next) {
          if (sc->id == result) {
            sc->done = 1;
            sc->status = status;

            if (prev) {
              prev->next = sc->next;
            } else
              rktio->system_children = sc->next;
          }
        }
      } else {
        if (is_unused) {
          unused_prev = unused;
          unused = unused[1];
        }
      }
    } while ((result > 0) || is_unused);
  }
}