1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//! Child-side controlling-terminal setup, run after fork and before exec.
use io;
use Command as TokioCommand;
/// Install the `pre_exec` hook that makes the slave PTY the child's controlling terminal.
///
/// By the time the hook runs,
/// the spawn machinery has already dup'd the slave onto the child's fds 0/1/2. The hook then:
/// 1. `setsid()` — start a new session
/// so the child is a session leader with no controlling terminal (a prerequisite for acquiring one),
/// which also makes it a process-group leader whose group id equals its pid.
/// 2. `ioctl(0, TIOCSCTTY)` — acquire the slave (now fd 0) as the controlling terminal, so the child
/// and its descendants see a real interactive tty.
///
/// Because `setsid` establishes the process group,
/// this hook intentionally replaces the plain `setpgid` isolation used for pipe-backed modes;
/// the resulting group id still equals the child pid.
/// `setsid` is mandatory for acquiring a controlling terminal, so PTY mode always starts a new session
/// and process group: it requires [`SignalPolicy::create_process_group`] to be enabled
/// and rejects the run otherwise (see `run_pty_mode`). Given that,
/// the group layout matches the pipe-backed path,
/// so group-targeted termination under [`SignalPolicy`] behaves identically to the non-PTY modes.
///
/// [`SignalPolicy`]: crate::SignalPolicy
/// [`SignalPolicy::create_process_group`]: crate::SignalPolicy::create_process_group
pub