# Is there a way to drain STDIN by reading characters in non-blocking mode?

**URL:** <https://swi-prolog.discourse.group/t/is-there-a-way-to-drain-stdin-by-reading-characters-in-non-blocking-mode/3704>\
**Category:** Help!\
**Tags:** how-to, character-io\
**Created:** [March 10, 2021, 8:42am UTC](https://swi-prolog.discourse.group/t/is-there-a-way-to-drain-stdin-by-reading-characters-in-non-blocking-mode/3704 "2021-03-10T08:42:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [March 10, 2021, 8:42am UTC](https://swi-prolog.discourse.group/t/is-there-a-way-to-drain-stdin-by-reading-characters-in-non-blocking-mode/3704/1 "2021-03-10T08:42:04Z")

</div>

I was looking at code (as used in `prolog_pack.pl`) to query the user for a Y/N answer.

This code doesn’t use line discipline whereby the input needs to be terminated by a EOL (that would be the case when reading user input via read\_line\_to\_string/2 for example) but just gets the next character from “the input buffer” (not sure who provides that, but it’s somewhere) with get\_single\_char/1 :

```plaintext
read_yes_no(YesNo, Default) :-
    get_single_char(Code),
    code_yes_no(Code, Default, YesNo),
    !.

code_yes_no(0'y, _, yes).
code_yes_no(0'Y, _, yes).
code_yes_no(0'n, _, no).
code_yes_no(0'N, _, no).
code_yes_no(_, none, _) :- !, fail.
code_yes_no(C, Default, Default) :-
    answered_default(C).

answered_default(0'\r).
answered_default(0'\n).
answered_default(0'\s).

```

get\_single\_char/1 _blocks_ until there is something in the buffer (or an EOF is signalled).

Here lies a problem: If the user typed `y` twice on a preceding question, the the second `y` will be picked up by the get\_single\_char/1 meant for the subsequent question. This leads to erroneous results (that’s a problem that does not occur when reading read\_line\_to\_string/2 as the user has to hit RETURN at least, so I really prefer read\_line\_to\_string/2, which also works nicely with a pipe-from-the-`yes`-command).

To make sure I’m getting the right `y`, I want to drain the input buffer before starting with the next question, i.e. read characters _in non-blocking mode_ until no characters are left, then ask. (What happens if someone pipes an infinite stream of `y` into the program? I guess that would be bad and subject to random outcomes.)

**Is it possible to read characters in non-blocking mode?**

The library for [Primitive character I/O](https://eu.swi-prolog.org/pldoc/man?section=chario) doesn’t seem to provide such a facility.

Indeed, even in C, you need to do a call to `fcntl`: [Nonblocking Get Character](https://stackoverflow.com/questions/20588002/nonblocking-get-character)

Note that I’m not even sure in which regime I’m working here:

> the POSIX manual and all other related documentation explicitly says never to mix IO done on `FILE*` s and file descriptors

This is probably working on top of the filedescriptors (i.e. `man 3P read`).

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [March 11, 2021, 6:37am UTC](https://swi-prolog.discourse.group/t/is-there-a-way-to-drain-stdin-by-reading-characters-in-non-blocking-mode/3704/2 "2021-03-11T06:37:36Z")

</div>

> [@dtonhofer](#):
>
> The library for [Primitive character I/O](https://eu.swi-prolog.org/pldoc/man?section=chario) doesn’t seem to provide such a facility.

did you try read\_pending\_codes/3 or read\_pending\_chars/3?

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [March 15, 2021, 12:37am UTC](https://swi-prolog.discourse.group/t/is-there-a-way-to-drain-stdin-by-reading-characters-in-non-blocking-mode/3704/3 "2021-03-15T00:37:18Z")

</div>

you may also want to check with\_tty\_raw/1, as pointed out by Jan here:

> [@How does one read keyboard input using SWI-prolog without local echo, specifically the arrow keys?](https://swi-prolog.discourse.group/t/how-does-one-read-keyboard-input-using-swi-prolog-without-local-echo-specifically-the-arrow-keys/998):
>
> Hi everyone, My question is old (16 years ago) … I got something in [https://swi-prolog.iai.uni-bonn.narkive.com/Sx1Ehw6M/keyboard-input](https://swi-prolog.iai.uni-bonn.narkive.com/Sx1Ehw6M/keyboard-input), where Jan and others answered, but I would resume it, once that I need a small game that accept ONLY arrows (left right up and dow). I am using the predicate get\_single\_char(Y), as the main predicate to get the key pressed. I am running in a Linux console… directly such: swipl -t main -q -f readings\_keyboard.pl Inside of Swipl interpreter some times ru…
