#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>

#define MAX 512

enum {READ,WRITE};

int main(int argc, char **argv)
{
 char *fname;
 int fdout[2], fdin[2];
 int fd, n;
 char puffer[MAX];

 /*Wir erzeugen 2 Pipes*/
 if(pipe(fdout) <0 || pipe(fdin) <0)
  { perror("pipe : "); exit(0); }

 /*Nun erzeugen wir einen neuen Prozeß*/
 switch(fork())
  {
   case -1  :  perror("fork : "); exit(0);
   case  0  :  /*Im Kindprozess*/
               close(0); /*stdin schließen*/
               dup(fdout[READ]); /*Lese-Deskriptor duplizieren*/
               close(1); /*stdout schließen*/
               dup(fdin[WRITE]); /*Schreib-Deskriptor duplizieren*/
               /*Kindprozess wird von grep überlagert daher benötigen wir diese
                 Deskriptoren nicht mehr. Alle Vorsorgen haben wir eben gemacht...*/
               close(fdout[READ]);
               close(fdout[WRITE]);
               close(fdin[READ]);
               close(fdin[WRITE]);

               /*Nach dieser Zeile wird der Kindprozeß überlagert....*/
               execlp("grep", "grep", "^#include", NULL);

   default  :  /*Elternprozeß*/
               close(fdout[READ]); /*Elternprozeß schreibt nur in die Pipe fdout*/
               close(fdin[WRITE]); /*Elternprozeß liest nur von Pipe fdin aus grep*/

               /*Datei öffnen*/
               fd=open(argv[1], O_RDONLY);
               if(fd < 0)
                 {  perror("open : "); exit(0); }

               /*Aus Datei lesen*/
               while((n = read(fd, puffer, MAX)) != 0)
                {
                  if(n==-1)
                   exit(0);
                  /*Wir schreiben etwas in die Pipe fdout an grep*/
                  if(write(fdout[WRITE], puffer, n) == -1)
                     {  perror("write : "); exit(0); }
                }
               /*Datei schließen*/
               close(fd);
               /*Schreibseite schließen*/
               close(fdout[WRITE]);
               /*Das ist das Zeichen für grep zum lesen aus der Pipe fdout*/
               /*Nun wollen wir lesen was grep mit unseren Daten gemacht hat*/
               /*read blockiert solange bis grep fertig ist*/
               while(( n=read(fdin[READ], puffer, MAX)) != 0)
                {
                 if(n==-1)
                   exit(0);
                 /*Jetzt wollen wir das ganze auf dem Bildschirm ausgeben*/
                 if(write(STDOUT_FILENO,puffer, n) == -1)
                    { perror("write :"); exit(0); }
                }
               /*Jetzt noch die Leseseite schließen wir sind fertig*/
               close(fdin[READ]);
  }
 return 0;
}