mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-07-08 03:41:37 +02:00
41113 (tweaked): Save current line linkage to history ring.
When saving history state save whether the current history line is linked into the ring and remove it, and restore as appropriate later. This avoids surprises where the history ring is freed and incorrectly frees the current state in curline, which has a different allocation strategy. Original patch tweaked to make restoring more logical.
This commit is contained in:
parent
171e7fa4c1
commit
94014ff65b
4 changed files with 35 additions and 15 deletions
|
@ -1,3 +1,9 @@
|
|||
2017-05-18 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 41113 (tweaked): Src/hashtable,c, Src/hist.c, Src/zsh.h: Save
|
||||
and restore state of linking of current history line into history
|
||||
ring, to avoid an attempt to free the current history line.
|
||||
|
||||
2017-05-12 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
|
||||
|
||||
* 41090: Src/Zle/zle_refresh.c, Src/compat.c, Src/pattern.c,
|
||||
|
|
|
@ -1448,6 +1448,7 @@ freehistdata(Histent he, int unlink)
|
|||
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));
|
||||
|
|
42
Src/hist.c
42
Src/hist.c
|
@ -87,6 +87,9 @@ mod_export zlong curhist;
|
|||
/**/
|
||||
struct histent curline;
|
||||
|
||||
/***/
|
||||
int curline_linked;
|
||||
|
||||
/* current line count of allocated history entries */
|
||||
|
||||
/**/
|
||||
|
@ -261,6 +264,9 @@ 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;
|
||||
|
@ -300,6 +306,9 @@ 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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -990,6 +999,7 @@ nohwe(void)
|
|||
|
||||
/* these functions handle adding/removing curline to/from the hist_ring */
|
||||
|
||||
/**/
|
||||
static void
|
||||
linkcurline(void)
|
||||
{
|
||||
|
@ -1002,11 +1012,15 @@ 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) {
|
||||
|
@ -1016,6 +1030,7 @@ unlinkcurline(void)
|
|||
hist_ring = curline.up;
|
||||
}
|
||||
curhist--;
|
||||
curline_linked = 0;
|
||||
}
|
||||
|
||||
/* initialize the history mechanism */
|
||||
|
@ -1035,6 +1050,7 @@ 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
|
||||
|
@ -1292,11 +1308,10 @@ putoldhistentryontop(short keep_going)
|
|||
Histent
|
||||
prepnexthistent(void)
|
||||
{
|
||||
Histent he;
|
||||
int curline_in_ring = hist_ring == &curline;
|
||||
Histent he;
|
||||
int relink_curline = curline_linked;
|
||||
|
||||
if (curline_in_ring)
|
||||
unlinkcurline();
|
||||
unlinkcurline();
|
||||
if (hist_ring && hist_ring->node.flags & HIST_TMPSTORE) {
|
||||
curhist--;
|
||||
freehistnode(&hist_ring->node);
|
||||
|
@ -1320,7 +1335,7 @@ prepnexthistent(void)
|
|||
he = hist_ring;
|
||||
}
|
||||
he->histnum = ++curhist;
|
||||
if (curline_in_ring)
|
||||
if (relink_curline)
|
||||
linkcurline();
|
||||
return he;
|
||||
}
|
||||
|
@ -1395,8 +1410,7 @@ hend(Eprog prog)
|
|||
queue_signals();
|
||||
if (histdone & HISTFLAG_SETTY)
|
||||
settyinfo(&shttyinfo);
|
||||
if (!(histactive & HA_NOINC))
|
||||
unlinkcurline();
|
||||
unlinkcurline();
|
||||
if (histactive & HA_NOINC) {
|
||||
zfree(chline, hlinesz);
|
||||
zfree(chwords, chwordlen*sizeof(short));
|
||||
|
@ -3624,7 +3638,7 @@ int
|
|||
pushhiststack(char *hf, zlong hs, zlong shs, int level)
|
||||
{
|
||||
struct histsave *h;
|
||||
int curline_in_ring = (histactive & HA_ACTIVE) && hist_ring == &curline;
|
||||
int relink_curline = curline_linked;
|
||||
|
||||
if (histsave_stack_pos == histsave_stack_size) {
|
||||
histsave_stack_size += 5;
|
||||
|
@ -3632,8 +3646,7 @@ pushhiststack(char *hf, zlong hs, zlong shs, int level)
|
|||
histsave_stack_size * sizeof (struct histsave));
|
||||
}
|
||||
|
||||
if (curline_in_ring)
|
||||
unlinkcurline();
|
||||
unlinkcurline();
|
||||
|
||||
h = &histsave_stack[histsave_stack_pos++];
|
||||
|
||||
|
@ -3668,7 +3681,7 @@ pushhiststack(char *hf, zlong hs, zlong shs, int level)
|
|||
savehistsiz = shs;
|
||||
inithist(); /* sets histtab */
|
||||
|
||||
if (curline_in_ring)
|
||||
if (relink_curline)
|
||||
linkcurline();
|
||||
|
||||
return histsave_stack_pos;
|
||||
|
@ -3680,13 +3693,12 @@ int
|
|||
pophiststack(void)
|
||||
{
|
||||
struct histsave *h;
|
||||
int curline_in_ring = (histactive & HA_ACTIVE) && hist_ring == &curline;
|
||||
int relink_curline = curline_linked;
|
||||
|
||||
if (histsave_stack_pos == 0)
|
||||
return 0;
|
||||
|
||||
if (curline_in_ring)
|
||||
unlinkcurline();
|
||||
unlinkcurline();
|
||||
|
||||
deletehashtable(histtab);
|
||||
zsfree(lasthist.text);
|
||||
|
@ -3709,7 +3721,7 @@ pophiststack(void)
|
|||
histsiz = h->histsiz;
|
||||
savehistsiz = h->savehistsiz;
|
||||
|
||||
if (curline_in_ring)
|
||||
if (relink_curline)
|
||||
linkcurline();
|
||||
|
||||
return histsave_stack_pos + 1;
|
||||
|
|
|
@ -2931,6 +2931,7 @@ struct hist_stack {
|
|||
void (*addtoline) _((int));
|
||||
unsigned char *cstack;
|
||||
int csp;
|
||||
int curline_linked;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue