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.
This commit is contained in:
Benno Schulenberg
2019-05-28 11:06:42 +02:00
parent b53dffaeed
commit d946f38a2b
3 changed files with 38 additions and 23 deletions

View File

@@ -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);