This close c что это
close закрывает файловый дескриптор, который после этого не ссылается ни на один и файл и может быть использован повторно. Все блокировки, находящиеся на соответствующем файле, снимаются (независимо от того, был ли использован для установки блокировки именно этот файловый дескриптор).
Если fd является последней копией какого-либо файлового дескриптора, то ресурсы, связанные с ним, освобождаются; если дескриптор был последней ссылкой на файл, удаленный с помощью unlink (2), то файл окончательно удаляется.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
close возвращает ноль при успешном завершении или -1, если произошла ошибка.
ОШИБКИ
EBADF fd является неверным файловым дескриптором. EINTR Системный вызов close () был прерван сигналом. EIO Произошла ошибка ввода/вывода.
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, SVID, POSIX, X/OPEN, BSD 4.3. SVr4 документирует дополнительный код ошибки ENOLINK.
ЗАМЕЧАНИЯ
Не проверять значение, возвращаемое функцией close — обычная, но от этого не менее серьезная ошибка программирования. Вполне возможно, что ошибка в предыдущей операции write (2) впервые даст о себе знать при выполнении close . Отсутствие проверки возвращаемого значение при закрытии файла, может привести к потере данных. Особенно это касается таких аспектов как NFS и дисковые квоты.
Успешное выполнение close() не гарантирует, что данные успешно записаны на диск, потому что ядро откладывает запись. Обычно файловые системы не сбрасывают буфера на диск при закрытии потока. Если вам нужно удостовериться, что данные физически сохранены на диске, используйте fsync (2). (В этом случае всё будет зависить от железа и самого диска.)
СМОТРИ ТАКЖЕ
open (2), fcntl (2), shutdown (2), unlink (2), fclose (3), fsync (2)
ПЕРЕВОД
Copyright (C) Alexey Mahotkin 1999-2000, Виктор Вислобоков 2003
close
Имя close функции POSIX, реализованное корпорацией Майкрософт, является устаревшим псевдонимом для _close функции. По умолчанию он создает предупреждение компилятора (уровень 3) C4996. Имя устарело, так как оно не соответствует стандартным правилам C для имен, относящихся к реализации. Однако функция по-прежнему поддерживается.
Вместо этого рекомендуется использовать _close . Кроме того, вы можете продолжать использовать это имя функции и отключить предупреждение. Дополнительные сведения см. в разделе «Отключение имен функций предупреждения и POSIX».
Дополнительные ресурсы
Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)
Close – закрывает файл

Функция close закрывает файл, связанный с дескриптором handle. Аргумент handle обозначает дескриптор файла, присваиваемый ему при вызове функций _creat, creat, creatnew, creattemp, dup, dup2, _open или open.
Примечание. Эта функция не записывает символ Ctrl-Z в конец файла. Если вы хотите завершить файл этим символом, его следует явно вывести.
Возвращаемое значение
При успешном завершении close возвращают значение 0. Иначе возвращается значение -1. Если аргумент handle не является дескриптором открытого файла, это приводит к неудачному завершению операции. Функция errno получает следующее значение:
EBADF — неверный номер файла.
Переносимость
Поддерживается в системах UNIX.
Пример
#include #include #include int main(void)
[c/c++] Размышления про close()
Системный вызов close() теоретически может вернуть код ошибки EINTR. Я у себя использую заглушку try_close() которая перезапускает close() в случае EINTR и экстренно завершает приложение (с выбросом сообщения об ошибке) в случае остальных кодов ошибки.
Я тут смотрю многие вообще не проверяют возврат функции close().
1. Насколько это безопасно? Мне кажется, что очень небезопасно.
2. Кто? как? работает с close()? Если писать явно код обработки возвращаемого значения для каждого close(), то получится очень громоздко. Может у кого-нибудь есть красивые решения?

pathfinder ★★★★
07.07.11 13:17:19 MSK

просто closе, если несколько потоков, то дождаться их а после закрывать.
Boy_from_Jungle ★★★★
( 07.07.11 13:24:50 MSK )

1. небезопасно только на третьем уровне. на первом и втором — самое оно.
2. у меня нет.
//хороший, годный вброс.
mi_estas ★
( 07.07.11 13:25:55 MSK )

Всегда проверяю, что возвращает close.
Не проверять значение, возвращаемое функцией close — обычная, но от этого не менее серьезная ошибка программирования. Вполне возможно, что ошибка в предыдущей операции write(2) впервые даст о себе знать при выполнении close. Отсутствие проверки возвращаемого значение при закрытии файла, может привести к потере данных. Особенно это касается таких аспектов как NFS и дисковые квоты.
rg-400
( 07.07.11 13:47:18 MSK )
Ответ на: комментарий от Boy_from_Jungle 07.07.11 13:24:50 MSK

просто closе, если несколько потоков, то дождаться их а после закрывать.
Т. е. в однопоточных приложениях результат выполнения close() ты вообще не проверяешь?
pathfinder ★★★★
( 07.07.11 14:40:05 MSK ) автор топика
Ответ на: комментарий от rg-400 07.07.11 13:47:18 MSK

Всегда проверяю, что возвращает close.
Терпишь громоздкость в своем коде, или у тебя есть какие-то фокусы?
pathfinder ★★★★
( 07.07.11 14:41:35 MSK ) автор топика
Ответ на: комментарий от mi_estas 07.07.11 13:25:55 MSK

1. небезопасно только на третьем уровне. на первом и втором — самое оно.
Не разпарсил. О каких уровнях идет речь?
//Так и хочется сказать: «Я программист 80-го уровня.» 🙂
pathfinder ★★★★
( 07.07.11 14:46:03 MSK ) автор топика

>Может у кого-нибудь есть красивые решения?
Юзать более высокоуровневые абстракции. Раз уж в заголовке упомятут С++, я как бы намеку на fstream и asio
yoghurt ★★★★★
( 07.07.11 15:00:13 MSK )
Ответ на: комментарий от pathfinder 07.07.11 14:46:03 MSK

да понятие такое есть «ожидаемое качество кода». почитай если интерестно. для задачки, которую запустят один раз нет смысла проверять. А вот для драйвера например — есть.
mi_estas ★
( 07.07.11 15:03:35 MSK )

Зачем проверять, как завершился close? Если тебе нужно, чтобы данные гарантированно легли на блины, используй fsync/fdatasync.
tailgunner ★★★★★
( 07.07.11 15:08:24 MSK )
Ответ на: комментарий от tailgunner 07.07.11 15:08:24 MSK

>Зачем проверять, как завершился close?
Чтобы из лимита открытых дескрипторов не вылезти, не?
yoghurt ★★★★★
( 07.07.11 15:16:09 MSK )
Ответ на: комментарий от pathfinder 07.07.11 14:40:05 MSK

нет не проверяю, если у тебя мега работата с файлами чтение-запись можешь в конце вызвать (f)sync.
Boy_from_Jungle ★★★★
( 07.07.11 15:29:59 MSK )

Человек описал вопрос как-то абстрактно, поэтому ответы очевидны.
Boy_from_Jungle ★★★★
( 07.07.11 15:31:11 MSK )
Ответ на: комментарий от yoghurt 07.07.11 15:16:09 MSK
Допустим, close вернул ошибку. Т.е. файловый дескриптор остался занятым. Вопрос: как действовать в этом случае?
Eddy_Em ☆☆☆☆☆
( 07.07.11 15:33:40 MSK )

1) Конечно не безопасно.
Последствия для примитивной программы и демона работающего 24/7 конечно разные — в первом случае это не очень критично, а во втором есть риск что кончатся дескрипторы и тогда демон не сможет делать практически ничего полезного.
2) Вариантов тут не так много и все опять же зависит от контекста.
Просто перезапускать вызов при получении EINTR не получится, потому что повторный вызов может тоже вернуть EINTR. В этом случае нужен цикл с ожиданием между попытками. Опять же что делать если после N попыток все еще возвращается EINTR, то есть для программы ошибка больше не soft, а hard.
Здесь уже классическая проблема о том как обрабатывать ошибки. Все опять же зависит от контекста и предложить можно:
1) Завершать приложение
2) Выводить сообщение в лог, но продолжать на свой страх и риск
3) Кидать exception если код вызывающий close не знает как обработать ошибку, а код на уровне выше знает.
Если особо не заморачиваться то можно использовать функцию с таким прототипом (она может быть в библиотеке):
do_close(fd, retires, timeout, hard_error_handling_policy)
Первые три параметра очевидны, а 4-й может задавать политику обработки hard ошибок.