home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / unix / bsd / 11131 < prev    next >
Encoding:
Internet Message Format  |  1993-01-11  |  4.5 KB

  1. Xref: sparky comp.unix.bsd:11131 comp.lang.c:19551
  2. Newsgroups: comp.unix.bsd,comp.lang.c
  3. Path: sparky!uunet!cs.utexas.edu!hellgate.utah.edu!fcom.cc.utah.edu!cs.weber.edu!terry
  4. From: terry@cs.weber.edu (A Wizard of Earth C)
  5. Subject: Re: a unix terminal question
  6. Message-ID: <1993Jan11.215312.2080@fcom.cc.utah.edu>
  7. Sender: news@fcom.cc.utah.edu
  8. Organization: Weber State University  (Ogden, UT)
  9. References: <1iql6kINNisk@ub.d.umn.edu>
  10. Date: Mon, 11 Jan 93 21:53:12 GMT
  11. Lines: 77
  12.  
  13. In article <1iql6kINNisk@ub.d.umn.edu> cbusch@ub.d.umn.edu (Chris) writes:
  14. >
  15. >   How does one read in a character from standard input without having
  16. >the program wait for the key.  Basically, I want to do something like:
  17. >    if(kbhit()) c=getch();
  18. >Except that is not standard, and I want it to work on all platforms.
  19.  
  20. This is a bad thing to do, unless you have processing to do when characters
  21. aren't present, and you do your checks relatively infrequently compared to
  22. the procesing itself; otherwise, you will be in a buzz-loop and suck your
  23. CPU through the floor.  This is common practice under DOS where there is
  24. nothing else running, but is a generally bad thing to do.
  25.  
  26. The CORRECT way to do this:  use the select() or poll() system call to
  27. wait for an interval or a character to be present.  Resoloution is
  28. generally 1/1000th of a second; you can effect a poll by having a
  29. zero-valued timeval struct (as opposed to passing (struct timeval *)NULL).
  30. This will cause the behaviour you have asked for.  When the select()
  31. returns that there are characters available, do a read() on the descriptor
  32. (otherwise, return as if the read() has returned 0 characters).  It
  33. should be noted that some systems are sensitive to select/read pairing,
  34. and if you do this, you should have a select() call prior to every read()
  35. call, regardless of whther or not you use the select information aro simply
  36. read anyway.
  37.  
  38. Another method would be to put the terminal in raw mode, and set the vmin
  39. to 0 and the vtime based on whether you wanted to screw everyone on your
  40. system every time your program is run (set it to 0 to poll and screw
  41. everyone).  Normal reads will return 0 characters read.
  42.  
  43. An older mechanism for BSD systems which is no longer in common use is
  44. the rdchk() library routine, which ioctl'ed with a FIONREAD to count
  45. the number of characters pending input (this is still used in SCO Xenix).
  46. If the number was larger than 0, then you do the read.
  47.  
  48. In general, these mechanisms are not usable with stdio routines.  This is
  49. because the stdio routines operate on user-space buffering.  If I am using
  50. "getchar()" to read characters, and I typ the string "fred", if I type
  51. it fast enough, it will be read into the stdin buffer in its entirety.
  52. When I check the number of characters pending input on the fd, the answer
  53. will be 0, even though there are still 3 characters pending input on the
  54. stdin file pointer.  You can either check that the number of characters
  55. in the stdin buffer is not 0 (extremely system dependant), then check to
  56. see if there are no characters on the fd, and only then skip your getchar.
  57. For portability, you should use raw I/O (read/write/select) rather than
  58. character counting the stdio buffer contents.
  59.  
  60. If the reason you are doing this is a game, you are probably SOL: you
  61. will eat the machine when you run it.  Even then, using a timeout on
  62. select for the background processing will allow you to adjust the
  63. speed of the background tasks relative to the player's movement,
  64. and will not eat the machine in the majority case.  This also makes
  65. your game timing dependent on your players use/nonuse of the control
  66. entry window rather than on whther or not the player is doing something
  67. (ie: it's bad if by entering commands I cause the game to become "jerky"
  68. in it's movements).
  69.  
  70. If the reason you need to do this is to read from two file descriptors
  71. at once, then select() or poll() is your best bet (there are other
  72. methods to do this as well, but select/poll are more efficient in terms
  73. of system call overhead).  You may want to do this if you are writing a
  74. terminal emulation or chat program.
  75.  
  76. Good luck.
  77.  
  78.  
  79.                     Terry Lambert
  80.                     terry@icarus.weber.edu
  81.                     terry_lambert@novell.com
  82. ---
  83. Any opinions in this posting are my own and not those of my present
  84. or previous employers.
  85. -- 
  86. -------------------------------------------------------------------------------
  87.                                         "I have an 8 user poetic license" - me
  88.  Get the 386bsd FAQ from agate.berkeley.edu:/pub/386BSD/386bsd-0.1/unofficial
  89. -------------------------------------------------------------------------------
  90.