Ответ 1
Когда-то (24 марта 2007 г.) Эрик Сосман имел следующую историю, чтобы поделиться в группе comp.lang.c:
(Позвольте мне начать с исповедания маленькой белой лжи: это не было fclose(), чей отказ не обнаружен, но POSIX close() функция; эта часть приложения использовала POSIX I/O. Ложь хотя и небезопасен, поскольку средства ввода-вывода C будут иметь не удалось точно таким же образом, и необнаруженный сбой имели те же последствия. Я расскажу, что произошло в члены C I/O, чтобы избежать слишком многого для POSIX.)
Ситуация была такой же, как описал Ричард Тобин. Приложение представляет собой систему управления документами, которая загружает файл документа в память, применяет изменения пользователя к копия памяти, а затем написал все в новый файл, когда он сказал для сохранения изменений. Он также поддерживал одноуровневую "старую версию", резервное копирование для безопасности: операция сохранения написана в соответствии с темпом файл, а затем, если это было удалено, удалена старая резервная копия, переименовал старый файл документа в имя резервной копии и переименовал temp в документ. bak → trash, doc → bak, tmp → doc.
В шаге write-to-temp проверяется почти все. fopen(), очевидно, но также и все fwrite() s и даже финальные fflush() были проверены на наличие ошибок - но fclose() не было. И на одной системе случилось, что последние несколько дисков блоки фактически не были распределены до тех пор, пока fclose() - ввод-вывод система сидела поверх оборудования доступа к файлам более низкого уровня VMS и в аранжировке было немного асинхронности.
В системе клиента были задействованы дисковые квоты, а жертва была близка к своему пределу. Он открыл документ, отредактировал какое-то время, сохранил его работу до сих пор и превысил его квота - которая не была обнаружена, потому что ошибка не появилась пока не будет отмечен fclose(). Думая, что сэкономление удалось, приложение отменило старую резервную копию, переименовало оригинал документ, чтобы стать резервным, и переименовал укороченный темп файл - новый документ. Пользователь работал немного дольше и сохранили снова - то же самое, за исключением того, что вы заметите, что на этот раз единственный сохранившийся полный файл был удален, и оба резервное копирование и файл основного документа усечены. Результат: весь файл документа стал мусором, а не только последней сессией работы, но все, что было раньше.
Как и Мерфи, жертва была боссом отдел, который купил несколько сотен лицензий для наших программное обеспечение, и я получил привилегию полета в Сент-Луис, чтобы быть брошенным львам.
[...]
В этом случае отказ fclose() будет (если обнаружен) остановил последовательность удаления и переименования. Пользователь был бы сказал: "Эй, проблема с сохранением документа, что-то сделать об этом и попробуйте еще раз. Между тем на диске ничего не изменилось". Даже если бы он не смог сохранить свою последнюю партию работы, он бы по крайней мере, не потеряли все, что было раньше.