fcntl()的返回值是否带有F_GETFD标志?

时间:2018-10-30 05:53:30

标签: c linux sockets select fcntl

我正在通过以下调用在文件描述符上使用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,以及如何处理这种情况。

1 个答案:

答案 0 :(得分:1)

更新:

if (Retval <= 0)可能会更改为if (Retval < 0)

Retval为零时,select运行正常。

Retval为-1且errno为EBADF时,请使用fcntl检查fd是否有效。

您看到fcntl总是返回0,这是因为:

  1. 尚未设置fd的FD_CLOEXEC标志

  2. 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?

  1. open一个文件时,标志FD_CLOEXEC被默认禁用。您可以这样启用它。

    fd = open(filepath, O_RDONLY | O_CLOEXEC)
    
  2. 调用fcntl(fd, F_SETFD, FD_CLOEXEC)以启用标志FD_CLOEXEC