diff --git a/include/sudo_util.h b/include/sudo_util.h index 4fbc3e9f7..285228188 100644 --- a/include/sudo_util.h +++ b/include/sudo_util.h @@ -319,13 +319,15 @@ sudo_dso_public mode_t sudo_strtomode_v2(const char *cp, const char **errstr); extern int (*sudo_printf)(int msg_type, const char * restrict fmt, ...); /* term.c */ +#define SUDO_TERM_ISIG 0x01U +#define SUDO_TERM_OFLAG 0x02U sudo_dso_public bool sudo_term_cbreak_v1(int fd); #define sudo_term_cbreak(_a) sudo_term_cbreak_v1((_a)) sudo_dso_public bool sudo_term_copy_v1(int src, int dst); #define sudo_term_copy(_a, _b) sudo_term_copy_v1((_a), (_b)) sudo_dso_public bool sudo_term_noecho_v1(int fd); #define sudo_term_noecho(_a) sudo_term_noecho_v1((_a)) -sudo_dso_public bool sudo_term_raw_v1(int fd, int isig); +sudo_dso_public bool sudo_term_raw_v1(int fd, unsigned int flags); #define sudo_term_raw(_a, _b) sudo_term_raw_v1((_a), (_b)) sudo_dso_public bool sudo_term_restore_v1(int fd, bool flush); #define sudo_term_restore(_a, _b) sudo_term_restore_v1((_a), (_b)) diff --git a/lib/util/term.c b/lib/util/term.c index a7e4f6841..a605dd630 100644 --- a/lib/util/term.c +++ b/lib/util/term.c @@ -178,22 +178,30 @@ sudo_term_noecho_v1(int fd) } /* - * Set terminal to raw mode with optional terminal signals. + * Set terminal to raw mode as modified by flags. * Returns true on success or false on failure. */ bool -sudo_term_raw_v1(int fd, int isig) +sudo_term_raw_v1(int fd, unsigned int flags) { struct termios term; + tcflag_t oflag; debug_decl(sudo_term_raw, SUDO_DEBUG_UTIL); if (!changed && tcgetattr(fd, &oterm) != 0) debug_return_bool(false); (void) memcpy(&term, &oterm, sizeof(term)); - /* Set terminal to raw mode but optionally enable terminal signals. */ + /* + * Set terminal to raw mode but optionally enable terminal signals + * and/or preserve output flags. + */ + if (ISSET(flags, SUDO_TERM_OFLAG)) + oflag = term.c_oflag; cfmakeraw(&term); - if (isig) + if (ISSET(flags, SUDO_TERM_ISIG)) SET(term.c_lflag, ISIG); + if (ISSET(flags, SUDO_TERM_OFLAG)) + term.c_oflag = oflag; if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == 0) { changed = 1; debug_return_bool(true); diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c index 27f132fe8..2960b43e5 100644 --- a/plugins/sudoers/sudoreplay.c +++ b/plugins/sudoers/sudoreplay.c @@ -629,7 +629,7 @@ setup_terminal(struct eventlog *evlog, bool interactive, bool resize) /* Open fd for /dev/tty and set to raw mode. */ if (interactive) { ttyfd = open(_PATH_TTY, O_RDWR); - while (!sudo_term_raw(ttyfd, 1)) { + while (!sudo_term_raw(ttyfd, SUDO_TERM_ISIG)) { if (errno != EINTR) sudo_fatal("%s", U_("unable to set tty to raw mode")); kill(getpid(), SIGTTOU);