diff --git a/contrib/less/NEWS b/contrib/less/NEWS index 468f59441b28..b1f8771c6c31 100644 --- a/contrib/less/NEWS +++ b/contrib/less/NEWS @@ -9,6 +9,44 @@ Report bugs, suggestions or comments at https://github.com/gwsw/less/issues. +====================================================================== + + Major changes between "less" versions 633 and 643 + +* Fix problem when a program piping into less reads from the tty, + like sudo asking for password (github #368). + +* Fix search modifier ^E after ^W. + +* Fix bug using negated (^N) search (github #374). + +* Fix bug setting colors with -D on Windows build (github #386). + +* Fix reading special chars like PageDown on Windows (github #378). + +* Fix mouse wheel scrolling on Windows (github #379). + +* Fix erroneous EOF when terminal window size changes (github #372). + +* Fix compile error with some definitions of ECHONL (github #395). + +* Fix crash on Windows when writing logfile (github #405). + +* Fix regression in exit code when stdin is /dev/null and + output is a file (github #373). + +* Add lesstest test suite to production release (github #344). + +* Change lesstest output to conform with + automake Simple Test Format (github #399). + +====================================================================== + + Major changes between "less" versions 632 and 633 + +* Fix build on systems which have ncurses/termcap.h or + ncursesw/termcap.h but not termcap.h. + ====================================================================== Major changes between "less" versions 608 and 632 diff --git a/contrib/less/ch.c b/contrib/less/ch.c index b297e7483e7b..fd53b2d66e38 100644 --- a/contrib/less/ch.c +++ b/contrib/less/ch.c @@ -406,6 +406,8 @@ public void sync_logfile(void) BLOCKNUM block; BLOCKNUM nblocks; + if (logfile < 0) + return; nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE; for (block = 0; block < nblocks; block++) { diff --git a/contrib/less/command.c b/contrib/less/command.c index 88c0cb49ee77..c1003d55fada 100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@ -181,7 +181,7 @@ static void mca_search1(void) { if (search_type & SRCH_SUBSEARCH(i)) { - char buf[8]; + char buf[INT_STRLEN_BOUND(int)+8]; SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i); cmd_putstr(buf); } @@ -558,6 +558,7 @@ static int mca_search_char(int c) case CONTROL('E'): /* ignore END of file */ if (mca != A_FILTER) flag = SRCH_PAST_EOF; + search_type &= ~SRCH_WRAP; break; case '@': if (less_is_more) @@ -571,7 +572,7 @@ static int mca_search_char(int c) flag = SRCH_NO_MOVE; break; case CONTROL('S'): { /* SUBSEARCH */ - char buf[32]; + char buf[INT_STRLEN_BOUND(int)+24]; SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS); clear_bot(); cmd_putstr(buf); diff --git a/contrib/less/edit.c b/contrib/less/edit.c index 1896694456e5..3ca5e4cc7d31 100644 --- a/contrib/less/edit.c +++ b/contrib/less/edit.c @@ -975,7 +975,7 @@ public void use_logfile(char *filename) /* * Overwrite: create the file. */ - logfile = creat(filename, 0644); + logfile = creat(filename, CREAT_RW); break; case 'A': case 'a': /* diff --git a/contrib/less/forwback.c b/contrib/less/forwback.c index 6faec94d225b..b020fe5d85eb 100644 --- a/contrib/less/forwback.c +++ b/contrib/less/forwback.c @@ -232,7 +232,7 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank) (forw_scroll >= 0 && n > forw_scroll && n != sc_height-1); #if HILITE_SEARCH - if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) { + if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) { prep_hilite(pos, pos + 4*size_linebuf, ignore_eoi ? 1 : -1); pos = next_unfiltered(pos); } @@ -408,8 +408,8 @@ public void back(int n, POSITION pos, int force, int only_last) squish_check(); do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0); #if HILITE_SEARCH - if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) { - prep_hilite((pos < 3*size_linebuf) ? 0 : pos - 3*size_linebuf, pos, -1); + if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) { + prep_hilite((pos < 3*size_linebuf) ? 0 : pos - 3*size_linebuf, pos, -1); } #endif while (--n >= 0) @@ -492,7 +492,7 @@ public void forward(int n, int force, int only_last) { back(1, position(TOP), 1, 0); pos = position(BOTTOM_PLUS_ONE); - } while (pos == NULL_POSITION); + } while (pos == NULL_POSITION && !ABORT_SIGS()); } } else { diff --git a/contrib/less/funcs.h b/contrib/less/funcs.h index 071e80b050a7..1c9b181c0459 100644 --- a/contrib/less/funcs.h +++ b/contrib/less/funcs.h @@ -36,6 +36,7 @@ public int apply_at_specials(int attr); public void putbs(void); public int win32_kbhit(void); public char WIN32getch(void); +public void WIN32ungetch(int ch); public void WIN32setcolors(int fg, int bg); public void WIN32textout(char *text, int len); public void match_brac(char obrac, char cbrac, int forwdir, int n); diff --git a/contrib/less/help.c b/contrib/less/help.c index 363b7eccddf2..423e0393e383 100644 --- a/contrib/less/help.c +++ b/contrib/less/help.c @@ -1,4 +1,4 @@ -/* This file was generated by mkhelp.pl from less.hlp at 17:26 on 2023/4/6 */ +/* This file was generated by mkhelp.pl from less.hlp at 22:43 on 2023/7/20 */ #include "less.h" constant char helpdata[] = { '\n', diff --git a/contrib/less/less.h b/contrib/less/less.h index 4a4f26d83f05..2ba8c353deeb 100644 --- a/contrib/less/less.h +++ b/contrib/less/less.h @@ -273,6 +273,15 @@ typedef off_t LINENUM; #endif #endif +/* + * Flags for creat() + */ +#if MSDOS_COMPILER +#define CREAT_RW (S_IREAD|S_IWRITE) +#else +#define CREAT_RW 0644 +#endif + /* * Set a file descriptor to binary mode. */ diff --git a/contrib/less/less.nro b/contrib/less/less.nro index c0ef536db8a3..ab0ea975df45 100644 --- a/contrib/less/less.nro +++ b/contrib/less/less.nro @@ -1,5 +1,5 @@ '\" t -.TH LESS 1 "Version 632: 06 Apr 2023" +.TH LESS 1 "Version 643: 20 Jul 2023" .SH NAME less \- opposite of more .SH SYNOPSIS @@ -120,7 +120,7 @@ while it is being viewed. (The behavior is similar to the "tail \-f" command.) To stop waiting for more data, enter the interrupt character (usually \(haC). On systems which support -.BR poll (1) +.BR poll (2) you can also use \(haX or the character specified by the \-\-intr option. If the input is a pipe and the \-\-exit-follow-on-close option is in effect, .B less @@ -210,6 +210,8 @@ Search forward in the file for the N-th line containing the pattern. N defaults to 1. The pattern is a regular expression, as recognized by the regular expression library supplied by your system. +By default, searching is case-sensitive (uppercase and lowercase +are considered different); the \-i option can be used to change this. The search starts at the first line displayed (but see the \-a and \-j options, which change this). .sp @@ -489,10 +491,10 @@ so it may be necessary to use the R or F command to see more data. The \-\-intr option can be used to specify a different character to use instead of \(haX. This command works only on systems that support the -.BR poll (1) +.BR poll (2) function. On systems without -.BR poll (1), +.BR poll (2), the interrupt character (usually \(haC) can be used instead. . .SH OPTIONS @@ -720,6 +722,11 @@ CHAR_INFO.Attributes values .nh https://docs.microsoft.com/en-us/windows/console/char-info-str). .hy +.PP +On MS-DOS only, the \-Da option may be used to specify strict parsing of +ANSI color (SGR) sequences when the \-R option is used. +Without this option, sequences that change text attributes +(bold, underline, etc.) may clear the text color. .RE .IP "\-e or \-\-quit-at-eof" Causes diff --git a/contrib/less/lessecho.nro b/contrib/less/lessecho.nro index 6637cb947173..bd9c6b4f91c7 100644 --- a/contrib/less/lessecho.nro +++ b/contrib/less/lessecho.nro @@ -1,4 +1,4 @@ -.TH LESSECHO 1 "Version 632: 06 Apr 2023" +.TH LESSECHO 1 "Version 643: 20 Jul 2023" .SH NAME lessecho \- expand metacharacters .SH SYNOPSIS diff --git a/contrib/less/lesskey.nro b/contrib/less/lesskey.nro index 2f7c4864dc2f..324710547a3e 100644 --- a/contrib/less/lesskey.nro +++ b/contrib/less/lesskey.nro @@ -1,5 +1,5 @@ '\" t -.TH LESSKEY 1 "Version 632: 06 Apr 2023" +.TH LESSKEY 1 "Version 643: 20 Jul 2023" .SH NAME lesskey \- customize key bindings for less .SH "SYNOPSIS (deprecated)" @@ -48,7 +48,7 @@ Customizes line-editing key bindings. .IP #env Defines environment variables. .PP -Blank lines and lines which start with a pound sign (#) are ignored, +Blank lines and lines which start with a hash mark (#) are ignored, except as noted below. . .SH "COMMAND SECTION" @@ -108,7 +108,7 @@ l l. A backslash followed by any other character indicates that character is to be taken literally. Characters which must be preceded by backslash include -caret, space, tab and the backslash itself. +caret, space, tab, hash mark and the backslash itself. .PP An action may be followed by an "extra" string. When such a command is entered while running @@ -361,6 +361,11 @@ the same variable's original definition (with an = line), without any intervening definitions of other variables. It can append only to a variable defined earlier in the file; it cannot append to a variable in the system environment. +The string is appended literally, without any extra whitespace added, +so if whitespace is desired, +it should be appended to the end of the preceding line. +(It cannot be added to the beginning of the += string because space after +the equals sign is ignored, as noted above.) . .SH CONDITIONAL CONFIGURATION If a line begins with #version followed by a relational operator and a version number, @@ -410,7 +415,9 @@ is run and, on version 595 and higher, adds a \-\-color option. .sp .nf #env - LESS = \-i\ \-S + ## (Note that there must be a space at the end of the next line, + ## to separate the --color option from the -S option.) + LESS = \-i\ \-S\ #version\ >=\ 595\ \ LESS\ +=\ \-\-color=Hkc .fi . diff --git a/contrib/less/optfunc.c b/contrib/less/optfunc.c index da7e54c3d60a..974a6f6c8c8b 100644 --- a/contrib/less/optfunc.c +++ b/contrib/less/optfunc.c @@ -196,7 +196,7 @@ public void opt_j(int type, char *s) error("Position target at screen line %d", &parg); } else { - char buf[24]; + char buf[INT_STRLEN_BOUND(long)+2]; SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction); len = (int) strlen(buf); while (len > 2 && buf[len-1] == '0') @@ -213,7 +213,7 @@ public void calc_jump_sline(void) { if (jump_sline_fraction < 0) return; - jump_sline = muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM); + jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM); } /* @@ -256,7 +256,7 @@ public void opt_shift(int type, char *s) error("Horizontal shift %d columns", &parg); } else { - char buf[24]; + char buf[INT_STRLEN_BOUND(long)+2]; SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction); len = (int) strlen(buf); while (len > 2 && buf[len-1] == '0') @@ -273,7 +273,7 @@ public void calc_shift_count(void) { if (shift_count_fraction < 0) return; - shift_count = muldiv(sc_width, shift_count_fraction, NUM_FRAC_DENOM); + shift_count = (int) muldiv(sc_width, shift_count_fraction, NUM_FRAC_DENOM); } #if USERFILE diff --git a/contrib/less/os.c b/contrib/less/os.c index 56e3bf32ec9e..046270e68fc4 100644 --- a/contrib/less/os.c +++ b/contrib/less/os.c @@ -48,6 +48,7 @@ static int use_poll = TRUE; #endif #if USE_POLL #include +static int any_data = FALSE; #endif /* @@ -88,10 +89,10 @@ extern char *ttyin_name; public void init_poll(void) { - char *delay = lgetenv("LESS_DATA_DELAY"); - int idelay = (delay == NULL) ? 0 : atoi(delay); - if (idelay > 0) - waiting_for_data_delay = idelay; + char *delay = lgetenv("LESS_DATA_DELAY"); + int idelay = (delay == NULL) ? 0 : atoi(delay); + if (idelay > 0) + waiting_for_data_delay = idelay; #if USE_POLL #if defined(__APPLE__) /* In old versions of MacOS, poll() does not work with /dev/tty. */ @@ -113,6 +114,15 @@ static int check_poll(int fd, int tty) { struct pollfd poller[2] = { { fd, POLLIN, 0 }, { tty, POLLIN, 0 } }; int timeout = (waiting_for_data && !(scanning_eof && follow_mode == FOLLOW_NAME)) ? -1 : waiting_for_data_delay; + if (!any_data) + { + /* + * Don't do polling if no data has yet been received, + * to allow a program piping data into less to have temporary + * access to the tty (like sudo asking for a password). + */ + return (0); + } poll(poller, 2, timeout); #if LESSTEST if (ttyin_name == NULL) /* Check for ^X only on a real tty. */ @@ -193,6 +203,11 @@ public int iread(int fd, unsigned char *buf, unsigned int len) sigmask(~0); #endif #endif +#endif +#if !MSDOS_COMPILER + if (fd != tty && !ABORT_SIGS()) + /* Non-interrupt signal like SIGWINCH. */ + return (READ_AGAIN); #endif return (READ_INTR); } @@ -207,7 +222,7 @@ public int iread(int fd, unsigned char *buf, unsigned int len) * available, because that makes some background programs * believe DOS is busy in a way that prevents those * programs from working while "less" waits. - * {{ This code was added 12 Jan 2007; still needed? }} + * {{ This code was added 12 Jan 2007; still needed? }} */ fd_set readfds; @@ -234,11 +249,18 @@ public int iread(int fd, unsigned char *buf, unsigned int len) } #else #if MSDOS_COMPILER==WIN32C - if (win32_kbhit() && WIN32getch() == intr_char) + if (win32_kbhit()) { - sigs |= S_INTERRUPT; - reading = 0; - return (READ_INTR); + int c; + + c = WIN32getch(); + if (c == intr_char) + { + sigs |= S_INTERRUPT; + reading = 0; + return (READ_INTR); + } + WIN32ungetch(c); } #endif #endif @@ -282,6 +304,10 @@ public int iread(int fd, unsigned char *buf, unsigned int len) #endif return (READ_ERR); } +#if USE_POLL + if (fd != tty && n > 0) + any_data = TRUE; +#endif return (n); } diff --git a/contrib/less/screen.c b/contrib/less/screen.c index 6b389d7b0df0..8b15b7fdd8de 100644 --- a/contrib/less/screen.c +++ b/contrib/less/screen.c @@ -68,9 +68,17 @@ extern int fd0; #endif #endif +#if HAVE_NCURSESW_TERMCAP_H +#include +#else +#if HAVE_NCURSES_TERMCAP_H +#include +#else #if HAVE_TERMCAP_H #include #endif +#endif +#endif #ifdef _OSK #include #endif @@ -141,6 +149,8 @@ static WORD curr_attr; static int pending_scancode = 0; static char x11mousebuf[] = "[M???"; /* Mouse report, after ESC */ static int x11mousePos, x11mouseCount; +static int win_unget_pending = FALSE; +static int win_unget_data; static HANDLE con_out_save = INVALID_HANDLE_VALUE; /* previous console */ static HANDLE con_out_ours = INVALID_HANDLE_VALUE; /* our own */ @@ -160,8 +170,8 @@ static void win32_deinit_term(); #define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4))) #define APPLY_COLORS() { if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \ error("SETCOLORS failed", NULL_PARG); } -#define SET_FG_COLOR(fg) { curr_attr |= (fg); APPLY_COLORS(); } -#define SET_BG_COLOR(bg) { curr_attr |= ((bg)<<4); APPLY_COLORS(); } +#define SET_FG_COLOR(fg) { curr_attr &= ~0x0f; curr_attr |= (fg); APPLY_COLORS(); } +#define SET_BG_COLOR(bg) { curr_attr &= ~0xf0; curr_attr |= ((bg)<<4); APPLY_COLORS(); } #define SETCOLORS(fg,bg) { curr_attr = MAKEATTR(fg,bg); APPLY_COLORS(); } #endif @@ -321,7 +331,7 @@ static void set_termio_flags( #ifdef ECHOK | ECHOK #endif -#if ECHONL +#ifdef ECHONL | ECHONL #endif ); @@ -1694,7 +1704,7 @@ static void ltputs(char *str, int affcnt, int (*f_putc)(int)) #endif /* MSDOS_COMPILER */ /* - * Configure the termimal so mouse clicks and wheel moves + * Configure the terminal so mouse clicks and wheel moves * produce input to less. */ public void init_mouse(void) @@ -2791,7 +2801,7 @@ public int win32_kbhit(void) INPUT_RECORD ip; DWORD read; - if (keyCount > 0) + if (keyCount > 0 || win_unget_pending) return (TRUE); currentKey.ascii = 0; @@ -2896,6 +2906,13 @@ public int win32_kbhit(void) /* * Read a character from the keyboard. + * + * Known issues: + * - WIN32getch API should be int like libc (with unsigned char values or -1). + * - The unicode code below can return 0 - incorrectly indicating scan code. + * - UTF16-LE surrogate pairs don't work (and return 0). + * - If win32_kbhit returns true then WIN32getch should never block, but it + * will block till the next keypress if it's numlock/capslock scan code. */ public char WIN32getch(void) { @@ -2904,6 +2921,12 @@ public char WIN32getch(void) static int utf8_size = 0; static int utf8_next_byte = 0; + if (win_unget_pending) + { + win_unget_pending = FALSE; + return (char) win_unget_data; + } + // Return the rest of multibyte character from the prior call if (utf8_next_byte < utf8_size) { @@ -2919,19 +2942,18 @@ public char WIN32getch(void) } do { - while (win32_kbhit() == FALSE) + while (!win32_kbhit()) { Sleep(20); if (ABORT_SIGS()) return ('\003'); - continue; } - keyCount --; + keyCount--; // If multibyte character, return its first byte - if (currentKey.ascii != currentKey.unicode) + if (currentKey.unicode > 0x7f) { - utf8_size = WideCharToMultiByte(CP_UTF8, 0, ¤tKey.unicode, 1, &utf8, sizeof(utf8), NULL, NULL); - if (utf8_size == 0 ) + utf8_size = WideCharToMultiByte(CP_UTF8, 0, ¤tKey.unicode, 1, (LPSTR) &utf8, sizeof(utf8), NULL, NULL); + if (utf8_size == 0) return '\0'; ascii = utf8[0]; utf8_next_byte = 1; @@ -2948,6 +2970,15 @@ public char WIN32getch(void) return ascii; } + +/* + * Make the next call to WIN32getch return ch without changing the queue state. + */ +public void WIN32ungetch(int ch) +{ + win_unget_pending = TRUE; + win_unget_data = ch; +} #endif #if MSDOS_COMPILER diff --git a/contrib/less/search.c b/contrib/less/search.c index 758e4491f1ce..98f01e5fcedd 100644 --- a/contrib/less/search.c +++ b/contrib/less/search.c @@ -944,6 +944,8 @@ static void hilite_line(POSITION linepos, char *line, int line_len, int *chpos, do { char *lep = sp[0]; int i; + if (sp[0] == NULL || ep[0] == NULL) + break; for (i = 1; i < nsp; i++) { if (sp[i] == NULL || ep[i] == NULL) diff --git a/contrib/less/version.c b/contrib/less/version.c index b0e4e6668da3..8c20787bfd4e 100644 --- a/contrib/less/version.c +++ b/contrib/less/version.c @@ -981,6 +981,18 @@ v629 2/26/23 Delay "waiting for data" message for 500 ms. v630 3/18/23 Add LESS_DATA_DELAY. v631 3/26/23 Fix input of dead keys on Windows. v632 4/6/23 Make lesstest work on MacOS; minor fixes. +v633 5/3/23 Fix build on systems with ncurses/termcap.h or ncursesw/termcap.h. +v634 5/29/23 Allow program piping into less to access tty; + fix search modifier ^E after ^W. +v635 6/2/23 Fix crash with ! search modifier. +v636 6/18/23 Fix -D in MS-DOS build; fix mouse wheel in MS-DOS build. +v637 6/28/23 Fix early EOF when SIGWINCH is received. +v638 6/29/23 Fix compile error with ECHONL. +v639 6/29/23 Fix SIGWINCH while reading tty. +v640 7/10/23 Add lesstest to release. +v641 7/10/23 Fix release. +v642 7/10/23 Fix release. +v643 7/20/23 Fix crash on Windows with -o. */ -char version[] = "632"; +char version[] = "643"; diff --git a/contrib/less/xbuf.c b/contrib/less/xbuf.c index 1ed369e175f2..92076764d314 100644 --- a/contrib/less/xbuf.c +++ b/contrib/less/xbuf.c @@ -93,7 +93,7 @@ static int help_fixup(void *r, uintmax val, int rsize, int rsigned) int *pr = r; if (INT_MAX < val) return TRUE; - *pr = val; + *pr = (int) val; #ifdef LLONG_MAX } else if (rsize == sizeof (long long)) { @@ -114,19 +114,19 @@ static int help_fixup(void *r, uintmax val, int rsize, int rsigned) long *pr = r; if (LONG_MAX < val) return TRUE; - *pr = val; + *pr = (long) val; } } else { if (rsize == sizeof (unsigned)) { unsigned *pr = r; if (UINT_MAX < val) return TRUE; - *pr = val; + *pr = (unsigned) val; } else if (rsize == sizeof (unsigned long)) { unsigned long *pr = r; if (ULONG_MAX < val) return TRUE; - *pr = val; + *pr = (unsigned long) val; #ifdef ULLONG_MAX } else if (rsize == sizeof (unsigned long long)) { long long *pr = r; diff --git a/usr.bin/less/defines.h b/usr.bin/less/defines.h index e6087d63f3eb..018d98a48162 100644 --- a/usr.bin/less/defines.h +++ b/usr.bin/less/defines.h @@ -262,12 +262,15 @@ /* Define HAVE_LOCALE if you have locale.h and setlocale. */ #define HAVE_LOCALE 1 -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - /* Define to 1 if you have the `nanosleep' function. */ #define HAVE_NANOSLEEP 1 +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSESW_TERMCAP_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_TERMCAP_H */ + /* Define HAVE_OSPEED if your termcap library has the ospeed variable. */ #define HAVE_OSPEED 1 @@ -451,14 +454,11 @@ /* Define to 1 if the `S_IS*' macros in do not work properly. */ /* #undef STAT_MACROS_BROKEN */ -/* Define to 1 if you have the ANSI C header files. */ +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ #define STDC_HEADERS 1 -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */