Listing 2. Terminal I/O Examples
#include <termios.h>
#include <signal.h>
#include <stdlib.h>
/* This will be used for new terminal settings */
static struct termios current;
/* This will hold the initial state so that we
* can restore it later. */
static struct termios initial;
/* Restore the terminal settings to those saved
* when term_init was called. */
void term_restore(void)
{
tcsetattr(0, TCSANOW, &initial);
}
/* Clean up terminal; called on exit */
void term_exit()
{
term_restore();
}
/* Will be called when control-Z is pressed;
* this correctly handles the terminal. */
void term_ctrlz()
{
signal(SIGTSTP, term_ctrlz);
term_restore();
signal(getpid(), SIGSTOP);
}
/* Will be called when the application is
* continued after having been stopped. */
void term_cont()
{
signal(SIGCONT, term_cont);
tcsetattr(0, TCSANOW, ¤t);
}
/* Needs to be called to initialize the terminal */
void term_init(void)
{
/* If stdin isn't a terminal this fails. But
* then so does tcsetattr so it doesn't matter. */
tcgetattr(0, &initial);
/* Save a copy to work with later */
current = initial;
/* We _must_ clean up when we exit */
signal(SIGINT, term_exit);
signal(SIGQUIT, term_exit);
/* Control-Z must also be handled */
signal(SIGTSTP, term_ctrlz);
signal(SIGCONT, term_cont);
atexit(term_exit);
}
/* Set character-by-character input mode */
void term_character(void)
{
/* One or more characters are sufficient
* to cause a read to return. */
current.c_cc[VMIN] = 1;
/* No timeout; read waits forever
* until ready. */
current.c_cc[VTIME] = 0;
/* Line-by-line mode off */
current.c_lflag &= ~ICANON;
tcsetattr(0, TCSANOW, ¤t);
}
/* Return to line-by-line input mode */
void term_line(void)
{
current.c_lflag |= ICANON;
tcsetattr(0, TCSANOW, ¤t);
}
Features
Porting DOS Applications to Linux