118

I tried searching on the net, but there are hardly any resources. A small example would suffice.

EDIT I mean, two different C programs communicating with each other. One program should send "Hi" and the other should receive it. Something like that.

  • 1
    Presumably you don't mean something like `ls | grep ".o"`? Perhaps a bit more explanation of what you do mean would help... – Jerry Coffin May 06 '10 at 21:09
  • 14
    Come on man... a little effort. Google "c pipes example code". The first result is exact: http://tldp.org/LDP/lpg/node11.html – Stephen May 06 '10 at 21:12
  • 4
    I want communication between two completely different programs. I was not able to find a resource for that. –  May 06 '10 at 21:16
  • 1
    If you are not forking a process, then you need to look at "named pipes". – Judge Maygarden May 07 '10 at 13:49

7 Answers7

162

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 1024

int 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.

Community
  • 1
  • 1
jschmier
  • 15,458
  • 6
  • 54
  • 72
  • 6
    What is considered *related processes*? – Pithikos Aug 29 '14 at 18:00
  • 7
    Probably processes which are related via one or more parent/child relations (e.g. includes siblings). The common ancestor would have created the two ends of the pipe. Unrelated processes lack that common ancestor. – MSalters Nov 05 '14 at 15:58
  • 6
    This will not work if the reader kicks off first. A quick fix would be to put the `open()` of the reader inside a loop. However +1 because you provide a two programs example. – gsamaras Nov 15 '14 at 12:12
  • I take it this example needs some tweaking to work on windows? unistd.h being POSIX and all... – David Karlsson Mar 04 '15 at 12:01
  • Yes, it will need tweaking for Windows. The [Wikipedia article on named pipes](http://en.wikipedia.org/wiki/Named_pipe) discusses some of the Unix/Windows differences and a quick [Google search](http://www.google.com/search?q=Windows+named+pipe+MSDN) can help with the Windows implementation. – jschmier Mar 04 '15 at 16:46
  • @gsamaras hey man, how will we run this code I have no idea about socket programming, can you help me out? – Mohsin Sep 08 '16 at 19:08
  • I am sorry @Mohsin (great name!), but I haven't touched these for a while..I mean I barely remember how did I [answer this](http://stackoverflow.com/questions/26716255/why-does-this-program-print-forked-4-times/26716300#26716300), let alone sockets. Good luck! – gsamaras Sep 08 '16 at 19:10
  • @jschmier how will we exit from the continuous loop? I'm trying to implement between two functions once one of the functions sends the string and the other receives the string, it should exit. How can we do that? – Mohsin Sep 08 '16 at 19:47
  • Minor improvement: open calls block until the other side is open-ed. Might need " | O_NONBLOCK" in a real applications if they need to continue, do other things and read / write later, e.g. on a timer. – Aelian Jul 02 '18 at 14:51
  • Can we pass std::string variable as a parameter in read and write methods ? – goodman Oct 03 '19 at 15:03
43

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);
}
Isa A
  • 1,342
  • 13
  • 31
Stephen
  • 47,994
  • 7
  • 61
  • 70
  • 1
    Hey Stephen, anyway I can use this code for two different functions? meaning writing to the pipe is done in one function and reading the pipe in another function?? a working code like this would be appreciated. – Mohsin Sep 08 '16 at 15:40
8
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
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
mlouk
  • 81
  • 1
  • 1
6

What one program writes to stdout can be read by another via stdin. So simply, using c, write prog1 to print something using printf() and prog2 to read something using scanf(). Then just run

./prog1 | ./prog2
Johan
  • 5,003
  • 3
  • 36
  • 50
4

Here's a sample:

int main()
{
    char buff[1024] = {0};
    FILE* cvt;
    int status;
    /* Launch converter and open a pipe through which the parent will write to it */
    cvt = popen("converter", "w");
    if (!cvt)
    {
        printf("couldn't open a pipe; quitting\n");
        exit(1)
    }
    printf("enter Fahrenheit degrees: " );
    fgets(buff, sizeof (buff), stdin); /*read user's input */
    /* Send expression to converter for evaluation */
    fprintf(cvt, "%s\n", buff);
    fflush(cvt);
    /* Close pipe to converter and wait for it to exit */
    status=pclose(cvt);
    /* Check the exit status of pclose() */
    if (!WIFEXITED(status))
        printf("error on closing the pipe\n");
    return 0;
}

The important steps in this program are:

  1. The popen() call which establishes the association between a child process and a pipe in the parent.
  2. The fprintf() call that uses the pipe as an ordinary file to write to the child process's stdin or read from its stdout.
  3. The pclose() call that closes the pipe and causes the child process to terminate.
Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
  • I think this example misses the point of the question, although I grant that the "converter" program is a different program. The first comment addresses communication between completely independent programs that do not have a sibling/parent/second-cousin relationship. – cmm Mar 09 '15 at 16:19
2

First, have program 1 write the string to stdout (as if you'd like it to appear in screen). Then the second program should read a string from stdin, as if a user was typing from a keyboard. then you run:

$ program_1 | program_2
NAND
  • 663
  • 8
  • 22
lfagundes
  • 2,978
  • 5
  • 24
  • 25
2

This answer might be helpful for a future Googler.

#include <stdio.h>
#include <unistd.h>

int main(){     
     int p, f;  
     int rw_setup[2];   
     char message[20];      
     p = pipe(rw_setup);    
     if(p < 0){         
        printf("An error occured. Could not create the pipe.");  
        _exit(1);   
     }      
     f = fork();    
     if(f > 0){
        write(rw_setup[1], "Hi from Parent", 15);    
     }  
     else if(f == 0){       
        read(rw_setup[0],message,15);       
        printf("%s %d\n", message, r_return);   
     }  
     else{      
        printf("Could not create the child process");   
     }      
     return 0;

}

You can find an advanced two-way pipe call example here.

Anjana
  • 462
  • 2
  • 14