c - 如何判断 "exceptional condition"是什么导致 select() 对 errorfds 使用react?

标签 c unix select low-level-io

根据其手册页,select()系统调用提供对一个或多个文件描述符的三个不同方面的监视:它们是否准备好读取、准备好写入,或者是否发生“错误”或“异常情况”(语言不同)。应监视其中哪一个,通过三个称为 readfdswritefdserrorfdsfd_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/

相关文章:

linux - 基本Unix复习查询: ls -ld

linux - 从源代码构建软件比从包管理器安装它们有什么优势吗?

mysql - 日期之间的查询也返回前几个月的行

sql - 选择有条件的日期时间(Oracle)

c - 当我使用 free() 时,C 中的程序随机崩溃

unix - Unix 中的用户无法运行 hadoop 命令

C char* 与 URL 内容

Jquery 选择更改

c - 我怎么知道c中指针变量的分配内存大小

c - 在 Tiva C 中按下开关时 LED 闪烁