Edit: So, with some additional debugging, EOF successfully writes to the pipe (I know this because I tested the function to write()return 0 on produceStdin. HOWEVER , when reading from the same channel, it says that I encountered EOF ( good), but the value of the EOF element is 255 (usually -1 instead of -1) Does anyone know why this is so?
I am trying to write this program, but when I come across EOF from stdin, I am not writing -1 to the channel. For some reason, when trying to go through the EOF through the pipes, garbage is recorded, and therefore all subsequent processes are captured in an endless loop.
All of these print instructions, other than the one that prints the array in the function printOut(), I am trying to debug (cannot use the debugger due to forks)
Also: some of these comments are reworked, so if you see a mention of the “buffer”, this is because it was preprogrammed using buffers instead of pipes.
Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_CHARS 81
#define NUM_CHILDREN 3
void produceStdin(int writePipe);
void child1(int readPipe, int writePipe);
void child2(int readPipe, int writePipe);
void printOut(int readPipe);
int main(int argc, char const *argv[])
{
int i,pipe1[2],pipe2[2],pipe3[2];
pid_t childPid;
if(pipe(pipe1)==-1||pipe(pipe2)==-1||pipe(pipe3)==-1)
{
fprintf(stderr, "Error in creating pipe");
}
for(i=0;i<NUM_CHILDREN;i++)
{
childPid=fork();
switch (childPid) {
case -1:
perror("fork() failed. Aborting.");
exit(EXIT_FAILURE);
case 0:
switch (i) {
case 0:
close(pipe1[0]);
close(pipe2[0]);
close(pipe2[1]);
printf("right before calling stdin i=%d\n",i);
produceStdin(pipe1[1]);
break;
case 1:
close(pipe1[1]);
close(pipe2[0]);
close(pipe3[0]);
close(pipe3[1]);
printf("right before calling child1 i=%d\n",i);
child1(pipe1[0], pipe2[1]);
break;
case 2:
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[1]);
close(pipe3[0]);
printf("right before calling child2 i=%d\n",i);
child2(pipe2[0], pipe3[1]);
break;
default:
break;
}
default:
if(i==2)
{
close(pipe1[1]);
close(pipe1[0]);
close(pipe2[1]);
close(pipe2[0]);
close(pipe3[1]);
printOut(pipe3[0]);
}
break;
}
}
return 0;
}
void produceStdin(int writePipe)
{
int c=0;
while(c!=EOF)
{
c=fgetc(stdin);
write(writePipe, &c, sizeof(char));
}
printf("Got EOF in ProdStdin\n");
printf("EOF has a value of: %d",c);
exit(0);
}
void child1(int readPipe, int writePipe)
{
int c=0;
while(c!=EOF)
{
read(readPipe,&c,sizeof(char));
if(c=='\n')
{
c=' ';
}
write(writePipe, &c, sizeof(char));
}
exit(0);
}
void child2(int readPipe, int writePipe)
{
int c=0;
int c2=0;
while(c!=EOF && c2!=EOF)
{
read(readPipe, &c, sizeof(char));
if(c=='*')
{
read(readPipe, &c2, sizeof(char));
if(c2=='*')
{
c='^';
write(writePipe,&c,sizeof(char));
}
else
{
write(writePipe,&c,sizeof(char));
write(writePipe,&c2,sizeof(char));
}
}
else
{
write(writePipe,&c,sizeof(char));
}
}
exit(0);
}
void printOut(int readPipe)
{
int c=0,numChars=0;
char output[MAX_CHARS];
while (c!=EOF)
{
read(readPipe, &c, sizeof(char));
if (numChars==MAX_CHARS-2)
{
printf("%s\n",output);
memset(output, '\0', sizeof(char)*MAX_CHARS);
numChars=0;
}
output[numChars]=c;
numChars++;
}
printf("ABOUT TO EXIT PRINTOUT()\n");
exit(0);
}