I'm trying to understand how pipes work and it is rather confusing when I was reading this code in my textbook. In the line
dup(fd2[0]); close(fd2[0]);
why are we duplicating fd2[0],then close it right after we duplicated it?
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
struct timespec ts1, ts2;
pid_t newpid;
int fd1[2], fd2[2];
char m0[] = "\nabout to fork....\n";
char m1[] = "message from parent to child\n";
char m2[] = "message from child to parent\n";
char m3[] = "\ndone....\n";
char rbuf1[256];
char rbuf2[256];
int cn1, cn2;
ts1.tv_sec=(time_t)1;
ts1.tv_nsec=(long)1;
ts2.tv_sec=(time_t)1;
ts2.tv_nsec=(long)1;
if ((pipe(fd1)==-1)) printf("error\n");
if ((pipe(fd2)==-1)) printf("error\n");
printf("fd1 %d %d fd2 %d %d\n", fd1[0], fd1[1], fd2[0], fd2[1]);
if ((newpid=fork()) ==-1) {
printf("failed to fork\n\n");
return 0;
}
if (newpid > 0) { // parent ***************
close(fd1[1]); close(fd2[0]); // closing 4 and 5
dup(fd2[1]); close(fd2[1]); // taking 4 in place of 6
write(4, m1, sizeof(m1)); // parent_to_child messg
usleep(10000);
cn1=read(3, rbuf1, 256);
write(1, rbuf1, cn1);
} else { // child ***************
close(fd1[0]); close(fd2[1]); // closing 3 and 6
dup(fd2[0]); close(fd2[0]); // taking 3 in place of 5
write(4, m2, sizeof(m2)); // child_to_parent messg
usleep(10000);
cn2=read(3, rbuf2, 256);
write(1, rbuf2, cn2);
}
write(2, m3, sizeof(m3));
return 0;
}
You did not show us your code, however, from the man page of
dup()and
This clearly says,
dup()will return a new file descriptor foroldfd. you need to assign the return value ofdup()to get the newfd. Once you get the newfd, you can close the oldfdand use the newly returned descriptor to access the file.Once more approach, commonly used, is to close a well-known file descriptor and after that call
dup()which will assign the recently closedfdas the newfd. [Example :STDIN_FILENO]