如何让 tcsetpgrp() 在 C 中工作?
我正在尝试为子进程(通过 fork())提供对终端的前台访问权限。
在我 fork()
之后,我在子进程中运行以下代码:
setpgid(0, 0);
并且:
setpgid(child, child);
在父进程中。
这为子进程提供了自己的进程组。对 setpgid()
的调用工作正常。
现在我想让孩子访问终端。
我在 setpgid()
调用之后向子进程添加了以下内容:
if (!tcsetpgrp(STDIN_FILENO, getpid())) {
perror("tcsetpgrp failed");
}
之后,有一个 execv()
命令来生成 /usr/bin/nano< /代码>。
然而,nano
并没有出现,什么也没有发生,并且终端看起来好像在等待用户输入。
此外,在 tcsetpgrp() 调用之后似乎没有代码执行。
我在某处读到,我需要向子进程发送 SIGCONT
信号才能使其正常工作。如果该过程停止了,我该怎么办?家长必须发出信号吗?
如果这是解决方案,我该如何发送 SIGCONT
信号?
raise(SIGCONT);
另外,我不确定这是否有帮助,但是如果我运行我的程序:
exec ./program
而不是:
./program
有什么想法吗? 代码工作正常并生成 nano
。非常感谢!
I'm trying to give a child process (via fork()
) foreground access to the terminal.
After I fork()
, I run the following code in the child process:
setpgid(0, 0);
And:
setpgid(child, child);
In the parent process.
This gives the child its own process group. The call to setpgid()
works correctly.
Now I want to give the child access to the terminal.
I added the following to the child after the setpgid()
call:
if (!tcsetpgrp(STDIN_FILENO, getpid())) {
perror("tcsetpgrp failed");
}
After that, there is an execv()
command to spawn /usr/bin/nano
.
However, instead of having nano
come up, nothing happens, and the terminal looks as if it's expecting user input.
Further, no code seems to execute after the tcsetpgrp()
call.
I read somewhere that I need to send a SIGCONT
signal to the child process to get it to work. If the process is stopped, how can I do that? Does the parent have to send the signal?
How do I go about sending the SIGCONT
signal if that is the solution?
raise(SIGCONT);
Also, I'm not sure if this helps, but the code works fine and spawns nano
if I run my program with:
exec ./program
Instead of:
./program
Any ideas? Thanks so much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
想通了。我必须忽略任何 SIGTTOU 信号。
我通过添加以下内容来做到这一点:
在 tcsetpgrp() 调用之前。
Figured it out. I have to ignore any SIGTTOU signals.
I did that by adding:
Before the
tcsetpgrp()
call.man 3 tcsetpgrp 指出:
您需要在父进程而不是子进程中调用 tcsetpgrp()。但是,如果您的父进程启动并移至后台,它将收到 SIGTTOU 并将被停止。
man 3 tcsetpgrp states:
You need to call tcsetpgrp() in your parent process not in child. However if your parent process started and moved into background it will receive SIGTTOU and will be stopped.
应该由父级而不是子级调用 tcsetpgrp()。 setpgid() 调用后,子进程将成为后台进程。一个有效的情况是前台组放弃其权限,让另一个后台组成为前台,而自己成为后台。后台组中的进程无法获取控制终端。示例代码可能如下所示:
It's the parent rather than child who should invoke tcsetpgrp(). After setpgid() call, the child becomes a background process. A valid case is the foreground group gives up its permission, let another background group become foreground and itself background. A process in background group can't grab controlling terminal. Example code maybe look like: