libbb: consolidate the code to set termios unbuffered mode
function old new delta set_termios_to_raw - 116 +116 count_lines 72 74 +2 powertop_main 1458 1430 -28 top_main 943 914 -29 more_main 759 714 -45 fsck_minix_main 2969 2921 -48 conspy_main 1197 1135 -62 rawmode 99 36 -63 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/6 up/down: 118/-275) Total: -157 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
8944c67b1f
commit
01ccdd1d3c
15
editors/vi.c
15
editors/vi.c
@ -354,7 +354,7 @@ struct globals {
|
|||||||
#if ENABLE_FEATURE_VI_USE_SIGNALS
|
#if ENABLE_FEATURE_VI_USE_SIGNALS
|
||||||
sigjmp_buf restart; // catch_sig()
|
sigjmp_buf restart; // catch_sig()
|
||||||
#endif
|
#endif
|
||||||
struct termios term_orig, term_vi; // remember what the cooked mode was
|
struct termios term_orig; // remember what the cooked mode was
|
||||||
#if ENABLE_FEATURE_VI_COLON
|
#if ENABLE_FEATURE_VI_COLON
|
||||||
char *initial_cmds[3]; // currently 2 entries, NULL terminated
|
char *initial_cmds[3]; // currently 2 entries, NULL terminated
|
||||||
#endif
|
#endif
|
||||||
@ -462,7 +462,6 @@ struct globals {
|
|||||||
#define context_end (G.context_end )
|
#define context_end (G.context_end )
|
||||||
#define restart (G.restart )
|
#define restart (G.restart )
|
||||||
#define term_orig (G.term_orig )
|
#define term_orig (G.term_orig )
|
||||||
#define term_vi (G.term_vi )
|
|
||||||
#define initial_cmds (G.initial_cmds )
|
#define initial_cmds (G.initial_cmds )
|
||||||
#define readbuffer (G.readbuffer )
|
#define readbuffer (G.readbuffer )
|
||||||
#define scr_out_buf (G.scr_out_buf )
|
#define scr_out_buf (G.scr_out_buf )
|
||||||
@ -2731,15 +2730,9 @@ static char *swap_context(char *p) // goto new context for '' command make this
|
|||||||
//----- Set terminal attributes --------------------------------
|
//----- Set terminal attributes --------------------------------
|
||||||
static void rawmode(void)
|
static void rawmode(void)
|
||||||
{
|
{
|
||||||
tcgetattr(0, &term_orig);
|
// no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals
|
||||||
term_vi = term_orig;
|
set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL);
|
||||||
term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG on - allow intr's
|
erase_char = term_orig.c_cc[VERASE];
|
||||||
term_vi.c_iflag &= (~IXON & ~ICRNL);
|
|
||||||
term_vi.c_oflag &= (~ONLCR);
|
|
||||||
term_vi.c_cc[VMIN] = 1;
|
|
||||||
term_vi.c_cc[VTIME] = 0;
|
|
||||||
erase_char = term_vi.c_cc[VERASE];
|
|
||||||
tcsetattr_stdin_TCSANOW(&term_vi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cookmode(void)
|
static void cookmode(void)
|
||||||
|
@ -1438,6 +1438,10 @@ int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FU
|
|||||||
int get_terminal_width(int fd) FAST_FUNC;
|
int get_terminal_width(int fd) FAST_FUNC;
|
||||||
|
|
||||||
int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
|
int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
|
||||||
|
#define TERMIOS_CLEAR_ISIG (1 << 0)
|
||||||
|
#define TERMIOS_RAW_CRNL (1 << 1)
|
||||||
|
#define TERMIOS_RAW_INPUT (1 << 2)
|
||||||
|
int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC;
|
||||||
|
|
||||||
/* NB: "unsigned request" is crucial! "int request" will break some arches! */
|
/* NB: "unsigned request" is crucial! "int request" will break some arches! */
|
||||||
int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
|
int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
|
||||||
|
@ -2325,7 +2325,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
|
|||||||
/* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
|
/* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
|
||||||
/* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
|
/* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
|
||||||
new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG);
|
new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG);
|
||||||
/* reads would block only if < 1 char is available */
|
/* reads will block only if < 1 char is available */
|
||||||
new_settings.c_cc[VMIN] = 1;
|
new_settings.c_cc[VMIN] = 1;
|
||||||
/* no timeout (reads block forever) */
|
/* no timeout (reads block forever) */
|
||||||
new_settings.c_cc[VTIME] = 0;
|
new_settings.c_cc[VTIME] = 0;
|
||||||
|
@ -311,6 +311,43 @@ int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
|
|||||||
return tcsetattr(STDIN_FILENO, TCSANOW, tp);
|
return tcsetattr(STDIN_FILENO, TCSANOW, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags)
|
||||||
|
{
|
||||||
|
//TODO: lineedit, microcom and less might be adapted to use this too:
|
||||||
|
// grep for "tcsetattr"
|
||||||
|
|
||||||
|
struct termios newterm;
|
||||||
|
|
||||||
|
tcgetattr(fd, oldterm);
|
||||||
|
newterm = *oldterm;
|
||||||
|
|
||||||
|
/* Turn off buffered input (ICANON)
|
||||||
|
* Turn off echoing (ECHO)
|
||||||
|
* and separate echoing of newline (ECHONL, normally off anyway)
|
||||||
|
*/
|
||||||
|
newterm.c_lflag &= ~(ICANON | ECHO | ECHONL);
|
||||||
|
if (flags & TERMIOS_CLEAR_ISIG) {
|
||||||
|
/* dont recognize INT/QUIT/SUSP chars */
|
||||||
|
newterm.c_lflag &= ~ISIG;
|
||||||
|
}
|
||||||
|
/* reads will block only if < 1 char is available */
|
||||||
|
newterm.c_cc[VMIN] = 1;
|
||||||
|
/* no timeout (reads block forever) */
|
||||||
|
newterm.c_cc[VTIME] = 0;
|
||||||
|
if (flags & TERMIOS_RAW_CRNL) {
|
||||||
|
/* dont convert CR to NL on input */
|
||||||
|
newterm.c_iflag &= ~(IXON | ICRNL);
|
||||||
|
/* dont convert NL to CR on output */
|
||||||
|
newterm.c_oflag &= ~(ONLCR);
|
||||||
|
}
|
||||||
|
if (flags & TERMIOS_RAW_INPUT) {
|
||||||
|
/* dont convert anything on input */
|
||||||
|
newterm.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcsetattr(fd, TCSANOW, &newterm);
|
||||||
|
}
|
||||||
|
|
||||||
pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
|
pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
|
||||||
{
|
{
|
||||||
pid_t r;
|
pid_t r;
|
||||||
|
@ -316,7 +316,7 @@ static void init_tty_attrs(int speed)
|
|||||||
/* non-raw output; add CR to each NL */
|
/* non-raw output; add CR to each NL */
|
||||||
G.tty_attrs.c_oflag = OPOST | ONLCR;
|
G.tty_attrs.c_oflag = OPOST | ONLCR;
|
||||||
|
|
||||||
/* reads would block only if < 1 char is available */
|
/* reads will block only if < 1 char is available */
|
||||||
G.tty_attrs.c_cc[VMIN] = 1;
|
G.tty_attrs.c_cc[VMIN] = 1;
|
||||||
/* no timeout (reads block forever) */
|
/* no timeout (reads block forever) */
|
||||||
G.tty_attrs.c_cc[VTIME] = 0;
|
G.tty_attrs.c_cc[VTIME] = 0;
|
||||||
|
@ -105,12 +105,12 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
|
ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//TODO: use set_termios_to_raw()
|
||||||
tcgetattr(STDIN_FILENO, &oterm);
|
tcgetattr(STDIN_FILENO, &oterm);
|
||||||
term = oterm;
|
term = oterm;
|
||||||
term.c_iflag &= ~BRKINT;
|
term.c_iflag |= IGNBRK; /* ignore serial break (why? VTs don't have breaks, right?) */
|
||||||
term.c_iflag |= IGNBRK;
|
term.c_iflag &= ~BRKINT; /* redundant? "dont translate break to SIGINT" */
|
||||||
term.c_lflag &= ~ISIG;
|
term.c_lflag &= ~(ISIG | ECHO | ECHOCTL); /* ignore ^C ^Z, echo off */
|
||||||
term.c_lflag &= ~(ECHO | ECHOCTL);
|
|
||||||
tcsetattr_stdin_TCSANOW(&term);
|
tcsetattr_stdin_TCSANOW(&term);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -213,6 +213,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
, signal_handler);
|
, signal_handler);
|
||||||
|
|
||||||
#if ENABLE_FEATURE_CHAT_TTY_HIFI
|
#if ENABLE_FEATURE_CHAT_TTY_HIFI
|
||||||
|
//TODO: use set_termios_to_raw()
|
||||||
tcgetattr(STDIN_FILENO, &tio);
|
tcgetattr(STDIN_FILENO, &tio);
|
||||||
tio0 = tio;
|
tio0 = tio;
|
||||||
cfmakeraw(&tio);
|
cfmakeraw(&tio);
|
||||||
|
@ -363,7 +363,6 @@ int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|||||||
int conspy_main(int argc UNUSED_PARAM, char **argv)
|
int conspy_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
char tty_name[sizeof(DEV_TTY "NN")];
|
char tty_name[sizeof(DEV_TTY "NN")];
|
||||||
struct termios termbuf;
|
|
||||||
unsigned opts;
|
unsigned opts;
|
||||||
unsigned ttynum;
|
unsigned ttynum;
|
||||||
int poll_timeout_ms;
|
int poll_timeout_ms;
|
||||||
@ -414,16 +413,14 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
bb_signals(BB_FATAL_SIGS, cleanup);
|
bb_signals(BB_FATAL_SIGS, cleanup);
|
||||||
|
|
||||||
// All characters must be passed through to us unaltered
|
|
||||||
G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY);
|
G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY);
|
||||||
tcgetattr(G.kbd_fd, &G.term_orig);
|
|
||||||
termbuf = G.term_orig;
|
// All characters must be passed through to us unaltered
|
||||||
termbuf.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
|
set_termios_to_raw(G.kbd_fd, &G.term_orig, 0
|
||||||
//termbuf.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n
|
| TERMIOS_CLEAR_ISIG // no signals on ^C ^Z etc
|
||||||
termbuf.c_lflag &= ~(ISIG|ICANON|ECHO);
|
| TERMIOS_RAW_INPUT // turn off all input conversions
|
||||||
termbuf.c_cc[VMIN] = 1;
|
);
|
||||||
termbuf.c_cc[VTIME] = 0;
|
//Note: termios.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n
|
||||||
tcsetattr(G.kbd_fd, TCSANOW, &termbuf);
|
|
||||||
|
|
||||||
poll_timeout_ms = 250;
|
poll_timeout_ms = 250;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
// set raw tty mode
|
// set raw tty mode
|
||||||
static void xget1(int fd, struct termios *t, struct termios *oldt)
|
static void xget1(int fd, struct termios *t, struct termios *oldt)
|
||||||
{
|
{
|
||||||
|
//TODO: use set_termios_to_raw()
|
||||||
tcgetattr(fd, oldt);
|
tcgetattr(fd, oldt);
|
||||||
*t = *oldt;
|
*t = *oldt;
|
||||||
cfmakeraw(t);
|
cfmakeraw(t);
|
||||||
|
@ -263,6 +263,7 @@ int rx_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
termios_err = tcgetattr(read_fd, &tty);
|
termios_err = tcgetattr(read_fd, &tty);
|
||||||
if (termios_err == 0) {
|
if (termios_err == 0) {
|
||||||
|
//TODO: use set_termios_to_raw()
|
||||||
orig_tty = tty;
|
orig_tty = tty;
|
||||||
cfmakeraw(&tty);
|
cfmakeraw(&tty);
|
||||||
tcsetattr(read_fd, TCSAFLUSH, &tty);
|
tcsetattr(read_fd, TCSAFLUSH, &tty);
|
||||||
|
@ -683,7 +683,6 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv)
|
|||||||
ullong cur_duration[MAX_CSTATE_COUNT];
|
ullong cur_duration[MAX_CSTATE_COUNT];
|
||||||
char cstate_lines[MAX_CSTATE_COUNT + 2][64];
|
char cstate_lines[MAX_CSTATE_COUNT + 2][64];
|
||||||
#if ENABLE_FEATURE_USE_TERMIOS
|
#if ENABLE_FEATURE_USE_TERMIOS
|
||||||
struct termios new_settings;
|
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
|
|
||||||
pfd[0].fd = 0;
|
pfd[0].fd = 0;
|
||||||
@ -707,14 +706,11 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv)
|
|||||||
puts("Collecting data for "DEFAULT_SLEEP_STR" seconds");
|
puts("Collecting data for "DEFAULT_SLEEP_STR" seconds");
|
||||||
|
|
||||||
#if ENABLE_FEATURE_USE_TERMIOS
|
#if ENABLE_FEATURE_USE_TERMIOS
|
||||||
tcgetattr(0, (void *)&G.init_settings);
|
/* Turn on unbuffered input; turn off echoing, ^C ^Z etc */
|
||||||
memcpy(&new_settings, &G.init_settings, sizeof(new_settings));
|
set_termios_to_raw(STDIN_FILENO, &G.init_settings, TERMIOS_CLEAR_ISIG);
|
||||||
/* Turn on unbuffered input, turn off echoing */
|
bb_signals(BB_FATAL_SIGS, sig_handler);
|
||||||
new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
|
|
||||||
/* So we don't forget to reset term settings */
|
/* So we don't forget to reset term settings */
|
||||||
atexit(reset_term);
|
atexit(reset_term);
|
||||||
bb_signals(BB_FATAL_SIGS, sig_handler);
|
|
||||||
tcsetattr_stdin_TCSANOW(&new_settings);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Collect initial data */
|
/* Collect initial data */
|
||||||
|
10
procps/top.c
10
procps/top.c
@ -1089,9 +1089,6 @@ int top_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
unsigned interval;
|
unsigned interval;
|
||||||
char *str_interval, *str_iterations;
|
char *str_interval, *str_iterations;
|
||||||
unsigned scan_mask = TOP_MASK;
|
unsigned scan_mask = TOP_MASK;
|
||||||
#if ENABLE_FEATURE_USE_TERMIOS
|
|
||||||
struct termios new_settings;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
|
||||||
@ -1141,11 +1138,8 @@ int top_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
#if ENABLE_FEATURE_USE_TERMIOS
|
#if ENABLE_FEATURE_USE_TERMIOS
|
||||||
else {
|
else {
|
||||||
tcgetattr(0, (void *) &initial_settings);
|
/* Turn on unbuffered input; turn off echoing, ^C ^Z etc */
|
||||||
memcpy(&new_settings, &initial_settings, sizeof(new_settings));
|
set_termios_to_raw(STDIN_FILENO, &initial_settings, TERMIOS_CLEAR_ISIG);
|
||||||
/* unbuffered input, turn off echo */
|
|
||||||
new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
|
|
||||||
tcsetattr_stdin_TCSANOW(&new_settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_signals(BB_FATAL_SIGS, sig_catcher);
|
bb_signals(BB_FATAL_SIGS, sig_catcher);
|
||||||
|
@ -143,7 +143,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
|
|||||||
// Setting it to more than 1 breaks poll():
|
// Setting it to more than 1 breaks poll():
|
||||||
// it blocks even if there's data. !??
|
// it blocks even if there's data. !??
|
||||||
//tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
|
//tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
|
||||||
/* reads would block only if < 1 char is available */
|
/* reads will block only if < 1 char is available */
|
||||||
tty.c_cc[VMIN] = 1;
|
tty.c_cc[VMIN] = 1;
|
||||||
/* no timeout (reads block forever) */
|
/* no timeout (reads block forever) */
|
||||||
tty.c_cc[VTIME] = 0;
|
tty.c_cc[VTIME] = 0;
|
||||||
|
@ -1226,7 +1226,6 @@ void check2(void);
|
|||||||
int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
|
int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
struct termios tmp;
|
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
|
|
||||||
xfunc_error_retval = 8;
|
xfunc_error_retval = 8;
|
||||||
@ -1271,10 +1270,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
read_tables();
|
read_tables();
|
||||||
|
|
||||||
if (OPT_manual) {
|
if (OPT_manual) {
|
||||||
tcgetattr(0, &sv_termios);
|
set_termios_to_raw(STDIN_FILENO, &sv_termios, 0);
|
||||||
tmp = sv_termios;
|
|
||||||
tmp.c_lflag &= ~(ICANON | ECHO);
|
|
||||||
tcsetattr_stdin_TCSANOW(&tmp);
|
|
||||||
termios_set = 1;
|
termios_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ struct globals {
|
|||||||
unsigned terminal_width;
|
unsigned terminal_width;
|
||||||
unsigned terminal_height;
|
unsigned terminal_height;
|
||||||
struct termios initial_settings;
|
struct termios initial_settings;
|
||||||
struct termios new_settings;
|
|
||||||
} FIX_ALIASING;
|
} FIX_ALIASING;
|
||||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||||
@ -101,12 +100,9 @@ int more_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
return bb_cat(argv);
|
return bb_cat(argv);
|
||||||
|
|
||||||
G.tty_fileno = fileno(tty);
|
G.tty_fileno = fileno(tty);
|
||||||
tcgetattr(G.tty_fileno, &G.initial_settings);
|
|
||||||
G.new_settings = G.initial_settings;
|
/* Turn on unbuffered input; turn off echoing */
|
||||||
G.new_settings.c_lflag &= ~(ICANON | ECHO);
|
set_termios_to_raw(G.tty_fileno, &G.initial_settings, 0);
|
||||||
G.new_settings.c_cc[VMIN] = 1;
|
|
||||||
G.new_settings.c_cc[VTIME] = 0;
|
|
||||||
tcsetattr_tty_TCSANOW(&G.new_settings);
|
|
||||||
bb_signals(BB_FATAL_SIGS, gotsig);
|
bb_signals(BB_FATAL_SIGS, gotsig);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
Loading…
Reference in New Issue
Block a user