1

Is it possible to detect whether a user is simply typing anything into stdin?

man select says:

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible).

I guess "ready" means EOF or NL. But what about single characters? Could you program a timer-callback in C, which starts when the user has been idle for some seconds? If yes, how?

user1511417
  • 1,880
  • 3
  • 20
  • 41
  • Well, yes,and no, you'd need to actually read the console using the *raw mode* – Antti Haapala -- Слава Україні Nov 19 '17 at 21:33
  • 1
    In this context "ready" means that a `read()` or `write()` operation on the file descriptor wouldn't block. On the other hand, what you are trying to do won't work like this, because by default the standard input is buffered, so that the user can edit the input line. You want to set the terminal on "raw" mode. – AlexP Nov 19 '17 at 21:34

1 Answers1

3

Yes, this is possible, but you have to put your terminal into character mode. By default, programs usually start in line mode, where your program doesn't get notified for input until a whole line was entered.

You should use a library like for example ncurses to put your terminal into character mode, for example with

initscr();
cbreak();

Now, if you select() your standard input, you will be notified for each character entered, which you can retrieve with getch().

For more details, the NCURSES Programming HowTo might help.

Edit on request of the OP:

If you just have to support linux, you would set the appropriate options in the terminal configuration.

First, read in the current parameters:

struct termios config;
tcgetattr(0, &config);

Then, switch canonical (line mode) off:

config.c_lflag &= ~ICANON;

and specify, that a single character suffices to return from read:

config.c_cc[VMIN] = 1;

Finally, set these parameters on your stdin terminal:

tcsetattr(0, TCSANOW, &config);

Now, a read() should return on a single character read.

Ctx
  • 18,090
  • 24
  • 36
  • 51
  • Why do you recommend using a library? Would a proper solution be too difficult? – user1511417 Nov 19 '17 at 21:57
  • Not too difficult, but tedious if you want to be portable; There are potentially many environments to support, if you use ncurses, you support many of them and the code is easy. If you want to do it by hand, you have much more code and only support one single environment. – Ctx Nov 19 '17 at 22:01
  • Let's say I just have to support Linux. How could I do this? – user1511417 Nov 19 '17 at 22:08
  • @user1511417 I explained it in the answer above – Ctx Nov 19 '17 at 22:24
  • I've tried this! It works!! Thank you. *Note*: You have to `#include `. – user1511417 Nov 20 '17 at 11:23