根据其手册页,select()系统调用提供对一个或多个文件描述符的三个不同方面的监视:它们是否准备好读取、准备好写入,或者是否发生“错误”或“异常情况”(语言不同)。应监视其中哪一个,通过三个称为 readfds
、writefds
和 errorfds
的 fd_set
参数指定。虽然有很多关于正确使用 readfds 和 writefds 的优秀文档和示例,但我几乎找不到关于 errorfds 的任何有用信息。
无论如何,由于下面讨论的原因,我尝试了 errorfds
的使用,并且确实发现了一些情况,其中 select()
在我的runloop 响应其文件描述符之一上的“异常情况”。例如,连接到 PTY 的 TTY,当后者从其主端关闭时,会引发这样的情况。
但是现在怎么办?我知道文件描述符上发生了一些“异常情况”,但是一般来说,我怎样才能找出到底是什么原因导致的呢?仅查看 errno 肯定不会给出答案(此时它始终为 0)。也许有一些我应该注意的“神奇”ioctl
?
一些进一步的背景:我的许多程序(大部分用 C 语言编写)通过串行端口与外部硬件通信。为了进行测试,我还编写了一个简单的服务器,它创建一个 PTY,我的其他程序可以连接到该 PTY,就像它是一个串行端口一样。虽然在基本层面上,所有这些都运行得很好,但目前根本没有真正实现对错误或其他异常情况的处理,这有时会导致相当令人讨厌的行为。这需要改变!
我特别感兴趣的一个特殊情况是连接是否已断开。例如,如果某个端口消失(例如,因为用户拔出了 USB 转串口适配器),那么能够注意到这一点就很不错了。正确处理读取和写入错误似乎可以避免最令人讨厌的意外副作用,但我想知道是否还有更多我应该做的事情(观察 errorfds
,或者可能是其他一些信号)。不幸的是,我根本不熟悉 UNIX 信号处理。
最佳答案
I know that some "exceptional condition" occurred on a file descriptor, but how, in general, can I find out what exactly caused it? Is there perhaps some "magical" ioctl that I should be aware of?
您应该尝试读取 0 字节。至少在 Linux 中,man 2 read
指出:
If count is zero, read() may detect the errors described below.
因此,在 read(fd, NULL,0)
之后,您应该有一个 errno
告诉您更多信息,而无需实际读取任何内容。手册页中的黄鼠狼一词可能意味着这可能不太可移植(参见 read(fd, NULL, 0); what does it do? is it well-defined? )
关于c - 如何判断 "exceptional condition"是什么导致 select() 对 errorfds 使用react?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27411178/