Как проверить, является ли данный файловый дескриптор, сохраненный в переменной, действительным?
У меня есть файловый дескриптор, хранящийся в переменной скажем var. Как я могу проверить, является ли этот дескриптор допустимым на более позднем этапе?
fdvar1= open(.....);
fdvar2 = fdvar1; // Please ignore the bad design
....
// lots of loops , conditionals and threads. It can call close(fdvar2) also.
....
if(CheckValid(fdvar1)) // How can I do this check ?
write(fdvar1, ....);
Теперь я хочу проверить, действительно ли var1 (который все еще содержит открытый дескриптор) все еще действителен. Любой API для этого?
6 ответов
fcntl(fd, F_GETFD)
канонический самый дешевый способ проверить, что fd
является допустимым дескриптором открытого файла. Если вам нужно много раз проверить пакет, используя poll
с нулевым таймаутом и тому events
элемент установлен в 0 и проверка на POLLNVAL
в revents
после того, как это возвращается, более эффективно.
С учетом сказанного, операция "проверить, является ли данный дескриптор ресурса по-прежнему действительным", почти всегда в корне неверна. После освобождения дескриптора ресурса (например, fd close
d) его значение может быть переназначено следующему такому ресурсу, который вы выделите. Если есть какие-либо оставшиеся ссылки, которые могут быть использованы, они будут неправильно работать с новым ресурсом, а не со старым. Таким образом, реальный ответ, вероятно, таков: если вы еще не знаете по логике своей программы, у вас есть серьезные фундаментальные логические ошибки, которые необходимо исправить.
Вы можете использовать fcntl()
функция:
int fd_is_valid(int fd)
{
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}
Я не думаю, что есть какая-либо функция, которая может сказать вам, если дескриптор все еще действителен. Дескриптор обычно представляет собой небольшое целое число, например 6, и ваш libc может выбрать повторное использование этого числа, если вы закроете файл и откроете новый позже.
Вместо этого вы должны рассмотреть возможность использования dup()
скопировать дескриптор файла. Дублируя файловый дескриптор вместо использования одного и того же дескриптора в нескольких местах, вам может быть проще узнать, является ли файловый дескриптор все еще действительным. Вам просто нужно помнить, чтобы закрыть как оригинальный дескриптор, так и дублированный, когда вы закончите.
Из этой статьи на форуме:
int is_valid_fd(int fd)
{
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
}
fcntl (GETFL), вероятно, является самой дешевой и наименее вероятной ошибочной операцией, которую вы можете выполнить с дескриптором файла. В частности, спецификация предполагает, что он не может быть прерван сигналами и не подвержен влиянию какой-либо блокировки, удерживаемой где-либо.
Мне кажется, что если вы хотите знать, указывает ли он на тот же ресурс, один (неидеальный) подход будет fstat()
дескриптор сразу после открытия, а затем вы можете сделать это снова и сравнить результаты. Начните с просмотра .st_mode
& S_IFMT
и оттуда - это объект файловой системы? смотреть на .st_dev / .st_ino.
Это гнездо? Пытаться getsockname()
, getpeername()
, Он не будет на 100% уверен, но он может сказать вам, если это точно не то же самое.
Я решил эту проблему для себя. я не знаю, можно ли его использовать для общего назначения, но для последовательных соединений он работает нормально (например, /dev/ttyUSB0)!
struct stat s;
fstat(m_fileDescriptor, &s);
// struct stat::nlink_t st_nlink; ... number of hard links
if( s.st_nlink < 1 ){
// treat device disconnected case
}
Подробности смотрите, например, на странице man http://linux.die.net/man/2/fstat
Ура, Фло