close(2) System Calls Manual close(2) NAZWA close - zamyka deskryptor pliku BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int close(int fd); OPIS close() zamyka deskryptor pliku, tak ze nie odnosi sie on juz pozniej do zadnego pliku i moze byc uzyty ponownie. Wszelkie blokady na poziomie rekordu (zob. fcntl(2)) utrzymywane na pliku, z ktorymi deskryptor byl zwiazany, i ktorych wlascicielem byl proces, zostaja usuniete, niezaleznie od deskryptora plikow, ktorego uzyto dla uzyskanie blokady. Ma to pewne niefortunne skutki, dlatego nalezy byc szczegolnie ostroznym przy uzywaniu pomocniczego zakladania blokad na poziomie rekordow. W podreczniku fcntl(2) opisano ryzyka i konsekwencje oraz (prawdopodobnie preferowane) blokady opisu otwartego pliku (ang. open file description (OFD) lock). Jesli fd jest ostatnim deskryptorem pliku odnoszacego sie do podleglego opisu otwartego pliku (OFD, zob. open(2)), to zasoby zwiazane z opisem otwartego pliku zostaja zwolnione; jesli deskryptor pliku byl ostatnim odniesieniem do pliku, ktory usunieto za pomoca polecenia unlink(2), to plik jest kasowany. WARTOSC ZWRACANA close() w przypadku powodzenia zwraca zero. W razie wystapienia bledu zwracane jest -1 i ustawiana jest zmienna errno wskazujac na blad. BLEDY EBADF fd nie jest prawidlowym deskryptorem otwartego pliku. EINTR Funkcja close() zostala przerwana przez sygnal; zobacz signal(7). EIO Wystapil blad wejscia/wyjscia. ENOSPC EDQUOT W NFS, bledy te nie sa zwykle zglaszane wobec wobec pierwszego zapisu, ktory przekroczyl dostepna przestrzen dyskowa, lecz wobec kolejnego write(2), fsync(2) lub close(). Zob. UWAGI, aby dowiedziec sie dlaczego close() nie powinien byc powtarzany po wystapieniu bledu. STANDARDY POSIX.1-2008. HISTORIA POSIX.1-2001, SVr4, 4.3BSD. UWAGI Pomyslne zamkniecie nie gwarantuje, ze dane zostana pomyslnie zapisane na dysku, gdyz jadro uzywa bufora do opoznienia zapisow. Zwykle systemy plikow nie oprozniaja buforow przy zamykaniu pliku. Jesli istnieje potrzeba zapewnienia, aby dane zostaly zapisane fizycznie na nosniku, nalezy uzyc fsync(2) (zapis zalezy w tym momencie od wlasciwosci sprzetowych dysku). Znacznik deskryptora pliku zamknij-przy-wykonaniu moze byc uzyty do upewnienia sie, ze dany deskryptor pliku jest automatycznie zamkniety po pomyslnym execve(2); wiecej szczegolow w podreczniku fcntl(2). Procesy wielowatkowe i close() Prawdopodobnie nie jest roztropnie zamykac deskryptory pliku w chwili, gdy moga byc one uzywane przez wywolania systemowe w innych watkach tego samego procesu. Poniewaz deskryptora pliku mozna uzyc ponownie, istnieja pewne zawile sytuacje hazardu, ktore moga przyniesc pewnie nieprzewidziane skutku uboczne. Co wiecej, prosze rozwazyc nastepujacy scenariusz, gdy dwa watki przeprowadzaja operacje na tym samym deskryptorze pliku: (1) Jeden watek jest zablokowany w wywolaniu wejscia/wyjscia na deskryptorze pliku. Moze to byc na przyklad proba write(2) do zapelnionego potoku lub proba read(2) z gniazda strumieniowego, ktore aktualnie nie dysponuje danymi. (2) Inny watek zamyka deskryptor pliku. Zachowanie w takiej sytuacji rozni sie w roznych systemach. W niektorych, po zamknieciu deskryptora pliku, blokujace wywolanie systemowe natychmiast powroci z bledem. W Linuksie (i prawdopodobnie w niektorych innych systemach) zachowanie jest inne: blokujace wywolanie systemowe wejscia/wyjscia utrzymuje referencje do podleglego opisu otwartego pliku (OFD) i to odniesienie utrzymuje opis otwarty do momentu zakonczenia wywolania systemowego wejscia/wyjscia (zob. open(2) aby dowiedziec sie wiecej o opisach otwartego pliku). Z tego wzgledu, blokujace wywolanie systemowe w pierwszym watku moze sie pomyslnie zakonczyc po close() w drugim watku. Zajmowanie sie bledami zwroconymi przez close() Ostrozny programista sprawdzi wartosc zwracana przez close(), poniewaz moze sie zdarzyc, ze bledy wczesniejszej operacji write(2) zostana zgloszone jedynie przy konczacym close(), zwalniajacym opis otwartego pliku (OFD). Niesprawdzenie zwroconej podczas zamykania pliku wartosci moze doprowadzic do niesygnalizowanej utraty danych. Jest to obserwowane zwlaszcza w przypadku NFS i przy uzywaniu przydzialow dyskowych. Prosze jednak zauwazyc, ze zwrocenie bledu powinno byc uzywane jedynie do celow diagnostycznych (tj. jako ostrzezenie dla aplikacji, ze wciaz moze istniec oczekujace wejscie/wyjscie lub wejscie/wyjscie moglo sie nie powiesc) lub do celow zaradczych (np. ponowny zapis pliku lub utworzenie kopii). Ponowna proba wykonania close() po zwroceniu bledu nie jest wlasciwym zachowaniem, poniewaz moze to spowodowac zamkniecie uzytego ponownie deskryptora pliku z innego watku. Moze sie tak zdarzyc, poniewaz jadro Linux zawsze uwalnia deskryptor plikow wczesnie przy operacji zamykania, zwalniajac go do ponownego uzytku; kroki mogace zwrocic blad, takie jak oproznianie danych do systemu plikow lub urzadzenia, moga wystapic przy operacji zamykania jedynie pozniej. Wiekszosc innych implementacji zachowuje sie podobnie zamykajac deskryptor plikow zawsze (z wyjatkiem EBADF oznaczajacego, ze deskryptor pliku byl nieprawidlowy) nawet, gdy nastepnie zwroca blad przy powrocie z close(). POSIX.1 nie wypowiada sie obecnie na ten temat, ale istnieja plany nakazania tego zachowania w nastepnym glownym wydaniu standardu Ostrozny programista, chcacy posiasc informacje o bledach wejscia/wyjscia, moze poprzedzic close() wywolaniem do fsync(2). Blad EINTR jest poniekad szczegolnym przypadkiem. Odnosnie bledu EINTR norma POSIX.1-2008 wspomina: Jesli close() zostanie przerwane majacym byc przechwyconym sygnalem, ma zwrocic wartosc -1 z errno ustawionym na EINTR, a stan fildes jest nieokreslony. Zezwala to na zachowanie wystepujace w Linuksie i wielu innych implementacjach, gdzie, jak w przypadku innych bledow, jakie moze zwrocic close(), deskryptor pliku zostanie na pewno zamkniety. Istnieje jednak rowniez inna mozliwosc: ze implementacja zwroci blad EINTR i utrzyma otwarty deskryptor pliku (zgodnie z dokumentacja HP-UX, jego close() tak czyni). Wywolujacy musi wowczas uzyc close() ponownie, aby zamknac deskryptor pliku i aby uniknac wycieku deskryptora pliku. Ta rozbieznosc w implementacji czyni trudnosci przenosnym aplikacjom, poniewaz w wielu implementacjach close() nie musi byc ponownie wywolywane po bledzie EINTR, a w przynajmniej jednej, close() musi byc ponownie wywolane. Istnieja plany rozwiazania tej zagwozdki w nastepnym glownym wydaniu standardu POSIX.1. ZOBACZ TAKZE close_range(2), fcntl(2), fsync(2), open(2), shutdown(2), unlink(2), fclose(3) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Przemek Borys , Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.06 31 pazdziernika 2023 r. close(2)