C ++管道问题 [英] C++ piping issue
问题描述
我试图fork我的c ++程序,并将父输出到childs输入,我使用pipe()和fork()。在程序的目录中有一个名为input.txt的文件。不幸的是,我得到的唯一输出是wc:stdin:read:Bad file descriptor。有人知道为什么是这样吗?如果是这样我做错了什么?感谢
I am trying to to fork my c++ program and direct the parents output into the childs input, I am using pipe() and fork(). In the directory of the program there is a file called input.txt. Unfortunately the only output I get is "wc: stdin: read: Bad file descriptor". Does anyone know why this is? If so what am I doing wrong? Thanks
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main(int argc, char *argv[]){
int pipes[2],pid,stdIn,stdOut;
stdIn = dup(0);
stdOut = dup(1);
pipe(pipes);
pid = fork();
if(pid == 0){
dup2(pipes[1],0);
close(pipes[1]);
execlp("wc","wc",NULL);
}
else{
dup2(pipes[0],1);
close(pipes[0]);
std::cout<<"input.txt"<<std::endl;
dup2(stdOut,0);
std::cout<<"parent done\n";
wait(NULL);
}
std::cout<<"after"<<std::endl;
return 0;
}
推荐答案
在您的程序中固定:
- 使用
STDIN_FILENO
和STDOUT_FILENO
而不是0和1.这个值可能会在不同的平台上更改,你也犯了一个错误,如果你使用名称而不是值,可能可以避免,例如dup2(stdOut,0);
重复stdin
,您需要复制stdout $
从 -
您没有调用
pipe()
或execlp()
检查故障。你应该这样做:
stdin
中读取 wc
,然后将input.txt字符串传递给它 - 它将返回stats那个字符串,不是为文件。你可以修复它为该文件打开一个文件描述符,或者使用 exec c>与 cat
。
- Use
STDIN_FILENO
andSTDOUT_FILENO
instead of 0 and 1. This values may change on different platforms and you have also made a mistake which could probably be avoided if you've used names instead of value, e.g.dup2(stdOut,0);
duplicatedstdin
and you need to duplicatestdout
here. - You should close write end of the pipe in both child and parent.
- By making
wc
read fromstdin
, you are then passing "input.txt" string to it - it will return stats for that string, not for the file. You could either fix it be opening a file descriptor for that file or usingexec*
withcat
. None of your calls the functions like
pipe()
orexeclp()
checks for failure. You should do it like that:
if (pipe(pipes) == -1) {
perror("pipe");
exit(1);
}
您不需要 stdIn
变量。
您将在下面找到固定代码(5)中描述的):
You will find fixed code below (it does not implement what I've described in the (5) though):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int pipes[2], pid, stdOut;
stdOut = dup(STDOUT_FILENO);
pipe(pipes);
pid = fork();
if (pid == 0) {
dup2(pipes[0], STDIN_FILENO);
/* You need to close write end of the pipe here */
close(pipes[1]);
execlp("wc", "wc", NULL);
} else {
std::cout << "Parent setup" << std::endl;
dup2(pipes[1], STDOUT_FILENO);
/* You need to close write end of the pipe here as well */
close(pipes[1]);
/* This will only send the string "input.txt" through the pipe, to the
* wc command */
std::cout << "input.txt" << std::endl;
dup2(stdOut, STDOUT_FILENO);
std::cout << "Parent done" << std::endl;
wait(NULL);
}
std::cout << "Program finished" << std::endl;
return 0;
}
EDIT:其他答案,你可以简单地使用 xargs wc
来读取stdint作为文件参数:
As suggested in the comment to the other answer, you could simple use xargs wc
to read stdint as file argument:
execlp("xargs", "xargs","wc",NULL);
这篇关于C ++管道问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!