缩短的问题:
我有一个创建子进程的父进程,如下所示:
int me2them[2], them2me[2];
pipe(me2them);pipe(them2me);
if (!fork()){
close(0); dup2(me2them[0],0); close(me2them[0]);
close(1); dup2(them2me[1],1); close(them2me[1]);
char * cmds[] = {"wish", "myProg.tcl",NULL};
execvp(cmds[0], cmds);
fprintf(stderr, "Unable to exec 1\n");
exit(-1);
}
close(0); dup2(them2me[0],0); close(them2me[0]);
close(1); dup2(me2them[1],1); close(me2them[1]);
但是,我需要子进程能够接收用户的输入。使用此方法,子项的stdin从键盘更改为父项的stdout。如何与键盘和父母保持通信?
此外,父级是服务器的客户端,因此多个父级可以在相同或不同的计算机上运行,使得父级和子级之间的共享文件很难,因为任何父级的子级都可以访问任何其他父级。父母的档案。
注意:我更喜欢将父节点的stdout映射到子节点的输入,因为我没有编写c代码,我想将其printf语句重新路由到儿童。
原始版本:
我使用tcl为c代码制作GUI。 tcl是c代码的子进程,我使用I / O重定向使c的stdout成为tcl的stdin,而tcl的stdout成为c的stdin。但是,有一个部分,其中c请求用户的名称,它通过stdout将请求发送到tcl代码的stdin,没有问题,然后tcl请求名称。 tcl名称请求存在两个问题:
1)tcl实际上是将请求发送到c代码,导致c代码将请求误认为是实际名称(通过将请求发送到stderr而不是stdout来解决)
2)当tcl尝试获取名称的用户输入时,它将检查stdin,它被映射为从c代码而不是键盘接收,并且将无法读取用户的响应。 / p>
有没有办法指定从键盘获取响应?或者我应该将c代码的stdout映射到tcl的不同fd?如果是这样,我如何指定从键盘/新fd。
以下是我如何使tcl成为c代码的子进程:
int me2them[2], them2me[2];
pipe(me2them);pipe(them2me);
if (!fork()){
close(0); dup2(me2them[0],0); close(me2them[0]);
close(1); dup2(them2me[1],1); close(them2me[1]);
char * cmds[] = {"wish", "myProg.tcl",NULL};
execvp(cmds[0], cmds);
fprintf(stderr, "Unable to exec 1\n");
exit(-1);
}
close(0); dup2(them2me[0],0); close(them2me[0]);
close(1); dup2(me2them[1],1); close(me2them[1]);
答案 0 :(得分:1)
听起来好像孩子会有传统的命令行界面,例如行缓冲。我建议改变这些设计:
dup2
等来修改管道。这就留下了如何为孩子提供可用键盘界面的问题。/dev/tty
来解决 问题,并且(再次使用dup2
和朋友)将文件在/dev/tty
打开,进入孩子的标准输入和输出。例如,dialog程序具有通过管道(在shell级别,即其标准输入)读取数据的功能,并在初始化中将其更改为不同的流并打开{{ 1}}用于“真实”标准输入。您的问题稍微复杂一些(包括输入和输出管道),但阅读/dev/tty
源可能会有所帮助。作为参考,这是dialog
中的init_dialog
函数(来源here)。