| 276 | } |
| 277 | |
| 278 | static int |
| 279 | reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk) |
| 280 | { |
| 281 | struct proc *reap, *p2; |
| 282 | ksiginfo_t ksi; |
| 283 | struct reap_kill_tracker_head tracker; |
| 284 | struct reap_kill_tracker *t; |
| 285 | int error; |
| 286 | |
| 287 | sx_assert(&proctree_lock, SX_LOCKED); |
| 288 | if (IN_CAPABILITY_MODE(td)) |
| 289 | return (ECAPMODE); |
| 290 | if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG || |
| 291 | (rk->rk_flags & ~(REAPER_KILL_CHILDREN | |
| 292 | REAPER_KILL_SUBTREE)) != 0 || (rk->rk_flags & |
| 293 | (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) == |
| 294 | (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) |
| 295 | return (EINVAL); |
| 296 | PROC_UNLOCK(p); |
| 297 | reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p; |
| 298 | ksiginfo_init(&ksi); |
| 299 | ksi.ksi_signo = rk->rk_sig; |
| 300 | ksi.ksi_code = SI_USER; |
| 301 | ksi.ksi_pid = td->td_proc->p_pid; |
| 302 | ksi.ksi_uid = td->td_ucred->cr_ruid; |
| 303 | error = ESRCH; |
| 304 | rk->rk_killed = 0; |
| 305 | rk->rk_fpid = -1; |
| 306 | if ((rk->rk_flags & REAPER_KILL_CHILDREN) != 0) { |
| 307 | for (p2 = LIST_FIRST(&reap->p_children); p2 != NULL; |
| 308 | p2 = LIST_NEXT(p2, p_sibling)) { |
| 309 | reap_kill_proc(td, p2, &ksi, rk, &error); |
| 310 | /* |
| 311 | * Do not end the loop on error, signal |
| 312 | * everything we can. |
| 313 | */ |
| 314 | } |
| 315 | } else { |
| 316 | TAILQ_INIT(&tracker); |
| 317 | reap_kill_sched(&tracker, reap); |
| 318 | while ((t = TAILQ_FIRST(&tracker)) != NULL) { |
| 319 | MPASS((t->parent->p_treeflag & P_TREE_REAPER) != 0); |
| 320 | TAILQ_REMOVE(&tracker, t, link); |
| 321 | for (p2 = LIST_FIRST(&t->parent->p_reaplist); p2 != NULL; |
| 322 | p2 = LIST_NEXT(p2, p_reapsibling)) { |
| 323 | if (t->parent == reap && |
| 324 | (rk->rk_flags & REAPER_KILL_SUBTREE) != 0 && |
| 325 | p2->p_reapsubtree != rk->rk_subtree) |
| 326 | continue; |
| 327 | if ((p2->p_treeflag & P_TREE_REAPER) != 0) |
| 328 | reap_kill_sched(&tracker, p2); |
| 329 | reap_kill_proc(td, p2, &ksi, rk, &error); |
| 330 | } |
| 331 | free(t, M_TEMP); |
| 332 | } |
| 333 | } |
| 334 | PROC_LOCK(p); |
| 335 | return (error); |
no test coverage detected