From 0117308ab5509a5c31b7778f9551f7335c553f77 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Mon, 16 Jun 2014 15:04:08 +0200
Subject: Re-init terminal when awaking from ^Z
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

And simplify code that nobody touched in a long long timeā€¦ Fixes input
issues reported in #458.
---
 src/main.c     |  8 ++-----
 src/terminal.c | 67 +++++++++++++++++++---------------------------------------
 src/terminal.h |  6 ++----
 3 files changed, 26 insertions(+), 55 deletions(-)

diff --git a/src/main.c b/src/main.c
index fd87490..c4bb95a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -414,15 +414,11 @@ static void BarMainLoop (BarApp_t *app) {
 
 int main (int argc, char **argv) {
 	static BarApp_t app;
-	/* terminal attributes _before_ we started messing around with ~ECHO */
-	struct termios termOrig;
 
 	memset (&app, 0, sizeof (app));
 
 	/* save terminal attributes, before disabling echoing */
-	BarTermSave (&termOrig);
-	BarTermSetEcho (0);
-	BarTermSetBuffer (0);
+	BarTermInit ();
 
 	/* signals */
 	signal (SIGPIPE, SIG_IGN);
@@ -506,7 +502,7 @@ int main (int argc, char **argv) {
 	BarSettingsDestroy (&app.settings);
 
 	/* restore terminal attributes, zsh doesn't need this, bash does... */
-	BarTermRestore (&termOrig);
+	BarTermRestore ();
 
 	return 0;
 }
diff --git a/src/terminal.c b/src/terminal.c
index 44513ce..2715d89 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2008-2010
+Copyright (c) 2008-2014
 	Lars-Dominik Braun <lars@6xq.net>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -21,61 +21,38 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
 
-#ifndef __FreeBSD__
-#define _POSIX_C_SOURCE 1 /* fileno() */
-#define _BSD_SOURCE /* setlinebuf() */
-#define _DARWIN_C_SOURCE /* setlinebuf() on OS X */
-#endif
-
 #include <termios.h>
 #include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
 
 #include "terminal.h"
 
-/*	en/disable echoing for stdin
- *	@param 1 = enable, everything else = disable
- */
-void BarTermSetEcho (char enable) {
-	struct termios termopts;
+/* need a global variable here, since these functions get called from a signal
+ * handler */
+static struct termios restore;
 
-	tcgetattr (fileno (stdin), &termopts);
-	if (enable == 1) {
-		termopts.c_lflag |= ECHO;
-	} else {
-		termopts.c_lflag &= ~ECHO;
-	}
-	tcsetattr(fileno (stdin), TCSANOW, &termopts);
+/*	init terminal attributes when continuing, assuming the shell modified them;
+ *	tcget/setattr and signal are async signal safe */
+static void BarTermHandleCont (int sig) {
+	BarTermInit ();
 }
 
-/*	en/disable stdin buffering; when enabling line-buffer method will be
- *	selected for you
- *	@param 1 = enable, everything else = disable
- */
-void BarTermSetBuffer (char enable) {
-	struct termios termopts;
+void BarTermInit () {
+	struct termios newopt;
 
-	tcgetattr (fileno (stdin), &termopts);
-	if (enable == 1) {
-		termopts.c_lflag |= ICANON;
-		setlinebuf (stdin);
-	} else {
-		termopts.c_lflag &= ~ICANON;
-		setvbuf (stdin, NULL, _IONBF, 1);
-	}
-	tcsetattr(fileno (stdin), TCSANOW, &termopts);
-}
+	tcgetattr (STDIN_FILENO, &restore);
+	memcpy (&newopt, &restore, sizeof (newopt));
+
+	/* disable echoing and line buffer */
+	newopt.c_lflag &= ~(ECHO | ICANON);
+	tcsetattr (STDIN_FILENO, TCSANOW, &newopt);
 
-/*	Save old terminal settings
- *	@param save settings here
- */
-void BarTermSave (struct termios *termOrig) {
-	tcgetattr (fileno (stdin), termOrig);
+	signal (SIGCONT, BarTermHandleCont);
 }
 
-/*	Restore terminal settings
- *	@param Old settings
- */
-void BarTermRestore (struct termios *termOrig) {
-	tcsetattr (fileno (stdin), TCSANOW, termOrig);
+void BarTermRestore () {
+	tcsetattr (STDIN_FILENO, TCSANOW, &restore);
 }
 
diff --git a/src/terminal.h b/src/terminal.h
index 4ada438..c43d01b 100644
--- a/src/terminal.h
+++ b/src/terminal.h
@@ -24,9 +24,7 @@ THE SOFTWARE.
 #ifndef SRC_TERMINAL_H_WY8F3MNH
 #define SRC_TERMINAL_H_WY8F3MNH
 
-void BarTermSetEcho (char);
-void BarTermSetBuffer (char);
-void BarTermSave (struct termios *);
-void BarTermRestore (struct termios *termOrig);
+void BarTermInit ();
+void BarTermRestore ();
 
 #endif /* SRC_TERMINAL_H_WY8F3MNH */
-- 
cgit v1.2.3