The child_filter has to read values from pipefd and write these in a named pipe. The problem is that if i try to un-comment the comment[3] (the open of the named-pipe) the function won't print values, it seem to be stuck on read() call. Instead, if i do not open the fifo pipe it works. I need named pipe for other stuffs. What shall i modify? Maybe pipe and named-pipe conflicts using them together? Thanks.
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFONAME "./my-fgrep-named-pipe"
typedef struct{
int i;
int v;
int word;
int filename;
char word_string[250];
char filename_string[250];
}parameters;
int pipefd[2];
void child_reader(parameters params){
FILE* fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
if(params.filename==0)
fp = stdin;
else
fp = fopen(params.filename_string, "r");
close(pipefd[0]); /* Close unused read end */
if (fp != NULL){
while ((read = getline(&line, &len, fp)) != -1) {
//printf("Retrieved line of length %zu :\n", read);
//printf("%s", line);
write(pipefd[1], line, strlen(line));
}
fclose(fp);
}
free(line);
printf("child reader > end\n");
exit(0);
}
void child_filter(parameters params){
char c;
char temp[250];
int i=0;
char *temp2;
int fifofd;
close(pipefd[1]); /* Close unused write pipe end */
printf("read from pipe\n");
if( (fifofd = open(FIFONAME, O_WRONLY)) == -1) printf("Error WW\n");
while (read(pipefd[0], &c, 1) > 0){
if (c == '\n' || c == '\r'){
temp[i] = '\n';
if(i>0){
temp2=strtok(temp, "\n");
//temp2[i] = '\n';
// printf("[%s]\n", temp2);
write(fifofd, temp2, strlen(temp2));
}i=0;
}
else{
temp[i] = c;
i++;
}
}
close(fifofd);
printf("child filter > end\n");
exit(0);
}
void child_writer(parameters params){
char c;
int fifofd;
char temp[250];
int i=0;
char *temp2;
if( (fifofd = open(FIFONAME, O_RDONLY)) == -1) printf("Error RR\n");
while (read(fifofd, &c, 1) > 0){
printf("entry > [%c] \n", c);
}
printf("exit-------------\n");
close(fifofd);
unlink(FIFONAME);
exit(0);
}
int main(int argc, char *argv[]){
char* temp1;
parameters params;
int forkResult;
params.i=0;
params.v=0;
params.word=0;
params.filename=0;
int pid_r, pid_w, pid_f;
if(argc<2){
printf("error\n");
exit(0);
}
if(strcmp(argv[1],"-i") == 0)
params.i++;
if(strcmp(argv[1],"-v") == 0)
params.v++;
if(argc>2){
if(strcmp(argv[2],"-i") == 0)
params.i++;
if(strcmp(argv[2],"-v") == 0)
params.v++;
}
if(params.i == 0 && params.v == 0){
params.word++;
strcpy(params.word_string, argv[1]);
if(argc>2){
params.filename++;
strcpy(params.filename_string, argv[2]);
}
}
else if(params.i != 0 && params.v != 0){
if(argc>3){
params.word++;
strcpy(params.word_string, argv[3]);
}
if(argc>4){
params.filename++;
strcpy(params.filename_string, argv[4]);
}
}
else{
if(argc>2){
params.word++;
strcpy(params.word_string, argv[2]);
}
if(argc>3){
params.filename++;
strcpy(params.filename_string, argv[3]);
}
}
printf("Result: i[%d], v[%d], name[%d], filename[%d]\n", params.i, params.v, params.word, params.filename);
if(params.word==0){
printf("Error X\n");
exit(0);
}
if (pipe(pipefd) == -1) {
printf("pipe error\n");
exit(0);
}
unlink(FIFONAME);
if( mkfifo(FIFONAME, 0666) != 0) printf("Error fifo1\n");
if( (pid_r=fork()) == 0 ){
child_reader(params);
}
if( (pid_f=fork()) == 0 ){
child_filter(params);
}
if( (pid_w=fork()) == 0 ){
child_writer(params);
}
waitpid(pid_r, NULL, 0);
printf("Reader finished\n");
close(pipefd[1]);
waitpid(pid_f, NULL, 0);
close(pipefd[0]);
printf("filter finished\n");
waitpid(pid_w, NULL, 0);
printf("Done!\n");
exit(0);
}
If you open a named pipe for writing then it'll block until the other end is opened for reading. That's an expected behaviour.
I need named pipe for other stuffs
Well, if there's no one reading from the pipe then what other stuff can you do with the write end of the pipe? So, you have to ensure there's a reader from the pipe or delay opening the pipe until there's someone ready to read from it. One other option is to open with O_RDWR
.