[英]wc: standard input: Bad file descriptor on fork + pipe + execlp
I know this is a simple exercise but I'm having troubles with it. 我知道这是一个简单的练习,但是我遇到了麻烦。 I'm trying to emulate:
我正在尝试模仿:
grep arg1 arg2 | wc -l
I'm getting the following error: "wc: standard input: Bad file descriptor when executing". 我收到以下错误:“ wc:标准输入:执行时文件描述符错误”。 This is my code:
这是我的代码:
int main(int argc, char *argv[])
{
if (argc != 3) usage();
int pd[2]; //Pipe descriptor
pipe(pd);
int pid = fork();
if (pid < 0) perror("Something failed on trying to create a child process!\n");
else if (pid == 0) { //Child
dup2(pd[1], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
} else { //Parent
dup2(pd[0], 1);
close(pd[0]);
close(pd[1]);
execlp("grep", "grep", argv[1], argv[2], (char *)NULL);
}
}
What can be the problem? 可能是什么问题?
You have: 你有:
else if (pid == 0) { //Child
dup2(pd[1], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
}
You need: 你需要:
else if (pid == 0) { //Child
dup2(pd[0], 0);
close(pd[0]);
close(pd[1]);
execlp("wc", "wc", "-l", (char *)NULL);
fprintf(stderr, "Failed to execute 'wc'\n");
exit(1);
}
The crucial change is the dup2()
; 关键的更改是
dup2()
; your code copies the write end of the pipe to the child's standard input , which is not a recipe for happiness. 您的代码会将管道的写入端复制到孩子的标准输入中,这不是幸福的秘诀。 The revised code copies the read end of the pipe to the child's standard input.
修改后的代码将管道的读取端复制到孩子的标准输入中。 It's easy enough to remember which is which: stdin is file descriptor 0 and pipe descriptor 0 of the pair is the input descriptor (read end of the pipe), while stdout is file descriptor 1 and pipe descriptor 1 of the pair is the output descriptor (write end of the pipe).
容易记住哪个是:stdin是文件描述符0,而该对中的管道描述符0是输入描述符(管道的读取端),而stdout是文件描述符1,而该对中的管道描述符1是输出描述符。 (写出管道的末端)。
You need the converse change in the 'parent' code. 您需要在“父代”代码中进行相反的更改。
The error arises when wc
tries to read from a file descriptor that's only open for writing. 当
wc
尝试从仅开放用于写入的文件描述符中读取时,会出现此错误。
Note that if execlp()
— or any other member of the exec*()
family of functions — returns, it failed. 请注意,如果
execlp()
或exec*()
函数系列的任何其他成员返回,则它将失败。 It is important to deal with that error, usually by reporting a problem on standard error and exiting. 重要的是,通常通过报告有关标准错误的问题并退出来处理该错误。 It is seldom correct to have no statement after the
exec*()
operation. 在
exec*()
操作之后没有语句很少是正确的。
As I can see, you trying to replicate the terminal command of "wc -l | grep something something". 如我所见,您尝试复制终端命令“ wc -l | grep某些东西”。
The problem is that you are not providing input to wc. 问题是您没有向wc提供输入。 wc -l command requires an input for which it should count its lines.
wc -l命令需要一个输入,它应该为其行数。 Try something like:
尝试类似:
execlp("wc", "wc", "-l", "somefile.txt", (char *)NULL);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.