#include #include #include #include #include #include #include #define MAXLENGTH 255 const char *szCommand = "not set"; static int pipe1[2]; static int pipe2[2]; static pid_t pid1; static pid_t pid2; static FILE* pStream1 = (FILE*) 0; static FILE* pStream2 = (FILE*) 0; void BailOut(const char* szMessage); void FreeResources() { if(pStream1 != (FILE*) 0) { if(fclose((FILE*) pStream1) == EOF) { pStream1 = (FILE*) 0; BailOut("Cannot close pipe"); } } } void BailOut(const char* szMessage) { if(szMessage != (const char*) 0) { fprintf(stderr, "%s", szMessage); } FreeResources(); exit(EXIT_FAILURE); } void Usage() { printf("Just start and write..."); } void AllocateResources() { if(pipe(pipe1) == -1) { BailOut("Can't create pipe"); } if(pipe(pipe2) == -1) { BailOut("Can't create pipe"); } } void FatherProcess() { char buffer[MAXLENGTH +1]; if(close(pipe1[0]) == -1) { BailOut("Error closing the read descriptor"); } if((pStream1 = fdopen(pipe1[1], "w")) == (FILE*) NULL) { BailOut("Can't open pipe for writing"); } while(fgets(buffer, MAXLENGTH, stdin) != NULL) { if(fprintf(pStream1, buffer) < 0) BailOut("Can't write to pipe"); } FreeResources(); } void ChildProcess() { char buffer[MAXLENGTH +1]; char reverse[MAXLENGTH +1]; char *p = buffer; if(close(pipe1[1]) == -1) { BailOut("Error closing the write descriptor"); } if((pStream1 = fdopen(pipe1[0], "r")) == (FILE*) 0) { BailOut("Can't open pipe for reading"); } if(close(pipe2[0]) == -1) { BailOut("Error closing the read descriptor"); } if((pStream2 = fdopen(pipe2[1], "w")) == (FILE*) NULL) { BailOut("Can't open pipe for writing"); } while(fgets(buffer, MAXLENGTH, pStream1) != NULL) { p += strlen(buffer); p -= 2; int i; for(i = 0; i < strlen(buffer); i++, p--) { reverse[i] = *p; } fprintf(pStream2, reverse); } FreeResources(); } void GrandChildProcess() { char buffer[MAXLENGTH +1]; if(close(pipe2[1]) == -1) { BailOut("Error closing the write descriptor"); } if((pStream2 = fdopen(pipe2[0], "r")) == (FILE*) 0) { BailOut("Can't open pipe for reading"); } while(fgets(buffer, MAXLENGTH, pStream2) != NULL) { printf("%s\n", buffer); } } int main(int argc, char** argv) { pid_t wpid1; pid_t wpid2; int status1; int status2; szCommand = argv[0]; AllocateResources(); switch(pid1 = fork()) { case -1: BailOut("Fork failed"); break; case 0: switch(pid2 = fork()) { case -1: BailOut("Fork failed"); break; case 0: GrandChildProcess(); break; default: ChildProcess(); break; } default: FatherProcess(); while((wpid1 = wait(&status1)) != pid1) { if(wpid1 != -1) { continue; } if(wpid2 != -1) { continue; } if(errno == EINTR) { continue; } BailOut("Error waiting for child process"); } break; } exit(EXIT_SUCCESS); }