Что произойдет с дескриптором открытого файла в Linux, если указанный файл тем временем получит:
- Перемещено -> Сохраняется ли дескриптор файла?
- Удалено -> Приводит ли это к EBADF, указывающему на недопустимый дескриптор файла?
- Заменено новым файлом -> Указывает ли дескриптор файла на этот новый файл?
- Заменено жесткой ссылкой на новый файл -> Мой дескриптор файла "переходит" по этой ссылке?
- Заменено программной ссылкой на новый файл -> Мой дескриптор файла теперь попадает в этот файл мягкой ссылки?
Почему я задаю такие вопросы: я использую оборудование с горячей заменой (например, USB-устройства и т. Д.). Может случиться так, что устройство (а также его / dev / файл) будет повторно подключено пользователем или другим Гремлином.
Как лучше всего с этим справиться?
Дескрипторы файлов указывают на индексный дескриптор, а не на путь, поэтому большинство ваших сценариев по-прежнему работают так, как вы предполагаете, поскольку дескриптор по-прежнему указывает на файл.
В частности, в сценарии удаления - функция называется «unlink» по какой-то причине, она уничтожает «связь» между именем файла (dentry) и файлом. Когда вы открываете файл, а затем отсоединяете его, файл фактически все еще существует до тех пор, пока его счетчик ссылок не станет равным нулю, то есть когда вы закрываете дескриптор.
Изменить: в случае аппаратного обеспечения вы открыли дескриптор определенного узла устройства, если вы отключите устройство, ядро потерпит неудачу при любом доступе к нему, даже если устройство вернется. Вам придется закрыть устройство и снова открыть его.
источник
Я не уверен насчет других операций, но насчет удаления: Удаление просто не происходит (физически, то есть в файловой системе) до тех пор, пока не будет закрыт последний открытый дескриптор файла. Таким образом, не должно быть возможности удалить файл из-под вашего приложения.
Некоторые приложения (которые не приходят в голову) полагаются на это поведение, создавая, открывая и немедленно удаляя файлы, которые затем живут ровно столько же, сколько и приложение, что позволяет другим приложениям знать о жизненном цикле первого приложения без необходимости посмотрите карты процессов и тому подобное.
Возможно, аналогичные соображения применимы и к другим вещам.
источник
если вы хотите проверить, в порядке ли обработчик файла (дескриптор файла), вы можете вызвать эту функцию.
источник
if(!fcntl(fd, F_GETFL)) {
проверять? Я думаю, ты ищешьEBADF
там. (Вы также, вероятно, забыли инициализироватьerrno
значение 0).open(O_WRONLY|O_APPEND)
- st_nlink всегда оставаться> = 1, пока мой дескриптор открыт.Информация об удаленном файле в памяти (все приведенные вами примеры являются экземплярами удаленного файла), а также inodes на диске остаются в наличии до тех пор, пока файл не будет закрыт.
Оборудование время подключаемых в совершенно другой вопрос, и вы не должны ожидать , что ваша программа , чтобы остаться в живых долго , если дескрипторы на диске или метаданные изменились вообще .
источник
Следующий эксперимент показывает, что ответ MarkR правильный.
code.c:
данные:
Используйте
gcc code.c
для производстваa.out
. Беги./a.out
. Когда вы увидите следующий результат:Используйте
rm data
для удаленияdata
. Но./a.out
продолжит работу без ошибок и выдаст следующий результат:Я провел эксперимент на Ubuntu 16.04.3.
источник
В каталоге / proc / вы найдете список всех активных в настоящее время процессов, просто найдите свой PID и все данные о нем. Интересная информация - это папка fd /, вы найдете все обработчики файлов, открытые в данный момент процессом.
В конце концов вы найдете символическую ссылку на свое устройство (в / dev / или даже / proc / bus / usb /), если устройство зависнет, ссылка будет мертва и обновить этот дескриптор будет невозможно, процесс должен быть закрыт и откройте его снова (даже с переподключением)
Этот код может считывать текущий статус ссылки вашего PID
Этот последний код прост, вы можете играть с функцией linkat.
источник