diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2017-09-13 18:53:45 +0200 | 
|---|---|---|
| committer | Daniel Friesel <derf@finalrewind.org> | 2017-09-13 18:53:45 +0200 | 
| commit | 820838242134f6bc2078610a6498a62722bca239 (patch) | |
| tree | 1a85d0a80530dc503775b73c6aff55be3afd0824 | |
| parent | 284207b12dbfd13c25416cba69a151f54dabb6dc (diff) | |
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.
| -rw-r--r-- | src/feh.h | 4 | ||||
| -rw-r--r-- | src/keyevents.c | 35 | ||||
| -rw-r--r-- | src/main.c | 20 | 
3 files changed, 38 insertions, 21 deletions
| @@ -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 <termios.h>  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'; @@ -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) <https://github.com/derf/feh/issues/324>  	 */  	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); | 
