为什么 gnu readline 要求我按 control c 两次?
通常,Control-C 向程序发送一个 signint,如果没有被捕获则终止它。 gnureadline 库将为 sigint 安装处理程序。然而,即使在 haskell 中禁用这些处理程序,我仍然需要按两次 Control-C 来终止程序。这是怎么回事?
import System.Console.Readline
main = do
setCatchSignals False
mainLoop
mainLoop = do
maybeLine <- readline ">"
case maybeLine of
Nothing -> putStrLn ":("
Just line -> do
putStr line
putStr " catch:"
catch <- getCatchSignals
putStrLn $ show $ catch
mainLoop
Normally, Control-C sends a sigint to a program, and kills it if it's not caught. The gnureadline library will install handlers for sigint. However, even when disabling those handlers in haskell, I still need to hit Control-C twice to kill a program. What's going on?
import System.Console.Readline
main = do
setCatchSignals False
mainLoop
mainLoop = do
maybeLine <- readline ">"
case maybeLine of
Nothing -> putStrLn ":("
Just line -> do
putStr line
putStr " catch:"
catch <- getCatchSignals
putStrLn $ show $ catch
mainLoop
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这可能与 cooked/uncooked/rare 终端模式有关;
^C
并不总是发送信号。 readline 似乎可能会取消终端的功能,因此由键盘输入引起的任何信号必定是由 readline 本身内部的逻辑引起的;它似乎可能只在两个连续的^C
上触发 SIGINT(特别是对于许多使用 readline 的程序,如 shell 和 REPL,程序在单个^C< 上退出) /code> 会很烦人!)。
您可以通过使用 readline API 将
^C
重新绑定到您自己的一些触发 SIGINT 的代码来更改此行为。我没有使用 Haskell 的 readline,只是使用 C,所以我不确定你会如何处理这个问题,但是 绑定似乎足够丰富来实现它。This may be related to the cooked/uncooked/rare terminal modes;
^C
does not always send a signal. It seems likely that readline uncooks the terminal, and thus any signals caused by keyboard input must be due to logic within readline itself; it seems plausible that it might only trigger a SIGINT on two sequential^C
s (especially since for many programs that utilise readline such as shells and REPLs, the program exiting on a single^C
would be very annoying!).You might be able to change this behaviour by using the readline API to rebind
^C
to some of your own code that triggers a SIGINT. I haven't used readline from Haskell, just from C, so I'm not sure exactly how you'd go about this, but the binding seems rich enough to achieve it.