From d946f38a2bb245478be7c154401faae43b6ecbbf Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@telfort.nl>
Date: Tue, 28 May 2019 11:06:42 +0200
Subject: [PATCH] files: when needed, reconnect the keyboard and reenter curses
 mode

When after reading a file we are not in curses mode, it means we have
read data from standard input, either from the keyboard or from a pipe.
In the latter case, we first need to reconnect standard input to the tty.
And in both cases, we then need to reenter curses mode before being able
to display the number of lines that were read (or an error message).

So, move the reconnecting code from scoop_stdin() to its own function,
and call this function from read_file() when needed.

This fixes https://savannah.gnu.org/bugs/?56310.

Bug existed since version 2.1.8 when reading from stdin was introduced.
---
 src/files.c | 19 ++++++++++++++++---
 src/nano.c  | 41 +++++++++++++++++++++--------------------
 src/proto.h |  1 +
 3 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/src/files.c b/src/files.c
index abe6221e..e1192340 100644
--- a/src/files.c
+++ b/src/files.c
@@ -711,6 +711,8 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
 	int input_int;
 		/* The current value we read from the file, whether an input
 		 * character or EOF. */
+	int errornumber;
+		/* The error code, in case an error occurred during reading. */
 	bool writable = TRUE;
 		/* Whether the file is writable (in case we care). */
 #ifndef NANO_TINY
@@ -814,6 +816,8 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
 #endif
 	}
 
+	errornumber = errno;
+
 	/* We are done with the file, unlock it. */
 	funlockfile(f);
 
@@ -821,10 +825,19 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
 	block_sigwinch(FALSE);
 #endif
 
-	/* Perhaps this could use some better handling. */
-	if (ferror(f))
-		nperror(filename);
+	/* When reading from stdin, restore the terminal and reenter curses mode. */
+	if (isendwin()) {
+		if (!isatty(0))
+			reconnect_and_store_state();
+		terminal_init();
+		doupdate();
+	}
+
+	/* If there was a real error during the reading, let the user know. */
+	if (ferror(f) && errornumber != EINTR && errornumber != 0)
+		statusline(ALERT, strerror(errornumber));
 	fclose(f);
+
 	if (fd > 0 && !undoable) {
 		close(fd);
 		writable = (ISSET(VIEW_MODE) || access(filename, W_OK) == 0);
diff --git a/src/nano.c b/src/nano.c
index 5fee2e21..5d148771 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1075,11 +1075,30 @@ void restore_handler_for_Ctrl_C(void)
 	disable_kb_interrupt();
 }
 
+/* Reconnect standard input to the tty, and store its state. */
+void reconnect_and_store_state(void)
+{
+	int thetty = open("/dev/tty", O_RDONLY);
+
+	if (thetty < 1)
+		die(_("Could not reconnect stdin to keyboard\n"));
+
+	dup2(thetty, 0);
+	close(thetty);
+
+	/* If there were no signals, store the current state of the terminal. */
+	if (!control_C_was_pressed) {
+#ifndef NANO_TINY
+		if (!size_changed)
+#endif
+			tcgetattr(0, &oldterm);
+	}
+}
+
 /* Read whatever comes from standard input into a new buffer. */
 bool scoop_stdin(void)
 {
 	FILE *stream;
-	int thetty;
 
 	/* Exit from curses mode and put the terminal into its original state. */
 	endwin();
@@ -1110,27 +1129,9 @@ bool scoop_stdin(void)
 #ifdef ENABLE_COLOR
 	color_update();
 #endif
-	fprintf(stderr, ".\n");
-
-	/* Reconnect the tty as the input source. */
-	thetty = open("/dev/tty", O_RDONLY);
-	if (!thetty)
-		die(_("Couldn't reopen stdin from keyboard, sorry\n"));
-	dup2(thetty, 0);
-	close(thetty);
-
-	/* If there were no signals, store the current state of the terminal. */
-	if (!control_C_was_pressed) {
-#ifndef NANO_TINY
-		if (!size_changed)
-#endif
-			tcgetattr(0, &oldterm);
-	}
 
-	/* Restore the original ^C handler, the terminal setup, and curses mode. */
+	/* Restore the original ^C handler. */
 	restore_handler_for_Ctrl_C();
-	terminal_init();
-	doupdate();
 
 	if (!ISSET(VIEW_MODE) && openfile->totsize > 0)
 		set_modified();
diff --git a/src/proto.h b/src/proto.h
index 48765ac6..a83a4590 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -416,6 +416,7 @@ void do_exit(void);
 void close_and_go(void);
 void install_handler_for_Ctrl_C(void);
 void restore_handler_for_Ctrl_C(void);
+void reconnect_and_store_state(void);
 RETSIGTYPE handle_hupterm(int signal);
 #ifndef DEBUG
 RETSIGTYPE handle_crash(int signal);
-- 
2.20.1

