C: Child I/O with parent 和键盘
C: Child I/O with parent and keyboard
简化问题:
我有一个 parent 进程创建了一个 child 进程,如下所示:
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]);
但是,我需要 child 进程才能接收用户的输入。使用此方法,child 的标准输入从键盘更改为 parent 的标准输出。如何保持与键盘和 parent 的通信?
另外,parent是服务器的客户端,因此多个parent可以运行在同一台或不同的机器上,使[=之间共享文件49=] 和 child 困难,因为任何 parent 的 child 都可以访问任何其他 parent 的文件。
注意:我更愿意将 parent 的标准输出映射到 child 的输入,因为我没有编写 c 代码,我想 re-route 其 printf 语句为 child。
原版:
我正在使用 tcl 为 c 代码制作 GUI。 tcl是c代码的child进程,我使用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 代码而不是键盘接收,并且将无法读取用户的响应.
有没有办法指定从键盘获取响应?或者我应该将 c 代码的标准输出映射到 tcl 的不同 fd 吗?如果是这样,我如何指定从 keyboard/new fd.
以下是我如何使 tcl 成为 c 代码的 child 进程:
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]);
听起来好像 child 会有一个传统的 command-line 接口,例如 line-buffered。我建议这些设计更改:
- 将 two-way 管道修改为 child 的标准输入和输出以外的内容(您可以 read/write 在其他流上)
- 在 child
内进行更改可能最简单
- 你可以在child中使用
dup2
等来修改管道。这就留下了如何为 child. 获取可用的键盘界面的问题
- 您可以通过直接打开
/dev/tty
解决 那个 问题,然后(再次与 dup2
和朋友一起)使文件在 [=11= 上打开] 进入 child 的标准输入和输出。
例如,dialog program has a feature for reading data via a pipe (at the shell level, that is its standard input), and in initialization, changing that into a different stream and opening /dev/tty
for a "real" standard input. Your problem is a little more complicated (with both input and output pipes), but reading the dialog
source may be helpful. For reference, that is the init_dialog
function in util.c
(source here).
简化问题:
我有一个 parent 进程创建了一个 child 进程,如下所示:
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]);
但是,我需要 child 进程才能接收用户的输入。使用此方法,child 的标准输入从键盘更改为 parent 的标准输出。如何保持与键盘和 parent 的通信?
另外,parent是服务器的客户端,因此多个parent可以运行在同一台或不同的机器上,使[=之间共享文件49=] 和 child 困难,因为任何 parent 的 child 都可以访问任何其他 parent 的文件。
注意:我更愿意将 parent 的标准输出映射到 child 的输入,因为我没有编写 c 代码,我想 re-route 其 printf 语句为 child。
原版:
我正在使用 tcl 为 c 代码制作 GUI。 tcl是c代码的child进程,我使用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 代码而不是键盘接收,并且将无法读取用户的响应.
有没有办法指定从键盘获取响应?或者我应该将 c 代码的标准输出映射到 tcl 的不同 fd 吗?如果是这样,我如何指定从 keyboard/new fd.
以下是我如何使 tcl 成为 c 代码的 child 进程:
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]);
听起来好像 child 会有一个传统的 command-line 接口,例如 line-buffered。我建议这些设计更改:
- 将 two-way 管道修改为 child 的标准输入和输出以外的内容(您可以 read/write 在其他流上)
- 在 child 内进行更改可能最简单
- 你可以在child中使用
dup2
等来修改管道。这就留下了如何为 child. 获取可用的键盘界面的问题
- 您可以通过直接打开
/dev/tty
解决 那个 问题,然后(再次与dup2
和朋友一起)使文件在 [=11= 上打开] 进入 child 的标准输入和输出。
例如,dialog program has a feature for reading data via a pipe (at the shell level, that is its standard input), and in initialization, changing that into a different stream and opening /dev/tty
for a "real" standard input. Your problem is a little more complicated (with both input and output pipes), but reading the dialog
source may be helpful. For reference, that is the init_dialog
function in util.c
(source here).