gboolean mainloop_child_kill(pid_t pid) { GListPtr iter; mainloop_child_t *child = NULL; for (iter = child_list; iter != NULL; iter = iter->next) { child = iter->data; if (pid == child->pid) { break; } } if (child == NULL) { return FALSE; } if (child_kill_helper(child) != 0) { /* failed to terminate child process */ return FALSE; } /* It is impossible to block SIGKILL, this allows us to * call waitpid without WNOHANG here */ if (child_waitpid(child, 0) == FALSE) { /* not much we can do if this occurs */ return FALSE; } child_list = g_list_remove(child_list, child); child_free(child); return TRUE; }
int mainloop_child_kill(pid_t pid) { GListPtr iter; mainloop_child_t *child = NULL; mainloop_child_t *match = NULL; /* It is impossible to block SIGKILL, this allows us to * call waitpid without WNOHANG flag.*/ int waitflags = 0, rc = 0; for (iter = child_list; iter != NULL && match == NULL; iter = iter->next) { child = iter->data; if (pid == child->pid) { match = child; } } if (match == NULL) { return FALSE; } rc = child_kill_helper(match); if(rc == -ESRCH) { /* Its gone, but hasn't shown up in waitpid() yet * * Wait until we get SIGCHLD and let child_death_dispatch() * clean it up as normal (so we get the correct return * code/status) * * The blocking alternative would be to call: * child_waitpid(match, 0); */ crm_trace("Waiting for child %d to be reaped by child_death_dispatch()", match->pid); return TRUE; } else if(rc != 0) { /* If KILL for some other reason set the WNOHANG flag since we * can't be certain what happened. */ waitflags = WNOHANG; } if (child_waitpid(match, waitflags) == FALSE) { /* not much we can do if this occurs */ return FALSE; } child_list = g_list_remove(child_list, match); child_free(match); return TRUE; }
/** fehlerprüfung und daten einlesen */ static int child_read2(int hc) { int err; struct child_stat *child = mls(CLIST, hc); TRACE(1,""); /* einlesen ist non-blocking */ err = mrb_read_max(child->qin, child_read_fd(hc) ); if( ! err ) return 0; /* irgendetwas geht fürchterlich schief was ist mit dem subprocess? */ if( child_waitpid(hc) != 0 ) return 1; /* subprocess läuft, wie sieht es mit errno aus? */ TRACE(1,"err %s", strerror(err) ); if( (err == EINTR) || (err == EWOULDBLOCK) ) return 0; /* errno sagt nichts gutes, besser die verbindung beenden */ return 1; }
static void child_death_dispatch(int signal) { GListPtr iter = child_list; gboolean exited; while(iter) { GListPtr saved = NULL; mainloop_child_t *child = iter->data; exited = child_waitpid(child, WNOHANG); saved = iter; iter = iter->next; if (exited == FALSE) { continue; } crm_trace("Removing process entry %p for %d", child, child->pid); child_list = g_list_remove_link(child_list, saved); g_list_free(saved); child_free(child); } }