gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:05:50 24 4
gpt4 key购买 nike

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

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

几天来我一直在阅读引用资料,这类内容的选项数量惊人。答案可能在于终端设置、阻塞/非阻塞行为、在某处设置缓冲区大小、从 poll()/select() 报告的条件或某些组合。不过,我似乎找不到任何东西。我想知道是否有可能我需要编写自己的设备驱动程序,但似乎我应该能够做到这一点而不必走那么远。

所以,为了澄清:
- 问题是:我如何检测何时有人在 Linux 中打开了 pty(伪终端)的从属端?
- 我想让一个reader打开pty的slave端来接收reader打开pty后严格写入的数据(如果我的多写进程只是在reader打开slave端之前写了一会儿数据,数据会缓冲起来,然后最终作者将阻塞,而从属读者在打开时将立即获取所有缓冲数据——这是不可取的,因为我希望它只获取在紧邻时间附近生成的数据)
- 它必须是一个 pty,而不是命名管道、套接字等,因为 isatty() 和 tcsetattr() 等需要正常,这样现有的二进制文件才能工作

最佳答案

你找不到它的原因是因为没有专门允许它的文档化接口(interface)。但是,有一个技巧可以让您做到这一点。打开伪终端master(这里假设是文件描述符ptm)后,打开并立即关闭slave端:

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

这会在 tty 主机上设置 HUP 标志。您现在使用 poll() 定期轮询 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 是否有读取器 - 只需在数据源上阻止 read(),然后数据可用,同时 poll() 您所有的主 ttys,并将数据发送到任何没有设置 POLLHUP 的 ttys。

关于linux - 我如何检测何时有人在 Linux 中打开 pty(伪终端)的从属端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3486491/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com