C:包含父级和键盘的子I / O

时间:2015-04-29 23:13:34

标签: c user-interface pipe tcl io-redirection

缩短的问题:

我有一个创建子进程的父进程,如下所示:

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]);

1 个答案:

答案 0 :(得分:1)

听起来好像孩子会有传统的命令行界面,例如行缓冲。我建议改变这些设计:

  • 将对孩子的双向管道修改为标准输入和输出以外的其他管道(可以在其他流上读/写)
  • 在孩子中做出改变可能是最简单的
  • 您可以在子项内使用dup2等来修改管道。这就留下了如何为孩子提供可用键盘界面的问题。
  • 您可以直接打开/dev/tty来解决 问题,并且(再次使用dup2和朋友)将文件在/dev/tty打开,进入孩子的标准输入和输出。

例如,dialog程序具有通过管道(在shell级别,即其标准输入)读取数据的功能,并在初始化中将其更改为不同的流并打开{{ 1}}用于“真实”标准输入。您的问题稍微复杂一些(包括输入和输出管道),但阅读/dev/tty源可能会有所帮助。作为参考,这是dialog中的init_dialog函数(来源here)。