Linux 如何在 mini-shell 中处理信号 Ctrl + Z。C
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4891214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to handle the signal Ctrl + Z in mini-shell. C
提问by Khuseyn
I'm trying to suspend the process but it doesn't work. this is part of code. there are Ctrl+Z and Ctrl+C. Ctrl+C is working. I cannot get why with Z it doesn't work. (the actual code):
我正在尝试暂停该过程,但它不起作用。这是代码的一部分。有 Ctrl+Z 和 Ctrl+C。Ctrl+C 正在工作。我不明白为什么 Z 不起作用。(实际代码):
//ctrl+Z
void sigstop(int p){
signal(SIGTSTP,&sigstop);
kill(my_pid,SIGSTOP);
fflush(stdout);
}
// Ctrl+C
void sigkill(int p){
signal(SIGINT,&sigkill);
kill(my_pid,SIGKILL);
fflush(stdout);
}
Code in the main method:
主方法中的代码:
...
my_pid = fork();
if (my_pid == 0) {
signal(SIGTSTP,&sigstop); //for Ctrl+Z
signal(SIGINT,&sigkill); //for Ctrl+C
checkCommand();
execvp(argv[0], argv);
exit(getpid());
}
回答by zwol
Instead of installing signal handlers for SIGTSTP
and SIGINT
, put the terminal into raw mode with cfmakeraw
or tcsetattr
. ^Cand ^Zwill then be readable as ordinary characters, which should be much less troublesome. However, you will then need to implement line-editing yourself -- GNU readlineis your friend there. For further advice, please see the Implementing a Shelland Job Controlsections of the GNU C Library Manual. (You can safely ignore the part where it tries to warn you that job control might not be supported by the kernel -- if anyone is still using one of thosesystems anymore, they have only themselves to blame for it.)
不要为SIGTSTP
and安装信号处理程序,而是SIGINT
使用cfmakeraw
or将终端置于原始模式tcsetattr
。 ^C和^Z然后将是可读的作为普通字符,这应该是麻烦的要少得多。但是,您将需要自己实现行编辑——GNU readline是您的朋友。如需更多建议,请参阅GNU C 库手册的实现 Shell和作业控制部分。(您可以放心地忽略它试图警告你,作业控制可能不是由内核支持的部分-如果有人仍然使用的一个这些系统了,他们只能怪自己吧。)
回答by Magallo
I think that calling kill() in the sigkill function, just begins an infinite, recursive loop where the kill() just calls again the sigkill function, which calls kill() which calls again sigkill function... etc... Instead of calling kill(), set a global boolean variable and check for it in your main function. If this global boolean variable is set, you just exit gracefully.
我认为在 sigkill 函数中调用 kill() 只是开始一个无限的递归循环,其中 kill() 只是再次调用 sigkill 函数,它调用 kill() 再次调用 sigkill 函数......等等......而不是调用kill(),设置一个全局布尔变量并在你的主函数中检查它。如果设置了这个全局布尔变量,你就可以优雅地退出。
Something like:
就像是:
volatile bool gTerminate = false;
void sigkill(int p)
{
gTerminate = true;
signal(SIGINT, &sigkill);
}
int main(...)
{
//initialization stuff...
while( !gTerminate )
{
//do stuff
}
return -1;
}