Module Name: src Committed By: christos Date: Fri Sep 1 10:19:10 UTC 2017
Modified Files: src/lib/libedit: editline.3 hist.h histedit.h history.c readline.c src/lib/libedit/readline: readline.h Log Message: PR/51517: Jay West: Tty settings not restored on exit PR/51518: Jay West: prompt is interleaved with client output Both these issues are caused by rl_restore_handler not DTRT; fix it so that it kills the internal libedit state completely. This is inefficient, but it works. Also fix: 1. add append_history()/H_NSAVE_FP 2. call the rl_startup_hook before printing the first prompt as documented. callint it from rl_initialize breaks python, because the callback ends up being invoked before the readline module is installed, and we end up dereferencing a NULL pointer. 3. add el_resize_terminal. With those changes, s/lreadline/ledit/g in python works. To generate a diff of this commit: cvs rdiff -u -r1.96 -r1.97 src/lib/libedit/editline.3 cvs rdiff -u -r1.22 -r1.23 src/lib/libedit/hist.h cvs rdiff -u -r1.56 -r1.57 src/lib/libedit/histedit.h cvs rdiff -u -r1.57 -r1.58 src/lib/libedit/history.c cvs rdiff -u -r1.141 -r1.142 src/lib/libedit/readline.c cvs rdiff -u -r1.41 -r1.42 src/lib/libedit/readline/readline.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libedit/editline.3 diff -u src/lib/libedit/editline.3:1.96 src/lib/libedit/editline.3:1.97 --- src/lib/libedit/editline.3:1.96 Mon Jul 3 17:32:50 2017 +++ src/lib/libedit/editline.3 Fri Sep 1 06:19:10 2017 @@ -1,4 +1,4 @@ -.\" $NetBSD: editline.3,v 1.96 2017/07/03 21:32:50 wiz Exp $ +.\" $NetBSD: editline.3,v 1.97 2017/09/01 10:19:10 christos Exp $ .\" .\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -26,7 +26,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 27, 2017 +.Dd September 1, 2017 .Dt EDITLINE 3 .Os .Sh NAME @@ -843,6 +843,13 @@ Save the history list to the opened .Ft FILE pointer .Fa fp . +.It Dv H_NSAVE_FP , Fa "size_t n" , Fa "FILE *fp" +Save the last +.Ft n +history entries to the opened +.Ft FILE +pointer +.Fa fp . .It Dv H_SETUNIQUE , Fa "int unique" Set flag that adjacent identical event strings should not be entered into the history. Index: src/lib/libedit/hist.h diff -u src/lib/libedit/hist.h:1.22 src/lib/libedit/hist.h:1.23 --- src/lib/libedit/hist.h:1.22 Mon May 9 17:46:56 2016 +++ src/lib/libedit/hist.h Fri Sep 1 06:19:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: hist.h,v 1.22 2016/05/09 21:46:56 christos Exp $ */ +/* $NetBSD: hist.h,v 1.23 2017/09/01 10:19:10 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -59,14 +59,15 @@ typedef struct el_history_t { (((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \ HIST_FUN_INTERNAL(el, fn, arg)) -#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL) -#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) -#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL) -#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL) -#define HIST_SET(el, num) HIST_FUN(el, H_SET, num) -#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) -#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) -#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP fp) +#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL) +#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) +#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL) +#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL) +#define HIST_SET(el, num) HIST_FUN(el, H_SET, num) +#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) +#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) +#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP, fp) +#define HIST_NSAVE_FP(el, n, fp) HIST_FUN(el, H_NSAVE_FP, n, fp) libedit_private int hist_init(EditLine *); libedit_private void hist_end(EditLine *); Index: src/lib/libedit/histedit.h diff -u src/lib/libedit/histedit.h:1.56 src/lib/libedit/histedit.h:1.57 --- src/lib/libedit/histedit.h:1.56 Tue Apr 19 15:50:53 2016 +++ src/lib/libedit/histedit.h Fri Sep 1 06:19:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.56 2016/04/19 19:50:53 christos Exp $ */ +/* $NetBSD: histedit.h,v 1.57 2017/09/01 10:19:10 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -226,6 +226,7 @@ int history(History *, HistEvent *, int #define H_DELDATA 24 /* , int, histdata_t *);*/ #define H_REPLACE 25 /* , const char *, histdata_t); */ #define H_SAVE_FP 26 /* , FILE *); */ +#define H_NSAVE_FP 27 /* , size_t, FILE *); */ Index: src/lib/libedit/history.c diff -u src/lib/libedit/history.c:1.57 src/lib/libedit/history.c:1.58 --- src/lib/libedit/history.c:1.57 Mon Apr 11 14:56:31 2016 +++ src/lib/libedit/history.c Fri Sep 1 06:19:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $ */ +/* $NetBSD: history.c,v 1.58 2017/09/01 10:19:10 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $"); +__RCSID("$NetBSD: history.c,v 1.58 2017/09/01 10:19:10 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -140,7 +140,7 @@ static int history_getunique(TYPE(Histor static int history_set_fun(TYPE(History) *, TYPE(History) *); static int history_load(TYPE(History) *, const char *); static int history_save(TYPE(History) *, const char *); -static int history_save_fp(TYPE(History) *, FILE *); +static int history_save_fp(TYPE(History) *, size_t, FILE *); static int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int); static int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int); static int history_next_string(TYPE(History) *, TYPE(HistEvent) *, @@ -825,7 +825,7 @@ done: * TYPE(History) save function */ static int -history_save_fp(TYPE(History) *h, FILE *fp) +history_save_fp(TYPE(History) *h, size_t nelem, FILE *fp) { TYPE(HistEvent) ev; int i = -1, retval; @@ -838,14 +838,22 @@ history_save_fp(TYPE(History) *h, FILE * if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) goto done; - if (fputs(hist_cookie, fp) == EOF) + if (ftell(fp) == 0 && fputs(hist_cookie, fp) == EOF) goto done; ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); if (ptr == NULL) goto done; - for (i = 0, retval = HLAST(h, &ev); - retval != -1; - retval = HPREV(h, &ev), i++) { + if (nelem != (size_t)-1) { + for (retval = HFIRST(h, &ev); retval != -1 && nelem-- > 0; + retval = HNEXT(h, &ev)) + continue; + } else + retval = -1; + + if (retval == -1) + retval = HLAST(h, &ev); + + for (i = 0; retval != -1; retval = HPREV(h, &ev), i++) { str = ct_encode_string(ev.str, &conv); len = strlen(str) * 4 + 1; if (len > max_size) { @@ -880,7 +888,7 @@ history_save(TYPE(History) *h, const cha if ((fp = fopen(fname, "w")) == NULL) return -1; - i = history_save_fp(h, fp); + i = history_save_fp(h, (size_t)-1, fp); (void) fclose(fp); return i; @@ -1068,7 +1076,14 @@ FUNW(history)(TYPE(History) *h, TYPE(His break; case H_SAVE_FP: - retval = history_save_fp(h, va_arg(va, FILE *)); + retval = history_save_fp(h, (size_t)-1, va_arg(va, FILE *)); + if (retval == -1) + he_seterrev(ev, _HE_HIST_WRITE); + break; + + case H_NSAVE_FP: + retval = history_save_fp(h, va_arg(va, size_t), + va_arg(va, FILE *)); if (retval == -1) he_seterrev(ev, _HE_HIST_WRITE); break; Index: src/lib/libedit/readline.c diff -u src/lib/libedit/readline.c:1.141 src/lib/libedit/readline.c:1.142 --- src/lib/libedit/readline.c:1.141 Fri Apr 21 01:38:03 2017 +++ src/lib/libedit/readline.c Fri Sep 1 06:19:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.141 2017/04/21 05:38:03 abhinav Exp $ */ +/* $NetBSD: readline.c,v 1.142 2017/09/01 10:19:10 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.141 2017/04/21 05:38:03 abhinav Exp $"); +__RCSID("$NetBSD: readline.c,v 1.142 2017/09/01 10:19:10 christos Exp $"); #endif /* not lint && not SCCSID */ #include <sys/types.h> @@ -122,6 +122,7 @@ int readline_echoing_p = 1; int _rl_print_completions_horizontally = 0; VFunction *rl_redisplay_function = NULL; Function *rl_startup_hook = NULL; +int rl_did_startup_hook = 0; VFunction *rl_completion_display_matches_hook = NULL; VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; @@ -385,9 +386,6 @@ rl_initialize(void) _resize_fun(e, &rl_line_buffer); _rl_update_pos(); - if (rl_startup_hook) - (*rl_startup_hook)(NULL, 0); - return 0; } @@ -408,6 +406,11 @@ readline(const char *p) if (e == NULL || h == NULL) rl_initialize(); + if (rl_did_startup_hook == 0 && rl_startup_hook) { + rl_did_startup_hook = 1; + (*rl_startup_hook)(NULL, 0); + } + rl_done = 0; @@ -1365,6 +1368,28 @@ write_history(const char *filename) (errno ? errno : EINVAL) : 0; } +int +append_history(int n, const char *filename) +{ + HistEvent ev; + FILE *fp; + + if (h == NULL || e == NULL) + rl_initialize(); + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + + if ((fp = fopen(filename, "a")) == NULL) + return errno; + + if (history(h, &ev, H_NSAVE_FP, (size_t)n, fp) == -1) { + int serrno = errno ? errno : EINVAL; + fclose(fp); + return serrno; + } + fclose(fp); + return 0; +} /* * returns history ``num''th event @@ -2058,8 +2083,9 @@ rl_callback_handler_install(const char * void rl_callback_handler_remove(void) { - el_set(e, EL_UNBUFFERED, 0); rl_linefunc = NULL; + el_end(e); + e = NULL; } void @@ -2369,3 +2395,9 @@ rl_set_keyboard_input_timeout(int u __at { return 0; } + +void +rl_resize_terminal(void) +{ + el_resize(e); +} Index: src/lib/libedit/readline/readline.h diff -u src/lib/libedit/readline/readline.h:1.41 src/lib/libedit/readline/readline.h:1.42 --- src/lib/libedit/readline/readline.h:1.41 Fri Oct 28 14:32:35 2016 +++ src/lib/libedit/readline/readline.h Fri Sep 1 06:19:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.41 2016/10/28 18:32:35 christos Exp $ */ +/* $NetBSD: readline.h,v 1.42 2017/09/01 10:19:10 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -147,6 +147,7 @@ int rl_initialize(void); void using_history(void); int add_history(const char *); void clear_history(void); +int append_history(int, const char *); void stifle_history(int); int unstifle_history(void); int history_is_stifled(void); @@ -182,6 +183,7 @@ void rl_display_match_list(char **, in int rl_insert(int, int); int rl_insert_text(const char *); void rl_reset_terminal(const char *); +void rl_resize_terminal(void); int rl_bind_key(int, rl_command_func_t *); int rl_newline(int, int); void rl_callback_read_char(void);