From b9814db3ed0a911c4ad5661c276e1921a9b2ae81 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 30 Aug 2021 17:37:55 +0200 Subject: Restore terminal attributes if interrupting asroot prompt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- editasroot.c | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'editasroot.c') diff --git a/editasroot.c b/editasroot.c index 0036791..ca08aab 100644 --- a/editasroot.c +++ b/editasroot.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #define TEMPFILEPATTERN "tmpXXXXXX" @@ -16,6 +17,9 @@ static const char *argv0 = "editasroot"; static const char *unlink_this = NULL; +static int ttyfd = -1; +static int tcattrs_fetched = 0; +static struct termios tcattrs; static void @@ -33,6 +37,12 @@ cleanup(void) unlink(unlink_this); unlink_this = NULL; } + if (ttyfd >= 0) { + if (tcattrs_fetched) + tcsetattr(ttyfd, TCSAFLUSH, &tcattrs); + close(ttyfd); + ttyfd = -1; + } } @@ -50,15 +60,9 @@ static const char * get_editor(void) { const char *editor = NULL; - int fd, isbg; + int isbg; - fd = open(_PATH_TTY, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: open %s O_RDONLY: %s", argv0, _PATH_TTY, strerror(errno)); - exit(1); - } - isbg = getpgrp() != tcgetpgrp(fd); - close(fd); + isbg = getpgrp() != tcgetpgrp(ttyfd); if (isbg) editor = getenv("VISUAL"); @@ -137,6 +141,7 @@ run_child(const char *file, int fd, int close_this) case 0: close(STDIN_FILENO); close(STDOUT_FILENO); + close(ttyfd); close(close_this); prctl(PR_SET_PDEATHSIG, SIGKILL); sprintf(fdstr, "%i", fd); @@ -195,6 +200,29 @@ main(int argc, char *argv[]) if (--argc != 1) usage(); + if (atexit(cleanup)) { + fprintf(stderr, "%s: atexit: %s", argv0, strerror(errno)); + exit(1); + } + + /* Get terminal, needed for attributes and to chekh if VISUAL or EDITOR should be used */ + ttyfd = open(_PATH_TTY, O_RDONLY); + if (ttyfd < 0) { + fprintf(stderr, "%s: open %s O_RDONLY: %s", argv0, _PATH_TTY, strerror(errno)); + exit(1); + } + + /* Get terminal attributes, needed in case of interrupt during asroot prompt (didn't find a better alternative) */ + memset(&tcattrs, 0, sizeof(tcattrs)); + if (tcgetattr(ttyfd, &tcattrs)) { + fprintf(stderr, "%s: tcgetattr %s: %s\n", argv0, _PATH_TTY, strerror(errno)); + exit(1); + } + tcattrs_fetched = 1; + + /* Check that VISUAL or EDITOR is set before prompting for password, + * that way, the user sees why vi(1) is opened before it is being, + * opened, and can also abort and set EDITOR */ editor = get_editor(); /* Start copier, with a bidirectional channel to it for copying the file */ @@ -218,10 +246,6 @@ main(int argc, char *argv[]) exit(1); } unlink_this = path; - if (atexit(cleanup)) { - fprintf(stderr, "%s: atexit: %s", argv0, strerror(errno)); - exit(1); - } copy_file(fd, path, fds[0], ""); if (close(fd)) { fprintf(stderr, "%s: write %s: %s", argv0, path, strerror(errno)); @@ -232,6 +256,9 @@ main(int argc, char *argv[]) exit(1); } + /* Don't need to restore terminal attributes, if we got here, asroot as not interrupted */ + close(ttyfd); + /* Start file editor */ run_editor(editor, path, fds[0]); -- cgit v1.2.3-70-g09d2