终止 shell 的步骤

steps to terminate a shell

我已经阅读了 glibc 手册中关于作业控制的章节,但我想知道当 shell 终止时如何处理剩余的作业。

我假设以下步骤(遵循 posix 处理孤立进程组的惯例,前两个步骤似乎很明显):

我的问题是,如果这些工作幸存下来怎么办?

我认为可能会更改他们的会话 ID 以释放 sid 并解除进程组与终端的关联(不确定这是否有意义)

我应该ioctl(STDIN_FILENO, TIOCSCTTY)让会话进程失去控制终端并发送信号吗?

如何处理 tty?我应该启动登录并将其设置为 tty 的新控制终端进程组吗?

我还是很困惑,希望能提供线索。

  • 我是否应该启动登录并将其设置为 tty 的新控制终端进程组?

我看了一遍,我想答案应该是否定的。

对于基于字符的终端,根进程(initd/systemd/launchd 等)为预配置的终端或在特定事件中派生并执行 getty。 Getty 打开 read/write 的终端文件并将 std 文件描述符关联到终端,从配置文件设置一个简单的环境并提示输入用户名,然后使用该用户名执行登录。 登录更改终端的所有权和权限,更改进程的角色(有效和真实的 uid、gid、补充组),并执行登录 shell 当 shell 终止时,它的父进程会收到 sigchd 的通知,并重新启动 getty... 所以 tty initialization/destruction 不是 shell..

的任务

还不确定如何处理幸存的进程组..

send an HUP signal to the jobs with the shell's sid

不需要那个。当shell(会话负责人)终止时,内核将自己发送一个 HUP 信号。

send a CONT signal to the stopped jobs with the shell's sid

不需要那个。内核也会为您发送它;-)

free up the resource allocated for the job's data structures

也不需要。当进程终止时,进程使用的所有资源将由内核释放。

My problem is what if the jobs survive?

我猜你可以 SIGKILL 他们,如果那真的是个问题的话。在 Unix 中,如果它们处理 SIGHUP,它们 应该 存活下来。

"modern" systemd 采用了不同的方法,完全违背了这种精神,但我不会参与其中 ;-)

备注:

在linux中,它是来自drivers/tty/tty_jobctl.ckill_orphaned_pgrp() from kernel/exit.c which is responsible for sending the HUP+CONT to all stopped jobs from the session, and tty_signal_session_leader(),通过tty_vhangup_session()__tty_hangup()调用,负责将HUP发送到来自前台进程组。