home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / unix / wizards / 4661 < prev    next >
Encoding:
Text File  |  1992-11-14  |  3.7 KB  |  128 lines

  1. Newsgroups: comp.unix.wizards
  2. 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
  3. From: mueller@rbg.informatik.th-darmstadt.de (Klaus Mueller)
  4. Subject: Re: Keyboard hit in C programs
  5. Sender: news@news.th-darmstadt.de (The News System)
  6. Message-ID: <1992Nov13.171818@rbg.informatik.th-darmstadt.de>
  7. Date: Fri, 13 Nov 1992 16:18:18 GMT
  8. References:  <1dms9iINNa6m@agate.berkeley.edu>
  9. Nntp-Posting-Host: rbhp59.rbg.informatik.th-darmstadt.de
  10. Organization: TH Darmstadt
  11. Keywords: Keyboard hit, C programs, UNIX
  12. Lines: 114
  13.  
  14.  
  15. In article <1dms9iINNa6m@agate.berkeley.edu>, you write:
  16. > I am in the process of adapting a C program from the PC for
  17. > the UNIX environment (for SUN 3 running SUNOS 4.1.1).
  18. > In this program it is essential that
  19. > the user be able to stop certain parts of the program
  20. > (e.g. an inner loop) by hitting the keyboard (any key
  21. > is fine) while as long as the keyboard is not touched the execution
  22. > of the program will continue un-interupted (thus a procedure
  23. > which requires, or expects, the user to type in a key stroke at certain
  24. > intervals will not do). In the DOS environment
  25. > I have been able to do this with the "kbhit()" function.
  26. > My question is: what is the equivalent function in the UNIX
  27. > environment? or how does one go about creating such a function?
  28. > Any suggestions will be very welcome. Thanks a lot.
  29. > Bernt Skottun, bernt@valois.berkeley.edu 
  30. >  
  31.  
  32. Here is a solution to this problem that not even requires to poll the the
  33. the keyboard. It uses SIGIO to get notified, but the program continues with
  34. the loop after the signalhandler  has returned. So you have to think about 
  35. leaving the loop after execution continues :).
  36.  
  37. I don't know how portable this is, my system is HP-UX. The relevant man-pages 
  38. are: termio(7) and ioctl(5).
  39.  
  40.  
  41. #include <sys/ioctl.h>
  42. #include <unistd.h>
  43. #include <signal.h>
  44. #include <stdio.h>
  45. #include <termio.h>
  46.  
  47. struct termio term_old;
  48.  
  49. void resetfiles(void) {        /* resets all terminalstat we have changed */
  50.     int arg;
  51.  
  52.     arg = 0;
  53.     if (ioctl(STDIN_FILENO, FIOSSAIOSTAT, &arg)==-1) {
  54.         perror("unset async");
  55.         exit(1);
  56.     }
  57.     if (ioctl(STDIN_FILENO, TCSETA, &term_old) == -1) {
  58.         perror("set termios");
  59.         exit(1);
  60.     }
  61. }
  62.  
  63. void handler(int dummy) {    /* handels the SIGIO */
  64.     printf("got it\n");
  65.     resetfiles();    /* clear what we have done */
  66.     exit(0);
  67. }
  68.  
  69. int main (void) {
  70.     int arg;
  71.     struct termio term;
  72.     
  73.     arg = getpid();    /* tell the keyboard _we_ want the signal */
  74.     if (ioctl(STDIN_FILENO, FIOSSAIOOWN, &arg)==-1) { 
  75.     perror("set owner");
  76.     resetfiles();
  77.     exit(1);
  78.     }
  79.  
  80.             /* tell the system we want a _signal_ */
  81.  
  82.     arg = 1;
  83.     if (ioctl(STDIN_FILENO, FIOSSAIOSTAT, &arg)==-1) {
  84.     perror("set async");
  85.     resetfiles();
  86.     exit(1);
  87.     }
  88.  
  89.         /* keep the old stats */
  90.  
  91.     if (ioctl(STDIN_FILENO, TCGETA, &term_old) == -1) {    
  92.     perror("get termio1");
  93.     resetfiles();
  94.     exit(1);
  95.     }
  96.  
  97.         /* and get some stats we can change */
  98.  
  99.     if (ioctl(STDIN_FILENO, TCGETA, &term) == -1) {
  100.     perror("get termio2");
  101.     resetfiles();
  102.     exit(1);
  103.     }
  104.     term.c_lflag &= ~ICANON;          /* get the charcters immediately */
  105.     term.c_cc[VMIN] = (char) 0;        /* no char buffered */
  106.     term.c_cc[VTIME] = (char) 0;    /* and no timeout */
  107.  
  108.         /* use our new settings */
  109.  
  110.     if (ioctl(STDIN_FILENO, TCSETA, &term) == -1) {
  111.         perror("set termios");
  112.         resetfiles();
  113.         exit(1);
  114.     }
  115.  
  116.     signal(SIGIO, handler); /* where to go with the signal */
  117.  
  118.     sleep(20);        /* now let's do something (sleep) */
  119.  
  120.     resetfiles();    /* reset all we changed */
  121. }
  122.  
  123. -- 
  124. Klaus M"uller  (mueller@rbg.informatik.th-darmstadt.de)
  125. IRC: netmage       MUD: loren
  126.  
  127.