diff --git a/include/libbb.h b/include/libbb.h index 631799aca..6cda18c37 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -613,6 +613,7 @@ char *xmalloc_substitute_string(const char *src, int count, const char *sub, con /* Guaranteed to NOT be a macro (smallest code). Saves nearly 2k on uclibc. * But potentially slow, don't use in one-billion-times loops */ int bb_putchar(int ch) FAST_FUNC; +void bb_putchar_binary(int ch) FAST_FUNC; /* Note: does not use stdio, writes to fd 2 directly */ int bb_putchar_stderr(char ch) FAST_FUNC; char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 42d90df59..8639c7e5b 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -135,6 +135,8 @@ char *right_cmd = ESC"[C"; char *clear_to_end_of_screen_cmd = ESC"[J"; #endif +bool automargin; /* Does terminal have automatic margins? */ + char termcap_string_buf[TERMCAP_BUFSIZ]; /* Terminal escape sequences to process in input (used by read_key) */ @@ -267,6 +269,8 @@ void init_termcap(void) return; tgetent(termcap_buffer, term); + automargin = tgetflag("am"); + result = tgetstr("up", &string_buf); if (result != NULL) up_cmd = result; @@ -470,7 +474,10 @@ static void put_cur_glyph_and_inc_cursor(void) * have automargin (IOW: it is moving cursor to next line * by itself (which is wrong for VT-10x terminals)), * this will break things: there will be one extra empty line */ - puts("\r"); /* + implicit '\n' */ + if (!automargin) { + bb_putchar_binary('\r'); + bb_putchar_binary('\n'); + } #else /* VT-10x terminals don't wrap cursor to next line when last char * on the line is printed - cursor stays "over" this char. @@ -620,7 +627,7 @@ static void redraw(int y, int back_cursor) { if (y > 0) /* up y lines */ go_up(y); // UP -- not implemented; loop doing "up" - bb_putchar('\r'); + bb_putchar_binary('\r'); put_prompt(); put_till_end_and_adv_cursor(); tputs(clear_to_end_of_screen_cmd, 1, bb_putchar); @@ -2412,7 +2419,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman tcsetattr_stdin_TCSANOW(&new_settings); #else new_settings.sg_flags |= CBREAK; - new_settings.sg_flags &= ~ECHO; + new_settings.sg_flags &= ~(CRMOD|ECHO); ioctl(STDIN_FILENO, TIOCSETN, &new_settings); #endif diff --git a/libbb/xfuncs.printf.c b/libbb/xfuncs.printf.c index 970f30e15..737210e20 100644 --- a/libbb/xfuncs.printf.c +++ b/libbb/xfuncs.printf.c @@ -294,6 +294,18 @@ int FAST_FUNC bb_putchar(int ch) return putchar(ch); } +/* Write a character without any newline translation (useful for GNO) */ +void FAST_FUNC bb_putchar_binary(int ch) +{ +#ifndef __GNO__ + putchar(ch); +#else + fflush(stdout); + write(STDOUT_FILENO, &ch, 1); +#endif +} + + /* Die with an error message if we can't copy an entire FILE* to stdout, * then close that file. */ void FAST_FUNC xprint_and_close_file(FILE *file)