| 421 | } |
| 422 | |
| 423 | int |
| 424 | tty_wait_background(struct tty *tp, struct thread *td, int sig) |
| 425 | { |
| 426 | struct proc *p; |
| 427 | struct pgrp *pg; |
| 428 | ksiginfo_t ksi; |
| 429 | int error; |
| 430 | |
| 431 | MPASS(sig == SIGTTIN || sig == SIGTTOU); |
| 432 | tty_assert_locked(tp); |
| 433 | |
| 434 | p = td->td_proc; |
| 435 | for (;;) { |
| 436 | pg = p->p_pgrp; |
| 437 | PGRP_LOCK(pg); |
| 438 | PROC_LOCK(p); |
| 439 | |
| 440 | /* |
| 441 | * pg may no longer be our process group. |
| 442 | * Re-check after locking. |
| 443 | */ |
| 444 | if (p->p_pgrp != pg) { |
| 445 | PROC_UNLOCK(p); |
| 446 | PGRP_UNLOCK(pg); |
| 447 | continue; |
| 448 | } |
| 449 | |
| 450 | /* |
| 451 | * The process should only sleep, when: |
| 452 | * - This terminal is the controlling terminal |
| 453 | * - Its process group is not the foreground process |
| 454 | * group |
| 455 | * - The parent process isn't waiting for the child to |
| 456 | * exit |
| 457 | * - the signal to send to the process isn't masked |
| 458 | */ |
| 459 | if (!tty_is_ctty(tp, p) || p->p_pgrp == tp->t_pgrp) { |
| 460 | /* Allow the action to happen. */ |
| 461 | PROC_UNLOCK(p); |
| 462 | PGRP_UNLOCK(pg); |
| 463 | return (0); |
| 464 | } |
| 465 | |
| 466 | if (SIGISMEMBER(p->p_sigacts->ps_sigignore, sig) || |
| 467 | SIGISMEMBER(td->td_sigmask, sig)) { |
| 468 | /* Only allow them in write()/ioctl(). */ |
| 469 | PROC_UNLOCK(p); |
| 470 | PGRP_UNLOCK(pg); |
| 471 | return (sig == SIGTTOU ? 0 : EIO); |
| 472 | } |
| 473 | |
| 474 | if ((p->p_flag & P_PPWAIT) != 0 || |
| 475 | (pg->pg_flags & PGRP_ORPHANED) != 0) { |
| 476 | /* Don't allow the action to happen. */ |
| 477 | PROC_UNLOCK(p); |
| 478 | PGRP_UNLOCK(pg); |
| 479 | return (EIO); |
| 480 | } |
no test coverage detected