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:
Have not set fd's FD_CLOEXEC
flags
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?
When open
one file, the flag FD_CLOEXEC
is default disabled. You can enable it like this.
fd = open(filepath, O_RDONLY | O_CLOEXEC)
Call fcntl(fd, F_SETFD, FD_CLOEXEC)
to enable flag FD_CLOEXEC
.