Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
怎么说,什么;“例外情况”;是否导致select()对errorfds作出反应?_C_Unix_Select_Low Level Io - Fatal编程技术网

怎么说,什么;“例外情况”;是否导致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)
技巧更便携、更可靠的检测断开连接的方法