2016-07-22 31 views
-1

verwendet Der Child_filter muss Werte von Pipefd lesen und diese in einer Named Pipe schreiben. Das Problem ist, dass, wenn ich versuche, den Kommentar [3] (das Öffnen der Named-Pipe) zu kommentieren, die Funktion keine Werte ausgibt, scheint es auf lese() Anruf stecken. Stattdessen, wenn ich die Fifo-Pipe nicht öffne, funktioniert es. Ich brauche Named Pipe für andere Stoffe. Was soll ich ändern? Vielleicht Konflikte zwischen Pipe und Named-Pipe? Danke.Named Pipe Block Kindprozess, der Rohr in C

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


} 
+0

Sie * do * einrichten 'pipefd' irgendwo? Können Sie bitte versuchen, ein [minimales, vollständiges und verifizierbares Beispiel] (http://stackoverflow.com/help/mcve) zu erstellen und uns zu zeigen? Einschließlich, wie Sie 'pipefd' initialisieren und diese Funktion aufrufen? –

+0

Auch nicht, dass es *** *** sehr unwahrscheinlich ist, dass der "offene" Aufruf "0" zurückgeben würde, wenn es erfolgreich ist. Versuchen Sie stattdessen, nach "-1" zu suchen. –

Antwort

1

Wenn Sie eine Named Pipe zum Schreiben geöffnet, dann wird es blockiert, bis das andere Ende zum Lesen geöffnet wird. Das ist ein erwartetes Verhalten.

I Rohr für andere Stoffe genannt brauche

Nun, wenn es niemand aus dem Rohr zu lesen dann, was andere Sachen kann man mit dem Schreibende des Rohres zu tun? Sie müssen also sicherstellen, dass ein Leser aus der Pipe kommt oder dass Sie die Pipe verzögern, bis jemand bereit ist, von ihr zu lesen. Eine andere Möglichkeit besteht darin, mit O_RDWR zu öffnen.

+0

ok das war das problem. Vielen Dank! Und um es zu schließen? Ich muss den Leser zuerst schließen? Weil jetzt der Prozess jeden Wert der Pipe (FIFO) liest und druckt, aber nicht beendet ... –

0

Das Problem war, dass Gabeln dupe Dateideskriptoren und so waren sie noch geöffnet. Aus diesem Grund wird der untergeordnete Prozess nicht beendet. Festcode:

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