table of contents
pipe(2) | System Calls Manual | pipe(2) |
NAZWA¶
pipe, pipe2 - tworzy potok
BIBLIOTEKA¶
Standardowa biblioteka C (libc, -lc)
SKŁADNIA¶
#include <unistd.h>
int pipe(int pipefd[2]);
#define _GNU_SOURCE /* Zob. feature_test_macros(7) */ #include <fcntl.h> /* Definicja stałych O_* */ #include <unistd.h>
int pipe2(int pipefd[2], int flags);
/* Na Alpha, IA-64, MIPS, SuperH i SPARC/SPARC64, pipe() ma poniższy
prototyp; zob. WERSJE */
#include <unistd.h>
struct fd_pair { long fd[2]; }; struct fd_pair pipe(void);
OPIS¶
pipe() tworzy potok, jednokierunkowy kanał danych, służący do komunikacji między procesami. Tablica pipefd służy do zwrócenia dwóch deskryptorów pliku odnoszących się do końców potoku. pipefd[0] odnosi się do końca do odczytu. pipefd[1] odnosi się do końca do zapisu. Dane zapisywane do końca do zapisu potoku są buforowane przez jądro, do momentu ich odczytania z końca do odczytu potoku. Więcej szczegółów opisano w podręczniku pipe(7).
Jeśli flags ma wartość 0, to pipe2() jest równoważne pipe(). We flags można określić sumę bitową (OR) poniższych wartości, aby uzyskać odmienne zachowanie:
- O_CLOEXEC
- Ustawia znacznik zamknij-przy-wykonaniu (close-on-exec; FD_CLOEXEC) na dwóch nowych deskryptorach pliku. Powody, dla których może być to przydatne, wskazano w opisie tego samego znacznika w podręczniku open(2).
- O_DIRECT (od Linuksa 3.4)
- Tworzy potok, który przeprowadza wejście/wyjście w trybie „pakietowym”. Każdy zapis (write(2)) do potoku jest traktowany jako oddzielny pakiet, a odczyt (read(2)) z potoku odczyta jednocześnie pojedynczy pakiet. Proszę zauważyć, że:
- •
- Zapis więcej niż PIPE_BUF bajtów (zob. pipe(7)) zostanie podzielony na kilka pakietów. Stała PIPE_BUF jest zdefiniowana w <limits.h>.
- •
- Jeśli odczyt (read(2)) określi rozmiar bufora mniejszy niż następny pakiet, to odczytywana jest żądana liczba bajtów, a dodatkowe bajty pakietu są odrzucane. Podanie rozmiar bufora w wielkości PIPE_BUF wystarczy do odczytu nawet największych możliwych pakietów (zob. poprzedni punkt).
- •
- Pakiety zerowej długości nie są obsługiwane (odczyt — read(2), określający rozmiar bufora na zero, będzie instrukcją pustą i zwróci 0).
- Starsze jądra, które nie obsługują tego znacznika, zasygnalizują ten fakt za pomocą błędu EINVAL.
- Od Linuksa 4.5, można zmienić ustawienie O_DIRECT deskryptora pliku potoku za pomocą fcntl(2).
- O_NONBLOCK
- Ustawia znacznik stanu pliku O_NONBLOCK na opisach otwartego pliku (OFD), na które wskazują deskryptory nowych plików. Można w ten sposób oszczędzić sobie dodatkowych wywołań do fcntl(2), uzyskując ten sam rezultat.
- O_NOTIFICATION_PIPE
- Od Linuksa 5.8, wokół potoków zbudowano ogólny mechanizm powiadomień, w którym jądro wplata komunikaty z powiadomieniami do potoków otwartych przez przestrzeń użytkownika. Właściciel potoku musi przekazać jądru, jakie źródło zdarzeń ma obserwować oraz jakie filtry mają być zastosowane, w celu wybrania zdarzeń podrzędnych, które mają być umieszczone w potoku.
WARTOŚĆ ZWRACANA¶
Po pomyślnym zakończeniu zwracane jest zero. W przypadku błędu zwracane jest -1 i ustawiane errno wskazując błąd, a pipefd pozostaje bez zmian.
W Linuksie (i innych systemach), pipe() nie modyfikuje pipefd w przypadku błędu. Wymaganie standaryzujące to zachowanie dodano w normie POSIX.1-2008 TC2. Typowo linuksowe wywołanie systemowe pipe2() również nie modyfikuje pipefd w przypadku błędu.
BŁĘDY¶
- EFAULT
- pipefd jest nieprawidłowy.
- EINVAL
- (pipe2()) Nieprawidłowa wartość we flags.
- EMFILE
- Zostało osiągnięte ograniczenie na liczbę otwartych deskryptorów plików dla procesu.
- ENFILE
- Zostało osiągnięte systemowe ograniczenie na całkowitą liczbę otwartych plików.
- ENFILE
- Osiągnięto bezwzględny limit pamięci jaką można przydzielić potokom, a wywołujący nie jest uprzywilejowany, zob. pipe(7).
- ENOPKG
- (pipe2()) We flags podano O_NOTIFICATION_PIPE, a obsługa powiadomień (CONFIG_WATCH_QUEUE) nie została wbudowana w jądro.
WERSJE¶
ABI Systemu V na niektórych architekturach umożliwia używanie więcej niż jednego rejestru, w celu zwracania kilku wartości; wiele architektur (w tym Alpha, IA-64, MIPS, SuperH i SPARC/SPARC64) (nad)używa tej funkcjonalności w celu implementacji wywołania systemowego pipe() w sposób funkcyjny: wywołanie nie przyjmuje żadnych argumentów i zwraca parę deskryptorów pliku w przypadku powodzenia. Funkcja opakowująca pipe() z glibc radzi sobie z tym w sposób przezroczysty. Podręcznik syscall(2) zawiera więcej informacji na temat rejestrów używanych do przechowywania drugiego deskryptora pliku.
STANDARDY¶
HISTORIA¶
PRZYKŁADY¶
Poniższy program tworzy potok, następnie tworzy nowy proces potomny za pomocą fork(2); potomek dziedziczy zduplikowany zestaw deskryptorów pliku, odnoszący się do tego samego potoku. Po wykonaniu fork(2), każdy proces zamyka deskryptory pliku, które nie są potrzebne potokowi (zob. pipe(7)). Rodzic zapisuje następnie łańcuch zawierający argumenty wiersza poleceń programu do potoku, a potomek odczytuje ten łańcuch z potoku bajt po bajcie i wypisuje go na standardowe wyjście.
Kod źródłowy programu¶
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int main(int argc, char *argv[]) {
int pipefd[2];
char buf;
pid_t cpid;
if (argc != 2) {
fprintf(stderr, "Użycie: %s <łańcuch>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Potomek odczytuje z potoku */
close(pipefd[1]); /* Zamknięcie nieużywanego końca do zapisu */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* Rodzic zapisuje argv[1] do potoku */
close(pipefd[0]); /* Zamkn. nieuż. końca do odczytu */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Czytający zobaczy EOF */
wait(NULL); /* Czekanie na potomka */
exit(EXIT_SUCCESS);
} }
ZOBACZ TAKŻE¶
fork(2), read(2), socketpair(2), splice(2), tee(2), vmsplice(2), write(2), popen(3), pipe(7)
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.
2 maja 2024 r. | Linux man-pages (niewydane) |