Обработка сигнала в C

Как я могу реализовать Обработку сигнала для Ctrl-C и Ctrl-D в C.... Таким образом, Если Ctrl-C будет нажат затем, то программа проигнорирует и попытается получить вход от пользователя снова... Если Ctrl-D будет нажат затем, то программа завершится...

Моя программа следует:

int main(){
 char msg[400];

 while(1){
   printf("Enter: ");
   fgets(msg,400,stdin);
   printf("%s\n",msg); 
 }
}

Спасибо,

Dave

21
задан avakar 20 March 2010 в 22:30
поделиться

3 ответа

При работе с сигналами POSIX в вашем распоряжении есть два средства. Во-первых, простой (но устаревший) способ signal () . Во-вторых, более элегантный, современный, но сложный способ sigaction () . Пожалуйста, используйте sigaction (), если вы не обнаружите, что он недоступен на какой-либо платформе, над которой вам нужно работать.

Эта глава руководства по glibc объясняет различия между ними и дает хороший пример кода того, как использовать оба. Он также перечисляет сигналы, которые могут быть обработаны, рекомендует, как они должны обрабатываться, и более подробно описывает, как определить, как тот или иной сигнал обрабатывается (или не обрабатывается) в настоящее время . . Это намного больше кода, чем я хотел бы вставить здесь в ответ, отсюда и ссылки.

Это действительно стоит часа или двух, чтобы вы прочитали ссылки и поработали с примерами. Обработка сигналов (особенно в демонизирующих программах) чрезвычайно важна. Хорошая программа должна обрабатывать все фатальные сигналы, которые могут быть обработаны (например, SIGHUP), и явно игнорировать сигналы, которые она может не использовать (например, SIGUSR1 / SIGUSR2).

Также не помешает изучить разницу между сигналами в нормальном и реальном времени, по крайней мере, до понимания того, как ядро ​​объединяет предыдущие, а не последние.

После того, как вы проработаете это, вы, вероятно, почувствуете склонность написать легко изменяемый набор функций для обработки ваших сигналов и повторного использования этого кода снова и снова.

Извините за то, что не предоставил быстрый и грязный фрагмент кода, чтобы показать вам, как решить вашу срочную проблему, но это не быстрая и грязная тема :)

32
ответ дан 29 November 2019 в 20:03
поделиться

Во-первых, Ctrl + D - это индикатор EOF, который вы не можете перехватить, когда программа ожидает ввода, нажатие Ctrl + D означает конец файла и больше не ожидает ввода. С другой стороны, использование 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 */
}
14
ответ дан 29 November 2019 в 20:03
поделиться

В вашем примере кажется, что вам вообще не нужен CTRL-C handlind. Похоже, вам достаточно "signal(SIGINT,SIG_IGN)", если только ваше приложение не должно обрабатывать SIGINT, приходящий из какого-то другого источника. CTRL-D обычно не генерирует сигналов, а просто передает состояние EOF. Вы можете в целом контролировать поведение вашего терминала (мы говорим о консольном вводе, не так ли?) с помощью библиотеки termios (также здесь). Вы можете включить, переопределить или отключить символ "прерывания" (CTRL-C), символ EOF и многие другие (XON, XOFF, управление модемом...)

С уважением

.
2
ответ дан 29 November 2019 в 20:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: