我正在写一个由父母和他的孩子组成的C程序(使用叉)。 他们通过pipe道交stream。 父级通过标准输出写入pipe道,子级通过标准input从pipe道读取。 一旦他们连接,父母写入“hello world”到pipe道中,儿子调用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)<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 Worldn",12); close(a); wait(NULL); return 0; }
儿子执行的exec函数调用函数rev或wc。 如果没有参数调用,rev和wc应该被应用到标准input(在我的情况下是“hello world”)。 但是这不起作用,我不知道为什么。 任何帮助将非常感激。
如何使用c#访问控制面板 – >声音 – >通信对话框?
.NET:如何使用临时文件名传递命令行参数
是否有可能编程启用/禁用硬件?
“添加成员”到一个types,而不是在PowerShell中只有一个types的对象
C ++ Wordlist; 在vector/地图中find一个完整的描述
这不工作,我不知道为什么
因为你正在使用dup() 。 要将子进程的标准输入重定向到管道,正确的系统调用是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()调用。 只需写入管道的写入端:
write( fd[1],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] );
sprintf(argument,argv);
如果你通过./a.out wc运行程序,那么在这种情况下, /usr/bin/wc的参数就是./a.out wc ,即原来的参数列表为./a.out ,那么/usr/bin/wc将尝试在当前工作目录中打开一个名为wc的文件,而不是从标准输入中读取。
所以改变上面的代码
sprintf(argument,NULL);
应该修复这个问题,这次到/usr/bin/wc的参数列表将是一个空列表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。