怎么说,“异常情况”导致select()对errorfds做出反应?

时间:2014-12-10 21:30:18

标签: c unix select low-level-io

根据其手册页,select()系统调用提供对一个或多个文件描述符的三个不同方面的监视:它们是否准备好读取,准备写入,或者是否“错误”或已发生“特殊情况”(语言不同)。应通过称为fd_setreadfdswritefds的三个errorfds参数来指定监控其中的哪一个。虽然有很多关于正确使用readfdswritefds的良好文档和示例,但在errorfds上几乎找不到任何有用的内容。

无论如何,由于下面讨论的原因,我尝试使用errorfds,确实找到了一些情况,其中我的runloop中的select()调用响应了“异常情况”在其中一个文件描述符上。例如,连接到PTY的TTY,而后者从其主端关闭,会引发这样的情况。

但现在呢?我知道文件描述符上出现了一些“异常情况”,但一般来说,我怎样才能找出究竟是什么导致它?只看errno肯定没有给出答案(此时它始终为0)。是否有一些我应该注意的“神奇”ioctl

更多背景知识:我的许多程序(主要用C语言编写)通过串口与外部硬件进行通信。为了测试,我还写了一个简单的服务器,创建一个PTY,我的其他程序可以连接到相应的TTY,就好像它是一个串口。虽然在基本水平上所有这一切都运行良好,但是目前还没有真正实现错误或其他异常条件的处理,这偶尔会导致非常讨厌的行为。这需要改变!

我特别感兴趣的一个特殊情况是连接是否已被破坏。例如,很高兴注意到端口何时消失,比如因为用户拔出了USB转串口适配器。正确处理读写错误似乎可以避免最无意义的副作用,但我想知道是否还有更多(看errorfds,或者其他一些信号)我应该做的事情。不幸的是,UNIX信号处理是我一点都不熟悉的事情。

1 个答案:

答案 0 :(得分:1)

  

我知道一些特殊情况"发生在文件描述符上,但一般来说,我怎样才能找出究竟是什么原因造成的呢?是否有一些"魔法"我应该知道的ioctl?

您应该尝试读取0个字节。在linux中,至少man 2 read表示:

  

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

因此,在read(fd, NULL,0)之后,你应该有errno告诉你更多内容,而不必实际阅读任何内容。手册页中的黄鼠狼单词可能意味着这可能不太便于携带(cf read(fd, NULL, 0); what does it do? is it well-defined?