• 0

[C] Using pipe


Question

I am writing a simple shell-like program. I'm stuck on writing the pipeline part. (IE: program_A | program_B )

I'm assuming I need to use pipe(), but I'm unsure how to do this exactly.

program_A reads from stdin, then it write to a pipe? The other end of this pipe is read in by program_B (but program_B normally reads from stdin, so how do I redirect it without messing up program_A?). program_B then outputs to stdout.

Do I setup the pipe, let program_A run and output to the pipe, then start program_B (after redirecting stdin to the pipe)?

Thanks!

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Well,there are the dup functions that duplicates a file descriptor. Your program A should look something like this:

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

//all other includes

int main(void)
{
		int mypipe[2];
		char message[255];

		if(pipe(mypipe) == -1)
		{
				   perror("\nCould not pipe");
				   return 0;
		 }
		 //now the fork part,we redirect the output after we use fork
		 //since the child process is an exact copy of the parent,it will have the same pipe
		 //so we can use that communicate between the processes
		 if(fork() != 0)
		 {
					//it means that this part of if will only execute in the original process,the "parent"
					//because the fork function has different outputs in the processes
					//in the parent,it returns the child's pid which is different from 0
										//in the child it returns 0
					//1 is the default descriptor for stdout so we close this descriptor
					//so that we  can use the "free" slot to add our own output,in our case
					//the write end of the pipe,meaning mypipe[1]
					printf("\nPlease enter message");
					close(1);
					if(dup2(mypipe[1],1) == -1)
					{
							   perrror("\nCould not set stdout);
							   return 0;
					}
					//now we are ready to read from the keyboard 
					//and when it outputs something,it will output it to the write end of the pipe
					//instead of stdout
					scanf("%s",mesage);
					printf("%s",message);
					//the output will be read by the other process,or any other processes that it will start
		 }
		 else
		 {
				   close(0);
				   //we close the standard input so we can replace it with our pipe's read end
				   if(dup(mypipe[0],0) == -1)
				   {
							   perror("\nCould not duplicate descriptor");
							   return 0;
				   }
				   //now we are ready to use any of the exec commands to replace the current process with another one
				   //the new process will inherit the descriptors,so when we read anything in it
				   //it will read what the other process outputs
				   if(execlp("program_B","program_B",NULL) == -1)
				   {
							perror("\nCould not execute program");
							return 0;
				   }
		 }
		 return 0;

}

Hope that answers at least some of your questions. Be carefull though,that the program might hang if it doesn't receive any input from the other process so you need to be carefull about that. And in my case,if one of the dup's fail,the other process will still remain active.

Edited by Cold Blood
Link to comment
Share on other sites

  • 0

That was useful. So, I've gotten it so that a single pipeline will work. Now I have to get it so any number will work (prog_A | prog_B | prog_C etc).

I just need to figure out how to write the for loop. I think I should setup program_A outside, then enter a loop which pipes and starts the next programs until each is started. I'll post so code once I figure it out in case someone else in the world needs help.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.