From: G.raud Meyer Date: Thu, 29 Mar 2018 10:08:46 +0000 (+0200) Subject: rename: detect tty in cbreak mode to make ask() read a single byte X-Git-Tag: v2.33-rc1~309^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f43bdedaa7334412aabefa62b8ae559b5b1d9e63;p=thirdparty%2Futil-linux.git 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. --- diff --git a/misc-utils/rename.c b/misc-utils/rename.c index d98e9d8f90..1c24d7e329 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);