Поймать CTRL-\ сигнал
У меня есть пользовательский проект оболочки, где я пытаюсь реализовать cat
команда, но позволяет пользователю нажать CTRL-/
для отображения следующих х-строк. Я новичок в сигналах, так что я думаю, что у меня где-то неправильный синтаксис...
в основном...
while (fgets(buf, sizeof(buf), file) != NULL){ //CITE
//print out first four lines
if (j == 0){
for (i = 0; i < 4; i++){
printf("%s", buf);
fgets(buf, sizeof(buf), file);
}
j++;
}
signal(SIGQUIT, sig_int);
//now check for user input for the next x lines
if (keepRunning){
for (i = 0; i < 4; i++){
printf("%s", buf);
if (i < 3){
if (fgets(buf, sizeof(buf), file) == NULL){
fclose(file);
return 0;
}
}
}
keepRunning = 0;
}
Тогда я определил следующую функцию sig_int...
static volatile int keepRunning = 0;
void sig_int(int sig){
keepRunning = 1;
}
1 ответ
Основная проблема в том, что вы не замедляетесь и не останавливаетесь, когда сигнал не принимается. Вы могли бы использовать pause()
, например; возвращается только при получении сигнала. Вы бы тогда использовали это вместо if (keepRunning)
блок (включая условие).
В качестве альтернативы вы можете изменить режимы терминала, чтобы символы отправлялись по мере их ввода (режим "raw"), и пытаться прочитать символ перед продолжением. Однако, если вы это сделаете, на вас лежит обязанность гарантировать, что режим терминала будет сброшен до того, как программа закроется при максимально возможном количестве обстоятельств. Хорошая новость заключается в том, что в исходном режиме с клавиатуры не будет генерироваться никаких сигналов, но вам нужно беспокоиться о сигналах из других источников.
Возможно, вы захотите позволить другим сигналам разбудить программу и выйти из цикла, но если вы не установите для них обработчик сигналов, это произойдет автоматически. То есть после pause()
возвращается (он всегда будет возвращаться со статусом ошибки и errno
установить EINTR), вы можете проверить, keepRunning
сейчас 1 и выйдите из цикла, если нет.