我正在编写一个具有一些类似于Shell的功能的C程序,其中,在子进程中运行的程序是通过后台的readline接口启动的。
我目前遇到的一个问题是,一旦产生了这样的子进程并再次开始输入输入字符,这些字符便会通过stdin被产生的子进程接收。鉴于我不会在分支孩子的文件描述符后对其进行修改,并且我了解这意味着它们都与主进程共享STDIN_FILENO
底层的相同流,因此这并不奇怪。
但是,这不是我想要的。我希望我的程序像bash
在这方面,以便在后台启动正在进行的进程后重新获得提示后,在该提示上键入的任何字符只能由bash看到,而不能由生成的进程看到。这就是我的问题所在,因为我什至不了解bash是如何做到的。在/proc/.../fd/0
中寻找bash
以及所有产生的进程,它们始终指向同一伪终端。只需将生成的进程标准输入重定向到例如/dev/null
显然也会产生不同的行为。
这里我不需要完整的实现,只是一个一般提示。
编辑:我刚刚发现,如果我使用带有/dev/null
标志的/dev/null
命令打开open
,将stdin重定向到O_RDWR
确实可以完成。
然后,我的程序似乎按照我想要的方式运行,除了以这种方式启动的子进程在我运行<defunct>
时显示为ps
。我不确定为什么会这样。
编辑:我想我现在已经知道了,执行此操作的最简单方法似乎是创建一个伪终端从站,然后将孩子的标准输入重定向到它:
int master;
int slave;
openpty(&master, &slave, nullptr, nullptr, nullptr);
dup2(slave, STDIN_FILENO);
答案 0 :(得分:0)
好吧,因此您希望能够启动异步子进程,使其输入直接连接到/ dev / null,并且在死时不会变成僵尸(在Unix或类似Unix的系统上)。
对于重定向部分,常见的方法是关闭fork和exec之间的标准输入文件(文件号0):
pid = fork();
if (pid == 0) { // in child
close(0); // close standard input
execve(...);
}
如果不关闭文件1和2,则子项的输出仍将转到终端。您可以关闭它们,但是任何输出都会被静默丢弃...
对于僵尸()部分,在分叉之前就足以忽略SIGCHLD信号了:
signal(SIGCHLD, SIG_IGN);
pid = fork(); // this child will never become a zombie process
参考文献:男人叉子,男人等待,男人执行