From 151a4660e289c66d13b65d68ad2f10d93743d2d4 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 26 May 2017 11:06:59 +0100 Subject: 41164: Don't free a history entry if it's curline. This replaces 41113 / 94014ff65b with a simple local change for the immediate problem. It's not entirely clear if this reflects wider changes in the structure of the history code. --- ChangeLog | 5 +++++ Src/hashtable.c | 4 +++- Src/hist.c | 42 +++++++++++++++--------------------------- Src/zsh.h | 1 - 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb1af3488..03592c04d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-05-26 Peter Stephenson + + * 41164: Src/hashtable.c, Src/hist.c, Src/zsh.h: Don't free a + history entry if it's the current line. This replaces 41113. + 2017-05-28 Barton E. Schaefer * Sebastian: 41153: Src/Modules/db_gdbm.c: finish module setup diff --git a/Src/hashtable.c b/Src/hashtable.c index c34744cd8..6ec2ed220 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -1445,10 +1445,12 @@ freehistdata(Histent he, int unlink) if (!he) return; + if (he == &curline) + return; + if (!(he->node.flags & (HIST_DUP | HIST_TMPSTORE))) removehashnode(histtab, he->node.nam); - DPUTS(he->node.nam == chline, "Attempt to free chline in history data"); zsfree(he->node.nam); if (he->nwords) zfree(he->words, he->nwords*2*sizeof(short)); diff --git a/Src/hist.c b/Src/hist.c index 4c1039b67..350688d2d 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -87,9 +87,6 @@ mod_export zlong curhist; /**/ struct histent curline; -/***/ -int curline_linked; - /* current line count of allocated history entries */ /**/ @@ -264,9 +261,6 @@ hist_context_save(struct hist_stack *hs, int toplevel) */ hs->cstack = cmdstack; hs->csp = cmdsp; - hs->curline_linked = curline_linked; - - unlinkcurline(); stophist = 0; chline = NULL; @@ -306,9 +300,6 @@ hist_context_restore(const struct hist_stack *hs, int toplevel) zfree(cmdstack, CMDSTACKSZ); cmdstack = hs->cstack; cmdsp = hs->csp; - unlinkcurline(); - if (hs->curline_linked) - linkcurline(); } /* @@ -999,7 +990,6 @@ nohwe(void) /* these functions handle adding/removing curline to/from the hist_ring */ -/**/ static void linkcurline(void) { @@ -1012,15 +1002,11 @@ linkcurline(void) hist_ring = &curline; } curline.histnum = ++curhist; - curline_linked = 1; } -/**/ static void unlinkcurline(void) { - if (!curline_linked) - return; curline.up->down = curline.down; curline.down->up = curline.up; if (hist_ring == &curline) { @@ -1030,7 +1016,6 @@ unlinkcurline(void) hist_ring = curline.up; } curhist--; - curline_linked = 0; } /* initialize the history mechanism */ @@ -1050,7 +1035,6 @@ hbegin(int dohist) stophist = (!interact || unset(SHINSTDIN)) ? 2 : 0; else stophist = 0; - DPUTS(chline != NULL, "chline set at start of history"); /* * pws: We used to test for "|| (inbufflags & INP_ALIAS)" * in this test, but at this point we don't have input @@ -1308,10 +1292,11 @@ putoldhistentryontop(short keep_going) Histent prepnexthistent(void) { - Histent he; - int relink_curline = curline_linked; + Histent he; + int curline_in_ring = hist_ring == &curline; - unlinkcurline(); + if (curline_in_ring) + unlinkcurline(); if (hist_ring && hist_ring->node.flags & HIST_TMPSTORE) { curhist--; freehistnode(&hist_ring->node); @@ -1335,7 +1320,7 @@ prepnexthistent(void) he = hist_ring; } he->histnum = ++curhist; - if (relink_curline) + if (curline_in_ring) linkcurline(); return he; } @@ -1410,7 +1395,8 @@ hend(Eprog prog) queue_signals(); if (histdone & HISTFLAG_SETTY) settyinfo(&shttyinfo); - unlinkcurline(); + if (!(histactive & HA_NOINC)) + unlinkcurline(); if (histactive & HA_NOINC) { zfree(chline, hlinesz); zfree(chwords, chwordlen*sizeof(short)); @@ -3638,7 +3624,7 @@ int pushhiststack(char *hf, zlong hs, zlong shs, int level) { struct histsave *h; - int relink_curline = curline_linked; + int curline_in_ring = (histactive & HA_ACTIVE) && hist_ring == &curline; if (histsave_stack_pos == histsave_stack_size) { histsave_stack_size += 5; @@ -3646,7 +3632,8 @@ pushhiststack(char *hf, zlong hs, zlong shs, int level) histsave_stack_size * sizeof (struct histsave)); } - unlinkcurline(); + if (curline_in_ring) + unlinkcurline(); h = &histsave_stack[histsave_stack_pos++]; @@ -3681,7 +3668,7 @@ pushhiststack(char *hf, zlong hs, zlong shs, int level) savehistsiz = shs; inithist(); /* sets histtab */ - if (relink_curline) + if (curline_in_ring) linkcurline(); return histsave_stack_pos; @@ -3693,12 +3680,13 @@ int pophiststack(void) { struct histsave *h; - int relink_curline = curline_linked; + int curline_in_ring = (histactive & HA_ACTIVE) && hist_ring == &curline; if (histsave_stack_pos == 0) return 0; - unlinkcurline(); + if (curline_in_ring) + unlinkcurline(); deletehashtable(histtab); zsfree(lasthist.text); @@ -3721,7 +3709,7 @@ pophiststack(void) histsiz = h->histsiz; savehistsiz = h->savehistsiz; - if (relink_curline) + if (curline_in_ring) linkcurline(); return histsave_stack_pos + 1; diff --git a/Src/zsh.h b/Src/zsh.h index 405b27490..22f73f806 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2931,7 +2931,6 @@ struct hist_stack { void (*addtoline) _((int)); unsigned char *cstack; int csp; - int curline_linked; }; /* -- cgit 1.4.1