阻止MSYS'bash'杀死陷阱^ C的进程

我有一个控制台模式的Windows应用程序(从Unix移植),最初devise为在收到^ C (Unix SIGINT )时进行干净的退出。 在这种情况下,一个干净的退出涉及等待,可能相当长的时间,远程networking连接closures。 (我知道这不是^ C的正常行为,但我不能改变它。)这个程序是单线程的。

我可以捕获^ C signal(SIGINT) (如在Unix下)或SetConsoleCtrlHandler 。 当程序在CMD.EXE下运行时,可以正常工作。 但是,如果我使用MSYS附带的“bash”shell(我正在使用MinGW环境来构build程序,因为这样我可以重新使用Unix makefiles),那么程序会被强制终止一些随机的短时间100毫秒)。 这是不可接受的,因为正如我所提到的,程序需要等待远程networking连接closures。

人们很可能会希望在MSYS bash下运行这个程序。 此外,这个效果打破了testing套件。 我一直无法find任何方法来解决这个问题,无论是从程序(理想)还是通过shell的设置(可以接受)。 谁能推荐任何东西?

我有完全相同的问题 – 我用SIGINT / SIGTERM处理程序写了一个程序。 那个处理程序做了清理工作,有时需要一段时间。 当我从msys bash中运行程序时,ctrl-c会导致我的SIGINT处理程序被触发,但是它不会结束 – 程序在完成清理之前被终止(从外面“工作。

建立在phs的答案,并回答了类似的问题: https : //stackoverflow.com/a/23678996/2494650 ,我想出了以下解决方案。 它非常简单,它可能有一些我还没有发现的副作用,但它为我解决了这个问题。

使用以下行创建一个〜/ .bashrc文件:

 trap '' SIGINT 

而已。 这陷阱sigint信号,并防止msys bash终止你的程序“从外面”。 然而,它仍然让SIGINT信号通过你的程序,允许它进行优雅的清理/关闭。 我不能确切地告诉你为什么这样做,但它确实 – 至少对我来说。

祝你好运!

精灵 – 5分钟的评论编辑。 这是我想要写的:

作为一个解决方法,而不是尝试捕获CTRL-C事件,这也正在传播到shell我建议关闭在标准输入上的ENABLED_PROCESSED_INPUT,以便CTRL-C被报告为键盘输入而不是信号:

 DWORD mode; HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(hstdin, &mode); SetConsoleMode(hstdin, mode & ~ENABLE_PROCESSED_INPUT); /* disable CTRL-C processing as a signal */ 

然后,可以在主线程中处理键盘输入,而程序的其余部分在单独的线程中完成它的工作,并在收到CTRL-C时设置要清除的事件。

当你用MSYS bash运行你的程序时,你直接运行可执行文件,还是有一个包装(bash)shell脚本?

如果是这样的话,它可能会注册一个自定义的Ctrl-C处理程序与trap命令(这是一个睡眠,然后杀死)。如果存在这样的事情,改变或删除它。

如果没有注册trap ,或者没有包装脚本,请考虑制作这样的脚本并添加自己的陷阱来覆盖默认行为。 你可以在这里或在bash的手册页上看到如何使用它的例子(在SHELL BUILTINS部分)。

Ctrl-C是SIGINT? 我以为Ctrl-Z是SIGINT,但是Ctrl-C是SIGTERM。 检查一下。

你有一个CYGWIN环境设置(在控制面板/环境变量中)? 尝试设置CYGWIN = notty并重新打开一个新的MSYS bash shell – 问题是否持续?