Как уже говорилось, вы можете использовать sigaction
для перехвата ctrl-c илиselect
для перехвата любого стандартного ввода.
Однако обратите внимание, что с помощью последнего метода вам также необходимо настроить TTY так, чтобы он был в режиме «посимвольно», а не построчно. Последний вариант используется по умолчанию - если вы вводите строку текста, она не отправляется на стандартный ввод запущенной программы, пока вы не нажмете клавишу ввода.
Вам нужно будет использовать tcsetattr()
функцию, чтобы отключить режим ICANON, и, возможно, также отключить ECHO. По памяти вам также необходимо вернуть терминал в режим ICANON при выходе из программы!
Просто для полноты, вот код, который я только что набрал (примечание: без проверки ошибок!), Который устанавливает Unix TTY и эмулирует <conio.h>
функции DOS kbhit()
и getch()
:
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>
struct termios orig_termios;
void reset_terminal_mode()
{
tcsetattr(0, TCSANOW, &orig_termios);
}
void set_conio_terminal_mode()
{
struct termios new_termios;
tcgetattr(0, &orig_termios);
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
atexit(reset_terminal_mode);
cfmakeraw(&new_termios);
tcsetattr(0, TCSANOW, &new_termios);
}
int kbhit()
{
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return select(1, &fds, NULL, NULL, &tv);
}
int getch()
{
int r;
unsigned char c;
if ((r = read(0, &c, sizeof(c))) < 0) {
return r;
} else {
return c;
}
}
int main(int argc, char *argv[])
{
set_conio_terminal_mode();
while (!kbhit()) {
}
(void)getch();
}