Подтвердить что ты не робот

Как проверить, сохраняется ли данный файл-дескриптор, хранящийся в переменной?

У меня есть файловый дескриптор, хранящийся в переменной 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 для этого?

4b9b3361

Ответ 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