Мое использование приложения lseek()
искать желаемое положение для записи данных. Файл успешно открыт с помощью open()
и мое приложение смогло использовать lseek()
и write()
много времен.
В установленный срок, для некоторых пользователей и не легко восстанавливаемый, lseek()
возвраты-1 с errno
из 9. Файл не закрывается, прежде чем это и дескриптор файла (интервал) не сбрасываются.
После этого другой файл создается; open()
хорошо снова и lseek()
и write()
работы снова.
Для создания этого еще хуже этот пользователь попробовал полную последовательность снова, и все было хорошо.
Таким образом, мой вопрос, ОС может закрыть дескриптор файла для меня по некоторым причинам? Что могло вызвать это? Индексатор файла или какой-то сканер файла?
Что является лучшим способом решить это; действительно ли этот псевдо код является лучшим решением? (не берите в голову размещение кода, создаст функции для него),
int fd=open(...);
if (fd>-1) {
long result = lseek(fd,....);
if (result == -1 && errno==9) {
close(fd..); //make sure we try to close nicely
fd=open(...);
result = lseek(fd,....);
}
}
Кто-либо испытывает с чем-то подобным?
Сводка: файл ищет и пишет работы хорошо для данного fd, и внезапно отдает errno=9 без причины.
Я не знаю, какой тип настройки у вас есть, но следующий сценарий, мог бы я подумать, произвел бы такой эффект (или аналогичный ему). Я не проверял это, поэтому, пожалуйста, отнеситесь к этому с недоверием.
Если файл / устройство, которое вы открываете, реализовано как серверное приложение (например, NFS), подумайте, что может произойти, если серверное приложение выйдет из строя / перезапустится / перезагрузится. Дескриптор файла, хотя изначально действительный на стороне клиента, может больше не отображаться на действительный дескриптор файла на стороне сервера. Это, вероятно, может привести к последовательности событий, при которой клиент получит EBADF.
Надеюсь, это поможет.
Итак, мой вопрос в том, может ли ОС по какой-то причине закрыть ручку файла для меня? Что может вызвать > это? Какой-нибудь индексатор файлов или сканер файлов?
Нет, этого не произойдет.
Каков наилучший способ решить эту проблему; является ли этот псевдокод - лучшее решение? (не обращайте внимания на схему кода, буду создавать функции для этого)
Нет, лучший способ - найти ошибку и исправить ее.
Кто-нибудь сталкивался с чем-то подобным?
Я много раз видел, как fds путаются, приводя к EBADF в некоторых случаях, и эффектно взрываются в других, это были:
if(fd = foo[i].fd)
, когда они имели в виду if(fd == foo[i].fd)
Если вы можете найти способ воспроизвести эту проблему, запустите свою программу под 'strace', чтобы увидеть, что происходит.
Нет, ОС не должна закрывать дескрипторы файлов просто так, и другие приложения (сканеры файлов и т. Д.) Не должны делать это.
Не пытайтесь обойти проблему, найдите ее источник. Если вы не знаете, в чем была причина вашей проблемы, вы никогда не узнаете, действительно ли ваш обходной путь работает .
errno
в 0 перед вызовом? Действительно ли fd действителен в момент совершения вызова? (Я знаю, что вы сказали, что это так, но вы проверили это?) put (strerror (9));
на вашей платформе? ОС не должна случайным образом закрывать дескрипторы файлов (я предполагаю, что это Unix-подобная система). Если ваш дескриптор файла закрыт, значит, с вашим кодом что-то не так, скорее всего, где-то в другом месте (благодаря языку C и Unix API, это действительно может быть где угодно в коде и может быть связано, например, с небольшим буфером переполнение в каком-то фрагменте кода, который действительно выглядит не связанным).
Ваш псевдокод - наихудшее решение, так как он создаст впечатление, что проблема исправлена, а ошибка все еще скрывается.
Я предлагаю вам добавлять отладочные отпечатки (т.е. вызовы printf ()
) везде, где вы открываете и закрываете файл или сокет. Также попробуйте Valgrind .
(У меня только вчера произошло жуткое переполнение буфера размером менее 1, которое повредило наименее значимый байт временного слота, созданного компилятором для сохранения регистра ЦП; косвенным эффектом было то, что структура в другой функции, по-видимому, быть сдвинутым на несколько байтов. Мне потребовалось некоторое время, чтобы понять, что происходит, включая некоторое тщательное чтение ассемблерного кода Mips).