Commit 82083824 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

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.
parent 284207b1
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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
+33 −2
Original line number Diff line number Diff line
@@ -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';
+2 −18
Original line number Diff line number Diff line
@@ -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);