Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/select.h>
const int ReadEnd = 0, WriteEnd = 1;
void die(const char *msg) {
fprintf(stderr,"Grrr:%s:%d:%s\n",strerror(errno),errno,msg);
exit(1);
}
void childScreenWriter(int readfd) {
fprintf(stderr,"childScreenWriter enter\n");
char buff[BUFSIZ] = { 0 };
FILE *fp = fdopen(readfd,"r");
setvbuf(fp,NULL,_IOLBF,0); // make it line buffered, pipe ends start fully buffered
while ( fgets(buff,BUFSIZ,fp) ) {
printf("C:%s",buff); // tag as being received by child
}
fprintf(stderr,"childScreenWriter exiting\n");
fclose(fp); // also closes associated descriptor
}
void parentInputReader(int writefd) {
fprintf(stderr,"parentInputReader enter\n");
char buff[BUFSIZ];
FILE *fp = fdopen(writefd,"w");
setvbuf(fp,NULL,_IOLBF,0); // make it line buffered, pipe ends start fully buffered
while ( fgets(buff,BUFSIZ,stdin) ) {
fprintf(fp,"P:%s",buff); // tag as being sent from parent to child
}
fprintf(stderr,"parentInputReader exiting\n");
fclose(fp); // also closes associated descriptor
}
#define CHECK(op,expected,msg) \
if ( op != expected ) die(msg)
int main ()
{
int parent2child[2];
CHECK(pipe(parent2child),0,"pipe1");
pid_t p = fork();
if ( p == 0 ) {
printf("Child=%d\n",getpid());
CHECK(close(parent2child[WriteEnd]),0,"close1");
childScreenWriter(parent2child[ReadEnd]);
} else {
printf("Parent=%d\n",getpid());
CHECK(close(parent2child[ReadEnd]),0,"close3");
parentInputReader(parent2child[WriteEnd]);
int status;
fprintf(stderr,"Waiting...\n");
CHECK(waitpid(p,&status,0),p,"wait");
fprintf(stderr,"Exit status=%d\n",status);
}
return 0;
}
$ ./a.out
Parent=5186
parentInputReader enter
Child=5187
childScreenWriter enter
hello
C:P:hello
world
C:P:world
bye
C:P:bye
parentInputReader exiting
Waiting...
childScreenWriter exiting
Exit status=0