Как проверить, сохраняется ли данный файл-дескриптор, хранящийся в переменной?
У меня есть файловый дескриптор, хранящийся в переменной say 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 для этого?
Ответы
Ответ 1
fcntl(fd, F_GETFD)
- это канонический самый дешевый способ проверить, что fd
является допустимым дескриптором открытого файла. Если вам нужно многократно проверять партии, используя poll
с нулевым таймаутом, а член events
установлен в 0 и проверка на POLLNVAL
в revents
после его возврата более эффективна.
С учетом сказанного операция "проверить, действительно ли данный дескриптор ресурса по-прежнему действителен" почти всегда принципиально неверна. После освобождения дескриптора ресурса (например, fd is close
d) его значение может быть переназначено на следующий указанный вами ресурс. Если есть какие-либо другие ссылки, которые могут быть использованы, они будут ошибочно работать с новым ресурсом, а не с старым. Таким образом, реальный ответ, вероятно: если вы еще не знаете по логике своей программы, у вас есть основные фундаментальные логические ошибки, которые необходимо устранить.
Ответ 2
Вы можете использовать функцию fcntl()
:
int fd_is_valid(int fd)
{
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}
Ответ 3
Я не думаю, что есть какая-либо функция, которая может сказать вам, действительно ли дескриптор действителен. Дескриптор обычно представляет собой небольшое число, например 6, и ваш libc может выбрать повторное использование этого номера, если вы закроете файл и позже откроете новый.
Вместо этого вам следует использовать dup()
для копирования дескриптора файла. Путем дублирования дескриптора файла вместо того, чтобы использовать один и тот же дескриптор в нескольких местах, вам может быть проще узнать, действительно ли дескриптор файла действителен. Вам просто нужно запомнить, как закрыть исходный дескриптор и дублированный, когда вы закончите.
Ответ 4
Из эта статья форума:
int is_valid_fd(int fd)
{
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
}
fcntl (GETFL), вероятно, самый дешевый и наименее вероятный которую вы можете выполнять в файловом дескрипторе. В частности, указывает, что он не может быть прерван сигналами, ни это зависит от любого вида блокировки, хранящейся где угодно.
Ответ 5
Мне кажется, что если вы хотите знать, все ли он указывает на один и тот же ресурс, один (не идеальный) подход будет в fstat()
дескрипторе сразу после открытия, а затем позже вы сможете сделать это снова и сравнить результаты. Начните с просмотра .st_mode
& S_IFMT
и перейти оттуда - это объект файловой системы? Посмотрите .st_dev / .st_ino.
Это сокет? Попробуйте getsockname()
, getpeername()
. Это не будет на 100% уверенным, но это может сказать вам, если это определенно не то же самое.
Ответ 6
Я решил эту проблему для меня. я не знаю, может ли он использоваться для общего назначения, но для последовательных соединений он работает нормально (например,/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
Cheers,
Flo