when using persistent history (and not MKSH_SMALL), let the shells

concurrently accessing the same $HISTFILE be more synchronised with
each other: empty lines (just pressing Return) and duplicates (that
are split and written twice by the lines loaded from $HISTFILE in
the meantime); requested by Maximilian “mxey” Gaß in #!/bin/mksh
This commit is contained in:
tg
2010-01-25 16:12:57 +00:00
parent f3b3b4b1fb
commit 2765a07564
4 changed files with 65 additions and 27 deletions

View File

@@ -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 <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@@ -26,7 +26,7 @@
#include <sys/file.h>
#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: