#if ENABLE_FEATURE_VI_USE_SIGNALS
sigjmp_buf restart; // catch_sig()
#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
char *initial_cmds[3]; // currently 2 entries, NULL terminated
#endif
#define context_end (G.context_end )
#define restart (G.restart )
#define term_orig (G.term_orig )
-#define term_vi (G.term_vi )
#define initial_cmds (G.initial_cmds )
#define readbuffer (G.readbuffer )
#define scr_out_buf (G.scr_out_buf )
//----- Set terminal attributes --------------------------------
static void rawmode(void)
{
- tcgetattr(0, &term_orig);
- term_vi = term_orig;
- term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG on - allow intr's
- 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);
+ // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals
+ set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL);
+ erase_char = term_orig.c_cc[VERASE];
}
static void cookmode(void)
int get_terminal_width(int fd) 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! */
int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
/* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
/* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
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;
/* no timeout (reads block forever) */
new_settings.c_cc[VTIME] = 0;
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 r;
/* non-raw output; add CR to each NL */
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;
/* no timeout (reads block forever) */
G.tty_attrs.c_cc[VTIME] = 0;
ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
#endif
+//TODO: use set_termios_to_raw()
tcgetattr(STDIN_FILENO, &oterm);
term = oterm;
- term.c_iflag &= ~BRKINT;
- term.c_iflag |= IGNBRK;
- term.c_lflag &= ~ISIG;
- term.c_lflag &= ~(ECHO | ECHOCTL);
+ term.c_iflag |= IGNBRK; /* ignore serial break (why? VTs don't have breaks, right?) */
+ term.c_iflag &= ~BRKINT; /* redundant? "dont translate break to SIGINT" */
+ term.c_lflag &= ~(ISIG | ECHO | ECHOCTL); /* ignore ^C ^Z, echo off */
tcsetattr_stdin_TCSANOW(&term);
while (1) {
, signal_handler);
#if ENABLE_FEATURE_CHAT_TTY_HIFI
+//TODO: use set_termios_to_raw()
tcgetattr(STDIN_FILENO, &tio);
tio0 = tio;
cfmakeraw(&tio);
int conspy_main(int argc UNUSED_PARAM, char **argv)
{
char tty_name[sizeof(DEV_TTY "NN")];
- struct termios termbuf;
unsigned opts;
unsigned ttynum;
int poll_timeout_ms;
bb_signals(BB_FATAL_SIGS, cleanup);
- // All characters must be passed through to us unaltered
G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY);
- tcgetattr(G.kbd_fd, &G.term_orig);
- termbuf = G.term_orig;
- termbuf.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
- //termbuf.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n
- termbuf.c_lflag &= ~(ISIG|ICANON|ECHO);
- termbuf.c_cc[VMIN] = 1;
- termbuf.c_cc[VTIME] = 0;
- tcsetattr(G.kbd_fd, TCSANOW, &termbuf);
+
+ // All characters must be passed through to us unaltered
+ set_termios_to_raw(G.kbd_fd, &G.term_orig, 0
+ | TERMIOS_CLEAR_ISIG // no signals on ^C ^Z etc
+ | TERMIOS_RAW_INPUT // turn off all input conversions
+ );
+ //Note: termios.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n
poll_timeout_ms = 250;
while (1) {
// set raw tty mode
static void xget1(int fd, struct termios *t, struct termios *oldt)
{
+//TODO: use set_termios_to_raw()
tcgetattr(fd, oldt);
*t = *oldt;
cfmakeraw(t);
termios_err = tcgetattr(read_fd, &tty);
if (termios_err == 0) {
+//TODO: use set_termios_to_raw()
orig_tty = tty;
cfmakeraw(&tty);
tcsetattr(read_fd, TCSAFLUSH, &tty);
ullong cur_duration[MAX_CSTATE_COUNT];
char cstate_lines[MAX_CSTATE_COUNT + 2][64];
#if ENABLE_FEATURE_USE_TERMIOS
- struct termios new_settings;
struct pollfd pfd[1];
pfd[0].fd = 0;
puts("Collecting data for "DEFAULT_SLEEP_STR" seconds");
#if ENABLE_FEATURE_USE_TERMIOS
- tcgetattr(0, (void *)&G.init_settings);
- memcpy(&new_settings, &G.init_settings, sizeof(new_settings));
- /* Turn on unbuffered input, turn off echoing */
- new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
+ /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */
+ set_termios_to_raw(STDIN_FILENO, &G.init_settings, TERMIOS_CLEAR_ISIG);
+ bb_signals(BB_FATAL_SIGS, sig_handler);
/* So we don't forget to reset term settings */
atexit(reset_term);
- bb_signals(BB_FATAL_SIGS, sig_handler);
- tcsetattr_stdin_TCSANOW(&new_settings);
#endif
/* Collect initial data */
unsigned interval;
char *str_interval, *str_iterations;
unsigned scan_mask = TOP_MASK;
-#if ENABLE_FEATURE_USE_TERMIOS
- struct termios new_settings;
-#endif
INIT_G();
}
#if ENABLE_FEATURE_USE_TERMIOS
else {
- tcgetattr(0, (void *) &initial_settings);
- memcpy(&new_settings, &initial_settings, sizeof(new_settings));
- /* unbuffered input, turn off echo */
- new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
- tcsetattr_stdin_TCSANOW(&new_settings);
+ /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */
+ set_termios_to_raw(STDIN_FILENO, &initial_settings, TERMIOS_CLEAR_ISIG);
}
bb_signals(BB_FATAL_SIGS, sig_catcher);
// Setting it to more than 1 breaks poll():
// it blocks even if there's data. !??
//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;
/* no timeout (reads block forever) */
tty.c_cc[VTIME] = 0;
int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
{
- struct termios tmp;
int retcode = 0;
xfunc_error_retval = 8;
read_tables();
if (OPT_manual) {
- tcgetattr(0, &sv_termios);
- tmp = sv_termios;
- tmp.c_lflag &= ~(ICANON | ECHO);
- tcsetattr_stdin_TCSANOW(&tmp);
+ set_termios_to_raw(STDIN_FILENO, &sv_termios, 0);
termios_set = 1;
}
unsigned terminal_width;
unsigned terminal_height;
struct termios initial_settings;
- struct termios new_settings;
} FIX_ALIASING;
#define G (*(struct globals*)bb_common_bufsiz1)
#define INIT_G() do { setup_common_bufsiz(); } while (0)
return bb_cat(argv);
G.tty_fileno = fileno(tty);
- tcgetattr(G.tty_fileno, &G.initial_settings);
- G.new_settings = G.initial_settings;
- G.new_settings.c_lflag &= ~(ICANON | ECHO);
- G.new_settings.c_cc[VMIN] = 1;
- G.new_settings.c_cc[VTIME] = 0;
- tcsetattr_tty_TCSANOW(&G.new_settings);
+
+ /* Turn on unbuffered input; turn off echoing */
+ set_termios_to_raw(G.tty_fileno, &G.initial_settings, 0);
bb_signals(BB_FATAL_SIGS, gotsig);
do {