当另一端的进程终止时,为什么在 pty 上阻塞 read() 返回?

Igo*_*nko 5 linux c tty pty pseudoterminal

当未打开 pty 的从属端时,strace在该过程中,会read(master_fd, &byte, 1);显示以下内容:

read(3, 
Run Code Online (Sandbox Code Playgroud)

因此,当没有人连接到 pty 的从属端时,read()等待数据 - 它不会返回错误。

但是当 pty 的从属端被一个进程打开并且该进程退出时,这个进程会read()死掉:

read(3, 0xbf8ba7f3, 1)                  = -1 EIO (Input/output error)
Run Code Online (Sandbox Code Playgroud)

pty 是用

master_fd = posix_openpt(O_RDWR|O_NOCTTY)
Run Code Online (Sandbox Code Playgroud)

pty的slave端用

comfd = open(COM_PORT, O_RDWR|O_NOCTTY)
Run Code Online (Sandbox Code Playgroud)

为什么在read()打开 pty 从属端的进程退出时退出?这是在哪里描述的?

mos*_*svy 6

在 Linux 上,read()伪 tty 主端的 a 将在其从属端的所有句柄都关闭时返回-1并设置ERRNOEIO,但EAGAIN在从属首次打开之前阻塞或返回。

当试图从没有主站的从站读取时,也会发生同样的事情。对于主端,条件是暂时的;重新打开从站将导致read()主站再次工作。

在 *BSD 和 Solaris 上,行为类似,不同之处在于read()将返回0而不是-1+ EIO。此外,在 OpenBSD 上,aread()也会0在从属设备首次打开之前返回。

我不知道这是否有任何标准规范或基本原理,但它允许(粗略地)检测另一端何时关闭,并简化了诸如script只是创建一个 pty 并在其中运行另一个程序的程序的逻辑。

管理其他无关程序可以连接到的 pty 的主部分的程序中的解决方案是也打开并保持打开其从属端的句柄。

请参阅相关答案:当 pts 关闭时 read(2) 阻塞行为发生变化导致 read() 返回错误:-1 (EIO)

为什么在read()打开 pty 从属端的进程退出时退出?

当一个进程退出时,它的所有文件描述符都会自动关闭。