【发布时间】:2012-07-15 22:55:43
【问题描述】:
第二轮
看了一些答案,我修改后的代码是:
int pid = fork();
if (pid == -1) {
perror("fork");
} else if (pid == 0) {
if (in) { //if '<' char was found in string inputted by user
int fd0 = open(input, O_RDONLY, 0);
dup2(fd0, STDIN_FILENO);
close(fd0);
in = 0;
}
if (out) { //if '>' was found in string inputted by user
int fd1 = creat(output, 0644);
dup2(fd1, STDOUT_FILENO);
close(fd1);
out = 0;
}
execvp(res[0], res);
perror("execvp");
_exit(1);
} else {
waitpid(pid, 0, 0);
free(res);
}
它有效,但似乎没有重新连接标准输出或类似的东西。这是执行:
SHELL$ cat > file
hello, world
this is a test
SHELL$ cat < file //no output
SHELL$ ls //no output
'' 都可以工作,但是执行后没有输出。
第一轮
我一直在用 C 编写一个相对简单的 shell,但我在实现输入 () 重定向时遇到了麻烦。帮我找出以下代码中的问题:
int fd;
int pid = fork();
int current_out;
if (in) { //if '<' char was found in string inputted by user
fd = open(input, O_RDONLY, 0);
dup2(fd, STDIN_FILENO);
in = 0;
current_out = dup(0);
}
if (out) { //if '>' was found in string inputted by user
fd = creat(output, 0644);
dup2(fd, STDOUT_FILENO);
out = 0;
current_out = dup(1);
}
if (pid == -1) {
perror("fork");
} else if (pid == 0) {
execvp(res[0], res);
perror("execvp");
_exit(1);
} else {
waitpid(pid, 0, 0);
dup2(current_out, 1);
free(res);
}
我可能有一些不必要的材料,因为我一直在尝试不同的东西来让它发挥作用。我不确定出了什么问题。
【问题讨论】:
-
current_out感觉很格格不入;例如,dup(0)复制了标准输入描述符,而不是标准输出。你确定你已经正确解析了in和input吗?在open和dup2周围添加一些调试printf()调用——或者使用strace(1)来观察你正在进行的系统调用。 -
对输入和输入非常有信心。对处理输入重定向的任何事情都没有信心;这对我来说非常新鲜和陌生。
-
您不应该在某些时候使用“0”而在其他时候使用 STDIN_FILENO。选择一个或另一个。我不确定您为什么将 dup(0) 保存为 current_out。当然 current_in 更好(尽管老实说,保留另一个 ref 并没有任何帮助)。运行
strace -o/tmp/tr -f myshell 'cat < /etc/passwd'并向我们展示 open 和 fork 之间的系统调用将使事情变得更加清晰,然后向我们展示孩子(猫)做了什么也会很好。