【发布时间】:2015-06-19 04:51:44
【问题描述】:
我在玩了一下系统功能和文件编辑,发现了一个我不太了解的奇怪行为。
我有一个读取标准输入的第一个进程,然后在另一个也读取标准输入的进程上 fork(调用系统函数)。
在第一种情况下,我没有将任何内容重定向到第一个进程的标准输入,一切都按预期工作,两个进程都从我的提示中读取。
但在第二种情况下,我通过管道或将文件重定向到第一个进程,分叉的进程开始读取“随机”数据。
这是我的模拟示例:
fork.c
#include <stdlib.h>
#include <stdio.h>
int main() {
char buf[10];
fgets(buf,10,stdin);
printf("Buff: %s\n", buf);
system("./print");
fgets(buf,10,stdin);
printf("Buff: %s\n", buf);
return 0;
}
打印.c
#include <stdlib.h>
#include <stdio.h>
int main() {
char buf[10];
fgets(buf,10,stdin);
printf("Buff: %s\n", buf);
}
如果我跑
echo "just another awesome input" | ./fork
我明白了
Buff: just anot
Buff: Ðhuÿ
Buff: her aweso
对于孩子来说,输入总是不同的(我猜它正在读取内存中的某个随机位置......)。
谁能解释这种行为?我知道孩子继承了 fork 的文件描述符,但我不明白为什么它不能只读取与父级相同的输入,或者至少是确定性的。
我想知道在调用我的 fork 程序时是否有一个技巧,说我希望“fork”有这个输入,而它的子进程有另一个输入。
【问题讨论】:
-
问:你能给我们看看 fork() (以及,大概,随后的 exec())吗?
-
分叉由系统完成(我的代码中为
system("./print");)。 -
来自
man system,它像这样fork执行shell:execl("/bin/sh", "sh", "-c", command, (char *) 0);,所以它接收的io流完全不同。 -
查看 system.c 和 man exec,execl 不会对文件描述符进行任何更改。看一下 strace,似乎父母一次消耗了全部输入,这可以解释为什么孩子无法阅读它。但我想知道是否有办法将某些东西传递给孩子(不改变 C 代码)。
标签: c fork system stdin file-descriptor