Solved

Using pipes to pass the output to parent

Posted on 2008-10-26
12
457 Views
Last Modified: 2013-12-26
I need to write a code that pass the output of "ls -l" back to parent using pipe. The ls- l will be executed by child after the fork process. Previously I succeeded in using fork() and execl to call another program to do a similar read() and write() system call that mimic "cat" function. This is how i think my program will look like for pipe

Declare variables
Fork()
pipe()
execl("/bin/ls","ls","-l",0);
??

I am stuck at the part, where I do not know how to assign the output from execl() to string. I am thinking of using a string variable to store the result OR you suggest to use FILE to store the result and then use the read and write function to get back all the output ?

Other thing, please guide me on how to write this, I am confuse with pipes and I have been searching quite a lot of resources but I still failed to understand pipes in details.

Thanks for your help
0
Comment
Question by:msh79
  • 5
  • 5
  • 2
12 Comments
 
LVL 12

Expert Comment

by:hfraser
Comment Utility
Pipes are used to communicate between processes. They can be "named pipes", created ahead of time and accessed as file in the filesystem (see mkfifo) or dynamically (as in ls -1 | wc to get he number of files in a directory). Your program is doing the latter by creating an un-named pipe and creating a child thread to talk with.

The pipe function creates the pipe, and as with any pipe there are two ends. Typically, the parent will close the output handle, and listen on the input. The child does the opposite, closing the input and writing to the output, mimicing the stdin/stdout idea. In your example, you'll want to replace the stdout of the child process with it's half the pipe (see the response by ozo in question 21219592 for an example).

These steps are packaged into the popen function, but it invokes a shell to execute a command, introducing some additional overhead you may not want.
0
 

Author Comment

by:msh79
Comment Utility
When I try to search for 21219592, it only list my thread. So far I haven't succeeded in opening ozo thread for this similar question. I am in the midst of writing the code and let's me know if I am in the right direction.

a) Can I store execl result in a string so read() can get the input while Child is performing the action
b) How do I continue on the parent side to get the output

Attach is the source code. And I would love to read Ozo answer too. Pls provide guidenace
#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>
 

void list_child(int fd[]);

void list_parent(int fd[]);
 

int main ()

{

  int pid,status,fd[2];

  printf("This program list through pipe");
 

  /*create a pipe*/

  status=pipe(fd);

  if (status==-1) {

     perror("pipe");

     exit(1);

  }
 

  /*Fork to child process*/

  pid = fork();
 

  switch (pid) {

     case -1: perror("fork");

              break;

     case 0:  list_child(fd);

              break;

     default: list_parent(fd);

              break;
 

     }

  return 0;

}
 

void list_child(int pid[]){

   char listdir[];

   int status;
 

   /*close un-needed write part of the pipe*/

   close(fd[1]);
 

   /*now execl to list the directory*/

   listdir=execl("/bin/ls","ls","-l",0);
 

   /*?? not sure how to write to read data in string from execl */

   while ((status=read(fd[0],listdir,1))>0){

   }
 

   exit(0);
 
 

}
 

void list_parent(int fd[]);

{

     int status;
 

     /*close the un-needed read part of the pipe*/

     close(fd[0]);
 

    /*write back all the data from listdir or child*/

    // ?? not how to proceed

    

   
 

}

Open in new window

0
 
LVL 12

Expert Comment

by:hfraser
Comment Utility
I need to work on linking other contributor's work. Here's the full link to ozo's response. It contains examples you're looking for.

http://www.experts-exchange.com/Programming/Languages/C/Q_20336027.html?sfQueryTermInfo=1+execl+ozo+pipe
0
 

Author Comment

by:msh79
Comment Utility
I read Ozo contribution, I am confuse with filedes[]. For my single un-named pipe, do I need to create 2 separate filedes[] and also do I need to use dup function ?

Do you have much more simple example that I could digest - I am still beginner :). Thanks for your answer so far, really appreciate it
0
 
LVL 12

Expert Comment

by:hfraser
Comment Utility
Try this. It's almost exactly what you want.

http://www.dgp.toronto.edu/~ajr/209/notes/procfiles/pipe-example.c
0
 

Author Comment

by:msh79
Comment Utility
Hello hfraser, I am started able to code a bit. I could run the program and get the output but I am not sure whether the code is correct.

a) Is the execl is executed by the child (I put a pid and printf statement to check) ?
b) Do you think this is the correct way for parent to read the output from the pipe.

My understanding is there is only 1 pipe (upstream is at p[1] - write on the left end of pipe) & downstream is at p[0] - read on the right end of the pipe).

I am just afraid the code only execute because I use execl where it was not done by child ?

Please evaluate

Cheers !
#include <stdio.h>

#include <unistd.h>

#define BUFSIZE 100
 

int main()

{

int count,p[2],status;

char buffer[BUFSIZE];
 

pipe(p);
 

/*fork child*/

if (fork()==0){

  write(p[1],buffer,15);

  execl("/bin/ls","ls","-l",0);

  count=read(p[0],buffer,BUFSIZE);
 

  }

  /*Parent writing out the output*/

  write(1,buffer,count);

  wait(&status);
 

  return 0;

}

Open in new window

0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 84

Expert Comment

by:ozo
Comment Utility
for what you are doing, it sounds like popen may be an easier way to do it.
0
 

Author Comment

by:msh79
Comment Utility
Ozo - thanks for stepping in. You are the wizard, hfraser mentioned before :D

He also recommend popen, but my assignment have to use the basic function to demonstrate how a pipe works with child and output back to parent

Please share some ideas, I am running out of ideas.
0
 
LVL 12

Expert Comment

by:hfraser
Comment Utility
Try something like this:

        if (fork()==0){
                close(1);
                dup (p[1]);
                execl("/bin/ls","ls","-l",0);
                exit(0);
        }
        else {
                close(0);
                dup (p[0]);
                while (read(0, &c, 1) >0) {
                        write(1,&c,1);
                }
                exit(0);
        }

Standard I/O channels are 0 for stdin, and 1 for stdout. The parent has to replace it's stdin with one end of the pipe, and the child does the opposite.

0
 
LVL 84

Accepted Solution

by:
ozo earned 250 total points
Comment Utility
#include <stdio.h>
#include <unistd.h>
main(){
#define in 0
#define out 1
int pipefd[2];
int pid;
char string[10000];
int l;
pipe(pipefd);
if( (pid=fork()) < 0 ){
     perror("fork");
}else if( pid==0 ){
    close(pipefd[0]);
    dup2(pipefd[1],out);
    execl("/bin/ls","ls","-l",0);
    perror("execlp ls");
}
close(pipefd[1]);
dup2(pipefd[0],in);
l=read(in,string,sizeof(string));
write(fileno(stdout),string,l);
}
0
 

Author Comment

by:msh79
Comment Utility
Thanks guys - both the logic seems to be identical. Let me clarify a few things before I close this thread

1. Could I accept both the answers given - Ozo & hFraser as both of you have been very helpful so I assume I need to click on Accept Multiple Solutions on both entry. Correct ?

2. I read the article http://www.ftt.co.uk/tutorials/Sysprog_tutorial3.html, so from the above solutions the pipe - 0 or 1 (input and output). Can it be the other way ? Sorry for the dumb question - refer to attached file

3. Also do you think it looks better if I add these codes to close the pipe to close both end of the pipe and wait for child to finish

close(fd[0]);
close(fd[1]);
wait(0);


Thanks so much
programmer.gif
0
 
LVL 12

Expert Comment

by:hfraser
Comment Utility
The answer goes to ozo, who I tried to reference in the first place. I just messed up with the link.

The pipe is just a pipe. Either end can be used for reading or writing.

Closing both ends isn't necessary, since they're destroyed when the process exits. But it is cleaner coding and does make a difference if the pipe was being re-used in a more complex program. Same applies to the wait.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
linearIn  challenge 23 65
maxMirror challenge 10 88
mapShare challenge 13 67
Re-position sub-options beneath the TAB 7 36
Iteration: Iteration is repetition of a process. A student who goes to school repeats the process of going to school everyday until graduation. We go to grocery store at least once or twice a month to buy products. We repeat this process every mont…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

771 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

10 Experts available now in Live!

Get 1:1 Help Now