有管道,叉子,dup2的问题

Vin*_*Vin 1 c linux fork pipe

我使用管道,fork,dup2来实现"ls | 更多"或"ls | 排序"等我在这里无法理解这个问题.当我运行我的程序时,我收到此错误:

./a.out  
Missing filename ("less --help" for help)
Run Code Online (Sandbox Code Playgroud)

为什么我会"少"?

这段代码有什么问题?如果我再次将"更多"更改为"ls",则可以正常工作.我的意思是,它就像做ls | LS.

#define STDIN 0
#define STDOUT 1

int main()
{
   int fd[2];
   int pid;
   char *lschar[20]={"ls",NULL};
   char *morechar[20]={"more",NULL};
   pid = fork();
   if (pid == 0) {
   /* child */
     int cpid;
     cpid = fork();
     if(cpid == 0) {
       //printf("\n in ls \n");
       pipe(fd);
       dup2(fd[1], STDOUT);
       close(fd[0]);
       close (fd[1]);
       execvp("ls",lschar);
     } else if(cpid>0) {
       waitpid(cpid, NULL,0);
       dup2(fd[0],STDIN);
       close(fd[0]);
       close(fd[1]);
       execvp("more", morechar);
     }
   } else if (pid > 0) {
     /* Parent */
     waitpid(pid, NULL,0);
   }
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助.

Fat*_*ror 6

您的主要问题在于您pipe()拨打电话.你必须把它之前fork():

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

#define STDIN 0
#define STDOUT 1

int main()
{
  int fd[2];
  int pid;
  char *lschar[20]={"ls",NULL};
  char *morechar[20]={"more", NULL};
  pid = fork();
  if (pid == 0) {
    /* child */
    int cpid;
    pipe(fd);
    cpid = fork();
    if(cpid == 0) {
      //printf("\n in ls \n");
      dup2(fd[1], STDOUT);
      close(fd[0]);
      close (fd[1]);
      execvp("ls",lschar);
    } else if(cpid>0) {
      dup2(fd[0],STDIN);
      close(fd[0]);
      close(fd[1]);
      execvp("more", morechar);
    }
  } else if (pid > 0) {
    /* Parent */
    waitpid(pid, NULL,0);
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

否则,更多进程没有正确的文件描述符.此外,更多进程中的waitpid()是有问题的和不必要的(更多将等待自己的输入).如果ls的输出特别长,则管道可能会变满,导致ls阻塞其写入.结果是死锁,它永远等待.因此,我也删除了违规waitpid()电话.

另外,如果你做检查的函数的返回值一样的好的做法pipe()dup2()这个错误本来是很容易找到-你会看到,你dup2()是失败.