Signal für "beliebige Taste"
-
Hallo @all,
ich habe folgendes Problem.
Ich lasse per printf() in einer unendlichen Schleife entsprechende Ausgaben auf dem Terminal ausgeben.Um den Vorgang zu unterbrechen und das Terminal in den Urspungszustand zurückzusetzen, fange ich die Tastenkombinationen bzw. Signale SIGINT (Control-C) und SIGTSTP(Control-Z) ab.
Ich möchte aber gerne eine Funktionalität einbauen um auf jeden beliebigen Tastendruck zu reagieren, und somit die Abarbeitung des Programms zu beenden und daraufhin das Terminal zurückzusetzen.
Wie kann ich das umsetzen?
Ist es möglich dafür SIGUSR1 bzw. SIGUSR2 dementsprechend zu modifizieren, so dass auf alle Tastatureingaben reagiert wird?
-
Spontan fällt mir nur die Funktion kbhit() ein.
Da es die nur unter Windows gibt, hier eine Linux-Version (aus http://www.c-plusplus.net/forum/viewtopic.php?t=39509):#include <termios.h> int kbhit(void) { struct termios term, oterm; int fd = 0; int c = 0; tcgetattr(fd, &oterm); memcpy(&term, &oterm, sizeof(term)); term.c_lflag = term.c_lflag & (!ICANON); term.c_cc[VMIN] = 0; term.c_cc[VTIME] = 1; tcsetattr(fd, TCSANOW, &term); c = getchar(); tcsetattr(fd, TCSANOW, &oterm); if (c != -1) ungetc(c, stdin); return ((c != -1) ? 1 : 0); }
mfg, loose
-
Hi loose,
danke für den Tipp mit kbhit().
Wenn ich die Abfrage ob kbhit()=1 liefert in die for-Schleife einbaue, funktioniert das zwar prinzipiell, aber das Programm und die Ausgabe auf dem Terminal wird VIEL zu langsam, da ja jedes Mal die Funktion geprüft werden muss!Über weitere Lösungsansätze wäre ich daher sehr dankbar.
Wie könnte man das Thema noch anders lösen?
-
Hallo,
falls bei dir evdev läuft (muss im Kernel aktiviert sein) (kann man testen indem man mit cat /dev/input/eventX ausliest) kannst dus ja mal so probieren:
#include <linux/input.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> int main(int argc, char **argv) { int ifd; struct input_event iev; if (argc != 2) { fprintf(stderr, "Usage: a.out <input_device>\n"); return EXIT_FAILURE; } if ((ifd = open(argv[1], O_RDONLY)) == -1) { perror("Error in open()"); return EXIT_FAILURE; } while (read(ifd, &iev, sizeof (iev)) > 0) { if (iev.type == EV_KEY && iev.value == 0) printf("Key release for key with code %d!\n", iev.code); } close(ifd); return EXIT_SUCCESS; }
Aufruf bspw.:
Code:a.out /dev/input/event1
Gruß,
RedWing
-
Hi RedWing,
danke für deinen Post/Quelltext.
Das hört sich für mich aber sehr Linux-spezifisch an.
Ich brauch aber ne Möglichkeit die unter allen UNIX-Derivaten funktioniert (z. B. Linux, HP-UX, Solaris etc.)Vielleicht kann ich ja einen Geschwindigkeitsvorteil erreichen, wenn ich das Ganze mit einem extra fork() auslagere.
Etwas assemblerseitig zu programmieren wird vermutlich auch nicht funktionieren, da das wieder plattformabhängig ist.