【问题标题】:File descriptor for ioctl call to make a controlling terminal用于创建控制终端的 ioctl 调用的文件描述符
【发布时间】:2021-04-19 05:56:20
【问题描述】:

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

【问题讨论】:

  • 我尝试 not 为 fd 调用 ioctl() 并解析 stat 文件,我看到 ctty 设备 ID 仍然为 0。所以,当在 open() 的手册页中时说'O_NOCTTY',这是否意味着我需要始终进行ioctl()调用,然后无论是否使用'O_NOCCTTY',终端都会成为控制终端?

标签: linux process file-descriptor ioctl pty


【解决方案1】:

我什至需要在 posix_openpt() 之后调用 ioctl(fd, TIOCSCTTY, 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 作为“解决方法”,所以这并不重要。

【讨论】:

  • 什么是“控制过程”?
  • @JosephSible-ReinstateMonica 其实我说的是getppid()返回的“父进程”。但是,signal (7)man 页面上的SIGHUP 部分正在谈论“控制过程”。我不确定,但“父进程”和“控制进程”似乎是一回事。但也许流程负责人的意思是......
  • 谢谢@MartinRosenau。主 fd 和从 fd 都为我工作以进行终身管理。我仍然不确定使用一个是否比另一个更好,或者是否有更好的方法来实现我想要的(我最初怀疑有一个更高级别的实用程序来控制进程树的生命周期,但我我没有找到任何东西...)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
相关资源
最近更新 更多