了解系统如何调用pipe(),fork和dup工作

时间:2017-04-22 09:37:58

标签: c shell

我在C中编写一个处理重定向操作符和管道的shell。以下想法是否适合处理管道?所以我按以下方式创建了一个管道:

  int pipefd[2];
  if (pipe(pipefd) == -1) {
        perror("pipe");
        myshell_exit(-1);
    }

然后我分叉一个新进程并在新进程中将stdout重定向到管道的一端,如下所示:

dup2(STDOUT_FILENO,pipefd[1]);

所以父进程现在可以从管道中读取并将stdin重定向到用于读取的管道的末尾。像这样。

dup2(STDIN_FILENO,pipefd[0]);

然后我分叉一个新进程,所以执行下一个命令或程序时输入pipefd[0]

示例:cat file.txt | grep string

总之,我在父进程中分叉了两个进程。一个用于执行当前程序,另一个用于下一个程序。这项任务是归纳的。

这个想法是对的吗?

这是主要功能的代码。假设所有奇怪的功能都有效。

int myshell_execute(struct processNode* list)
{
  int i;
  char* program = list->program;  // Get the program to be executed
  char ** program_args = list->program_arguments; // get the programs and arguments to be executed
  char ** redirection_string = list->redirection; //get the part of the command that contains redirection
  int *status;
  int* stdout;
  int stdout_num = 1;
  stdout = &stdout_num;
  int fileDescriptor;
  pid_t pid;
  struct processNode* next_node  = (*list).next; // next node to be handled



    if(strcmp(program,"cd") == 0)
    {
      return myshell_cd(program_args);
    }
    else if (strcmp(program,"exit") == 0)
    {
      return myshell_exit(0);
    }


  int pipefd[2];
  if (pipe(pipefd) == -1) {
        perror("pipe");
        myshell_exit(-1);
    }


// Execute the current program
  pid = fork();
  if(pid == 0)
  {  
    if(sizeOfLine(redirection_string) != 0)
    {
    redirectionHandler(redirection_string,stdout); // This works. This just handles redirection properly
    }

    if(*stdout == 1 && list->next !=NULL)
    {
       dup2(STDOUT_FILENO,pipefd[1]); // with this line of code, I intend to redirect the stdout to the file descriptor pipefd[1], so the next command can use it if there are pipes. The reason why I put it in an if is because 1) stdout may be handled by the function redirectionHandler, so we don't touch it or we are in the last node
    }
    if(execvp(program,program_args) !=-1)
    {
      perror("myshell:");
    }
     myshell_exit(-1);
  }
  else if (pid <0)
    {
      perror("myshell: ");
      myshell_exit(-1);
   }
  else
   {
     wait(status);
   }

  // Go to the next command to be executed
   if(list->next != NULL) // I parse the command line in a convenient mannner. Thar works too
   {
     dup2(STDIN_FILENO,pipefd[0]);

      pid = fork();
      if(pid == 0)
       {  
         return myshell_execute(next_node);
       }
      else if (pid <0)
      {
          perror("myshell: ");
          myshell_exit(-1);
      }
      else
      {
      wait(status);
      }

    }
   else
   {
     myshell_exit(0);
   }



} 

所有不包含管道的命令都可以正确处理,但问题是当有管道要处理时。

0 个答案:

没有答案
相关问题