From 2765a0756417166c5b6d3e92ddeb327e5da86999 Mon Sep 17 00:00:00 2001 From: tg Date: Mon, 25 Jan 2010 16:12:57 +0000 Subject: [PATCH] =?UTF-8?q?when=20using=20persistent=20history=20(and=20no?= =?UTF-8?q?t=20MKSH=5FSMALL),=20let=20the=20shells=20concurrently=20access?= =?UTF-8?q?ing=20the=20same=20$HISTFILE=20be=20more=20synchronised=20with?= =?UTF-8?q?=20each=20other:=20empty=20lines=20(just=20pressing=20Return)?= =?UTF-8?q?=20and=20duplicates=20(that=20are=20split=20and=20written=20twi?= =?UTF-8?q?ce=20by=20the=20lines=20loaded=20from=20$HISTFILE=20in=20the=20?= =?UTF-8?q?meantime);=20requested=20by=20Maximilian=20=E2=80=9Cmxey?= =?UTF-8?q?=E2=80=9D=20Ga=C3=9F=20in=20#!/bin/mksh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- histrap.c | 65 +++++++++++++++++++++++++++++++++++++++---------------- lex.c | 15 ++++++++++--- mksh.1 | 5 ++--- sh.h | 7 ++++-- 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/histrap.c b/histrap.c index aebaecd..db8d128 100644 --- a/histrap.c +++ b/histrap.c @@ -2,7 +2,7 @@ /* $OpenBSD: trap.c,v 1.22 2005/03/30 17:16:37 deraadt Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -26,7 +26,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.90 2009/12/12 22:27:08 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.91 2010/01/25 16:12:55 tg Exp $"); /*- * MirOS: This is the default mapping type, and need not be specified. @@ -51,7 +51,7 @@ static int sprinkle(int); static int hist_execute(char *); static int hist_replace(char **, const char *, const char *, int); -static char **hist_get(const char *, int, int); +static char **hist_get(const char *, bool, bool); static char **hist_get_oldest(void); static void histbackup(void); @@ -368,7 +368,7 @@ hist_replace(char **hp, const char *pat, const char *rep, int globr) * pattern is a number or string */ static char ** -hist_get(const char *str, int approx, int allow_cur) +hist_get(const char *str, bool approx, bool allow_cur) { char **hp = NULL; int n; @@ -407,7 +407,7 @@ hist_get(const char *str, int approx, int allow_cur) /* Return a pointer to the newest command in the history */ char ** -hist_get_newest(int allow_cur) +hist_get_newest(bool allow_cur) { if (histptr < history || (!allow_cur && histptr == history)) { bi_errorf("no history (yet)"); @@ -592,6 +592,27 @@ init_histvec(void) * It turns out that there is a lot of ghastly hackery here */ +#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY +/* do not save command in history but possibly sync */ +bool +histsync(void) +{ + bool changed = false; + + if (histfd) { + int lno = hist_source->line; + + hist_source->line++; + writehistfile(0, NULL); + hist_source->line--; + + if (lno != hist_source->line) + changed = true; + } + + return (changed); +} +#endif /* * save command in history @@ -606,7 +627,11 @@ histsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups) if ((cp = strchr(c, '\n')) != NULL) *cp = '\0'; - if (ignoredups && !strcmp(c, *histptr)) { + if (ignoredups && !strcmp(c, *histptr) +#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY + && !histsync() +#endif + ) { afree(c, APERM); return; } @@ -962,19 +987,21 @@ writehistfile(int lno, char *cmd) goto bad; } } - /* - * we can write our bit now - */ - hdr[0] = COMMAND; - hdr[1] = (lno>>24)&0xff; - hdr[2] = (lno>>16)&0xff; - hdr[3] = (lno>>8)&0xff; - hdr[4] = lno&0xff; - bytes = strlen(cmd) + 1; - if ((write(histfd, hdr, 5) != 5) || - (write(histfd, cmd, bytes) != bytes)) - goto bad; - hsize = lseek(histfd, (off_t)0, SEEK_END); + if (cmd) { + /* + * we can write our bit now + */ + hdr[0] = COMMAND; + hdr[1] = (lno>>24)&0xff; + hdr[2] = (lno>>16)&0xff; + hdr[3] = (lno>>8)&0xff; + hdr[4] = lno&0xff; + bytes = strlen(cmd) + 1; + if ((write(histfd, hdr, 5) != 5) || + (write(histfd, cmd, bytes) != bytes)) + goto bad; + hsize = lseek(histfd, (off_t)0, SEEK_END); + } (void)flock(histfd, LOCK_UN); return; bad: diff --git a/lex.c b/lex.c index 5ac5e94..65f14e9 100644 --- a/lex.c +++ b/lex.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.103 2009/12/05 20:17:59 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.104 2010/01/25 16:12:56 tg Exp $"); /* * states while lexing word @@ -1321,7 +1321,7 @@ static void getsc_line(Source *s) { char *xp = Xstring(s->xs, xp), *cp; - int interactive = Flag(FTALKING) && s->type == SSTDIN; + bool interactive = Flag(FTALKING) && s->type == SSTDIN; int have_tty = interactive && (s->flags & SF_TTY); /* Done here to ensure nothing odd happens when a timeout occurs */ @@ -1413,8 +1413,17 @@ getsc_line(Source *s) shf_fdclose(s->u.shf); s->str = NULL; } else if (interactive && *s->str && - (cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) + (cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) { histsave(&s->line, s->str, true, true); +#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY + } else if (interactive && cur_prompt == PS1) { + cp = Xstring(s->xs, xp); + while (*cp && ctype(*cp, C_IFSWS)) + ++cp; + if (!*cp) + histsync(); +#endif + } if (interactive) set_prompt(PS2, NULL); } diff --git a/mksh.1 b/mksh.1 index 5b60cc6..422d4a0 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.208 2010/01/25 14:25:15 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.209 2010/01/25 16:12:56 tg Exp $ .\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 @@ -1727,8 +1727,7 @@ below for more information. .It Ev HISTFILE The name of the file used to store command history. When assigned to, history is loaded from the specified file. -Also, several invocations of the shell -running on the same machine will share history if their +Also, several invocations of the shell will share history if their .Ev HISTFILE parameters all point to the same file. .Pp diff --git a/sh.h b/sh.h index 7def725..bc1b025 100644 --- a/sh.h +++ b/sh.h @@ -148,7 +148,7 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.375 2010/01/25 14:38:03 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.376 2010/01/25 16:12:57 tg Exp $"); #endif #define MKSH_VERSION "R39 2010/01/08" @@ -1432,6 +1432,9 @@ void hist_init(Source *); void hist_finish(void); #endif void histsave(int *, const char *, bool, bool); +#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY +bool histsync(void); +#endif int c_fc(const char **); void sethistsize(int); #if HAVE_PERSISTENT_HISTORY @@ -1441,7 +1444,7 @@ char **histpos(void); int histnum(int); int findhist(int, int, const char *, int); int findhistrel(const char *); -char **hist_get_newest(int); +char **hist_get_newest(bool); void inittraps(void); void alarm_init(void); Trap *gettrap(const char *, int);