怎么说,什么;“例外情况”;是否导致select()对errorfds作出反应?
根据其手册页,系统调用提供了对一个或多个文件描述符的三个不同方面的监控:它们是否准备读取、准备写入,或者是否发生了“错误”或“异常情况”(语言不同)。通过三个怎么说,什么;“例外情况”;是否导致select()对errorfds作出反应?,c,unix,select,low-level-io,C,Unix,Select,Low Level Io,根据其手册页,系统调用提供了对一个或多个文件描述符的三个不同方面的监控:它们是否准备读取、准备写入,或者是否发生了“错误”或“异常情况”(语言不同)。通过三个fd\u set参数指定应监控哪一个,这些参数被称为readfds、writefds和errorfds。虽然有大量关于正确使用readfds和writefds的优秀文档和示例,但我几乎找不到任何关于errorfds的有用信息 无论如何,出于下面讨论的原因,我尝试了使用errorfds,并确实发现了一些情况,在这些情况下,我的runloop中
fd\u set
参数指定应监控哪一个,这些参数被称为readfds
、writefds
和errorfds
。虽然有大量关于正确使用readfds
和writefds
的优秀文档和示例,但我几乎找不到任何关于errorfds
的有用信息
无论如何,出于下面讨论的原因,我尝试了使用errorfds
,并确实发现了一些情况,在这些情况下,我的runloop中的select()
调用响应了其中一个文件描述符上的“异常情况”。例如,当PTY从其主侧关闭时,连接到PTY的TTY会引发此类情况
但是现在呢?我知道在文件描述符上发生了一些“异常情况”,但一般来说,我如何才能找出到底是什么导致了它?只看errno
肯定不会给出答案(此时它总是0)。也许有一些“神奇的”ioctl
我应该知道吗
一些进一步的背景:我的许多程序(大部分用C编写)通过串行端口与外部硬件通信。为了进行测试,我还编写了一个简单的服务器,它创建了一个PTY,我的其他程序可以连接到该PTY,就好像它是一个串行端口一样。虽然在基本层面上,所有这些都运行得很好,但目前根本没有真正实现对错误或其他异常情况的处理,这偶尔会导致相当恶劣的行为。这需要改变
我特别感兴趣的一个例外情况是,连接是否已断开。例如,当一个端口消失时,如果能注意到这一点就好了,比如说,因为用户拔出了一个USB到串行适配器。正确处理读写错误似乎可以避免最糟糕的意外副作用,但我想知道是否还有更多(观看errorfds
,或者其他一些信号)我应该做。不幸的是,我对UNIX信号处理一点也不熟悉
我知道在文件描述符上发生了一些“异常情况”,但一般来说,我如何才能找出到底是什么导致了它?也许有一些“神奇的”ioctl我应该知道吗
您应该尝试读取0字节。在linux中,至少,MAN2 read
声明:
如果count为零,read()可能会检测到下面描述的错误
因此,在
read(fd,NULL,0)
之后,您应该有一个errno
来告诉您更多信息,而不必实际读取任何内容。手册页中的“黄鼠狼”一词可能意味着这可能不是很方便携带,尽管(cf)我知道刚才指出的另一个问题,这确实与我的问题非常相似。但是,我觉得它并不完全匹配。事实上,从这里给出的答案中,我想知道除了“不可能在这个用例中使用errorfds
”之外,我的问题是否还有其他答案。。。但在继续之前,您希望确定。为了更安全,您可以提供一个指向某些已分配内存的有效指针,并请求0字节:char c;如果(read(fd,&c,0)<0){…errno中有一些信息…}
。但是,将0字节传递给函数(系统调用)可能仍然会出现EINVAL错误。@Jonathan:是的,这应该更可靠,但是,由于它不可移植,无论如何,YMMV。在Steven感兴趣的场景中(断开连接),select()
将被SIGHUP
中断,即使没有设置errorfds
。我怀疑捕捉SIGHUP
将是一种比read(fd,NULL,0)
技巧更便携、更可靠的检测断开连接的方法