Что делает флаг fcntl () FD_CLOEXEC?

82

Вот так:

Хотя я читал man fcntl, но не могу понять, что он делает.

компилятор
источник

Ответы:

74

Он устанавливает флаг close-on-exec для файлового дескриптора, который вызывает автоматическое (и атомарное) закрытие файлового дескриптора при execуспешном завершении любой из функций -family.

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

R .. GitHub НЕ ПОМОГАЕТ ICE
источник
4
Обратите внимание, что он ничего не делает для очистки любого файлового потока ( FILE *), связанного с файловым дескриптором. Одно из правильных применений FD_CLOEXEC - закрыть файл журнала, который родительский процесс открыл при выполнении процесса оболочки. Обратите внимание, что в POSIX 2008 есть опция open(2)для O_CLOEXEC, поэтому вы можете установить это свойство при открытии файла, что будет очень полезно, когда он станет широко доступным.
Джонатан Леффлер
Атомарная установка флага при открытии файла очень важна для любой многопоточной программы, которая может открывать файлы, в то время как другой поток может выполнять внешние программы. К сожалению , он доступен только для openи accept, socket, pipeи т.д ...
R .. GitHub СТОП ПОМОГАТЬ ICE
Да, есть проблемы с дизайном при добавлении O_CLOEXEC или эквивалента к другим функциям создания файловых дескрипторов (хотя dup()и dup2()не затрагиваются, конечно). Вероятно, вам понадобятся новые функции с дополнительным параметром 'mode' или 'flags', что, вероятно, и не произошло. Если бы вы могли использовать O_CLOEXEC в сокете, то вы могли бы предположить, что accept()это клонирует этот флаг в дескрипторе, который он возвращает. Но socket()и pipe()хитрее.
Джонатан Леффлер
3
dupи dup2страдают. Флаг закрытия при запуске применяется к дескрипторам файлов, а не к описаниям открытых файлов, поэтому он не используется для дублированных дескрипторов файлов. Это очень хорошо.
R .. GitHub НЕ ПОМОГАЕТ ICE
3
Вслед за разговор в комментариях, POSIX принят для включения в следующем выпуске новых интерфейсов , которые фиксируют недостатки: dup3, pipe2и accept4. Также socketимеется SOCK_CLOEXECфлаг, который можно комбинировать с запрошенным типом сокета.
R .. GitHub НЕ ПОМОГАЕТ ICE
33

Он помечает файловый дескриптор так, чтобы он close()автоматически запускался, когда процесс или его дочерние fork()элементы вызывают одну из exec*()семейства функций. Это полезно иметь утечку дескрипторов файлов для случайных программ , управляемых например system().

гикозавр
источник
Это проблема безопасности?
zach
1
@zach можно было бы так сказать; но тогда на самом деле любой рефакторинг, который вы делаете, например, инкапсулирование разрозненной логики в один объект, можно назвать "проблемой безопасности", потому что он снижает вероятность ошибок из-за неправильного использования этого объекта, а "ошибка" - это абстрактная вещь. это включает в себя, в частности, ошибки сегментации и утечку информации.
Hi-Angel
Итак, я реорганизую код сокета, и между получением сокета и подключением () к удаленному серверу они используют F_SETFD для добавления флага FD_CLOEXEC в FD сокета. Затем после успешного подключения FD_CLOEXEC удаляется. Я не могу найти никаких вызовов exec (), задействованных в этой области кода, и мне интересно, являются ли они остатками старого кода, который нужно было удалить, но не было. Не уверен, что искать, чтобы узнать цель всего этого.
JoeManiaci