I am trying to set up a pipeline to communicate between a child process and a parent process using pipe(). I read some posts on stackoverflow some use the dup() and dup2() functions. Can someone explain what is the use of these functions in this scenario?
2 Answers
You could use dup2
to redirect the stdin and stdout of a child and parent process respectively to send messages through a pipe used with file descriptors created with the instruction pipe
. To illustrate its functionality in a more concrete way, here is a detailed example on how to do so.
#include <unistd.h>
#include <stdio.h>
#define READ 0
#define WRITE 1
int main (int argc, char * argv [ ] )
{
int fd[2];
pipe(fd); // creating an unnamed pipe
if (fork() !=0)
{
close(fd[READ]); // Parent close the reading descriptor
dup2(fd[WRITE], 1); // copy fd[WRITE]] in the descriptor 1 (stdout)
close (fd[WRITE]); // closing the writing descriptor, not needed anymore because of stdout
if(execlp(argv[1], argv[1], NULL) ==-1) // execute the program writer passed as an argument to myprog
perror("error in execlp");
}
else // child process (reader)
{
// closing unused writing descriptor
close(fd[WRITE]);
// copy fd[READ] in descriptor 0 (stdin)
dup2(fd[READ],0);
close (fd[READ]); // closing reading descriptor, not needed anymore because of stdin
// execute reading command
if(execlp(argv[2], argv[2], NULL) == -1) // Execute the reader passed as an argument to myprog
perror("connect");
}
return 0 ;
}
With that, every messages sent by the parent process through the standard output will be redirected to the standard input of the child process. For example, when executing the command myprog who wc
(with the code shown above), it behaves just like doing who | wc
in the terminal. You can see my parent process who
will send messages to wc
through the standard output.
As it is for the difference between dup
and dup2
. You can check out this link.

- 523
- 7
- 17
-
It's fine to omit error checking for clarity, but why leave it in on the `execlp`? Be consistent, and explain that production code needs to check the return values of `fork`, `pipe`, etc. – William Pursell Mar 15 '16 at 16:58
-
I will correct this to be consistent, but my main goal was to teach something to OP even though his question didn't ask for any code. *You are right*, but I won't insist and explain why error checking would be needed for fork and pipe in production code. – pandaman1234 Mar 15 '16 at 19:39
-
if you needed to pass string messages from child to parent would you use write(pipeEnds1[1],str,strlen(str))? – Varun Mar 15 '16 at 20:31
-
@Varun assuming your pipeEnds1[1]...is a variable for your file descriptors (or your pipe ends if I understand correctly) you could, but you wouldn't need `dup` or `dup2` if you do it that way. You don't need *dup* or *dup2* to write through processes as stated by Mou. And assuming pipeEnds1[1] would be your writer descriptor, yes you would write to that file descriptor when being in the child and read from pipeEnds1[0] from your parent process. Please edit your question if that's what you want to know. Also, please upvote or resolve the answer if you think if it responds to your question. – pandaman1234 Mar 16 '16 at 00:29
-
when the pipe is full and I try to write to it it gives me an error is there a system call I can make so that the data will be saved in a buffer until the pipe has room? – Varun Mar 16 '16 at 11:52
-
Until the pipe has room? You would suggest to *wait* until it has a room? How can you make the assumption that your pipe is *full*? Even if it is, you have plenty of questions already answering that, [here](http://stackoverflow.com/questions/259355/how-can-you-flush-a-write-using-a-file-descriptor) or [here](http://stackoverflow.com/questions/23797793/how-to-flush-pipes-to-clean-the-buffer-in-c-when-both-pipes-are-part-of-same-p). – pandaman1234 Mar 16 '16 at 13:28
pipe()
creates new file descriptors, it means you can write and read them like you do to a file, standard input, etc.
dup2
and dup
is to rename a file descriptor, for example replacing standard output to a program
to communicate with child process and parent, you don't actually need dup
or dup2
you could use the new file descriptors which pipe()
gave you instead, and keep standard input/output openned
here is a simple communication parent to child process
int main()
{
int fd[2];
int pid;
if (pipe(fd) == -1)
return (1);
pid = fork();
if (pid == 0)
{
/* child process
reading parent process */
char rdbuff[10];
close(fd[1]);
read(fd[0], rdbuff, 10);
printf("got: %s\n", rdbuff);
}
else if (pid > 0)
{
/* parent
sending string to child process */
close(fd[0]);
write(fd[1], "sup!", 5);
}
else
{
/* error */
return (1);
}
}

- 1,079
- 13
- 26