ioctl 调用的文件描述符以创建控制终端

问题描述

在 Linux 上,为了能够控制从我的主进程分叉出来的进程的生命周期,我通过调用 setsid() 使主进程成为会话和组长。然后看起来我需要让主进程为进程组创建一个控制终端,然后,一旦主进程终止,进程组中的所有其他进程都会收到一个 SIGHUP。我尝试为文件系统上的常规文件调用 open(),但 ioctl() 拒绝接受此带有“不适当文件描述符”的 fd。我应该改posix_openpt() 吗?手册页说它将创建一个伪终端并为其返回一个文件描述符。在 ioctl(fd,TIOCSCTTY,0) 之后我是否还需要一个 posix_openpt() 调用,或者我真正需要的只是不使用 O_NOCTTY?谢谢!

解决方法

在 posix_openpt() 之后我是否还需要 ioctl(fd,TIOCCSCTTY,0) 调用,或者我真的只需要不使用 O_NOCTTY ?

我刚刚在 Ubuntu 18.04.5 上试过:

如果您不这样做并且控制进程关闭,则 systemd 进程将成为子进程的新控制进程并且子进程不会收到 SIGHUP

我不确定其他 Linux 发行版是否也有这种行为。

posix_openpt() 是我应该使用的吗?

试试下面的代码:

int master,tty;

master = posix_openpty(O_RDWR);
grantpt(master);
unlockpt(master);
tty = open(ptsname(master),O_RDWR);
ioctl(tty,TIOCSCTTY,0);

这必须在调用 setsid() 的同一进程中完成。

注意:一旦您完全关闭 master 文件,进程将收到一个 SIGHUP

(“完全”的意思是:当您关闭由 dup() 创建的所有副本或通过创建继承句柄的子进程时。)

如果你真的想使用伪 TTY,你不应该继承 master 子进程的句柄(或 close() 子进程中的句柄。但是,在你的情况下,你只想要使用伪 TTY 作为“解决方法”,所以这并不重要。