C编程-使用管道处理stdout和stdin [英] C programming - handling stdout and stdin using pipes

查看:129
本文介绍了C编程-使用管道处理stdout和stdin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个由父母和他的孩子组成的C程序(使用fork).他们通过管道沟通.父级通过标准输出写入管道,子级通过标准输入从管道读取.连接后,父级将"hello world"写入管道,而子级调用exec.我的代码如下:

I am writting a C program formed by a parent and his child (using fork). They comunicate through a pipe. Parent writes into the pipe through the standard output and child reads from the pipe through the standard input. Once they are connected, parent writes "hello world" into the pipe, and son calls exec. My code looks like this:

int main(int argc, char *argv[])
{
 int p, a;
 char buf[1024];
 FILE *file;
 size_t nread;
 int fd[2];
 char argument[PATH_MAX];

 if(pipe(fd)<0){
 return 1;
 }

 p = fork();
 switch(p){
   case -1: perror("Error en el fork()"); return 1;
   case 0:
     close(fd[1]);
     close (0);
     dup(fd[0]);
     close(fd[0]);
     sprintf(argument,"/usr/bin/%s",argv[1]);
     execvp(argument,argv);
     perror("Error en el execv");
     exit(1);
   default: break;
 }
 close(fd[0]);
 close(1);
 a = dup(fd[1]);
 close(fd[1]);
 write(1,"Hello World\n",12);
 close(a);
 wait(NULL);
 return 0;
}

由子级执行的

exec函数调用rev或wc函数.如果不带参数调用,则应将rev和wc应用于标准输入(在我的情况下为"hello world").但这是行不通的,我也不知道为什么.任何帮助将不胜感激.

exec function executed by the son calls functions rev or wc. If called without arguments, rev and wc should be applied to the standard input ("hello world" in my case). But this is not working and I don't know why. Any help would be really appreciated.

推荐答案

这不起作用,我也不知道为什么

因为您正在使用dup().要将子进程的标准输入重定向到管道,要使用的正确系统调用是dup2()

Because you are using dup(). To redirect the standard input of the child process to the pipe, the correct system call to use is dup2()

case 0:
    close( fd[1] );
    dup2( fd[0], 0 ); // this "dup"s the read-end of the pipe onto STDIN
    close( fd[0] );

请注意,在父代码分支中根本不需要dup()调用.只需写入管道的写入端即可:

Note that you don't need the dup() call at all in the parent code branch. Just write to the write-end of the pipe:

write( fd[1], "Hello World\n", 12 );

但是,如果您还想在父分支中使用execvp来启动另一个程序并重定向其标准输出,那么您也必须在这里使用dup2():

However, if you want to use execvp in the parent branch also, to launch another program with its standard output redirected, then you would have to use dup2() here also:

dup2( fd[1], 1 ); // this "dup"s the write-end of the pipe onto STDOUT
close( fd[1] );

有关dup2的详细信息,请阅读联机帮助页.

Read the manpage for dup2 for details.

此外,您的代码的另一个问题是使用argv作为参数列表的execvp.这将导致revwc之类的程序接收父程序的整个命令行,从而找到要处理的参数,而不是从标准输入中读取.你可能想要

Also, another problem with your code is the use of execvp with argv as the argument list. This will cause programs like rev and wc to receive the entire command line of the parent program and thus find an argument to process rather than read from standard input. You probably want

execvp( argv[1], &argv[1] );

这篇关于C编程-使用管道处理stdout和stdin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆