simple pipe

Posted on 2004-11-11
Last Modified: 2008-02-01
I have got the below code and is working fine!!!
Example of running the below program is
$> ./a.out who less

Basically my code does the same as "who | less"

My Question
if I change
    if ( pid > 0 ){         /* parent will exec av[2]   */
    if ( pid == 0 ){         /* child will exec av[2]   */
then everything will go haywire!


/* pipe.c      
 *  * Demonstrates how to create a pipeline from one process to another
 *  * Takes two args, each a command, and connects
 *    av[1]'s output to input of av[2]
 *  * usage: pipe command1 command2
 *    effect: command1 | command2
 *  * Limitations: commands do not take arguments
 *  * uses execlp() since known number of args
 *  * Note: exchange child and parent and watch fun
#include    <stdio.h>
#include    <unistd.h>

#define oops(m,x)   { perror(m); exit(x); }

main(int ac, char **av)
    int thepipe[2],         /* two file descriptors */
        newfd,              /* useful for pipes */
        pid;                /* and the pid      */

    if ( ac != 3 ){
        fprintf(stderr, "usage: pipe cmd1 cmd2\n");
    if ( pipe( thepipe ) == -1 )        /* get a pipe       */
        oops("Cannot get a pipe", 1);

    /* ------------------------------------------------------------ */
    /*  now we have a pipe, now let's get two processes     */

    if ( (pid = fork()) == -1 )         /* get a proc   */
        oops("Cannot fork", 2);

    /* ------------------------------------------------------------ */
    /*  Right Here, there are two processes         */
    /*             parent will read from pipe           */

    if ( pid > 0 ){         /* parent will exec av[2]   */
        close(thepipe[1]);  /* parent doesn't write to pipe */                                                              
        if ( dup2(thepipe[0], 0) == -1 )                                                                                    
            oops("could not redirect stdin",3);                                                                            
        close(thepipe[0]);  /* stdin is duped, close pipe   */                                                              
        execlp( av[2], av[2], NULL);                                                                                        
        oops(av[2], 4);                                                                                                    
    /*   child execs av[1] and writes into pipe         */                                                                  
    close(thepipe[0]);      /* child doesn't read from pipe */                                                              
    if ( dup2(thepipe[1], 1) == -1 )                                                                                        
        oops("could not redirect stdout", 4);                                                                              
    close(thepipe[1]);      /* stdout is duped, close pipe  */                                                              
    execlp( av[1], av[1], NULL);                                                                                            
    oops(av[1], 5);                                                                                                        
Question by:sonic2000
    LVL 3

    Expert Comment

    Why 0? I don't think any process has that PID. And certainly no process has a negative PID. And afaik, you can't specify which PID to get when forking(may be just my inferiror knowledge).

    Author Comment

    it is possible to get a pid == -1 if the fork is unsuccessful (at least what is told by man fork)..
    FYI, the above code is taken from a book and I am just wonder why when I swap child and parent, the result is so different.
    LVL 3

    Expert Comment

    -1 is not the PID, but the exit status code of fork. ;)

    Well, doing something as "less | who" doesn't make sense from the start.

    Author Comment

    if ( (pid = fork()) == -1 )         /* get a proc   */
            oops("Cannot fork", 2);

    pid == -1 if fork returns -1 (unsuccessful). Of course I know the result is the fork() :)

    >>Well, doing something as "less | who" doesn't make sense from the start.
    I did not say the code is doing that. I said "who | less" if you were to run the program plus read my question :)

    Do you have better input?
    LVL 3

    Expert Comment

    >>I did not say the code is doing that. I said "who | less" if you were to run the program plus read my question :)
    Didn't you ask why it's strange if you reverse them?

    I'm guessing it's strange since only who generates output and only less can get piped input. So you are trying to get data from a silent command and give it to a deaf one. :D

    Author Comment

    i am actually trying to ask why "who" has to be handled by child. Why can't parent handle it?
    Is it because child will run first and so "who" should be handled by child?
    LVL 3

    Accepted Solution

    yes. The first command in a pipe generates output which is then <i>piped</i> forward to the next commands which use that as their stdin. In your code it's child | parent, so who, the generator, should be first (child) and less, the manipulator, second (parent).

    Any better? I hope so :)
    LVL 6

    Expert Comment

    Can you tell what goes haywire ?

    Does the program block, does it produce garbled output? What happens?

    Because i feel (as you do) that this switch of roles of parent and child should be legal. The last comment from lynx.. is not pertinent to this situation, he is talking about shell piping, which is different from constructing  your own programmatic pipe. Even if the listener would run first, it would block on the attempt to read from the pipe thereby releasing the processor to execute the producer...

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Find Ransomware Secrets With All-Source Analysis

    Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

    Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
    The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
    To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…
    This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor ( If you're looking for how to monitor bandwidth using netflow or packet s…

    760 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    7 Experts available now in Live!

    Get 1:1 Help Now