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; }
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 }
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 }