2017-02-21 28 views
0

Я пытаюсь читать файлы и возвращать строки, соответствующие ключевому слову, с дочерними процессами и передавать их родителям, порядок не имеет значения.Не удается получить каждую строку файла с помощью труб

Мой первый вопрос: возможно ли использовать только 1 трубу или первый процесс для завершения будет закрывать трубу?

Мой второй вопрос заключается в том, что я создал канал для каждого дочернего элемента, и все еще родитель не читает их всех, просто показывает все строки, соответствующие ключевому слову в первом файле, и первое соответствие второго файла и останавливается. (Я пробовал только с двумя файлами, но это не проблема)

Предположим, что все файлы открываются и закрываются. У меня есть проверка на все открытия файлов, pipe() и fork(). Остальное не проверено.

Мой код, как показано ниже:

#include "commons.h" 
//efmalloc is error-free malloc 

int main(int argc, char *argv[]){ 
    int numargs = argc-1; 
    int fds[numargs][2]; 
    pid_t n; 

    for (int i = 0; i < numargs; i++) 
     pipe(fds[i]); 
    for(int i = 0; i < argc-1;i++){ 
     n = fork(); 
     if(n==0){ 
      close(fds[i][0]);//closing the read end of the pipe for the children 
      FILE * fs = fopen(argv[i+1],"r"); 
      //// SETTING UP THE PARAMETERS FOR READING //// 
      char * outputdata = (char*) efmalloc(400*sizeof(char)); 
      *outputdata = '\0'; 
      char * line = NULL; 
      size_t len = 0; 
      int read = getline(&line, &len, fs); 
      int currentline = 1; 
      //// END OF READINGS SETUP //// 

      while (read >= 0) { 
       if(strstr(line,"keyword") != NULL) { 
        strcat(outputdata,argv[i+1]); 
        strcat(outputdata,line); 
        strcat(outputdata,"\0"); 
        //Write the data in the pipe in here 
        write(fds[i][1],outputdata,(strlen(outputdata)+1)); 
        *outputdata = '\0'; 
       } 
       read = getline(&line, &len, fs); 
       currentline++; 
       } 
      free(outputdata); 
      fclose(fs); 
      close(fds[i][1]); //now closing the write end of the pipe 
      exit(0); 
     } 
    } 
    /***** PARENT PROCESS *****/ 
    if(n!=0) { 
     for (int index = 0; index < numargs; index++) 
      close(fds[index][1]); 
     char * readmsg = (char*)efmalloc(BUFFER_SIZE*sizeof(char)); 
     for(int j = 0; j < numargs; j++){ 
      int bytes = read(fds[j][0],readmsg,BUFFER_SIZE); 
      while(bytes>0){ 
       readmsg[bytes] = 0; 
       printf("%s\n", readmsg); 
       bytes = read(fds[j][0],readmsg,BUFFER_SIZE); 
      } 
     } 
     for(int i = 0; i < numargs;i++) 
       wait(NULL); 
    } 
    return 0; 
} 
+1

Разделите свой код на функции. Это облегчит отладку. – sturcotte06

ответ

0

Я вижу несколько незначительных проблем, и два огромных них:

  • getline() и read() возвращают ssize_t, не int. Они не такие же.
  • strcat(outputdata,"\0"); ничего не делает. Если outputdata уже правильно завершен, он не нужен, и если outputdata еще не закончен, это неопределенное поведение.
  • Вы не предоставляете достаточно места для терминатора '\0' в readmsg - вы можете прочитать до BUFFER_SIZE байт, но readmsg[BUFFER_SIZE] = 0; находится за пределами выделенного буфера. Это неопределенное поведение.
  • Вы не можете быть уверены, что все ваши данные действительно вписываются в outputdata. Вы продолжаете набивать все больше и больше, независимо от того, насколько это действительно подходит. Если вы переполняете outputdata, вы снова находитесь в неопределенном поведении.
+0

Мне дали, что строка файла имеет не более 256 символов, а имя файла - не более 64 символов, и я выделяю 400, поэтому этого более чем достаточно. И спасибо, что я их исправлю. – user7601055