2

I'm trying to call a function when a user presses a key, somewhat like sending a signal with Ctrl-C. The idea is to be doing something, say in a while loop, and actively listen for, say, the 'f' key being pressed. When it is pressed, the program will stop performing the loop and do something else because the 'f' key was pressed.

Is there a way to customize the signal mapping? I didn't have much luck with this. There also seemed to be 1 or 2 available signals for customization, but I need 3.

If I use getchar(), the user needs to press the 'f' key AND THEN press the enter key. I would like for them to just press the 'f' key and not have to press the enter key.

It is very similar to using unix's more program where the user can just press the space bar to go through pages.

Any help is greatly appreciated!

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
user1472747
  • 529
  • 3
  • 10
  • 25
  • Windows has the concept of hooks. I don't know what Unix has, but that might help you find what you want. – chris Apr 05 '13 at 04:33
  • Yeah, I'm looking for it in Unix. – user1472747 Apr 05 '13 at 04:35
  • Looks like you have ncurses or [this](http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/). For reference: http://stackoverflow.com/questions/3392291/c-monitor-for-keyboard-input – chris Apr 05 '13 at 04:38
  • I've got an example of getting in and out of RAW mode with termios [here](http://stackoverflow.com/a/7411735/733077). – luser droog Apr 05 '13 at 05:37
  • You can change your terminal settings to make 'f' send and interrupt signal with `stty intr f` although this is likely to drive you insane in most normal scenarios. – CB Bailey Apr 05 '13 at 05:41

2 Answers2

3

If for some reason you do not like ncurses, you can try something like the following.

You can use a separate thread which uses select() on stdin then performs a read() on stdin and parses user input; if the key is what you are looking for, send a signal (i.e. USER1 or USER2 are unused) to your main thread. In your signal handler, perform whatever operation you are looking to do on the interrupt. Note that doing this means that your code must be interruptible so the interrupt does not break your computation.

RageD
  • 6,693
  • 4
  • 30
  • 37
3

By far the simplest option is to use ncurses.

However, if that's not acceptable, POSIX (and therefore Linux too) defines a series of routines for 'terminal control' — the names start with tc and include:

In this context, you primarily need tcgetattr() and tcsetattr(). You will need to study the strictures in the definitions for tcgetattr() and tcsetattr(), and will need to study the structures and flags in the <termios.h> header. Look at the ICANON local mode, for example: you will probably want to turn that off so that characters are available to read as soon as they are typed.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278