在Linux中,当有人打开pty(伪终端)的从机端时,我如何检测?

在Linux中,当有人打开pty(伪终端)的从机端时,我如何检测?,linux,file,file-descriptor,pty,Linux,File,File Descriptor,Pty,从串行设备/dev/ttyXX读取多个进程会使这两个进程无法获取所有数据——数据将以某种方式在它们之间分割。我想写一个程序,从串行设备读取数据,创建几个主/从pty对,然后允许从串行设备读取的程序改为从pty读取,以便所有读取过程都从串行设备接收数据,并使pty在开始从pty读取时仅获得最新数据的意义上与串行设备类似。换言之,在开始阅读之前,您不会得到任何写入的数据。根据我的经验,/dev/ttyXX设备就是这样工作的,或者至少是我正在读取的RS-232风速仪。命名管道可以通过捕获SIGPIPE

从串行设备/dev/ttyXX读取多个进程会使这两个进程无法获取所有数据——数据将以某种方式在它们之间分割。我想写一个程序,从串行设备读取数据,创建几个主/从pty对,然后允许从串行设备读取的程序改为从pty读取,以便所有读取过程都从串行设备接收数据,并使pty在开始从pty读取时仅获得最新数据的意义上与串行设备类似。换言之,在开始阅读之前,您不会得到任何写入的数据。根据我的经验,/dev/ttyXX设备就是这样工作的,或者至少是我正在读取的RS-232风速仪。命名管道可以通过捕获SIGPIPE来模拟这些语义,从而确定没有读取器,因此我们可以选择不写入特定的命名管道。但是,一些编写用于使用终端的二进制文件在与命名管道通信时可能会失败,因为在诸如tcsetattr之类的调用上检查isatty和errno条件可能会导致失败。这里的关键是能够使用为终端编写的现有二进制文件

因此,如果我能检测到pty的从端何时被打开以进行读取,这应该会给我大致相同的语义,因为在命名的管道案例中没有SIGPIPE。我注意到HP-UX将TIOCTRAP作为一个ioctl命令,它似乎正是我想要的,但遗憾的是它在Linux上不可用

我已经阅读参考资料好几天了,这类东西的选择数量惊人。答案可能在于终端设置、阻塞/非阻塞行为、在某处设置缓冲区大小、轮询/选择报告的条件或某些组合。不过,我似乎什么也找不到。我想知道是否有可能我需要编写自己的设备驱动程序,但似乎我应该能够做到这一点,而不必走那么远

因此,为了澄清: -问题是:在Linux中,当有人打开pty伪终端的从端时,我如何检测? -我希望打开pty从机侧的读卡器在读卡器打开pty后严格接收写入的数据如果我的多重写入过程只是在读卡器打开从机侧之前写入数据一段时间,数据将缓冲,最终读卡器将阻塞,从机读卡器打开时,将立即获得所有缓冲数据-这是不可取的,因为我希望它只获得在即时时间附近生成的数据
-它必须是一个pty,而不是命名管道、套接字等,因为isatty和tcsetattr等需要正常工作,以便现有二进制文件正常工作。您找不到它的原因是因为没有专门允许它的文档化接口。然而,有一个技巧可以让你做到这一点。打开此处假定为文件描述符ptm的伪终端主机后,打开并立即关闭从机端:

close(open(ptsname(ptm), O_RDWR | O_NOCTTY));
这将在tty主机上设置HUP标志。现在,只要数据来自您的数据源,您就可以使用poll say定期轮询HUP标志:

struct pollfd pfd = { .fd = ptm, .events = POLLHUP };
poll(&pfd, 1, 10 /* or other small timeout */);

if (!(pfd.revents & POLLHUP))
{
    /* There is now a reader on the slave side */
}
如果读者离开,POLLHUP将再次设置


在您的情况下,您可能甚至不需要从一个循环到下一个循环记住给定pty是否有读卡器-只要在数据源上阻塞读取,然后当数据可用时,同时轮询所有主TTY,并将数据发送给未设置POLLHUP的任何主TTY。

在从属pty上添加inotify手表并轮询该手表。您可以在open上获得inotify事件。然后可以轮询inotify文件描述符和主pty文件描述符。您可以在_open中为open获取inotify事件。当从机端打开时,这将取消阻止轮询。

感谢您的解释。我在socat的源代码中发现了这个技巧,但没有意识到我必须先打开然后关闭从端。即使在理解了这个技巧之后,我仍然有一些头发拉扯的情节,因为我使用的是openpty,而不是显式打开/dev/ptmx,它为pts提供了一个单独的、开放的fd,因此我最初无法获得HUP条件。调用openpty然后关闭从它返回的从属fd就足够了。再次感谢您的回复。你是怎么知道这个没有文档的功能的?我想我是通过在usenet上的帖子才发现的。不过,这个问题应该会让谷歌在未来更适合人们!