Подобається так:
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зазнають впливу. Прапор close-on-exec застосовується до дескрипторів файлів, а не до відкритих описів файлів, тому він не ділиться між дубльованими дескрипторами файлів. Це дуже добре.
dup3, pipe2і accept4. Крім того, socketє SOCK_CLOEXECпрапор, який ви можете поєднувати із запитуваним типом сокета.
Він позначає дескриптор файлу таким чином, що він автоматично буде close()d, коли процес або будь-яка дочка, яку він fork()викликає, із exec*()сімейства функцій. Це корисно, щоб уникнути витоку дескрипторів файлів до випадкових програм, що запускаються, наприклад system().
FILE *), пов’язаного з дескриптором файлу. Одним дійсним використанням FD_CLOEXEC є закриття файлу журналу, який батьківський процес відкрив під час виконання процесу оболонки. Зверніть увагу, що POSIX 2008 має опціюopen(2)для O_CLOEXEC - тому ви можете встановити цю властивість під час відкриття файлу, що буде дуже корисно, коли він стане широко доступним.