How execv gets the output from pipe?

懵懂的女人 提交于 2019-12-11 11:34:54

问题


referring to the old homework question : /* implementing "/usr/bin/ps -ef | /usr/bin/more" */ using pipes.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
  int fds[2];
  int child[2];
  char *argv[3];
  pipe(fds);
  if (fork()== 0) {
    close(fds[1]);
    close(STDIN_FILENO); dup(fds[0]); /* redirect standard input to fds[1] */
    argv[0] = "/bin/more";
    argv[1] = NULL;           /* check how the argv array is set */
    execv(argv[0], argv);// here how execv reads from stdin ??
    exit(0);


  }
  if (fork() == 0) {
    close(fds[0]);
    close(STDOUT_FILENO); dup(fds[1]);  /* redirect standard output to fds[0] */
    argv[0] = "/bin/ps";
    argv[1] = "-e"; argv[2] = NULL;
    execv(argv[0], argv);
    exit(0);

  }

  close(fds[1]);
  wait(&child[0]);
  wait(&child[0]);  
} 

After redirecting the fd to standard output, how does execv reads from it. Is it inbuilt in execv that it reads from standard input before executing the command? I am unable to get this concept.


回答1:


Your question is based on a false premise -- execv doesn't read from anywhere, nor does it need to. It is more that reads from the stdin it inherits across the call to execv. The reason more reads from stdin is because it's a filter and, like most filters, it defaults to reading from stdin if another input source isn't specified on the command line. (Otherwise, /usr/bin/ps -ef | /usr/bin/more wouldn't work.)




回答2:


In your second fork call, I would change the code from this:

  if (fork() == 0) {
    close(fds[0]);

to this:

  close(fds[0]);
  if (fork() == 0) {

The argv[1] for the ps call should be -ef.

All programs will read from stdin to get terminal input and write to stdout to deliver data to the terminal, if they do not do anything to change the default settings for those streams. What the code is doing is modifying stdin for more and modifying stdout for ps. The stdout for more is the same as the current process (the parent). Thus, your program is redirecting ps terminal output data to be the terminal input for more.

The pipe call returns two file descriptors that are connected to each other unidirectionally. When ps writes to its stdout, it is going to the dupd fds[1]. When more reads from its stdin, it is the dupd fds[0]. So, more picks up the output of ps.



来源:https://stackoverflow.com/questions/11373511/how-execv-gets-the-output-from-pipe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!