如何向子进程发送 Ctrl-C 控制字符或终端挂断消息?
我有一个在伪终端中运行的子进程。父进程不以 root 身份运行,但子进程通过 su 或 sudo 运行。因此,无法向子进程发送信号以强制其退出。我想通过以下方式之一强制它退出:
- 模拟 Ctrl-C。
- 模拟终端挂起。
我该怎么做?我已经有一个 pty master fd,并且我尝试过类似的操作:
write(master, &termios.c_cc[VINTR], 1)
但它没有做任何事情。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在我看来,如果你真的有一个pty(除非你用伪终端指的是其他东西),那么你所要做的就是向该FD发送一个Control-C。作为这一点的证据,我在 Python 中提交了以下代码(但与执行此操作所需的 C 相当接近):
这在 pty 下分叉了一个进程,该进程运行一个无限循环,打印
日期。然后父进程等待 3 秒并发送一个 control-C。
这会产生以下输出:
它运行了 3 秒多一点,打印了 3 次日期,然后退出。
It seems to me that if you truly have a pty (unless you mean something else by pseudo terminal), that all you have to do is send a Control-C to that FD. As evidence of this, I submit the following code in Python (but fairly close to the C required to do it):
This forks a process under a pty, which runs an infinite loop printing the
date. Then the parent waits 3 seconds and sends a control-C.
This results in the following output:
It ran just over 3 seconds, printed out the date 3 times, and exited.
我最终采用了以下解决方案:
分叉后,我不是立即执行 sudo,而是 exec() 一个辅助子进程,该子进程又分叉并执行 sudo 并在其上调用 waitpid。因此,进程层次结构如下所示:
通过终止辅助进程,pty 不再有前台进程。这将导致操作系统向整个前台进程组发送 SIGHUP,而不管用户是谁,因此 sudo 也会发出 SIGHUP 信号。
I eventually went with the following solution:
After forking, instead of exec'ing sudo immediately, I exec() a helper child process instead, which in turn forks and execs sudo and calls waitpid on it. So the process hierarchy looks like this:
By killing the helper process, the pty does not have a foreground process anymore. This will cause the OS to send SIGHUP to the entire foreground process group, regardless of the user, so sudo is SIGHUP'ed too.
我认为你需要使用
ioctl
来插入中断字符而不是write
。不幸的是,这种机制似乎不可移植。对于 Linux 来说,这看起来可能有效:I think you need to use
ioctl
to insert the interrupt character instead ofwrite
. Unfortunately the mechanism for this does not seem to be portable. For linux it looks this might work:有两种方法可以实现这一点:
想到了两个......抱歉,如果它对你没有进一步的帮助,
希望这有帮助,
此致,
汤姆.
There is two ways to achieve this:
There the two that comes to mind...sorry if its not of further help to you,
Hope this helps,
Best regards,
Tom.
关闭主站应该向从站的控制进程组发出挂起信号。
Closing the master should signal a hangup to the controlling process group of the slave.
我要检查的第一件事是您是否需要将其设为从属端的控制终端。事实证明,这更复杂 比我记得的要好,默认情况下 ptys 可能不会成为控制对象。该链接适用于 Linux,其他系统应该根据其 SysV 与 BSD 特性选择其中之一,但看起来 TIOCSCTTY 是一个不错的选择。
其次,我会检查您是否在 termios 中设置了 ISIG;如果没有,VINTR 和 VQUIT 将不起作用。
当然,如果另一端正在捕获 SIGINT 和 SIGQUIT,则会遇到其他问题。
The first thing I'd check is if you need to make it the controlling terminal on the slave side. It turns out this is more complex than I remember, with ptys possibly not becoming controlling by default. That link is for Linux, other systems should do one or the other depending on their SysV vs. BSD-ness, but it looks like the TIOCSCTTY is a good bet to try.
Secondly, I'd check if you're setting ISIG in your termios; if not, VINTR and VQUIT won't work.
Of course, if the other end is catching SIGINT and SIGQUIT, you will have other issues.