你如何判断一个fd是指向伪终端内部还是外部?

4
在Linux和NetBSD系统上,isatty函数对于在伪终端内部(/dev/pts/0, /dev/ttyp0等)或外部(/dev/ptmx, /dev/ptyp0等)打开的文件描述符返回true。我可以方便地测试所有的tcgetxxx操作也无法区分这两种情况。理论上,你可以通过调用fstat并查看st_rdev来判断文件描述符是否指向伪终端的外部,但是你必须知道哪些设备号用于什么,而这在不同的系统中是不一致的。
有没有一种可移植的方法,可以确定任意打开的文件描述符是否指向伪终端的外部,即使isatty函数返回true?由于POSIX只对伪终端进行了粗略的规定,因此我认为没有任何标准的方法,但我希望至少在当前的开源Unix系统中有一种方法可以实现,而不必编译一个支持的操作系统的设备号表。
(这将用于类似于lsof的检查工具,如果你想知道我为什么要知道这个。)

根据Linux上的ioctl_tty手册,TIOCPKT ioctl只能应用于伪终端的主端口,否则会得到ENOTTY错误。我没有测试过或者做任何实验。 - rici
注意:我故意使用“外部”和“内部”这两个术语来代替大多数伪终端文档中所称的“主”和“从”,因为我认为这在概念上更清晰。请不要更改此内容。 - zwol
1
并不是我干的,警官。但我认为,“内部”和“外部”这些术语可能更符合概念上的满足感,但“主”和“从”这些术语在普通用法中也比较常见,对于那些熟悉这些术语而不熟悉Zack的概念的人来说,把它们放在括号里可能会有所帮助。当然,在这种情况下,只需要理解两种术语之间存在一个双射映射即可,我并没有感觉需要去弄清楚它是什么。所以,也许指定它是不必要的。 - rici
不确定其他人是否也有同感,但“inside”和“outside”对我来说确实很令人困惑。PTY主和从就像两个端点,它们并不是“内部”和“外部”。 - user8680478
@EmilyE。对我来说,这很奇怪。对我来说,伪终端两侧的不对称性似乎恰好被“内部”和“外部”所捕捉。属于控制终端为pty的会话的进程具有内部fd打开,而负责捕获终端I/O并将其转发到屏幕或网络隧道或其他任何工作的进程则使用外部fd。为什么你觉得这个比喻不合适呢? - zwol
你能给我一些其他称呼为“内部”和“外部”的参考资料吗?我可以看看吗? - user8680478
1个回答

3
根据 ptsname 手册

char *ptsname(int fd);

ptsname() 函数返回与 fd 相对应的 伪终端设备的 设备名称。

如果 fd 不是伪终端 设备,则会失败并返回 ENOTTY
因此,您可以先调用 isatty() 然后再调用 ptsname()
ptsname() 符合 POSIX.1-2001、POSIX.1-2008。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接