Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

simple pipe

Posted on 2004-11-11
8
Medium Priority
?
365 Views
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]   */
to
    if ( pid == 0 ){         /* child will exec av[2]   */
then everything will go haywire!

Why?



/* 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");
        exit(1);
    }
    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);                                                                                                        
}
0
Comment
Question by:sonic2000
  • 4
  • 3
8 Comments
 
LVL 3

Expert Comment

by:lynxlupodian
ID: 12564890
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).
0
 

Author Comment

by:sonic2000
ID: 12564923
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.
0
 
LVL 3

Expert Comment

by:lynxlupodian
ID: 12565019
-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.
0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

Author Comment

by:sonic2000
ID: 12565338
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?
0
 
LVL 3

Expert Comment

by:lynxlupodian
ID: 12565538
>>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
0
 

Author Comment

by:sonic2000
ID: 12567119
sorry..
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?
0
 
LVL 3

Accepted Solution

by:
lynxlupodian earned 150 total points
ID: 12567192
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 :)
0
 
LVL 6

Expert Comment

by:de2Zotjes
ID: 12592551
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...
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…

810 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