带有 f getfd 标志的 fcntl ()返回值?

I'm using fcntl() on file descriptor with following call :

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;
}

But my process is going in infinite loop in else condition for fcntl() . It appears that fcntl() is returning 0.

I would like to know in which condition it returns 0 and what to do to handle this situation.

转载于:https://stackoverflow.com/questions/53058178/fcntls-return-value-with-f-getfd-flag

UPDATE:

if (Retval <= 0) may change to if (Retval < 0).

When Retval is zero, select is running ok.

When Retval is -1 and errno is EBADF, then use fcntl check fd is valid.

You watched fcntl it's always return 0, that's because:

  1. Have not set fd's FD_CLOEXEC flags

  2. select is not fail and fcntl not fail too, because all fd is valid.


fcntl have many kinds of cmd. When using F_GETFD, it means retrive file descriptor flags.

Check fcntl's manual, there is only one flag(FD_CLOEXEC) in this type. So if not set this flag for the fd, then F_GETFD will return value 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.

When will it not return 0?

  1. When open one file, the flag FD_CLOEXEC is default disabled. You can enable it like this.

    fd = open(filepath, O_RDONLY | O_CLOEXEC)
    
  2. Call fcntl(fd, F_SETFD, FD_CLOEXEC) to enable flag FD_CLOEXEC.