一尘不染

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

linux

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

因此,如果我可以检测到pty的从属端何时打开以进行读取,那么这应该给我大致相同的语义,与命名管道中没有SIGPIPE的语义相同。我注意到,HP-
UX将TIOCTRAP作为ioctl()命令,该命令似乎完全符合我的要求,但是遗憾的是,它在Linux上不可用。

我已经读了几天的参考书,这种类型的选择的数量是惊人的。答案可能在于终端设置,阻止/非阻止行为,在某处设置缓冲区大小,从poll()/
select()报告的条件或某种组合。不过,我似乎找不到任何东西。我想知道是否可能需要编写自己的设备驱动程序,但似乎我应该能够做到这一点而不必走太远。

因此,为澄清
起见:-问题是:如何检测到有人在Linux中打开pty(伪终端)的从属端?
-我希望读取器打开pty的从属端以接收在读取器打开pty之后严格写入的数据(如果我的多重写入过程只是在读取器打开从属端之前写入数据一段时间,则数据将缓冲并最终,写入器将阻塞,打开后的从属读取器将立即获取所有缓冲的数据-这是不可取的,因为我希望它仅获取在瞬时附近产生的数据)
- 必须 是pty,而不是命名为管道,套接字等,如isatty()和tcsetattr()等需要确定,以便现有的二进制文件能正常工作


阅读 475

收藏
2020-06-03

共1个答案

一尘不染

您找不到此原因的原因是,没有专门允许它的文档化接口。但是,有一个技巧可以使您做到这一点。在打开伪终端主机(假定为文件描述符ptm)之后,打开并立即关闭从机端:

close(open(ptsname(ptm), O_RDWR | O_NOCTTY));

这将在tty主机上设置HUP标志。现在,您可以定期轮询HUP标志poll()(例如,每当数据来自数据源时):

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是否具有读取器-
只需阻塞read()数据源,然后在数据可用时,同时同步poll()所有主tty并发送数据发送到任何未POLLHUP设置的位置。

2020-06-03