对 dup2 使用排序

Posted

技术标签:

【中文标题】对 dup2 使用排序【英文标题】:using sort with dup2 【发布时间】:2013-05-21 17:36:24 【问题描述】:

我正在 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 从标准输入读取它对吗?有人可以帮我解决这个问题吗?

非常感谢!

【问题讨论】:

【参考方案1】:

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

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

int n = read(pipe2_ends[0], buffer, 99);
if (n < 0)  perror("read"); exit(1); 
buffer[n] = 0;
printf("%s",buffer);

【讨论】:

以上是关于对 dup2 使用排序的主要内容,如果未能解决你的问题,请参考以下文章

unix pipe() 和dup2()的使用方法和原理

dup和dup2函数简单使用

Linux dup dup2函数理解

C++ dup2 和 execl

dup2 错误的文件描述符错误

Linux系统编程---dup和dup2详解