How to send a simple string between two programs using pipes?
A regular pipe can only connect two related processes. It is created by a process and will vanish when the last process closes it.
A named pipe, also called a FIFO for its behavior, can be used to connect two unrelated processes and exists independently of the processes; meaning it can exist even if no one is using it. A FIFO is created using the mkfifo()
library function.
Example
writer.c
#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>int main(){ int fd; char * myfifo = "/tmp/myfifo"; /* create the FIFO (named pipe) */ mkfifo(myfifo, 0666); /* write "Hi" to the FIFO */ fd = open(myfifo, O_WRONLY); write(fd, "Hi", sizeof("Hi")); close(fd); /* remove the FIFO */ unlink(myfifo); return 0;}
reader.c
#include <fcntl.h>#include <stdio.h>#include <sys/stat.h>#include <unistd.h>#define MAX_BUF 1024int main(){ int fd; char * myfifo = "/tmp/myfifo"; char buf[MAX_BUF]; /* open, read, and display the message from the FIFO */ fd = open(myfifo, O_RDONLY); read(fd, buf, MAX_BUF); printf("Received: %s\n", buf); close(fd); return 0;}
Note: Error checking was omitted from the above code for simplicity.
From Creating Pipes in C, this shows you how to fork a program to use a pipe. If you don't want to fork(), you can use named pipes.
In addition, you can get the effect of prog1 | prog2
by sending output of prog1
to stdout and reading from stdin
in prog2
. You can also read stdin by opening a file named /dev/stdin
(but not sure of the portability of that).
/***************************************************************************** Excerpt from "Linux Programmer's Guide - Chapter 6" (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: pipe.c *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>int main(void){ int fd[2], nbytes; pid_t childpid; char string[] = "Hello, world!\n"; char readbuffer[80]; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } if(childpid == 0) { /* Child process closes up input side of pipe */ close(fd[0]); /* Send "string" through the output side of pipe */ write(fd[1], string, (strlen(string)+1)); exit(0); } else { /* Parent process closes up output side of pipe */ close(fd[1]); /* Read in a string from the pipe */ nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); printf("Received string: %s", readbuffer); } return(0);}
dup2( STDIN_FILENO, newfd )
And read:
char reading[ 1025 ];int fdin = 0, r_control;if( dup2( STDIN_FILENO, fdin ) < 0 ){ perror( "dup2( )" ); exit( errno );}memset( reading, '\0', 1025 );while( ( r_control = read( fdin, reading, 1024 ) ) > 0 ){ printf( "<%s>", reading ); memset( reading, '\0', 1025 );}if( r_control < 0 ) perror( "read( )" ); close( fdin );
But, I think that fcntl
can be a better solution
echo "salut" | code