简体   繁体   中英

Having issues with pipe, fork, dup2

I am using pipes, fork , dup2 to implement “ls | more” or “ls | sort” etc. I am just not able to understand the issue here. When I run my program, I get this error:

./a.out  
Missing filename ("less --help" for help)

Why am I getting "less" ??

What is wrong with this code ? If I change “more” to “ls” again, it works fine. I mean, its like doing 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;
}

Appreciate your help.

Your main problem lies in your placement of the pipe() call. You must call it before you 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;
}

Otherwise, the more process doesn't have the correct file descriptors. Further, the waitpid() in your more process is problematic and unnecessary (more will wait for input on its own). If ls had a particularly long output the pipe could get full causing ls to block on its writes. The result is a deadlock and it waits forever. Hence, I've also removed the offending waitpid() call.

Also, if you make a good practice of checking the return values of functions like pipe() and dup2() this error would have been much easier to find -- you would have seen that your dup2() was failing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM