PDA

View Full Version : IPC between 2 programs using pipe



cbgb
09-22-2006, 09:29 AM
Hi. I have been looking through the posts for fork, pipe, dup2, and IPC, but I have not found an answer to my question, so here goes:

I want to set up a pipe between 2 separate programs using fork. I have a parent process (pgm1) that will create the child via execve, and then read the child's response. The child will read an input file and send some calculated results back to the parent through the pipe. Again, they are two separate programs... So I am doing the following, and I would like to know if I can use dup2 to set up stdin and stdout between the processes. If so, can anyone point me at an example that involves 2 programs? I am also wondering, what has to be declared in program 2 to establish a link to the pipeFDs decriptors that are declared in my pgm1?

Thanks a lot!!


int pipeFDs[2]; /* Pipe fds */
char CHILD_PROC_TO_LOAD_PIPE[] = {"./pgm2.o"}; /* Load process */
char *args[] = {NULL};
FILE *fdout; /* parent's output result file */

...

pid = fork();

switch(pid)
{
case -1:
printf("ERROR");
case 0:
dup2(0,pipeFDs[0]); /* Don't know if this is correct. Want */
dup2(1,pipeFDs[1]); /* to link pipes to pgm2 */
execve(CHILD_PROC_TO_LOAD_PIPE,args,NULL);
default:
processLoadedPipe(pipeFDs,fdout,pid); /* parent */
}

cbgb
09-22-2006, 10:05 AM
Sorry about that... this is my first post. I still can not find an example, so any help would be appreciated.

Thanks!

whiteflags
09-22-2006, 10:26 AM
> I want to set up a pipe between 2 separate programs
Sounds like a great idea except that you got caught up in all the ways to set up a process. If you need to have communication with another process - and will constantly be exchanging data and control back and forth - you should consider piping as a simple solution.

Formatted piping: man popen (http://bama.ua.edu/cgi-bin/man-cgi?popen+3C)
Low level piping: man pipe (http://www.hmug.org/man/2/pipe.php)

Once you figure out how to open a stream then it's really easy to communicate via the standard library.

Salem
09-22-2006, 10:40 AM
> ./pgm2.o
Is this really an executable file, or an object file?

Everything returns a status, you should check all of them. Maybe something is returning an error.

> char *args[] = {NULL};
I would use


char *argc[] = {
"./pgm2.o",
NULL,
};
....
execve(args[0],args,NULL);

Most exec functions work best with absolute paths. It's only the 'p' variants of exec which search the path for an executable.

Moved to linux board.

cbgb
09-22-2006, 11:39 AM
Thanks for the reply... Actually, the execve seems to be working fine. My question is more about the use of pipe() between 2 separate programs (BTW ./pgm2.o is an executable). Basically, do I need to use dup2() to allow the two programs to communicate with each other? If so, what does the file descriptor declaration AND the dup2 calls look like in BOTH programs?

That would be a big help. Thanks a lot, everybody.

Salem
09-22-2006, 11:47 AM
Well the child process just uses stdin and stdout as it would do anyway.
The parent would use the ends of the pipes (or it can dup2 them as well, if it wants to use stdio).

Yasir_Malik
09-23-2006, 06:57 PM
The following man page on dup2(), I think, has the clearest description of dup2: http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWaman/hman3c/dup2.3c.html

Each process has a file descriptor table that is indexed by integers. fd[0] refers to stdin. When you do dup2(pipes[0], 0), you make fd[0] refer to the file descriptor pipes[0]. You are in effect tricking the child process thinking that it is reading out of stdin.

fnoyan
09-28-2006, 01:16 PM
I recommend you to read IPC and threads sections of Advanced Linux programming. I am sure that you can find somethin useful.

Dalren
10-04-2006, 07:02 AM
Since I had to do something like this just two days ago, I still have the code in my head and will share some of it with you.


...
pid=fork()
switch(pid)
{
case -1:
//handle fork error here
break;
case 0:
//child
dup2(pipeFDs[1],STDOUT_FILENO);
close(pipeFDs[1]);
//execute process here
exit(0);
default:
dup2(pipeFDs[0],STDIN_FILENO);
close(pipeFDs[0]);
//do whatever you want with the input from child proc
}
...

That will set the child to replace stdout with the write end of the pipe, and the parent will replace stdin with the read end of the pipe.