summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/ksh/history.c42
-rw-r--r--bin/ksh/ksh.111
-rw-r--r--bin/ksh/sh.h3
-rw-r--r--bin/ksh/table.h21
-rw-r--r--bin/ksh/var.c11
5 files changed, 70 insertions, 18 deletions
diff --git a/bin/ksh/history.c b/bin/ksh/history.c
index e0f98e489e7..bfc34932deb 100644
--- a/bin/ksh/history.c
+++ b/bin/ksh/history.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: history.c,v 1.68 2017/08/28 19:41:55 jca Exp $ */
+/* $OpenBSD: history.c,v 1.69 2017/08/30 17:08:45 jca Exp $ */
/*
* command history
@@ -42,6 +42,8 @@ static FILE *histfh;
static char **current; /* current position in history[] */
static char *hname; /* current name of history file */
static int hstarted; /* set after hist_init() called */
+static int ignoredups; /* ditch duplicated history lines? */
+static int ignorespace; /* ditch lines starting with a space? */
static Source *hist_source;
static uint32_t line_co;
@@ -513,6 +515,28 @@ findhistrel(const char *str)
return start + rec + 1;
}
+void
+sethistcontrol(const char *str)
+{
+ char *spec, *tok, *state;
+
+ ignorespace = 0;
+ ignoredups = 0;
+
+ if (str == NULL)
+ return;
+
+ spec = str_save(str, ATEMP);
+ for (tok = strtok_r(spec, ":", &state); tok != NULL;
+ tok = strtok_r(NULL, ":", &state)) {
+ if (strcmp(tok, "ignoredups") == 0)
+ ignoredups = 1;
+ else if (strcmp(tok, "ignorespace") == 0)
+ ignorespace = 1;
+ }
+ afree(spec, ATEMP);
+}
+
/*
* set history
* this means reallocating the dataspace
@@ -608,6 +632,18 @@ histsave(int lno, const char *cmd, int dowrite)
{
char *c, *cp;
+ if (ignorespace && cmd[0] == ' ')
+ return;
+
+ c = str_save(cmd, APERM);
+ if ((cp = strrchr(c, '\n')) != NULL)
+ *cp = '\0';
+
+ if (ignoredups && histptr >= history && strcmp(*histptr, c) == 0) {
+ afree(c, APERM);
+ return;
+ }
+
if (dowrite && histfh) {
#ifndef SMALL
struct stat sb;
@@ -624,10 +660,6 @@ histsave(int lno, const char *cmd, int dowrite)
#endif
}
- c = str_save(cmd, APERM);
- if ((cp = strrchr(c, '\n')) != NULL)
- *cp = '\0';
-
if (histptr < history + histsize - 1)
histptr++;
else { /* remove oldest command */
diff --git a/bin/ksh/ksh.1 b/bin/ksh/ksh.1
index 23b9654bc67..4471043038f 100644
--- a/bin/ksh/ksh.1
+++ b/bin/ksh/ksh.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ksh.1,v 1.194 2017/08/30 17:02:53 jca Exp $
+.\" $OpenBSD: ksh.1,v 1.195 2017/08/30 17:08:45 jca Exp $
.\"
.\" Public Domain
.\"
@@ -1407,6 +1407,15 @@ It is also searched when a command can't be found using
See
.Sx Functions
below for more information.
+.It Ev HISTCONTROL
+A colon separated list of history settings.
+If
+.Li ignoredups
+is present, lines identical to the previous history line will not be saved.
+If
+.Li ignorespace
+is present, lines starting with a space will not be saved.
+Unknown settings are ignored.
.It Ev HISTFILE
The name of the file used to store command history.
When assigned to, history is loaded from the specified file.
diff --git a/bin/ksh/sh.h b/bin/ksh/sh.h
index b2b5164b887..6f0be4316d6 100644
--- a/bin/ksh/sh.h
+++ b/bin/ksh/sh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sh.h,v 1.62 2017/08/30 17:02:53 jca Exp $ */
+/* $OpenBSD: sh.h,v 1.63 2017/08/30 17:08:45 jca Exp $ */
/*
* Public Domain Bourne/Korn shell
@@ -457,6 +457,7 @@ void hist_finish(void);
void histsave(int, const char *, int);
#ifdef HISTORY
int c_fc(char **);
+void sethistcontrol(const char *);
void sethistsize(int);
void sethistfile(const char *);
char ** histpos(void);
diff --git a/bin/ksh/table.h b/bin/ksh/table.h
index 71cc3d17526..107790d3ce2 100644
--- a/bin/ksh/table.h
+++ b/bin/ksh/table.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: table.h,v 1.11 2015/10/10 07:35:16 nicm Exp $ */
+/* $OpenBSD: table.h,v 1.12 2017/08/30 17:08:45 jca Exp $ */
/* $From: table.h,v 1.3 1994/05/31 13:34:34 michael Exp $ */
@@ -160,15 +160,16 @@ extern const struct builtin shbuiltins [], kshbuiltins [];
#define V_MAILPATH 6
#define V_MAILCHECK 7
#define V_RANDOM 8
-#define V_HISTSIZE 9
-#define V_HISTFILE 10
-#define V_VISUAL 11
-#define V_EDITOR 12
-#define V_COLUMNS 13
-#define V_POSIXLY_CORRECT 14
-#define V_TMOUT 15
-#define V_TMPDIR 16
-#define V_LINENO 17
+#define V_HISTCONTROL 9
+#define V_HISTSIZE 10
+#define V_HISTFILE 11
+#define V_VISUAL 12
+#define V_EDITOR 13
+#define V_COLUMNS 14
+#define V_POSIXLY_CORRECT 15
+#define V_TMOUT 16
+#define V_TMPDIR 17
+#define V_LINENO 18
/* values for set_prompt() */
#define PS1 0 /* command */
diff --git a/bin/ksh/var.c b/bin/ksh/var.c
index fb19d36b59e..16805460d87 100644
--- a/bin/ksh/var.c
+++ b/bin/ksh/var.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: var.c,v 1.58 2017/08/30 10:18:48 jca Exp $ */
+/* $OpenBSD: var.c,v 1.59 2017/08/30 17:08:45 jca Exp $ */
#include <sys/stat.h>
@@ -98,6 +98,7 @@ initvar(void)
{ "POSIXLY_CORRECT", V_POSIXLY_CORRECT },
{ "TMPDIR", V_TMPDIR },
#ifdef HISTORY
+ { "HISTCONTROL", V_HISTCONTROL },
{ "HISTFILE", V_HISTFILE },
{ "HISTSIZE", V_HISTSIZE },
#endif /* HISTORY */
@@ -991,6 +992,9 @@ setspec(struct tbl *vp)
}
break;
#ifdef HISTORY
+ case V_HISTCONTROL:
+ sethistcontrol(str_val(vp));
+ break;
case V_HISTSIZE:
vp->flag &= ~SPECIAL;
sethistsize((int) intval(vp));
@@ -1082,6 +1086,11 @@ unsetspec(struct tbl *vp)
case V_MAILPATH:
mpset(NULL);
break;
+#ifdef HISTORY
+ case V_HISTCONTROL:
+ sethistcontrol(NULL);
+ break;
+#endif
case V_LINENO:
case V_MAILCHECK: /* at&t ksh leaves previous value in place */
case V_RANDOM: