2016-07-22 13 views
-1

child_filter는 pipefd에서 값을 읽고 명명 된 파이프에이 값을 써야합니다. 문제는 내가 주석 [3] (명명 된 파이프 열기) 함수가 값을 인쇄하지 않는다고 생각하면 read() 호출에서 멈춘 것처럼 보입니다. 대신, 나는 fifo 파이프를 열지 않으면 작동합니다. 다른 물건에는 명명 된 파이프가 필요합니다. 무엇을 수정해야합니까? 어쩌면 그것들을 함께 사용하는 파이프와 명명 된 파이프 충돌일까요? 감사합니다. .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

어딘가에 'pipefd'를 설정 했습니까? [최소, 완전하며 검증 가능한 예] (http://stackoverflow.com/help/mcve)를 만들어 보여 주시겠습니까? 'pipefd'를 어떻게 초기화하고이 함수를 호출 할까? –

+0

또한 ***** *** 성공했을 경우'open' 호출은'0'을 리턴하지 않을 것입니다. 대신에'-1'을 검사 해보십시오. –

답변

1

작성을 위해 명명 된 파이프를 열면 다른 쪽 끝이 읽기 위해 열릴 때까지 차단됩니다. 그것은 예상되는 행동입니다.

내가 다른 거즈

에 대한 명명 된 파이프 필요

글쎄, 당신은 파이프의 쓰기 마지막으로 할 수있는 어떤 다른 물건 후 파이프에서 읽기 아무도 존재하지 않는 경우는? 따라서 파이프에서 판독기가 있는지 확인하거나 누군가가 읽을 준비가 될 때까지 파이프를 여는 것을 지연해야합니다. 다른 옵션 중 하나는 O_RDWR으로 열리는 것입니다.

+0

그게 문제였습니다. 고맙습니다! 그리고 그것을 닫으시겠습니까? 나는 독자를 먼저 닫아야 만 하는가? 이제 프로세스가 파이프의 모든 값 (FIFO)을 읽고 인쇄하지만 끝나지 않으므로 ... –

0

문제는 포크가 파일 설명자를 포획했기 때문에 여전히 열렸습니다. 이러한 이유로 인해 하위 프로세스가 완료되지 않습니다. 고정 코드 :

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