home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.wizards
- Path: sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!elroy.jpl.nasa.gov!usc!sol.ctr.columbia.edu!ira.uka.de!math.fu-berlin.de!news.th-darmstadt.de!rbg.informatik.th-darmstadt.de!mueller
- From: mueller@rbg.informatik.th-darmstadt.de (Klaus Mueller)
- Subject: Re: Keyboard hit in C programs
- Sender: news@news.th-darmstadt.de (The News System)
- Message-ID: <1992Nov13.171818@rbg.informatik.th-darmstadt.de>
- Date: Fri, 13 Nov 1992 16:18:18 GMT
- References: <1dms9iINNa6m@agate.berkeley.edu>
- Nntp-Posting-Host: rbhp59.rbg.informatik.th-darmstadt.de
- Organization: TH Darmstadt
- Keywords: Keyboard hit, C programs, UNIX
- Lines: 114
-
-
- In article <1dms9iINNa6m@agate.berkeley.edu>, you write:
- >
- > I am in the process of adapting a C program from the PC for
- > the UNIX environment (for SUN 3 running SUNOS 4.1.1).
- > In this program it is essential that
- > the user be able to stop certain parts of the program
- > (e.g. an inner loop) by hitting the keyboard (any key
- > is fine) while as long as the keyboard is not touched the execution
- > of the program will continue un-interupted (thus a procedure
- > which requires, or expects, the user to type in a key stroke at certain
- > intervals will not do). In the DOS environment
- > I have been able to do this with the "kbhit()" function.
- > My question is: what is the equivalent function in the UNIX
- > environment? or how does one go about creating such a function?
- > Any suggestions will be very welcome. Thanks a lot.
- > Bernt Skottun, bernt@valois.berkeley.edu
- >
-
- Here is a solution to this problem that not even requires to poll the the
- the keyboard. It uses SIGIO to get notified, but the program continues with
- the loop after the signalhandler has returned. So you have to think about
- leaving the loop after execution continues :).
-
- I don't know how portable this is, my system is HP-UX. The relevant man-pages
- are: termio(7) and ioctl(5).
-
-
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <signal.h>
- #include <stdio.h>
- #include <termio.h>
-
- struct termio term_old;
-
- void resetfiles(void) { /* resets all terminalstat we have changed */
- int arg;
-
- arg = 0;
- if (ioctl(STDIN_FILENO, FIOSSAIOSTAT, &arg)==-1) {
- perror("unset async");
- exit(1);
- }
- if (ioctl(STDIN_FILENO, TCSETA, &term_old) == -1) {
- perror("set termios");
- exit(1);
- }
- }
-
- void handler(int dummy) { /* handels the SIGIO */
- printf("got it\n");
- resetfiles(); /* clear what we have done */
- exit(0);
- }
-
- int main (void) {
- int arg;
- struct termio term;
-
- arg = getpid(); /* tell the keyboard _we_ want the signal */
- if (ioctl(STDIN_FILENO, FIOSSAIOOWN, &arg)==-1) {
- perror("set owner");
- resetfiles();
- exit(1);
- }
-
- /* tell the system we want a _signal_ */
-
- arg = 1;
- if (ioctl(STDIN_FILENO, FIOSSAIOSTAT, &arg)==-1) {
- perror("set async");
- resetfiles();
- exit(1);
- }
-
- /* keep the old stats */
-
- if (ioctl(STDIN_FILENO, TCGETA, &term_old) == -1) {
- perror("get termio1");
- resetfiles();
- exit(1);
- }
-
- /* and get some stats we can change */
-
- if (ioctl(STDIN_FILENO, TCGETA, &term) == -1) {
- perror("get termio2");
- resetfiles();
- exit(1);
- }
- term.c_lflag &= ~ICANON; /* get the charcters immediately */
- term.c_cc[VMIN] = (char) 0; /* no char buffered */
- term.c_cc[VTIME] = (char) 0; /* and no timeout */
-
- /* use our new settings */
-
- if (ioctl(STDIN_FILENO, TCSETA, &term) == -1) {
- perror("set termios");
- resetfiles();
- exit(1);
- }
-
- signal(SIGIO, handler); /* where to go with the signal */
-
- sleep(20); /* now let's do something (sleep) */
-
- resetfiles(); /* reset all we changed */
- }
-
- --
- Klaus M"uller (mueller@rbg.informatik.th-darmstadt.de)
- IRC: netmage MUD: loren
-
-