-1

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);


}
  • You *do* set up `pipefd` somewhere? Can you please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show us? Including how you initialize `pipefd` and call this function? – Some programmer dude Jul 22 '16 at 07:59
  • Also not that it is ***very*** unlikely that the `open` call would return `0` if it's successful. Try checking for `-1` instead. – Some programmer dude Jul 22 '16 at 08:25

2 Answers2

1

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.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • ok that was the problem. Thank you! And for closing it? I have to close reader first? Because now the process read and print every value of the pipe(FIFO) but won't finish... – Orazio Contarino Jul 22 '16 at 08:52
0

The problem was that forks dupe file descriptors and so they were still opened. Due to this reason, child process won't finish. Fixed code:

    #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);
    close(pipefd[1]);          /* Close unused read end */
    printf("child reader > done\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 */

    if( (fifofd = open(FIFONAME, O_WRONLY))  == -1) printf("Error fifoWW\n"); 
    printf("read from pipe\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)); //prima senza +1;
                    }i=0;
            }
            else{
                    temp[i] = c;
                    i++;
            }
    }
    close(fifofd);
    close(pipefd[0]);    
    printf("child filter > done\n");
    exit(0);

    }

    void child_writer(parameters params){
    char c;
    char temp[250];     
    int i=0;
    char *temp2;
    int size;
    int fifofd;
    if( (fifofd = open(FIFONAME, O_RDONLY)) == -1) printf("Error fifoRR\n"); 
    do{
            printf("entry> [%c] \n", c);
            size = read(fifofd, &c, 1);
            printf("next size read> %d\n", size);
    }while(size > 0);
    close(fifofd);
    printf("exit-------------\n");
    //unlink(FIFONAME);
    exit(0);
    }

    int main(int argc, char *argv[]){
    char* temp1;
    parameters params;
    int esitoFork;
    params.i=0;
    params.v=0;
    params.word=0;
    params.filename=0;
    int pid_r, pid_w, pid_f;
    FILE *myfifo;
    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){                 // [3] ho il nome, [4] ho il filename
            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){        // [2] ho il nome, [3] ho il filename
            if(argc>3){
                    params.word++;
                    strcpy(params.word_string, argv[3]);
            }
            if(argc>4){
                    params.filename++;
                    strcpy(params.filename_string, argv[4]);
            }
    }
    else{                               // [3] ho il nome, [4] ho il filename
            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], nome[%d], filename[%d]\n", params.i, params.v, params.word, params.filename);

    if(params.word==0){
            printf("Error syntax\n");
            exit(0);
    }


    if (pipe(pipefd) == -1) {
            printf("pipe error\n");
            exit(0);
    }

    if( mkfifo(FIFONAME, 0666) != 0) printf("Error fifo\n"); 


    if( (pid_r=fork()) == 0 ){

            child_reader(params);
    }
    if( (pid_f=fork()) == 0 ){
            child_filter(params);
    }
    close(pipefd[0]);
    close(pipefd[1]);
    if( (pid_w=fork()) == 0 ){
            child_writer(params);
    }
    waitpid(pid_r, NULL, 0);
    printf("Reader finished\n");

    waitpid(pid_f, NULL, 0);
    printf("filter finished\n");

    waitpid(pid_w, NULL, 0);
    printf("Done!\n");
    unlink(FIFONAME);
    exit(0);
    }