UPDATE:
if (Retval <= 0)
может измениться на if (Retval < 0)
.
Когда Retval
равен нулю, select
работает нормально.
Если Retval
равно -1, а errno равно EBADF
, используйте fcntl, проверьте, что fd действителен.
Вы смотрели fcntl, он всегда возвращает 0, потому что:
Не установлены флаги FD_CLOEXEC
для fd
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
.