9

I'm currently implementing Scheme R5RS in C, and I am stuck trying to implement the (char-ready?) function.

I have the specs for the function quoted below. The function is guaranteed not to block. The standard C functions like fgetc() all block on input when called when there is no input ready.

Does anyone know if there is way to implement this in a nice simple way, without spawning a dedicated IO thread?

Edit: My input stream type is a FILE*, which could be stdin or a file opened with fopen().

(char-ready?) procedure

(char-ready? port) procedure

Returns #t if a character is ready on the input port and returns #f otherwise. If char-ready returns #t then the next read-char operation on the given port is guaranteed not to hang. If the port is at end of file then char-ready? returns #t. Port may be omitted, in which case it defaults to the value returned by current-input-port.

Rationale:

Char-ready? exists to make it possible for a program to accept characters from interactive ports without getting stuck waiting for input. Any input editors associated with such ports must ensure that characters whose existence has been asserted by char-ready? cannot be rubbed out. If char-ready? were to return #f at end of file, a port at end of file would be indistinguishable from an interactive port that has no ready characters.

Kara
  • 6,115
  • 16
  • 50
  • 57
Marc O'Morain
  • 3,699
  • 5
  • 28
  • 34

3 Answers3

5

You will need to go below the stdio level. On UNIX, you can use fileno() to get the file descriptor associated with the stream, and then you can use select() and read() system calls to do non-blocking reads.

zvrba
  • 24,186
  • 3
  • 55
  • 65
2

Perhaps this solution would work for you: How to check if stdin is still opened without blocking?

Community
  • 1
  • 1
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
2

Perhaps something like the code in this answer? But note with ungetc "only one pushback is guaranteed".

As a side note, most serious scheme implementations end up doing their own buffered (possibly non-blocking) IO.

Community
  • 1
  • 1
Eli Barzilay
  • 29,301
  • 3
  • 67
  • 110
  • Yeah, I forgot about the blocking part. In any case, note the second comment -- `FILE*` is likely to become less useful in the long run, and you'll switch to doing more things yourself. (Assuming that you'll want it to be more than a toy.) – Eli Barzilay Jun 01 '11 at 21:11