From f43bdedaa7334412aabefa62b8ae559b5b1d9e63 Mon Sep 17 00:00:00 2001 From: "G.raud Meyer" Date: Thu, 29 Mar 2018 12:08:46 +0200 Subject: [PATCH] rename: detect tty in cbreak mode to make ask() read a single byte Set tty_cbreak only when tty has a VMIN of 1 to avoid having to purge at all in cbreak mode. The prompt is still compatible with a non interactive input from a pipe. --- misc-utils/rename.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/misc-utils/rename.c b/misc-utils/rename.c index d98e9d8f9..1c24d7e32 100644 --- a/misc-utils/rename.c +++ b/misc-utils/rename.c @@ -20,6 +20,7 @@ for i in $@; do N=`echo "$i" | sed "s/$FROM/$TO/g"`; mv "$i" "$N"; done #include #include #include +#include #include #include @@ -33,6 +34,8 @@ for i in $@; do N=`echo "$i" | sed "s/$FROM/$TO/g"`; mv "$i" "$N"; done #define RENAME_EXIT_NOTHING 4 #define RENAME_EXIT_UNEXPLAINED 64 +static int tty_cbreak = 0; + static int string_replace(char *from, char *to, char *s, char *orig, char **newname) { char *p, *q, *where; @@ -68,7 +71,9 @@ static int ask(char *name) } else { buf[0] = c; buf[1] = '\0'; - if (c != '\n') + if (c != '\n' && tty_cbreak) /* no purge necessary */ + printf("\n"); + else if (c != '\n') while ((c = fgetc(stdin)) != '\n' && c != EOF); } if (rpmatch(buf) == RPMATCH_YES) @@ -202,6 +207,7 @@ int main(int argc, char **argv) { char *from, *to; int i, c, ret = 0, verbose = 0, noact = 0, nooverwrite = 0, interactive = 0; + struct termios tio; int (*do_rename)(char *from, char *to, char *s, int verbose, int noact, int nooverwrite, int interactive) = do_file; @@ -263,6 +269,14 @@ int main(int argc, char **argv) if (!strcmp(from, to)) return RENAME_EXIT_NOTHING; + tty_cbreak = 0; + if (interactive && isatty(STDIN_FILENO) != 0) { + if (tcgetattr(STDIN_FILENO, &tio) != 0) + warn(_("failed to get terminal attributes")); + else if (!(tio.c_lflag & ICANON) && tio.c_cc[VMIN] == 1) + tty_cbreak = 1; + } + for (i = 2; i < argc; i++) ret |= do_rename(from, to, argv[i], verbose, noact, nooverwrite, interactive);