I'm writing a program that consists of 2 processes. The parent reads data through stdin and then sends it to the child through a pipe. I'm using fgets() and fputs() to write and read the data.
The issue is that in certain situations the fgets() call of the child process seems to block. These are:
- When a text file is sent to stdin, everything works fine until the very last line of the file. The fgets of the child never executes and the process hangs.
- When I send /dev/urandom to the program the same situation occurs at a seemingly random moment.
I suspect the issue has something to do with EOF or /0 at the ends of these strings, but i can't quite pinpoint the issue. Any help would be greatly appreciated.
I'm using the message queues as a means of synchronisation. I'm also aware there is no cleaning up in this code. Here it is:
#define KEY5 7626
struct pidbuf
{
long mtype;
int mtext;
} msgpid;
int main(){
sleep(5);
int mqpid;
FILE * strumien;
int fd[2];
if (pipe(fd)== -1){
perror("Create pipe error");
exit(1);}
int buf_len = 128;
msgpid.mtext=0;
int size1=sizeof(struct pidbuf)-sizeof(long);
if((mqpid = msgget(KEY5, 0666 | IPC_CREAT))==-1){
return(-1);
}
char data[buf_len];
if(fork()!=0){
close(fd[0]);
strumien=fdopen(fd[1],"w");
while (fgets(data,buf_len,stdin) != NULL ) {
printf("1:\n%s\n",data);
fputs(data,strumien);
fflush(strumien);
msgpid.mtype=2;
if(msgsnd(mqpid,&msgpid,size1,0)==-1){perror("msgsnd failed: 1");}
msgrcv(mqpid,&msgpid,size1, 1, 0);
}
if(feof(stdin)!=0) printf("\nEnd of file\n");
}
else{
close(fd[1]);
strumien=fdopen(fd[0],"r");
msgrcv(mqpid,&msgpid,size1, 2, 0);
while(fgets(data,buf_len,strumien)!=NULL){
printf("2:\n%s\n\n",data);
msgpid.mtype=1;
if(msgsnd(mqpid,&msgpid,size1,0)==-1){perror("msgsnd failed: 1");}
msgrcv(mqpid,&msgpid,size1, 2, 0);
}
}
return 0;
}