Co robi flaga FD_CLOEXEC fcntl ()?

82

Tak jak to:

Chociaż czytałem man fcntl, nie wiem, co to robi.

kompilacja-fan
źródło

Odpowiedzi:

74

Ustawia flagę close-on-exec dla deskryptora pliku, co powoduje, że deskryptor pliku jest automatycznie (i niepodzielnie) zamykany, gdy którykolwiek zexec funkcji -family powiedzie się.

Sprawdza również wartość zwracaną, aby sprawdzić, czy operacja się nie powiodła, co jest raczej bezużyteczne, jeśli deskryptor pliku jest prawidłowy, ponieważ nie ma warunku, w którym operacja ta powinna zakończyć się niepowodzeniem na poprawnym deskryptorze pliku.

R .. GitHub PRZESTAŃ POMÓC LODOWI
źródło
4
Zauważ, że nie robi to nic z opróżnianiem jakiegokolwiek pliku stream ( FILE *) związanego z deskryptorem pliku. Jednym z poprawnych zastosowań FD_CLOEXEC jest zamknięcie pliku dziennika, który został otwarty przez proces nadrzędny podczas wykonywania procesu powłoki. Zauważ, że POSIX 2008 ma opcję open(2)O_CLOEXEC - możesz więc ustawić tę właściwość podczas otwierania pliku, co będzie bardzo przydatne, gdy będzie powszechnie dostępny.
Jonathan Leffler
Niepodzielne ustawienie flagi podczas otwierania pliku jest bardzo istotne dla każdego programu z wątkami, który może otwierać pliki, podczas gdy inny wątek może wykonywać programy zewnętrzne. Niestety jest ona dostępna tylko na opennie accept, socket, pipe, itd ...
R .. GitHub przestali pomagać ICE
Tak - istnieją problemy projektowe podczas dodawania O_CLOEXEC lub odpowiednika do innych funkcji tworzących deskryptor plików (choć dup()i dup2()oczywiście nie ma to wpływu). Prawdopodobnie musiałbyś mieć nowe funkcje z dodatkowym parametrem „tryb” lub „flagi”, co prawdopodobnie jest powodem, dla którego tak się nie stało. Gdyby można było użyć O_CLOEXEC w gnieździe, można by przypuszczać, accept()że sklonowałoby tę flagę w zwracanym deskryptorze. Ale socket()i pipe()są trudniejsze.
Jonathan Leffler
3
dupi dup2są dotknięte. Flaga close-on-exec dotyczy deskryptorów plików, a nie opisów otwartych plików, więc nie jest współdzielona między zduplikowanymi deskryptorami plików. To bardzo dobra rzecz.
R .. GitHub PRZESTAŃ POMÓC NA LODZIE
3
Nawiązując do rozmowy w komentarzach, POSIX przyjęła do umieszczenia w następnym numerze nowych interfejsów, które naprawić niedociągnięcia: dup3, pipe2, i accept4. Również socketma SOCK_CLOEXECflagę można połączyć z żądanego typu gniazda.
R .. GitHub ZATRZYMAJ SIĘ NA LODZIE
33

Zaznacza deskryptor pliku tak, że będzie on close()automatycznie d, gdy proces lub jakiekolwiek elementy podrzędne, fork()które wywołuje, są jedną z exec*()rodziny funkcji. Jest to przydatne, aby zapobiec wyciekowi deskryptorów plików do przypadkowych programów uruchamianych przez np system().

geekozaur
źródło
Czy to dotyczy bezpieczeństwa?
zach.
1
@zach można tak powiedzieć; ale tak naprawdę każde dokonane przez Ciebie refaktoryzacje, takie jak hermetyzacja rozproszonej logiki w pojedynczej jednostce, można nazwać „problemem dotyczącym bezpieczeństwa”, ponieważ zmniejsza prawdopodobieństwo wystąpienia błędów spowodowanych niewłaściwym użyciem tej jednostki, a „błąd” jest rzeczą abstrakcyjną dotyczy to w szczególności segfaultów i wycieków informacji.
Hi-Angel,
Więc refaktoryzuję kod gniazda i między pobraniem gniazda i połączeniem z serwerem zdalnym używają F_SETFD, aby dodać flagę FD_CLOEXEC do FD gniazda. Następnie po udanym połączeniu FD_CLOEXEC jest usuwany. Nie mogę znaleźć żadnych wywołań exec () związanych z tym obszarem kodu i zastanawiam się, czy są to pozostałości starego kodu, który powinien zostać usunięty, a nie został. Nie jestem pewien, czego szukać, aby poznać cel tego wszystkiego.
JoeManiaci