如何在C中实现Ctrl-C和Ctrl-D的信号处理...所以如果按下Ctrl-C,则程序将忽略并尝试再次获取用户输入...如果按下Ctrl-D,则程序将终止...
我的程序如下:
int main(){
char msg[400];
while(1){
printf("Enter: ");
fgets(msg,400,stdin);
printf("%s\n",msg);
}
}
谢谢,
Dave
如何在C中实现Ctrl-C和Ctrl-D的信号处理...所以如果按下Ctrl-C,则程序将忽略并尝试再次获取用户输入...如果按下Ctrl-D,则程序将终止...
我的程序如下:
int main(){
char msg[400];
while(1){
printf("Enter: ");
fgets(msg,400,stdin);
printf("%s\n",msg);
}
}
谢谢,
Dave
当处理 POSIX 信号时,您有两种手段。首先是简单(但不建议使用)的方式 signal()。其次是更加优雅、当前但复杂的方式 sigaction()。除非您发现需要使用的平台上不支持 sigaction(),否则请使用 sigaction()。
glibc 手册中的这一章节解释了这两种方式之间的差异,并给出了如何同时使用它们的良好示例代码。它还列出了可以处理的信号,推荐如何处理它们,并深入介绍了如何判断任何给定信号当前是否正在被处理。但由于篇幅较长,我不想在此回答中粘贴所有的代码,因此提供了链接。
值得花费一到两个小时阅读这些链接并透彻理解示例。信号处理(特别是在守护程序中)非常重要。一个好的程序应该处理所有可以处理的致命信号(例如 SIGHUP),并明确忽略可能没有使用到的信号(例如 SIGUSR1 / SIGUSR2)。
另外,学习普通信号和实时信号之间的区别也是有益的,至少要理解内核如何合并前者而不是后者。
一旦您解决了这个问题,可能会有意愿编写一组易于修改的函数来处理信号并重复使用该代码。很抱歉没有提供一个快速而简单的代码片段来展示如何解决您的即时需求,但这不是一个快速而简单的主题 :)首先,Ctrl+D是一个EOF指示器,无法捕获。当程序等待输入时,按下Ctrl+D表示文件结束(EOF),不再期望更多的输入。另一方面,使用Ctrl+C来终止程序 - 这是SIGINT信号,可以通过以下方式捕获:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>
static void signal_handler(int);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);
struct sigaction sigact;
char *progname;
int main(int argc, char **argv){
char *s;
progname = *(argv);
atexit(cleanup);
init_signals();
// do the work
exit(0);
}
void init_signals(void){
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
}
static void signal_handler(int sig){
if (sig == SIGINT) panic("Caught signal for Ctrl+C\n");
}
void panic(const char *fmt, ...){
char buf[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
exit(-1);
}
void cleanup(void){
sigemptyset(&sigact.sa_mask);
/* Do any cleaning up chores here */
}
sigaction()
时,内核会从结构体中复制所需的信息;之后无需保留该值。 - Jonathan Leffler这是一个用于处理按下 Ctrl+c 时信号的程序。
signal 函数的语法为:signal(信号名称, 函数名称);
#include<stdio.h>
#include<signal.h> // for handling signal
void signal_handler()
{
printf("Signal Handled here\n");
}
main()
{
printf("In main function..\n");
// SIGINT is signal name create when Ctrl+c will pressed
signal(SIGINT,signal_handler);
sleep(15);
printf("In main after called from signal_handle \n");
}
signal()
已被弃用,应尽可能避免使用,几乎所有现代平台(除了一些嵌入式平台)都提供了sigaction()
。 - Tim Postsignal()
从未被弃用。它提供的控制比sigaction()
少。但这并不等同于被弃用。 - P.Psignal()
可能尚未正式弃用,但强烈不建议使用。从man 2 signal
中可以看到:警告:signal()的行为在UNIX版本之间有所不同,并且在不同版本的Linux中也有所不同。避免使用它:改用sigaction(2)。请参见下面的可移植性。 它继续说道:signal()的唯一可移植用途是将信号的处理方式设置为SIG_DFL或SIG_IGN。当使用signal()来建立信号处理程序时,其语义在系统之间有所不同(并且POSIX.1明确允许此变化);不要将其用于此目的。 - Fonicsignal
没有被弃用 ;-) - P.P#include<signal.h>
#include<unistd.h>
#include<stdio.h>
void signal_catch()
{
printf("hi,Your signal catched Here");
}
int main()
{
signal(SIGINT,signal_catch);
//press ctrl+c
sleep(10);
return 0;
}//end main
//if you want to simply ignore ctrl+c interrupt use following code in main
int main()
{
signal(SIGINT,SIG_IGN);
sleep(100);
return 0;
}//end main
//this program wont accept ctrl+c interrupt for 100 seconds.