我通过以下调用在文件描述符上使用 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() 的 else 条件下进入无限循环。看起来 fcntl() 正在返回 0。
我想知道它在什么情况下返回 0 以及如何处理这种情况。
最佳答案
更新:
if (Retval <= 0)
可能会更改为 if (Retval < 0)
.
当 Retval
为零,select
运行正常。
当 Retval
是 -1 并且 errno 是 EBADF
, 然后使用 fcntl 检查 fd 是否有效。
你看过 fcntl 它总是返回 0,那是因为:
没有设置 fd 的
FD_CLOEXEC
旗帜select
不会失败,fcntl 也不会失败,因为所有的 fd 都是有效的。
fcntl
有很多种cmd
.使用 F_GETFD
时,这意味着检索文件描述符标志。
检查 fcntl
的手册,此类型中只有一个标志(FD_CLOEXEC)。因此,如果不为 fd 设置此标志,则 F_GETFD
将返回值 0。
File descriptor flags
The following commands manipulate the flags associated with a file descriptor. Currently, only one such flag is defined: FD_CLOEXEC, the close-on-exec flag. If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2), otherwise it will be closed.
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
.
关于c - fcntl() 的返回值带有 F_GETFD 标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53058178/