Вот так:
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
...
Хотя я читал man fcntl, но не могу понять, что он делает.
Вот так:
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
...
Хотя я читал man fcntl, но не могу понять, что он делает.
Ответы:
Он устанавливает флаг close-on-exec для файлового дескриптора, который вызывает автоматическое (и атомарное) закрытие файлового дескриптора при execуспешном завершении любой из функций -family.
Он также проверяет возвращаемое значение, чтобы увидеть, не удалось ли выполнить операцию, что довольно бесполезно, если файловый дескриптор действителен, поскольку нет условия, при котором эта операция должна завершиться неудачно для действительного файлового дескриптора.
openи accept, socket, pipeи т.д ...
dup()и dup2()не затрагиваются, конечно). Вероятно, вам понадобятся новые функции с дополнительным параметром 'mode' или 'flags', что, вероятно, и не произошло. Если бы вы могли использовать O_CLOEXEC в сокете, то вы могли бы предположить, что accept()это клонирует этот флаг в дескрипторе, который он возвращает. Но socket()и pipe()хитрее.
dupи dup2страдают. Флаг закрытия при запуске применяется к дескрипторам файлов, а не к описаниям открытых файлов, поэтому он не используется для дублированных дескрипторов файлов. Это очень хорошо.
dup3, pipe2и accept4. Также socketимеется SOCK_CLOEXECфлаг, который можно комбинировать с запрошенным типом сокета.
Он помечает файловый дескриптор так, чтобы он close()автоматически запускался, когда процесс или его дочерние fork()элементы вызывают одну из exec*()семейства функций. Это полезно иметь утечку дескрипторов файлов для случайных программ , управляемых например system().
FILE *), связанного с файловым дескриптором. Одно из правильных применений FD_CLOEXEC - закрыть файл журнала, который родительский процесс открыл при выполнении процесса оболочки. Обратите внимание, что в POSIX 2008 есть опцияopen(2)для O_CLOEXEC, поэтому вы можете установить это свойство при открытии файла, что будет очень полезно, когда он станет широко доступным.