sudo_term_raw: change the isig argument into a flags field

There are current two flags: SUDO_TERM_ISIG (enable terminal signals)
and SUDO_TERM_OFLAG (preserve output flags).
This commit is contained in:
Todd C. Miller
2023-07-14 13:12:51 -06:00
parent ff6ddff39b
commit 625653de08
3 changed files with 16 additions and 6 deletions

View File

@@ -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, ...); extern int (*sudo_printf)(int msg_type, const char * restrict fmt, ...);
/* term.c */ /* term.c */
#define SUDO_TERM_ISIG 0x01U
#define SUDO_TERM_OFLAG 0x02U
sudo_dso_public bool sudo_term_cbreak_v1(int fd); sudo_dso_public bool sudo_term_cbreak_v1(int fd);
#define sudo_term_cbreak(_a) sudo_term_cbreak_v1((_a)) #define sudo_term_cbreak(_a) sudo_term_cbreak_v1((_a))
sudo_dso_public bool sudo_term_copy_v1(int src, int dst); sudo_dso_public bool sudo_term_copy_v1(int src, int dst);
#define sudo_term_copy(_a, _b) sudo_term_copy_v1((_a), (_b)) #define sudo_term_copy(_a, _b) sudo_term_copy_v1((_a), (_b))
sudo_dso_public bool sudo_term_noecho_v1(int fd); sudo_dso_public bool sudo_term_noecho_v1(int fd);
#define sudo_term_noecho(_a) sudo_term_noecho_v1((_a)) #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)) #define sudo_term_raw(_a, _b) sudo_term_raw_v1((_a), (_b))
sudo_dso_public bool sudo_term_restore_v1(int fd, bool flush); sudo_dso_public bool sudo_term_restore_v1(int fd, bool flush);
#define sudo_term_restore(_a, _b) sudo_term_restore_v1((_a), (_b)) #define sudo_term_restore(_a, _b) sudo_term_restore_v1((_a), (_b))

View File

@@ -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. * Returns true on success or false on failure.
*/ */
bool bool
sudo_term_raw_v1(int fd, int isig) sudo_term_raw_v1(int fd, unsigned int flags)
{ {
struct termios term; struct termios term;
tcflag_t oflag;
debug_decl(sudo_term_raw, SUDO_DEBUG_UTIL); debug_decl(sudo_term_raw, SUDO_DEBUG_UTIL);
if (!changed && tcgetattr(fd, &oterm) != 0) if (!changed && tcgetattr(fd, &oterm) != 0)
debug_return_bool(false); debug_return_bool(false);
(void) memcpy(&term, &oterm, sizeof(term)); (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); cfmakeraw(&term);
if (isig) if (ISSET(flags, SUDO_TERM_ISIG))
SET(term.c_lflag, ISIG); SET(term.c_lflag, ISIG);
if (ISSET(flags, SUDO_TERM_OFLAG))
term.c_oflag = oflag;
if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == 0) { if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == 0) {
changed = 1; changed = 1;
debug_return_bool(true); debug_return_bool(true);

View File

@@ -629,7 +629,7 @@ setup_terminal(struct eventlog *evlog, bool interactive, bool resize)
/* Open fd for /dev/tty and set to raw mode. */ /* Open fd for /dev/tty and set to raw mode. */
if (interactive) { if (interactive) {
ttyfd = open(_PATH_TTY, O_RDWR); ttyfd = open(_PATH_TTY, O_RDWR);
while (!sudo_term_raw(ttyfd, 1)) { while (!sudo_term_raw(ttyfd, SUDO_TERM_ISIG)) {
if (errno != EINTR) if (errno != EINTR)
sudo_fatal("%s", U_("unable to set tty to raw mode")); sudo_fatal("%s", U_("unable to set tty to raw mode"));
kill(getpid(), SIGTTOU); kill(getpid(), SIGTTOU);