I'm trying to read a text file's string from a process, then deliver the string to another process via named pipes on LINUX. The problem is when i type './reader text.txt = receiver' to the console the recieving process' read() function returns an error if i put the line
fcntl(fd, F_SETFL, O_NONBLOCK);
or gets stuck on read() function if i remove it.
heres the process that reads the string (reader)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(int argc,char *argv1[]){
if(argc==4 && strcmp(argv1[2],"=") == 0){
char mesaj[99999]; //message to be delivered
char line[150];
FILE *fp =fopen(argv1[1],"r"); //reading from a text file
if(fp==NULL){
printf("text file error!");
exit(1);
}
while(fgets(line,sizeof(line),fp)){
strcat(mesaj,line); //append every line to message
}
fclose(fp);
mesaj[strlen(mesaj)-1]='\0';
int n =strlen(mesaj)+1;
//printf("got the text %s\n",mesaj);
if(mkfifo("myFifo",0777)== -1 && errno!= EEXIST){
printf("Pipe error");
exit(1);
}
printf("opening\n");
int fd= open("myFifo",O_RDWR);
if(fd==-1){
printf("open error");
exit(1);
}
printf("opened");
if( write(fd, mesaj,sizeof(char)*n)==-1){
printf("write error");
exit(1);
}
printf("written");
close(fd);
printf("closed");
fflush(stdout);
char mesajSizeChar[n];
sprintf(mesajSizeChar, "%d", n);
char *args[]={mesajSizeChar,NULL}; //send the message size as parameter for the other process
char program[]="./";
strcat(program,argv1[3]); // recieved process name as parameter
execv(program,args); // call the other process
perror("execv");
return 0;
}
}
and heres the recieving process (reciever)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc,char *argv1[]){
int mesajSize=atoi(argv1[0]); //convert message size to integer
char mesaj[99999];
printf("\ncame here\n");
int fd= open("myFifo",O_RDWR);
fcntl(fd, F_SETFL, O_NONBLOCK);
printf("\nopen \n");
if(fd==-1)
printf("pipe error\n");
if(read(fd,mesaj,sizeof(char)*mesajSize)==-1)
printf("read error\n");
printf("read \n");
printf("\nworked: %s \n",mesaj);
close(fd);
return 0;
}
The problem is that you closed the pipe in the first process. A pipe doesn't have any permanent storage, it can only hold data while it's open by at least one process. When you close the pipe, the data that you've written to it is discarded.
As a result, when the second process tries to read from the pipe, there's nothing available.
You need to keep the pipe FD open when you execute the second process. Get rid of close(fd);
in the reader program.