Если close (2) завершится неудачно с EIO, дескриптор файла все еще будет удален? - PullRequest
19 голосов
/ 04 сентября 2011

Если системный вызов close (2) завершится неудачно с EIO, дескриптор файла все еще будет удален?

Если да, то невозможно ли обработать ложную ошибку ввода-вывода, повторив попытку позже?Если нет, то как предотвратить утечку файлового дескриптора?

1 Ответ

12 голосов
/ 04 сентября 2011

Это сложный вопрос. Однако стандарт POSIX охватывает это в описании close():

Если close () прерывается сигналом, который должен быть перехвачен, он должен возвратить -1 с errno, установленным в [EINTR], и состояние файлов не определено. Если во время чтения или записи в файловую систему во время close () произошла ошибка ввода / вывода, она может вернуть -1, если для errno установлено значение [EIO]; если возвращается эта ошибка, состояние файлов не указывается.

Итак, состояние дескриптора файла не указано стандартом.

Для большинства практических целей он закрыт; с дескриптором файла мало что можно сделать, даже если он официально открыт. Вы можете попробовать безвредную операцию (например, fcntl() и F_GETFL) и посмотреть, получите ли вы обратно EBADF, указывая, что дескриптор формально закрыт. Но если он открыт и причина ошибки EIO постоянна, вы, вероятно, получите EIO каждый раз, когда пытаетесь что-либо с ним сделать (возможно, включая вызов fcntl()). Вы могли или не могли когда-либо получить тот же самый дескриптор, возвращенный другой открытой операцией. Не ясно, что даже dup2() может быть успешным с указанием «мертвого» файлового дескриптора в качестве цели, если дескриптор «мертвого» файла открыт, но не может быть закрыт.

...