C编程-使用管道处理stdout和stdin
我正在编写一个由父母和他的孩子组成的C程序(使用fork)。他们通过管道交流。父级通过标准输出写入管道,子级通过标准输入从管道读取。连接后,父级将“helloworld”写入管道,子级调用exec。我的代码如下所示:C编程-使用管道处理stdout和stdin,c,linux,exec,fork,pipe,C,Linux,Exec,Fork,Pipe,我正在编写一个由父母和他的孩子组成的C程序(使用fork)。他们通过管道交流。父级通过标准输出写入管道,子级通过标准输入从管道读取。连接后,父级将“helloworld”写入管道,子级调用exec。我的代码如下所示: 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
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;
}
intmain(intargc,char*argv[])
{
int p,a;
char-buf[1024];
文件*文件;
尺寸(单位:nread);
int-fd[2];
字符参数[PATH_MAX];
如果(管道(fd)这不起作用,我不知道为什么
因为您使用的是dup()
。要将子进程的标准输入重定向到管道,正确的系统调用是dup2()
请注意,在父代码分支中根本不需要调用dup()
。只需写入管道的写入端:
write( fd[1], "Hello World\n", 12 );
但是,如果您还想在父分支中使用execvp来启动另一个程序并重定向其标准输出,那么您还必须在此处使用dup2()
:
dup2( fd[1], 1 ); // this "dup"s the write-end of the pipe onto STDOUT
close( fd[1] );
有关详细信息,请阅读dup2的
另外,代码的另一个问题是使用execvp和argv
作为参数列表。这将导致rev
和wc
等程序接收父程序的整个命令行,从而找到要处理的参数,而不是从标准输入读取的参数。您可能希望
execvp( argv[1], &argv[1] );
您在以下代码中错误地使用了execvp()
:
sprintf(argument,"/usr/bin/%s",argv[1]);
execvp(argument,argv);
如果您通过/a.out wc
运行程序,那么在这种情况下/usr/bin/wc
的参数将是/a.out wc
,即/a.out
的原始参数列表,然后/usr/bin/wc
将尝试在当前工作目录中打开名为wc
的文件,而不是从标准输入读取
因此,将上述代码更改为
sprintf(argument,"/usr/bin/%s",argv[1]);
execvp(argument,NULL);
如果可以解决这个问题,这次/usr/bin/wc
的参数列表将是一个空列表。父亲仍在写入1
而不是写入a
,孩子也没有从管道中读取。
sprintf(argument,"/usr/bin/%s",argv[1]);
execvp(argument,NULL);