pipe(7) Miscellaneous Information Manual pipe(7) NAZWA pipe - przeglad potokow i FIFO OPIS Potoki i FIFO (zwane rowniez potokami nazwanymi lub laczami nazwanymi) udostepniaja jednokierunkowy kanal komunikacji miedzyprocesowej. Potok ma koniec do odczytu oraz koniec do zapisu. Dane zapisane do konca do zapisu moga byc odczytane z konca do odczytu potoku. Potok tworzy sie za pomoca pipe(2), ktore tworzy nowy potok i zwraca dwa deskryptory plikow, jeden odnoszacy sie do konca do odczytu potoku, a drugi odnoszacy sie do konca do zapisu. Potokow mozna uzyc do utworzenia kanalu komunikacji pomiedzy powiazanymi procesami; zob. pipe(2) aby zapoznac sie z przykladem. FIFO (skrot od ang. First In First Out - pierwszy na wejsciu, pierwszy na wyjsciu) posiada nazwe w systemie plikow (utworzona za pomoca mkfifo(3)) i jest otwierany przy uzyciu open(2). Kazdy proces moze otworzyc FIFO, o ile uprawnienia pliku na to zezwalaja. Koniec do odczytu otwiera sie za pomoca znacznika O_RDONLY; koniec do zapisu, za pomoca O_WRONLY. Wiecej szczegolow w podreczniku fifo(7). Uwaga: Choc FIFO maja sciezke w systemie plikow, to wejscie/wyjscie na FIFO nie przeprowadza operacji na podleglym urzadzeniu (jesli takie istnieje). Wejscie/wyjscie na potokach i FIFO Jedyna roznica pomiedzy potokami i FIFO polega na sposobie ich tworzenia i otwierania. Po ukonczeniu tych zadan, wejscie/wyjscie na potokach i FIFO korzysta z dokladnie tej samej semantyki. Gdy proces sprobuje odczytac z pustego potoku, read(2) zablokuje do momentu pojawienia sie danych. Gdy proces sprobuje zapisac do pelnego potoku (zob. nizej), write(2) zablokuje do momentu odczytania wystarczajacej ilosci danych z potoku, umozliwiajacej poprawne przeprowadzenie zapisu. Nieblokujace wejscie/wyjscie mozna uzyskac za pomoca operacji F_SETFL fcntl(2), w celu wlaczenia znacznika statusu otwartego pliku O_NONBLOCK lub otwierajac fifo(7) z O_NONBLOCK. Jesli jakis proces otworzy potok do zapisu, odczyt zawiedzie z bledem EAGAIN; w innych przypadkach, przy braku potencjalnych zapisujacych, odczyt powiedzie sie i powroci pusty. Kanal udostepniany przez potok jest strumienien bajtow: nie wystepuje koncept granic komunikatow. Jesli wszystkie deskryptory pliku odnoszace sie do konca do zapisu potoku zostana zamkniete, to proba odczytu za pomoca read(2) z potoku przyniesie koniec-pliku (read(2) zwroci 0). Jesli wszystkie deskryptory pliku odnoszace sie do konca do odczytu zostana zamkniete, to zapis za pomoca write(2) spowoduje wygenerowanie sygnalu SIGPIPE dla wywolujacego procesu. Jesli proces wywolujacy zignoruje ten sygnal, to write(2) zawiedzie z bledem EPIPE. Aplikacje uzywajace pipe(2) i fork(2) powinny korzystac z odpowiednich wywolan close(2), aby zamykac niepotrzebnie zduplikowane deskryptory pliku; to zapewni, ze koniec-pliku i SIGPIPE/EPIPE sa dostarczane tam, gdzie to konieczne. Do potoku nie da sie zastosowac lseek(2). Pojemnosc potoku Potok ma ograniczona pojemnosc. Po zapelnieniu potoku, write(2) zablokuje lub zawiedzie, w zaleznosci od tego, czy znacznik O_NONBLOCK jest ustawiony (zob. nizej). Rozne implementacje posiadaja odmienne limity pojemnosci potoku. Aplikacje nie powinny zalezec od jakiejs okreslonej pojemnosci, lecz nalezy je zaprojektowac tak, aby konsumowaly dane tak wczesnie jak to mozliwe, w celu unikniecia blokowania procesu zapisujacego. Przed Linuksem 2.6.11, pojemnosc potoku byla taka sama jak systemowy rozmiar strony (np. 4096 bajtow na architekturze i386). Od Linuksa 2.6.11, pojemnosc potoku wynosi 16 stron (tj. 65 536 bajtow w systemie o rozmiarze strony 4096 bajtow). Od Linuksa 2.6.35, domyslny rozmiar potoku wynosi 16 stron, ale mozna go odpytac i ustawic za pomoca operacji F_GETPIPE_SZ i F_SETPIPE_SZ fcntl(2). Wiecej szczegolow w podreczniku fcntl(2). Nastepujaca operacja ioctl(2), ktora mozna zastosowac do deskryptora pliku, odnoszacego sie do dowolnego konca potoku, umieszcza licznik nieodczytanych bajtow w potoku, w buforze int wskazanym ostatnim argumentem wywolania: ioctl(fd, FIONREAD, &nbytes); Operacja FIONREAD nie jest przewidziana zadnym standardem, ale udostepnia ja wiele implementacji. Pliki /proc W Linuksie, nastepujace pliki kontroluja wielkosc pamieci, jaka mozna przeznaczyc potokom: /proc/sys/fs/pipe-max-pages (tylko w Linuksie 2.6.34) Gorny limit pojemnosci, podany w stronach, jaka nieuprzywilejowany uzytkownik (nieposiadajacy przywileju (ang. capability) CAP_SYS_RESOURCE), moze ustawic dla potoku. Domyslna wartosc tego limitu to szesnastokrotnosc domyslnego rozmiaru potoku (zob. wyzej); dolny limit to dwie strony. Interfejs ten usunieto w Linuksie 2.6.35, na korzysc /proc/sys/fs/pipe-max-size. /proc/sys/fs/pipe-max-size (od Linuksa 2.6.35) Maksymalny rozmiar (w bajtach) poszczegolnych potokow, jaki moze byc ustawiany przez uzytkownikow bez przywileju CAP_SYS_RESOURCE. Wartosc przypisana do tego pliku moze byc zaokraglona w gore, w uwzglednieniu wartosci uzytej faktycznie, ze wzgledu na wygode implementacji. Aby sprawdzic wartosc zaokraglona, nalezy wyswietlic wartosc tego pliku, po przypisaniu mu wartosci. Domyslna wartoscia pliku jest 1048576 (1 MiB). Minimalna wartoscia, jaka mozna przypisac do tego pliku, jest systemowy rozmiar strony. Proby ograniczenia limitu ponizej rozmiaru strony spowoduja niepowodzenie write(2) z bledem EINVAL. Od Linuksa 4.9, wartosc pliku dziala rowniez jako gorny, domyslny limit pojemnosci nowego potoku lub nowo otwartego FIFO. /proc/sys/fs/pipe-user-pages-hard (od Linuksa 4.5) Bezwzgledny limit calkowitego rozmiaru (w stronach) wszystkich potokow utworzonych lub ustawionych przez pojedynczego nieuprzywilejowanego uzytkownika (tzn. nieposiadajacego przywilejow CAP_SYS_RESOURCE ani CAP_SYS_ADMIN). Gdy calkowita liczba stron przypisanych do buforow potoku dla danego uzytkownika osiagnie tej limit, proby tworzenia nowych potokow beda odmawiane, a takze proby zwiekszenia rozmiaru potoku beda odmawiane. Gdy wartosc limitu wynosi zero (tak jest domyslnie), bezwzgledny limit nie obowiazuje. /proc/sys/fs/pipe-user-pages-soft (od Linuksa 4.5) Miekki limit calkowitego rozmiaru (w stronach) wszystkich potokow utworzonych lub ustawionych przez pojedynczego nieuprzywilejowanego uzytkownika (tzn. nieposiadajacego przywilejow CAP_SYS_RESOURCE ani CAP_SYS_ADMIN). Gdy calkowita liczba stron przypisanych do buforow potoku dla danego uzytkownika osiagnie tej limit, poszczegolne potoki tworzone przez uzytkownika beda ograniczone do jednej strony, a proby zwiekszenia rozmiaru potoku beda odmawiane. Gdy wartosc limitu wynosi zero, miekki limit nie obowiazuje. Domyslna wartoscia tego pliku jest 16384, co pozwala na tworzenie do 1024 potokow o domyslnym rozmiarze. Przed Linuksem 4.9 pewne bledy wplywaly na obsluge limitow pipe-user-pages-soft i pipe-user-pages-hard; zob. USTERKI. PIPE_BUF POSIX.1 okresla, ze zapis mniej niz PIPE_BUF bajtow musi byc niepodzielny: dane wyjsciowe sa zapisywane do potoku jako ciagla sekwencja. Zapis wiecej niz PIPE_BUF nie musi byc niepodzielny: jadro moze przeplatac dane, z danymi zapisywanymi przez inne procesy. POSIX.1 wymaga, aby PIPE_BUF mial co najmniej 512 bajtow (w Linuksie PIPE_BUF ma 4096 bajtow). Dokladna semantyka zalezy od tego, czy deskryptor pliku jest nieblokujacy (O_NONBLOCK), czy wystepuje wiele zapisow do potoku oraz od n, liczby bajtow do zapisania: O_NONBLOCK wylaczone, n <= PIPE_BUF Wszystkie n bajtow jest zapisane niepodzielnie; write(2) moze zablokowac, jesli brak miejsca do natychmiastowego zapisu n bajtow O_NONBLOCK wlaczone, n <= PIPE_BUF Jesli jest miejsce na zapisanie n bajtow do potoku, to write(2) natychmiast powiedzie sie, zapisujac wszystkie n bajtow; w przeciwnym wypadku write(2) zawodzi, z errno ustawionym na EAGAIN. O_NONBLOCK wylaczone, n > PIPE_BUF Zapis jest podzielny: dane przekazane do write(2) moga ulec przepleceniu z write(2) innych procesow; write(2) blokuje do momentu zapisania n bajtow. O_NONBLOCK wlaczone, n > PIPE_BUF Gdy potok jest pelny, write(2) zawiedzie z errno ustawionym na EAGAIN. W przeciwnym wypadku, zapisanych moze ulec od 1 do n bajtow (tzn. moze wystapic ,,czesciowy zapis", wywolujacy powinien sprawdzic wartosc zwrocona przez write(2), aby przekonac sie, jak wiele bajtow faktycznie zapisano), bajty te moga byc przeplatane z zapisami z innych procesow. Znaczniki statusu otwartego pliku Jedyne znaczniki statusu otwartego pliku, jakie mozna sensownie zastosowac do potoku lub FIFO to O_NONBLOCK i O_ASYNC. Ustawienie znacznika O_ASYNC na koncu do odczytu potoku powoduje wygenerowanie sygnalu (domyslnie SIGIO), gdy nowe wejscie stanie sie dostepne na potoku. Cel dostarczenia sygnalow nalezy ustawic za pomoca polecenia F_SETOWN fcntl(2). W Linuksie O_ASYNC jest obslugiwane w przypadku potokow i FIFO dopiero od Linuksa 2.6. Uwagi dotyczace przenosnosci W niektorych systemach (ale nie w Linuksie), potoki sa dwukierunkowe: dane moga byc transmitowane w obu kierunkach pomiedzy wezlami koncowymi. POSIX.1 wymaga jedynie potokow jednokierunkowych. Przenosne aplikacje powinny unikac polegania na semantyce potokow dwukierunkowych. USTERKI Przed Linuksem 4.9 wystepowaly pewne bledy dotyczace obslugi limitow pipe-user-pages-soft i pipe-user-pages-hard przy uzywaniu operacji F_SETPIPE_SZ fcntl(2) do zmiany rozmiaru potoku: (a) Przy zwiekszaniu rozmiaru potoku, sprawdzenia dotyczace limitow miekkich i bezwzglednych, czynione byly wobec istniejacej zajetosci i z wylaczeniem pamieci wymaganej do zwiekszenia pojemnosci potoku. Nowo powiekszona pojemnosc potoku mogla wykroczyc (nawet znacznie) poza calkowita pamiec uzywana przez potoki uzytkownika (moglo to rowniez wyzwolic problem opisany jako nastepny). Od Linuksa 4.9, sprawdzenia limitow wliczaja pamiec potrzebna do nowej pojemnosci potoku. (b) Sprawdzenia limitow dokonywano nawet wowczas, gdy nowa pojemnosc potokow byla nizsza niz istniejaca. Moglo to prowadzic do problemow, gdy uzytkownik ustawil znaczna pojemnosc potoku, a nastepnie limity ograniczono, co powodowalo, ze uzytkownik nie mogl juz zmniejszyc pojemnosci potoku. Od Linuksa 4.9, sprawdzenia limitow nastepuja tylko przy zwiekszaniu pojemnosci potoku; uzytkownik nieuprzywilejowany moze zawsze zmniejszyc pojemnosc potoku. (c) Wyliczanie i sprawdzanie limitow odbywalo sie w nastepujacy sposob: (1) Sprawdzenie, czy uzytkownik przekroczyl limit. (2) Utworzenie nowego przydzielenia buforu potoku. (3) Wyliczenie nowego przydzielenia wobec limitow. Byla to sytuacja sprzyjajaca hazardowi. Punkt (1) moglo przekroczyc jednoczesnie wiele procesow, a przydzielone nastepnie bufory potoku byly wyliczane jedynie w kroku (3), co moglo prowadzic do przekroczenia limitu przez przydzielony bufor potoku uzytkownika. Od Linuksa 4.9, krok wyliczania jest dokonywany przed przydzieleniem, a operacja zawodzi, gdy limit mialby byc przekroczony. Przed Linuksem 4.9, bledy podobne do opisanych w punktach (a) i (c) mogly wystepowac rowniez przy przydzielaniu przez jadro pamieci buforowi nowego potoku tj. przy wywolywaniu pipe(2) i przy otwieraniu uprzednio nieotwartego FIFO. ZOBACZ TAKZE mkfifo(1), dup(2), fcntl(2), open(2), pipe(2), poll(2), select(2), socketpair(2), splice(2), stat(2), tee(2), vmsplice(2), mkfifo(3), epoll(7), fifo(7) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: 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. pipe(7)