Не проверять возвращаемое значение close (): насколько серьезно?

Linux" Man close " предупреждает (SVr4, 4.3 BSD, POSIX.1-2001):

Не проверять возвращаемое значение close () равно общие но тем не менее серьезные ошибка программирования. Вполне возможно, что ошибки предыдущей операции записи (2) сначала сообщаются при окончательном закрытии (). Не проверка возвращаемого значения при закрытии файла может привести к бесшумной потере данных. Это можно особенно наблюдать с NFS и с диском квота.

Я могу поверить, что эта ошибка общие (по крайней мере в приложениях; я не хакер ядра). Но как!--5-->серьезные это, сегодня или в любой момент за последние три десятилетия? В частности:

есть ли простой, воспроизводимый пример такой бесшумной потери данных? Даже надуманный, как отправка SIGKILL во время close ()?

если такой пример существует, можно ли обрабатывать потерю данных более изящно, чем просто

printf("Sorry, dude, you lost some data.n"); ?

2 ответов


типичные приложения


вызов в POSIX это close() может привести к errno значение:

  1. EBADF: плохой номер файла
  2. EINTR: Прерванный системный вызов
  3. EIO: ошибка ввода-вывода (из спецификации POSIX 6 on)

различные ошибки указывают на различные проблемы:

  1. EBADF указывает на ошибку программирования, так как программа должна была отслеживать, какие дескрипторы файлов / сокетов все еще открыты. Я бы рассмотрел тестирование этой ошибки как действие управления качеством.

  2. EINTR кажется наиболее сложным для обработки, поскольку неясно, является ли переданный дескриптор файла/сокета действительным после возврата функции или нет (в Linux это, вероятно, не так:http://lkml.org/lkml/2002/7/17/165). Наблюдая за этой ошибкой, вы, возможно, должны проверить способ обработки сигналов программы.

  3. EIO is ожидается, что он появится только в специальных условиях, как указано в man-pages. Однако, по крайней мере, только из-за этого следует отслеживать эту ошибку, как если это происходит, скорее всего там что-то пошло действительно неправильно.

в целом каждая из этих ошибок имеет по крайней мере одну вескую причину быть пойманным, так что просто сделайте это! ;-)

возможные специфические реакции:

  1. С точки зрения стабильности, игнорируя Ан EBADF может быть приемлемым, однако ошибки не произошло. Как указано, исправьте свой код, поскольку программа, похоже, действительно не знает, что она делает.

  2. видим EINTR могут указывать сигналы дичает. Это нехорошо. Поехать на первопричину. Поскольку неясно, были ли дескрипторы закрыты или не идут на перезапуск системы как можно скорее.

  3. работает в EIO определенно смогло inicate серьезный отказ внутри оборудование*1 участвует. Однако перед настоятельно рекомендуемым завершением работы системы, возможно, стоит просто повторить операцию, хотя те же проблемы, что и для EINTR что неизвестно, действительно ли дескриптор был закрыт или нет. В случае, если он был закрыт, плохая идея закрыть его снова, так как он уже может использоваться другим потоком. Перейти на выключение и оборудование*1 замена срочно.


*1 аппаратное обеспечение это можно увидеть в смысле Бродера здесь: сервер NFS действует как диск, поэтому EIO может быть просто из-за неправильно сконфигурированного сервера или сети или чего-либо еще, связанного с подключением NFS.