我在文件描述符上使用fcntl()并调用以下内容:
Retval = select(
MaxSocketId + 1,
&ReadSocketSet,
(fd_set *)NULL,
(fd_set *)NULL,
(struct timeval *)NULL
);
if (Retval <= 0) {
for (lIndexFD = 3; lIndexFD < (MaxSocketId + 1); lIndexFD++) {
if ((lFlag = fcntl(lIndexFD, F_GETFD)) < 0) {
if (errno == 9) {
FD_CLR(lIndexFD, &ActiveSocketSet);
}
}
else
printf(" n In fcntl Else cond %d ", lFlag);
}
continue;
}
但是我的进程在 fcntl() 的其他条件下处于无限循环中。看起来 fcntl() 返回 0。
我想知道它在哪种情况下返回 0 以及如何处理这种情况。
更新:
if (Retval <= 0)
可能会更改为if (Retval < 0)
。
当Retval
为零时,select
运行正常。
当Retval
为 -1 且 errnoEBADF
时,则使用 fcntl 检查 fd 是否有效。
你看了 fcntl 它总是返回 0,那是因为:
-
尚未设置 FD 的
FD_CLOEXEC
标志 -
select
不是失败,fcntl 也不会失败,因为所有 fd 都是有效的。
fcntl
有很多种cmd
。当使用F_GETFD
时,它表示检索文件描述符标志。
查看fcntl
手册,此类型中只有一个标志(FD_CLOEXEC)。因此,如果没有为 fd 设置此标志,则F_GETFD
将返回值 0。
文件描述符标志
以下命令操作与文件描述符关联的标志。 目前,只定义了一个这样的标志:FD_CLOEXEC,关闭执行标志。 如果FD_CLOEXEC位为 0,则文件 描述符将在 execve(2) 中保持打开状态,否则将被关闭。
F_GETFD (void) Read the file descriptor flags; arg is ignored. F_SETFD (int) Set the file descriptor flags to the value specified by arg.
什么时候不返回 0?
-
open
一个文件时,标志FD_CLOEXEC
默认禁用。您可以像这样启用它。fd = open(filepath, O_RDONLY | O_CLOEXEC)
-
调用
fcntl(fd, F_SETFD, FD_CLOEXEC)
以启用标志FD_CLOEXEC
。