home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / unix / bsd / 10772 < prev    next >
Encoding:
Text File  |  1992-12-30  |  3.5 KB  |  114 lines

  1. Xref: sparky comp.unix.bsd:10772 comp.unix.programmer:5801
  2. Newsgroups: comp.unix.bsd,comp.unix.programmer
  3. Path: sparky!uunet!paladin.american.edu!gatech!emory!swrinde!elroy.jpl.nasa.gov!ames!pacbell.com!UB.com!quack!dfox
  4. From: dfox@quack.sac.ca.us (David Fox)
  5. Subject: 386bsd: how to read characters non-blocking
  6. Message-ID: <fXiL7vY@quack.sac.ca.us>
  7. Followup-To: comp.unix.bsd
  8. Keywords: termios, kbhit(), non-blocking read
  9. Organization: The Duck Pond public unix: +1 408 249 9630, log in as 'guest'.
  10. Date: 30 Dec 1992 20:31:09 UTC
  11. Lines: 101
  12.  
  13. Hi *,
  14.  
  15. I've had some problems recently trying to emulate the MS-DOS function
  16. kbhit() in 386BSD.  I've gotten some good help, but the functions I've
  17. tried don't work the way I think they're supposed to.  In MS-DOS, a
  18. kbhit() simply returns (with a zero result) if no key has been pressed,
  19. enabling the rest of the program (usually, a while loop) to continue 
  20. processing.  That's what I want to do - loop until a key has been 
  21. pressed.  However, the functions that I've tried so far (termios, stty,
  22. read, cbreak, etc.) only emulate the getch() function which sits there until
  23. a key has been pressed, which doesn't allow my program to continue
  24. processing.
  25.  
  26. Why I've decided to post is because I received some example code that
  27. uses the BSD termio and sets up for a non-blocking read (which is
  28. apparently what I want).  This produces the expected behavior when
  29. run on a Sparc (the site I use for mail/news) - it continues processing
  30. in the loop, returning immediately if no key has been pressed.  After
  31. editing this to make it compile under 386BSD (taking into account that
  32. termio should be termios) it doesn't work the same way.  It simply sits
  33. there in the kbhit() function until I press a key.
  34.  
  35. ---  Begin sample code ---
  36.  
  37. #include <stdio.h>
  38. #include <sys/types.h>
  39. #include <termio.h>
  40.  
  41. main()
  42. {
  43. int ch;
  44.  
  45.     for (;;) {
  46.         if ((ch = kbhit()) != 0)
  47.             printf("a key was hit (%d)\n", ch);
  48.         if (ch == 3)
  49.             break;
  50.         printf(".");
  51.         fflush(stdout);
  52.     }
  53. }
  54.  
  55. /*
  56.  * return a non-zero value if a key has been pressed (the value returned
  57.  * is the ascii value of the key); note that this function does not do
  58.  * anything special with multibyte sequences (such as those returned by
  59.  * function keys or cursor motion keys)
  60.  */
  61. int
  62. kbhit()
  63. {
  64. struct termio old, new; /* I changed to struct termios */
  65. int retval;
  66. char ch;
  67.  
  68.     /*
  69.      * get the line settings for standard input and save them
  70.      * in ``old''; we also copy them to ``new'' so that we can
  71.      * change the settings appropriately
  72.      */
  73.     ioctl(0, TCGETA, &old); /* changed to TIOCGETA */
  74.     memcpy((char *)&new, (char *)&old, sizeof(struct termio));
  75.         /* changed termio to termios */
  76.     /*
  77.      * set ``raw'' mode, ignore breaks, don't post-process output,
  78.      * don't echo characters, etc.
  79.      */
  80.     new.c_iflag |= IGNBRK;
  81.     new.c_oflag &= ~OPOST;
  82.     new.c_lflag &= ~(ISIG|ICANON|ECHO);
  83.     new.c_cc[VMIN] = 0;
  84.     new.c_cc[VTIME] = 1;
  85.  
  86.     /*
  87.      * change the terminal line settings, read a character and
  88.      * then restore the terminal back to it's original state
  89.      */
  90.     ioctl(0, TCSETA, &new); /* changed to TIOCSETA */
  91.     retval = read(0, &ch, 1);
  92.     ioctl(0, TCSETA, &old); /* changed to TIOCSETA */
  93.  
  94.     /*
  95.      * ``retval'' will either contain 1 (which means a key was
  96.      * pressed), 0 (which means that no key was pressed), or -1
  97.      * (which means an error occurred, check errno)
  98.      */
  99.     if (retval > 0)
  100.         retval = (int)ch;
  101.  
  102.     return retval;
  103. }
  104.  
  105. ---- End of included code ----
  106.  
  107. Forgive my ignorance, I am not yet well-skilled in Unix C programming,
  108. but I'm fairly familiar with DOS C programming.
  109.  
  110. --
  111. David Fox
  112. dfox@quack.sac.ca.us
  113.  
  114.