1

我正在 linux 中试验这个 dup2 命令。我编写了如下代码:

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

int main()
{
    int pipe1_ends[2];
    int pipe2_ends[2];
    char string[]  = "this \n is \n not \n sorted";
    char buffer[100];
    pid_t pid;

    pipe(pipe1_ends);
    pipe(pipe2_ends);

    pid = fork();


    if(pid > 0) { /* parent */

        close(pipe1_ends[0]);
        close(pipe2_ends[1]);

        write(pipe1_ends[1],string,strlen(string));
        read(pipe2_ends[0], buffer, 100);   
        printf("%s",buffer);
        return 0;
   }

   if(pid == 0) { /* child */
       close(pipe1_ends[1]);
       close(pipe2_ends[0]);
       dup2(pipe1_ends[0], 0);
       dup2(pipe2_ends[1],1);
       char *args[2];
       args[0] = "/usr/bin/sort";
       args[1] = NULL;
       execv("/usr/bin/sort",args);    
   }
  return 0;
}

我希望这个程序的行为如下:它应该分叉一个孩子并用排序过程替换它的图像。并且由于 stdin 和 stdout 被 dup2 命令替换,我希望 sort 从管道读取输入并将输出写入由父级打印的另一个管道。但是排序程序似乎没有读取任何输入。如果没有给出命令行参数,sort 从标准输入读取它对吗?有人可以帮我解决这个问题吗?

非常感谢!

4

1 回答 1

1

嗯。发生的事情是您还没有完成写入:在将数据发送到子进程之后,您必须通过关闭 pipe1_ends[1] 或调用它来告诉它您已完成写入shutdown(2)。您还应该在循环中调用 write/read,因为在一般情况下,read 至少不会一次性给您所有结果。显然,完整的代码会检查所有返回值,不是吗?

最后一件事:您的 printf 严重损坏。它只能接受以null结尾的字符串,并且返回的结果read不会以null结尾(它是一个带长度的缓冲区,另一种知道结尾在哪里的常用方法)。你要:

int n = read(pipe2_ends[0], buffer, 99);
if (n < 0) { perror("read"); exit(1); }
buffer[n] = 0;
printf("%s",buffer);
于 2013-05-21T18:12:52.233 回答