Linux
2019-03-06
Aliases: pipe2(2), pipe2(2), pipe2(2), pipe2(2), pipe2(2), pipe2(2), pipe2(2), pipe2(2), pipe2(2), pipe2(2)
man-pages-ru
Russian man pages from the Linux Documentation Project
manpages-dev
Manual pages about using GNU/Linux for development
man-pages
Linux kernel and C library user-space interface documentation
ИМЯ
pipe, pipe2 - создаёт канал
ОБЗОР
#include <unistd.h>
/* На Alpha, IA-64, MIPS, SuperH и SPARC/SPARC64; смотрите ЗАМЕЧАНИЯ */ struct fd_pair { long fd[2]; }; struct fd_pair pipe();
/* На остальных архитектурах */ int pipe(int pipefd[2]);
#define _GNU_SOURCE /* Смотрите feature_test_macros(7) */ #include <fcntl.h> /* Определение констант O_* */ #include <unistd.h>
int pipe2(int pipefd[2], int flags);
ОПИСАНИЕ
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) из канала читает один пакет за раз. Заметим следующее:
|
|||||||
Старые ядра, которые не поддерживают этот флаг, возвращают ошибку EINVAL. | |||||||
Начиная с Linux 4.5, у файлового дескриптора канала возможно менять установку O_DIRECT с помощью fcntl(2). | |||||||
O_NONBLOCK | |||||||
Устанавливает флаг состояния файла O_NONBLOCK для открытого файлового описания, на которое ссылаются новые файловые дескрипторы. Использование данного флага делает ненужными дополнительные вызовы fcntl(2) для достижения того же результата. |
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, errno устанавливается в соответствующее значение, а pipefd не изменяется.
В Linux (и других системах) pipe() не изменяет pipefd при ошибке. Требование стандартизации этого поведения было добавлено в POSIX.1-2016. Системный вызов Linux pipe2() также не изменяет pipefd при ошибке.
ОШИБКИ
EFAULT | pipefd задан некорректно. |
EINVAL | (pipe2()) Некорректное значение flags. |
EMFILE | Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс. |
ENFILE | Достигнуто максимальное количество открытых файлов в системе. |
ENFILE | Достигнуто жёсткое пользовательское ограничение на выделение памяти для каналов и вызывающий не имеет дополнительных прав; смотрите pipe(7). |
ВЕРСИИ
Вызов pipe2() был добавлен в Linux начиная с версии 2.6.27; поддержка в glibc появилась начиная с версии 2.9.
ЗАМЕЧАНИЯ
SystemV ABI на некоторых архитектурах позволяет использовать более одного регистра для возврата нескольких значений; в нескольких архитектурах (Alpha, IA-64, MIPS, SuperH и SPARC/SPARC64) использована эта возможность для реализации системного вызова pipe() подобно функциям: вызов не использует параметры и при успешном выполнении возвращает пару файловых дескрипторов как результат. Обёрточная функция glibc pipe() учитывает это. Описание регистров хранения второго файлового дескриптора смотрите в syscall(2).
СООТВЕТСТВИЕ СТАНДАРТАМ
pipe(): POSIX.1-2001, POSIX.1-2008.
Вызов pipe2() есть только в Linux.
ПРИМЕР
Следующая программа создаёт канал, и затем выполняет fork(2) для создания потомка; потомок наследует скопированный набор файловых дескрипторов, которые указывают на тот же канал. После fork(2) каждый процесс закрывает файловые дескрипторы, которые ненужны каналу (см. pipe(7)). Затем родитель записывает строку, переданную в качестве аргумента командной строки, в канал, а потомок читает эту строку из канала по байту за раз, и выводит её на стандартный вывод.
Исходный код программы
#include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h>
int main(int argc, char *argv[]) {
int pipefd[2];
pid_t cpid;
char buf;
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr, "Использование: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
fprintf(stderr, "Использование: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Потомок читает из канала */
close(pipefd[1]); /* Закрывает неиспользуемый конец для записи */
close(pipefd[1]); /* Закрывает неиспользуемый конец для записи */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
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);
} }
close(pipefd[0]); /* Закрывает неиспользуемый конец для чтения */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Читатель видит EOF */
wait(NULL); /* Ожидание потомка */
exit(EXIT_SUCCESS);
} }
СМОТРИТЕ ТАКЖЕ
REFERENCED BY
eventfd(2), fork(2), getrlimit(2), socketpair(2), statfs(2), popen(3), capabilities(7), fifo(7), man-pages(7), pipe(7), inode(7), ksh(1), ksh93(1), iv_event_raw(3), PMDA(3), pmdaConnect(3), stat(2), fifo(4), __pmProcessClosePipe(3), sec(1), vlimit(3), eventtest(6), bosh(1), obosh(1), syscall(2), ksh2020(1)