popen2()如何在c中工作?

时间:2015-11-04 11:35:55

标签: c pipe fork dup2

我试图在我的程序中使用pipe,fork和dup.i执行md5sume命令,找到成功运行的和代码,但我无法理解某些代码行。这是我的代码:

event.target.tagName
int infp, outfp;

char buf[128];

if (popen2("md5sum", &infp, &outfp) <= 0)

  {

    printf("Unable to exec sort\n");

    exit(1);

  }

write(infp, "hello\n", 2);

close(infp);

*buf = '\0';

read(outfp, buf, 128);

printf("buf = '%s'\n", buf);

return 0;

}

我不懂popen功能。这条线究竟做了什么?

int p_stdin[2], p_stdout[2];

pid_t pid;

if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)

  return -1;

pid = fork();

if (pid < 0)

  return pid;

if (pid == 0)

  {

    close(p_stdin[WRITE]);

    dup2(p_stdin[READ], READ);

    close(p_stdout[READ]);

    dup2(p_stdout[WRITE], WRITE);

    execl("/bin/sh", "sh", "-c", command, NULL);

    perror("execl");

    exit(1);

  }

else 

  {

if (infp == NULL)

    close(p_stdin[WRITE]);

else

    *infp = p_stdin[WRITE];

if (outfp == NULL)

    close(p_stdout[READ]);

else

    *outfp = p_stdout[READ];
  }

return pid;

}

管道如何相互通信?

1 个答案:

答案 0 :(得分:1)

  

我不懂popen功能。

     

管道如何相互通信?

pipe():管道是单向的,内核中是字节流缓冲区。由于它是字节流类型,因此写入器可以以任意数量的字节写入,读取器可以读出任意数量的字节。但是,请注意顺序读取是可能的,但是搜索(如lseek)是不可能的。由于管道是单向的,因此写入管道的数据应在内核中缓冲,直到从管道的读取端读取。此外,如果管道已满,则写入块。

让我们考虑fd是一个包含2个文件描述符的整数数组(int fd [2]),然后管道(fd)系统调用将创建一个管道并返回一对文件描述符,使得fd [1](stdout)是1)应该是管道的写端,而fd [0](stdin为0)应该是管道的读端。与命名管道(如FIFO - 文件系统中具有名称的管道)不同,匿名管道只能在父子等相关进程之间使用。因此,fork应该在子节点中复制这两个父文件描述符,从而父节点与子节点共享管道,以便子节点写入写入端,父节点应从管道的读取端读取,或者父节点应写入写入 - 结束和孩子应从管道的读取端读取。应注意确保按照方案关闭父节点或子节点的未使用的读取(fd [0])文件描述符/未使用的写入(fd [1])文件描述符。

popen(): popen使您可以将另一个程序作为新进程调用,从而向其传输数据或从中接收数据。如果是popen,请注意数据流的方向基于第二个参数。我们不需要手动创建子进程,因为popen会自动创建子进程,启动shell并执行通过popen传递的命令参数。它还根据类型参数自动在父级和子级之间建立适当的读取或写入流。

因此,popen()简化了事情,因为它避免了手动调用/调用管道,fork,exec的需要,并且根据参数类型自动简化父/子之间的适当流的建立。但是,popen的另一面是,应该注意的是,popen()的每次调用都会导致创建额外的进程 - 也就是说,每次调用shell时,都会调用shell,而不是正在调用的程序。转向导致高资源消耗。