管道来自同一父级的多个孩子

时间:2014-03-21 02:22:12

标签: c exec fork pipe pipeline

早上好,我已经"战斗"用这种方法很长一段时间,最后我决定寻求帮助,因为我不知道我做错了什么。我正在尝试从同一个父母创建多个孩子并制作孩子1"的STDOUT。孩子2"的STDIN这样,直到没有更多的孩子喜欢管道。

我的实际代码

void filter(void) {

 if(Number_cmd != 0) {

 int p,i;
 int fd[2];

 for(i=0;i<Number_cmd;i++)
     pipe(fd);

 for(p=(Number_cmd-1); p>=0; p--){
     switch(fork()) {
     case -1:
           perror("fork");
           exit(1);
     case  0:  
        /* Child */
           close(fd[1]);
           close(0);
           dup(fd[0]);
           close(fd[0]); 

           execlp(filter[p], filter[p], NULL);
           perror("exec");
           exit(1);
     default:            
         /* Father */
           close(fd[0]);          
           close(1);
           dup(fd[1]);                
           close(fd[1]);
           break;
         }
      }
   } 
}

void directory(char* directory_name) {

   DIR* dir = NULL;
   struct dirent* ent;
   char fich[1024];
   char buff[4096];
   int fd, reading;
   struct stat sdata;

   dir = opendir(directory_name);

   while((ent=readdir(dir))!=NULL) {
        if(ent->d_name[0]=='.')
          continue;

        fich[0]='\0'; 
        strcat(fich, directory_name); 
        strcat(fich, "/");          
        strcat(fich, ent->d_name); 
        stat(fich,&sdata);

        if(S_ISDIR(sdata.st_mode))
          continue;

        fd = open(fich, O_RDONLY);

        while((reading= read(fd, buff, 4096)) > 0){
           (write(1, buff, reading) < reading);
           continue;
       }
        close(fd);  
   }
   closedir(dir);
}

问题是当我试图用多个命令调用该方法时,它看起来像ii什么都不做,但是当我用一个命令运行它时工作正常。 提前感谢大家。 (抱歉我的英语;它不是我的母语)

修改

这是主要方法:

char** cmd;
int Number_cmd;

int main(int argc, char* argv[]){ 

    cmd = &(argv[2]);            /*list of the commands*/
    Number_cmd = argc-2;         /* number of commands*/

      filter();
      directory(argv[1]);
      return 0;
}

1 个答案:

答案 0 :(得分:0)

问题1:

  for(i=0;i<Number_cmd;i++)
      pipe(fd);

除非变量Number_cmd为1(或更小),否则泄漏管道描述符就像疯了一样。您需要某种文件描述符数组:

int fds[Number_cmd][2];

for (int i = 0; i < Number_cmd; i++)
    if (pipe(fd[i]) != 0)
        …report error and abandon ship (remembering to close any opened pipes)…

问题2:

这主要是问题1的结果 - 但是你没有关闭足够的文件描述符。基本上,如果您打开N个管道,您的孩子将在将两个文件描述符复制到标准输入和标准输出后最终关闭2 * N个文件描述符。第一个和最后一个孩子将是不同的;它们不会分别覆盖标准输入和标准输出。

可能还有其他问题,但是这两个问题可以通过相当快速的查看代码来解决。