Що робить прапор FD_CLOEXEC fcntl ()?


82

Подобається так:

Хоча я читав man fcntl, я не можу зрозуміти, що це робить.

Відповіді:


74

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

Він також перевіряє значення, що повертається, щоб перевірити, чи не вдалася операція, що є досить марним, якщо дескриптор файлу є дійсним, оскільки немає жодної умови, за якої ця операція повинна провалитися з дійсним дескриптором файлу.


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зазнають впливу. Прапор close-on-exec застосовується до дескрипторів файлів, а не до відкритих описів файлів, тому він не ділиться між дубльованими дескрипторами файлів. Це дуже добре.
R .. GitHub СТОП ДОПОМОГАЙ ЛЕД

3
Слідом за розмову в коментарях, POSIX прийнятий для включення в наступному випуску нових інтерфейсів , які фіксують недоліки: dup3, pipe2і accept4. Крім того, socketє SOCK_CLOEXECпрапор, який ви можете поєднувати із запитуваним типом сокета.
R .. GitHub СТОП ДОПОМОГАЙ ЛЕДІ

33

Він позначає дескриптор файлу таким чином, що він автоматично буде close()d, коли процес або будь-яка дочка, яку він fork()викликає, із exec*()сімейства функцій. Це корисно, щоб уникнути витоку дескрипторів файлів до випадкових програм, що запускаються, наприклад system().


Це проблема безпеки?
zach

1
@zach можна так сказати; але тоді насправді будь-який рефакторинг, який ви робите, як інкапсуляція розсіяної логіки до однієї сутності, можна назвати "проблемою безпеки", оскільки він зменшує ймовірність помилок через неправильне використання цієї сутності, а "помилка" - абстрактна річ що включає, зокрема, сегментаційні помилки та витік інформації.
Hi-Angel,

Отже, я переробляю деякий код сокета, і між отриманням сокета та підключенням (віддаленим сервером) вони використовують F_SETFD, щоб додати прапор FD_CLOEXEC до FD сокета. Потім після успішного підключення FD_CLOEXEC видаляється. Я не можу знайти жодних викликів exec (), які беруть участь у цій області коду, і мені цікаво, чи це залишки старого коду, які слід було видалити, але ні. Не знаю, на що звертати увагу, щоб з’ясувати мету всього цього.
JoeManiaci
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.