c语言 - 如何判断,是什么"exceptional condition"导致 select() 对错误fds 做出反应?



根据其手册页,select(( 系统调用提供了对一个或多个文件描述符的三个不同方面的监视:它们是否准备好读取、准备写入,或者是否发生了"错误"或"异常情况"(语言变化(。其中哪一个应该被监视,通过三个fd_set参数指定,称为readfdswritefdserrorfds。虽然有很多关于正确使用readfdswritefds的良好文档和示例,但我几乎找不到任何有用的errorfds

无论如何,出于下面讨论的原因,我尝试了errorfds的使用,并且确实发现了一些情况,其中我的 runloop 中的 select() 调用响应其文件描述符之一的"异常条件"。例如,连接到 PTY 的 TTY,而后者从其主侧关闭,会引发这样的条件。

但是现在呢?我知道文件描述符上发生了一些"异常情况",但一般来说,我如何才能找出究竟是什么导致了它?只看errno肯定不会给出答案(此时它总是 0(。也许有一些"神奇"的ioctl是我应该注意的吗?

一些进一步的背景:我的许多程序(大部分是用C编写的(通过串行端口与外部硬件通信。为了进行测试,我还编写了一个简单的服务器,用于创建一个PTY,我的其他程序可以连接到该PTY,就好像它是串行端口一样。虽然在基本层面上所有这些都运行良好,但目前根本没有真正实现错误或其他异常情况的处理,这偶尔会导致非常讨厌的行为。这需要改变!

我特别感兴趣的一个特殊情况是连接是否已断开。例如,最好注意端口何时消失,例如,因为用户拉了USB到串行适配器。正确处理读写错误似乎可以避免最恶劣的意外副作用,但我想知道我是否应该做更多(观察errorfds,或者其他一些信号(。不幸的是,UNIX信号处理是我根本不熟悉的东西。

我知道文件描述符上发生了一些"异常情况",但一般来说,我如何才能找出究竟是什么导致了它?也许有一些"神奇"的ioctl是我应该注意的吗?

您应该尝试读取 0 字节。至少在 Linux 中,man 2 read 指出:

如果计数为零,read(( 可能会检测到下面描述的错误。

因此,read(fd, NULL,0)之后,您应该有一份告诉您更多内容的errno,而无需实际阅读任何内容。手册页中的鼬鼠词可能意味着这可能不是很便携(cf read(fd, NULL, 0(;它有什么作用?它的定义是否明确?(

最新更新