Linux pipe example c

How to use pipe function in C language

A pipe is a medium for communication between processes. One process writes data to the pipe, and another process reads the data from the pipe. In this article, we will see how the pipe() function is used to implement the concept using C language.

About Pipe

In the pipe, the data is maintained in a FIFO order, which means writing data to one end of the pipe sequentially and reading data from another end of the pipe in the same sequential order.

If any process reads from the pipe, but no other process has not written to the pipe yet, then read returns end-of-file. If a process wants to write to a pipe, but there is no other process attached to the pipe for reading, then this is an error condition, and the pipe generates a SIGPIPE signal.

Header File

Arguments

This function takes a single argument, an array of two integers (filedes). filedes[0] is used for reading from the pipe, and filedes[1] is used for writing to the pipe. The process which wants to read from the pipe should close filedes[1], and the process which wants to write to the pipe should close filedes[0]. If the unnecessary ends of the pipe are not explicitly closed, then end-of-file(EOF) will never be returned.

Return values

On success, the pipe() returns 0, for failure the function returns -1.

Pictorially, we can represent the pipe() function as follows:

Below are a few examples depicting how to use the pipe function in C language.

Example1

In this example, we will see how the pipe function works. Though using a pipe in a single process is not very useful, but we will get an idea.

int main ( )
{
int n ;
int filedes [ 2 ] ;
char buffer [ 1025 ] ;
char * message = «Hello, World!» ;

pipe ( filedes ) ;
write ( filedes [ 1 ] , message , strlen ( message ) ) ;

if ( ( n = read ( filedes [ 0 ] , buffer , 1024 ) ) >= 0 ) {
buffer [ n ] = 0 ; //terminate the string
printf ( «read %d bytes from the pipe: » % s » \n » , n , buffer ) ;
}
else
perror ( «read» ) ;
exit ( 0 ) ;
}

Here we have first created a pipe using pipe() function then written to the pipe using fildes[1] end. Then, the data has been read using the other end of the pipe, which is filedes[0]. For reading and writing to the file, we used to read() and write() functions.

Читайте также:  Arch linux btrfs install

Example2

In this example, we will see how parent and child processes communicate using the pipe.

int main ( )
{
int filedes [ 2 ] , nbytes ;
pid_t childpid ;
char string [ ] = «Hello, world! \n » ;
char readbuffer [ 80 ] ;

if ( ( childpid = fork ( ) ) == — 1 )
{
perror ( «fork» ) ;
exit ( 1 ) ;
}

if ( childpid == 0 )
{
close ( filedes [ 0 ] ) ; //Child process does not need this end of the pipe

/* Send «string» through the output side of pipe */
write ( filedes [ 1 ] , string , ( strlen ( string ) + 1 ) ) ;
exit ( 0 ) ;
}
else
{
/* Parent process closes up output side of pipe */
close ( filedes [ 1 ] ) ; //Parent process does not need this end of the pipe

/* Read in a string from the pipe */
nbytes = read ( filedes [ 0 ] , readbuffer , sizeof ( readbuffer ) ) ;
printf ( «Read string: %s» , readbuffer ) ;
}

First, one pipe has been created using pipe function then a child process has been forked. Then, the child process closes the read end and writes to the pipe. The parent process closes the write end and reads from the pipe and displays it. Here data flow is only one way that is from child to parent.

Conclusion:

pipe() is a powerful system call in Linux. In this article, we have seen only one-way data flow, one process writes, and another process reads, creating two pipes we can achieve bi-directional data flow also.

About the author

Bamdeb Ghosh

Bamdeb Ghosh is having hands-on experience in Wireless networking domain.He’s an expert in Wireshark capture analysis on Wireless or Wired Networking along with knowledge of Android, Bluetooth, Linux commands and python. Follow his site: wifisharks.com

Источник

Linux pipe example c

The primitive for creating a pipe is the pipe function. This creates both the reading and writing ends of the pipe. It is not very useful for a single process to use a pipe to talk to itself. In typical use, a process creates a pipe just before it forks one or more child processes (see Creating a Process). The pipe is then used for communication either between the parent or child processes, or between two sibling processes.

The pipe function is declared in the header file unistd.h .

Function: int pipe (int filedes [2])

Preliminary: | MT-Safe | AS-Safe | AC-Safe fd | See POSIX Safety Concepts.

The pipe function creates a pipe and puts the file descriptors for the reading and writing ends of the pipe (respectively) into filedes [0] and filedes [1] .

An easy way to remember that the input end comes first is that file descriptor 0 is standard input, and file descriptor 1 is standard output.

Читайте также:  What is job control in linux

If successful, pipe returns a value of 0 . On failure, -1 is returned. The following errno error conditions are defined for this function:

The process has too many files open.

There are too many open files in the entire system. See Error Codes, for more information about ENFILE . This error never occurs on GNU/Hurd systems.

Here is an example of a simple program that creates a pipe. This program uses the fork function (see Creating a Process) to create a child process. The parent process writes data to the pipe, which is read by the child process.

#include #include #include #include /* Read characters from the pipe and echo them to stdout. */ void read_from_pipe (int file) < FILE *stream; int c; stream = fdopen (file, "r"); while ((c = fgetc (stream)) != EOF) putchar (c); fclose (stream); >/* Write some random text to the pipe. */ void write_to_pipe (int file) < FILE *stream; stream = fdopen (file, "w"); fprintf (stream, "hello, world!\n"); fprintf (stream, "goodbye, world!\n"); fclose (stream); >int main (void) < pid_t pid; int mypipe[2];

/* Create the pipe. */ if (pipe (mypipe))

/* Create the child process. */ pid = fork (); if (pid == (pid_t) 0) < /* This is the child process. Close other end first. */ close (mypipe[1]); read_from_pipe (mypipe[0]); return EXIT_SUCCESS; > else if (pid < (pid_t) 0) < /* The fork failed. */ fprintf (stderr, "Fork failed.\n"); return EXIT_FAILURE; > else < /* This is the parent process. Close other end first. */ close (mypipe[0]); write_to_pipe (mypipe[1]); return EXIT_SUCCESS; > >

Источник

Linux pipe example c

#include
int pipe(int pipefd[2]);
#define _GNU_SOURCE /* Смотрите feature_test_macros(7) */
#include /* Определение констант O_* */
#include
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) из канала читает один пакет за раз. Заметим следующее: * Запись более PIPE_BUF байт (смотрите pipe(7)) будет разделена на несколько пакетов. Константа PIPE_BUF определена в . * Если в read(2) указан размер буфера меньше чем следующий пакет, то читается запрашиваемое количество байт, а лишние байты пакета отбрасываются. Указание PIPE_BUF в качестве размера буфера будет достаточно для чтения самых больших пакетов (смотрите предыдущее примечание). * Пакеты нулевой длины не поддерживаются (вызов read(2) с нулевым размером буфера ничего не делает и возвращает 0). Старые ядра, которые не поддерживают этот флаг, возвращают ошибку EINVAL. O_NONBLOCK Устанавливает флаг состояния файла O_NONBLOCK для двух новых открытых файловых дескрипторов. Использование данного флага заменяет дополнительные вызовы fcntl(2) для достижения того же результата.

Читайте также:  Linux удалить строку до символа

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

При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

EFAULT pipefd задан некорректно. EINVAL (pipe2()) Некорректное значение flags. EMFILE Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс. ENFILE Достигнуто максимальное количество открытых файлов в системе.

ВЕРСИИ

Вызов pipe2() был добавлен в Linux начиная с версии 2.6.27; поддержка в glibc появилась начиная с версии 2.9.

СООТВЕТСТВИЕ СТАНДАРТАМ

ПРИМЕР

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

Исходный код программы

#include #include #include #include #include #include int main(int argc, char *argv[]) < int pipefd[2]; pid_t cpid; char buf; if (argc != 2) < fprintf(stderr, "Использование: %s \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); >>

Источник

Оцените статью
Adblock
detector