Provided by: manpages-ru-dev_4.19.0-7_all bug

ИМЯ

       pipe, pipe2 - создаёт канал

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <unistd.h>

       int pipe(int pipefd[2]);

       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <fcntl.h>              /* Definition of O_* constants */
       #include <unistd.h>

       int pipe2(int pipefd[2], int flags);

       /* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64, pipe() has the
          following prototype; see NOTES */

       #include <unistd.h>

       struct fd_pair {
       long fd[2];
       };
       struct fd_pair pipe(void);

ОПИСАНИЕ

       pipe()   создаёт   однонаправленный   канал   данных,   который   можно  использовать  для
       взаимодействия между процессами. Массив pipefd используется  для  возврата  двух  файловых
       описателей,  указывающих  на концы канала. pipefd[0] указывает на конец канала для чтения.
       pipefd[1] указывает на конец  канала  для  записи.  Данные,  записанные  в  конец  канала,
       буферизируются  ядром  до  тех  пор,  пока  не будут прочитаны из конца канала для чтения.
       Подробней см. pipe(7).

       Если flags равно 0, то pipe2() выполняет то же что и pipe(). Следующие значения могут быть
       побитово сложены в flags для получения различного поведения:

       O_CLOEXEC
              Устанавливает  флаг  close-on-exec  (FD_CLOEXEC)  для  двух новых открытых файловых
              дескрипторов. Смотрите описание того же флага в open(2) для того, чтобы узнать  как
              это может пригодиться.

       O_DIRECT (начиная с Linux 3.4)
              Создаёт  канал,  в  котором  ввод-вывод  выполняется  в  «пакетном»  режиме. Каждый
              write(2) в канал рассматривается как отдельный пакет, а read(2)  из  канала  читает
              один пакет за раз. Заметим следующее:

              •  Запись  более  PIPE_BUF  байт  (смотрите  pipe(7))  будет разделена на несколько
                 пакетов. Константа PIPE_BUF определена в <limits.h>.

              •  Если в read(2) указан размер буфера меньше  чем  следующий  пакет,  то  читается
                 запрашиваемое  количество  байт,  а  лишние байты пакета отбрасываются. Указание
                 PIPE_BUF в качестве размера буфера будет достаточно  для  чтения  самых  больших
                 пакетов (смотрите предыдущее примечание).

              •  Пакеты  нулевой длины не поддерживаются (вызов read(2) с нулевым размером буфера
                 ничего не делает и возвращает 0).

              Старые ядра, которые не поддерживают этот флаг, возвращают ошибку EINVAL.

              Начиная с Linux 4.5, у  файлового  дескриптора  канала  возможно  менять  установку
              O_DIRECT с помощью fcntl(2).

       O_NONBLOCK
              Устанавливает  флаг состояния файла O_NONBLOCK для открытого файлового описания, на
              которое ссылаются новые файловые дескрипторы. Использование  данного  флага  делает
              ненужными дополнительные вызовы fcntl(2) для достижения того же результата.

       O_NOTIFICATION_PIPE
              Since  Linux  5.8,  general  notification mechanism is built on the top of the pipe
              where kernel splices notification messages into pipes opened by  user  space.   The
              owner  of  the  pipe  has  to  tell the kernel which sources of events to watch and
              filters can also be applied to select which subevents should  be  placed  into  the
              pipe.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       On  success,  zero  is  returned.   On error, -1 is returned, errno is set to indicate the
       error, and pipefd is left unchanged.

       В  Linux  (и  других  системах)  pipe()  не  изменяет  pipefd   при   ошибке.   Требование
       стандартизации  этого  поведения  было добавлено в POSIX.1-2008 TC2. Системный вызов Linux
       pipe2() также не изменяет pipefd при ошибке.

ОШИБКИ

       EFAULT pipefd задан некорректно.

       EINVAL (pipe2())  Некорректное значение flags.

       EMFILE Было  достигнуто  ограничение  по  количеству  открытых  файловых  дескрипторов  на
              процесс.

       ENFILE Достигнуто максимальное количество открытых файлов в системе.

       ENFILE Достигнуто  жёсткое  пользовательское ограничение на выделение памяти для каналов и
              вызывающий не имеет дополнительных прав; смотрите pipe(7).

       ENOPKG (pipe2())  O_NOTIFICATION_PIPE was passed in flags and  support  for  notifications
              (CONFIG_WATCH_QUEUE)  is not compiled into the kernel.

ВЕРСИИ

       pipe2()  was added in Linux 2.6.27; glibc support is available starting with glibc 2.9.

СТАНДАРТЫ

       pipe(): POSIX.1-2001, POSIX.1-2008.

       Вызов pipe2() есть только в Linux.

ЗАМЕЧАНИЯ

       System  V  ABI  на некоторых архитектурах позволяет использовать более одного регистра для
       возврата нескольких значений; в нескольких архитектурах  (Alpha,  IA-64,  MIPS,  SuperH  и
       SPARC/SPARC64)  использована  эта  возможность  для  реализации  системного  вызова pipe()
       подобно функциям: вызов не использует параметры и при успешном выполнении возвращает  пару
       файловых  дескрипторов  как  результат.  Обёрточная  функция  glibc  pipe() учитывает это.
       Описание регистров хранения второго файлового дескриптора смотрите в  syscall(2).

ПРИМЕРЫ

       Следующая программа создаёт канал, и затем выполняет fork(2) для создания потомка; потомок
       наследует  скопированный  набор  файловых дескрипторов, которые указывают на тот же канал.
       После fork(2) каждый процесс закрывает файловые дескрипторы, которые ненужны  каналу  (см.
       pipe(7)).  Затем  родитель  записывает  строку,  переданную в качестве аргумента командной
       строки, в канал, а потомок читает эту строку из канала по байту за раз, и  выводит  её  на
       стандартный вывод.

   Исходный код программы
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.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, "Использование: %s <string>\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) {    /* Потомок читает из канала */
               close(pipefd[1]);          /* Закрывает неиспользуемый конец для записи */

               while (read(pipefd[0], &buf, 1) > 0)
                   write(STDOUT_FILENO, &buf, 1);

               write(STDOUT_FILENO, "\n", 1);
               close(pipefd[0]);
               _exit(EXIT_SUCCESS);

           } else {            /* Родитель пишет значение argv[1] в канал */
               close(pipefd[0]);          /* Закрывает неиспользуемый конец для чтения */
               write(pipefd[1], argv[1], strlen(argv[1]));
               close(pipefd[1]);          /* Читатель видит EOF */
               wait(NULL);                /* Ожидание потомка */
               exit(EXIT_SUCCESS);
           }
       }

СМ. ТАКЖЕ

       fork(2),  read(2),  socketpair(2),  splice(2),  tee(2),  vmsplice(2),  write(2), popen(3),
       pipe(7)

ПЕРЕВОД

       Русский  перевод  этой  страницы  руководства   был   сделан   Alexey,   Azamat   Hackimov
       <azamat.hackimov@gmail.com>,   kogamatranslator49  <r.podarov@yandex.ru>,  Kogan,  Max  Is
       <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.