Only add trailing carriage return to messages if output is a raw tty.
If output is being written to a terminal in "raw" mode, we need to add a carriage return after the newline to avoid "stair-step" output. However, we should not write the carriage return if the terminal is in "cooked" mode, output to a pipe, or output redirected to a file. Bug #1042.
This commit is contained in:
@@ -349,6 +349,8 @@ sudo_dso_public bool sudo_term_raw_v1(int fd, int isig);
|
||||
#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))
|
||||
sudo_dso_public bool sudo_term_is_raw_v1(int fd);
|
||||
#define sudo_term_is_raw(_a) sudo_term_is_raw_v1((_a))
|
||||
|
||||
/* ttyname_dev.c */
|
||||
sudo_dso_public char *sudo_ttyname_dev_v1(dev_t tdev, char *name, size_t namelen);
|
||||
|
@@ -239,7 +239,7 @@ warning(const char *errstr, const char *fmt, va_list ap)
|
||||
fputs(": ", stderr);
|
||||
fputs(errstr, stderr);
|
||||
}
|
||||
if (isatty(fileno(stderr)))
|
||||
if (sudo_term_is_raw(fileno(stderr)))
|
||||
putc('\r', stderr);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
@@ -288,3 +288,27 @@ sudo_term_copy_v1(int src, int dst)
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if fd refers to a tty in raw mode, else false.
|
||||
*/
|
||||
bool
|
||||
sudo_term_is_raw_v1(int fd)
|
||||
{
|
||||
struct termios term;
|
||||
debug_decl(sudo_term_is_raw, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (tcgetattr(fd, &term) != 0)
|
||||
debug_return_bool(false);
|
||||
|
||||
if (term.c_cc[VMIN] != 1 || term.c_cc[VTIME] != 0)
|
||||
debug_return_bool(false);
|
||||
|
||||
if (ISSET(term.c_oflag, OPOST))
|
||||
debug_return_bool(false);
|
||||
|
||||
if (ISSET(term.c_oflag, ECHO|ECHONL|ICANON))
|
||||
debug_return_bool(false);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
@@ -145,6 +145,7 @@ sudo_term_cbreak_v1
|
||||
sudo_term_copy_v1
|
||||
sudo_term_eof
|
||||
sudo_term_erase
|
||||
sudo_term_is_raw_v1
|
||||
sudo_term_kill
|
||||
sudo_term_noecho_v1
|
||||
sudo_term_raw_v1
|
||||
|
@@ -91,11 +91,16 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
||||
const char *crnl = NULL;
|
||||
bool written = false;
|
||||
int ttyfd = -1;
|
||||
bool raw_tty = false;
|
||||
|
||||
if (ISSET(msg->msg_type, SUDO_CONV_PREFER_TTY) &&
|
||||
!ISSET(tgetpass_flags, TGP_STDIN))
|
||||
!ISSET(tgetpass_flags, TGP_STDIN)) {
|
||||
ttyfd = open(_PATH_TTY, O_WRONLY);
|
||||
if (len != 0 && (ttyfd != -1 || isatty(fileno(fp)))) {
|
||||
raw_tty = sudo_term_is_raw(ttyfd);
|
||||
} else {
|
||||
raw_tty = sudo_term_is_raw(fileno(fp));
|
||||
}
|
||||
if (len != 0 && raw_tty) {
|
||||
/* Convert nl -> cr nl in case tty is in raw mode. */
|
||||
if (msg->msg[len - 1] == '\n') {
|
||||
if (len == 1 || msg->msg[len - 2] != '\r') {
|
||||
@@ -177,6 +182,7 @@ sudo_conversation_printf(int msg_type, const char *fmt, ...)
|
||||
case SUDO_CONV_INFO_MSG:
|
||||
/* Convert nl -> cr nl in case tty is in raw mode. */
|
||||
len = strlen(fmt);
|
||||
if (sudo_term_is_raw(fileno(ttyfp ? ttyfp : fp))) {
|
||||
if (len < ssizeof(fmt2) && len > 0 && fmt[len - 1] == '\n') {
|
||||
if (len == 1 || fmt[len - 2] != '\r') {
|
||||
memcpy(fmt2, fmt, len - 1);
|
||||
@@ -185,6 +191,7 @@ sudo_conversation_printf(int msg_type, const char *fmt, ...)
|
||||
crnl = "\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vfprintf(ttyfp ? ttyfp : fp, fmt, ap);
|
||||
va_end(ap);
|
||||
|
Reference in New Issue
Block a user