2021年2月6日星期六

Implementing Linux shell in C; parent doesn't wait for child process to communicate through pipe

I'm trying to implement a pipe so that I can carry out commands like "ls | sort". My main process forks a child process which creates a pipe, forks another child, and then executes the command on the left side of the pipe, using execvp. It's child (the grandchild process) should also run the code on the right side of the pipe. My code works, however, for some reason, after having executed the execvp call in the child process, my program refuses to wait for the child's child, prints out my user input prompt token ("SHELL:~$"), and then prints out the grandchild's output. For instance, with an input of ls | sort, I get an output of

SHELL:~$ a  boing.txt  c  d  t  

I don't get another SHELL:~$ prompt after I receive that output, but I can continue to issue more commands for my shell, and they'll execute perfectly. I just want to know how to make the child process wait for it's child's process until it's ready so that I can print the output before my code loops through and prints SHELL:~$ again. Am I on the right track assuming it's a matter of manipulating the first child process when it executes the execvp command? Here's my relevant code:

pid_t pipid = fork();              if(pipid < 0)              {                  fprintf(stderr, "Fork Failed");                  return 1;              }             if(pipid == 0)             {                                 if(background == 1)                  {                      setpgid(0, 0);                  }                  int iopipe[2];                  if(pipe(iopipe) < 0)                  {                      fprintf(stderr, "Error occurred opening a pipe\n");                      return 1;                  }                  pid_t pipid2;                  int status;                  pipid2 = fork();                  int status2;                  if(pipid2 < 0)                  {                      fprintf(stderr, "Fork Failed");                      return 1;                  }                                    if(pipid2 == 0)                  {                      int fdpipch = dup2(iopipe[0], STDIN_FILENO);                      if(fdpipch < 0)                      {                          perror("Error redirecting output into pipe\n");                          exit(1);                      }                        close(iopipe[1]);                      close(iopipe[0]);                                            int exechild = execvp(argsp2[0], argsp2);                      if(exechild == -1)                      {                          printf("%s: Command not found.\n", argsp2[0]);                          exit(1);                      }                        close(fdpipch);                  }                            else if(pipid2 > 0)                      {                             int fdpippar = dup2(iopipe[1], STDOUT_FILENO);                          close(iopipe[0]);                          close(iopipe[1]);                          if(fdpippar < 0)                          {                              perror("Error redirecting output into pipe\n");                              exit(1);                          }                          int exepar = execvp(argsp1[0], argsp1);                          printf("YO %d\n", exepar);                                                    if(exepar == -1)                          {                              printf("%s: Command not found.\n", argsp1[0]);                              exit(1);                          }                          close(fdpippar);                          waitpid(pipid2, &status, 0);                     }                               }                      wait(NULL);     
https://stackoverflow.com/questions/66083245/implementing-linux-shell-in-c-parent-doesnt-wait-for-child-process-to-communic February 07, 2021 at 08:00AM

没有评论:

发表评论