From 820838242134f6bc2078610a6498a62722bca239 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 13 Sep 2017 18:53:45 +0200 Subject: Improve handling of lost terminals When feh loses its controlling terminal at runtime, e.g. due to backgrounding / disowning, it will no longer issue a warning on each terminal keystroke. --- src/feh.h | 4 +++- src/keyevents.c | 35 +++++++++++++++++++++++++++++++++-- src/main.c | 20 ++------------------ 3 files changed, 38 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/feh.h b/src/feh.h index fb9fefe..a4a0a7b 100644 --- a/src/feh.h +++ b/src/feh.h @@ -141,6 +141,8 @@ char *slideshow_create_name(feh_file * file, winwidget winwid); char *thumbnail_create_name(feh_file * file, winwidget winwid); void init_keyevents(void); void init_buttonbindings(void); +void setup_stdin(void); +void restore_stdin(void); void feh_event_handle_keypress(XEvent * ev); void feh_event_handle_stdin(); void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button); @@ -201,6 +203,6 @@ extern char *mode; /* label for the current mode */ /* to terminate long-running children with SIGALRM */ extern int childpid; -extern int control_via_stdin; +extern unsigned char control_via_stdin; #endif diff --git a/src/keyevents.c b/src/keyevents.c index a6833a6..14f1a14 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -29,8 +29,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "filelist.h" #include "winwidget.h" #include "options.h" +#include fehkb keys; +struct termios old_term_settings; +unsigned char control_via_stdin = 0; + +void setup_stdin() { + struct termios ctrl; + + control_via_stdin = 1; + + if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) + eprintf("tcgetattr failed"); + if (tcgetattr(STDIN_FILENO, &ctrl) == -1) + eprintf("tcgetattr failed"); + + ctrl.c_iflag &= ~(PARMRK | ISTRIP + | INLCR | IGNCR | IXON); + ctrl.c_lflag &= ~(ECHO | ICANON | IEXTEN); + ctrl.c_cflag &= ~(CSIZE | PARENB); + ctrl.c_cflag |= CS8; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &ctrl) == -1) + eprintf("tcsetattr failed"); +} + +void restore_stdin() { + if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) + eprintf("tcsetattr failed"); +} static void feh_set_kb(fehkey *key, unsigned int s0, unsigned int y0, unsigned int s1, unsigned int y1, unsigned int s2, unsigned int y2) { @@ -274,8 +302,11 @@ void feh_event_handle_stdin() char stdin_buf[2]; KeySym keysym = NoSymbol; if (read(STDIN_FILENO, &stdin_buf, 1) == -1) { - if (control_via_stdin) - weprintf("reading a command from stdin failed"); + control_via_stdin = 0; + if (isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) { + weprintf("reading a command from stdin failed - disabling control via stdin"); + restore_stdin(); + } return; } stdin_buf[1] = '\0'; diff --git a/src/main.c b/src/main.c index bb4dec4..605c113 100644 --- a/src/main.c +++ b/src/main.c @@ -38,9 +38,6 @@ char **cmdargv = NULL; int cmdargc = 0; char *mode = NULL; -struct termios old_term_settings; -int control_via_stdin = 0; - int main(int argc, char **argv) { atexit(feh_clean_exit); @@ -122,19 +119,7 @@ int feh_main_iteration(int block) * also don't get input from stdin anyway. */ if (isatty(STDIN_FILENO) && !opt.multiwindow && getpgrp() == (tcgetpgrp(STDIN_FILENO))) { - control_via_stdin = 1; - struct termios ctrl; - if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) - eprintf("tcgetattr failed"); - if (tcgetattr(STDIN_FILENO, &ctrl) == -1) - eprintf("tcgetattr failed"); - ctrl.c_iflag &= ~(PARMRK | ISTRIP - | INLCR | IGNCR | IXON); - ctrl.c_lflag &= ~(ECHO | ICANON | IEXTEN); - ctrl.c_cflag &= ~(CSIZE | PARENB); - ctrl.c_cflag |= CS8; - if (tcsetattr(STDIN_FILENO, TCSANOW, &ctrl) == -1) - eprintf("tcsetattr failed"); + setup_stdin(); } } @@ -243,8 +228,7 @@ void feh_clean_exit(void) * around with it) */ if (control_via_stdin && isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) - if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) - eprintf("tcsetattr failed"); + restore_stdin(); if (opt.filelistfile) feh_write_filelist(filelist, opt.filelistfile); -- cgit v1.2.3