Module Name: src
Committed By: kre
Date: Sat Jul 13 13:43:58 UTC 2024
Modified Files:
src/bin/sh: histedit.c input.c myhistedit.h mystring.c mystring.h sh.1
trap.c var.c var.h
Log Message:
Implement the HISTFILE and HISTAPPEND variables.
See the (newly updated) sh(1) for details.
Also add the -z option to fc (clear history).
None of this exists in SMALL shells.
To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/bin/sh/histedit.c
cvs rdiff -u -r1.72 -r1.73 src/bin/sh/input.c
cvs rdiff -u -r1.15 -r1.16 src/bin/sh/myhistedit.h
cvs rdiff -u -r1.20 -r1.21 src/bin/sh/mystring.c
cvs rdiff -u -r1.11 -r1.12 src/bin/sh/mystring.h
cvs rdiff -u -r1.261 -r1.262 src/bin/sh/sh.1
cvs rdiff -u -r1.56 -r1.57 src/bin/sh/trap.c
cvs rdiff -u -r1.83 -r1.84 src/bin/sh/var.c
cvs rdiff -u -r1.40 -r1.41 src/bin/sh/var.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/bin/sh/histedit.c
diff -u src/bin/sh/histedit.c:1.70 src/bin/sh/histedit.c:1.71
--- src/bin/sh/histedit.c:1.70 Fri Jul 12 07:30:30 2024
+++ src/bin/sh/histedit.c Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: histedit.c,v 1.70 2024/07/12 07:30:30 kre Exp $ */
+/* $NetBSD: histedit.c,v 1.71 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1993
@@ -37,13 +37,15 @@
#if 0
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: histedit.c,v 1.70 2024/07/12 07:30:30 kre Exp $");
+__RCSID("$NetBSD: histedit.c,v 1.71 2024/07/13 13:43:58 kre Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
@@ -62,6 +64,7 @@ __RCSID("$NetBSD: histedit.c,v 1.70 2024
#include "myhistedit.h"
#include "error.h"
#include "alias.h"
+#include "redir.h"
#ifndef SMALL /* almost all the rest of this file */
@@ -78,6 +81,11 @@ int displayhist;
static FILE *el_in, *el_out;
static int curpos;
+static char *HistFile = NULL;
+static const char *HistFileOpen = NULL;
+FILE *HistFP = NULL;
+static int History_fd;
+
#ifdef DEBUG
extern FILE *tracefile;
#endif
@@ -88,6 +96,7 @@ static int str_to_event(const char *, in
static int comparator(const void *, const void *);
static char **sh_matches(const char *, int, int);
static unsigned char sh_complete(EditLine *, int);
+static FILE *Hist_File_Open(const char *);
/*
* Set history and editing status. Called whenever the status may
@@ -112,9 +121,10 @@ histedit(void)
hist = history_init();
INTON;
- if (hist != NULL)
+ if (hist != NULL) {
sethistsize(histsizeval(), histsizeflags());
- else
+ sethistfile(histfileval(), histfileflags());
+ } else
out2str("sh: can't initialize history\n");
}
if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
@@ -260,13 +270,294 @@ sethistsize(char *hs, int flags)
if (hist != NULL) {
INTOFF;
- history(hist, &he, H_SETSIZE, histsize);
+ /* H_SETSIZE actually sets n-1 as the limit */
+ history(hist, &he, H_SETSIZE, histsize + 1);
history(hist, &he, H_SETUNIQUE, 1);
INTON;
}
}
void
+sethistfile(char *hs, int flags)
+{
+ const char *file;
+ HistEvent he;
+
+ CTRACE(DBG_HISTORY, ("Set HISTFILE=%s [%x] %s\n",
+ (hs == NULL ? "''" : hs), flags, "!hist" + (hist != NULL)));
+
+ if (hs == NULL || *hs == '\0' || (flags & VUNSET)) {
+ if (HistFP != NULL) {
+ fclose(HistFP);
+ HistFP = NULL;
+ }
+ if (HistFile != NULL) {
+ free(HistFile);
+ HistFile = NULL;
+ HistFileOpen = NULL;
+ }
+ return;
+ }
+
+ if (hist != NULL) {
+ file = expandvar(hs, flags);
+ if (file == NULL || *file == '\0')
+ return;
+
+ INTOFF;
+
+ history(hist, &he, H_LOAD, file);
+
+ /*
+ * This is needed so sethistappend() can work
+ * on the current (new) filename, not the previous one.
+ */
+ if (HistFile != NULL)
+ free(HistFile);
+
+ HistFile = strdup(hs);
+ /*
+ * We need to ensure that HistFile & HistFileOpen
+ * are not equal .. we know HistFile has just altered.
+ * If they happen to be equal (both NULL perhaps, or
+ * the strdup() just above happned to return the same
+ * buffer as was freed the line before) then simply
+ * set HistFileOpen to something which cannot be the
+ * same as anything allocated, or NULL. Its only
+ * use is to compare against HistFile.
+ */
+ if (HistFile == HistFileOpen)
+ HistFileOpen = "";
+
+ sethistappend((histappflags() & VUNSET) ? NULL : histappval(),
+ ~VUNSET & 0xFFFF);
+
+ INTON;
+ }
+}
+
+void
+sethistappend(char *s, int flags __diagused)
+{
+ CTRACE(DBG_HISTORY, ("Set HISTAPPEND=%s [%x] %s ",
+ (s == NULL ? "''" : s), flags, "!hist" + (hist != NULL)));
+
+ INTOFF;
+ if (flags & VUNSET || !boolstr(s)) {
+ CTRACE(DBG_HISTORY, ("off"));
+
+ if (HistFP != NULL) {
+ CTRACE(DBG_HISTORY, (" closing"));
+
+ fclose(HistFP);
+ HistFP = NULL;
+ HistFileOpen = NULL;
+ }
+ } else {
+ CTRACE(DBG_HISTORY, ("on"));
+
+ if (HistFileOpen != HistFile || HistFP == NULL) {
+ if (HistFP != NULL) {
+ CTRACE(DBG_HISTORY, (" closing prev"));
+ fclose(HistFP);
+ HistFP = NULL;
+ }
+ if (hist != NULL &&
+ HistFile != NULL &&
+ HistFP == NULL) {
+ CTRACE(DBG_HISTORY, ("\n"));
+
+ save_sh_history();
+
+ CTRACE(DBG_HISTORY, ("opening: "));
+
+ HistFP = Hist_File_Open(HistFile);
+ if (HistFP != NULL)
+ HistFileOpen = HistFile;
+ else {
+ CTRACE(DBG_HISTORY, ("open failed"));
+ }
+ }
+ }
+ }
+ INTON;
+
+ CTRACE(DBG_HISTORY, ("\n"));
+}
+
+static void
+History_FD_Renumbered(int from, int to)
+{
+ if (History_fd == from)
+ History_fd = to;
+
+ VTRACE(DBG_HISTORY, ("History_FD_Renumbered(%d,%d)-> %d\n",
+ from, to, History_fd));
+}
+
+/*
+ * The callback functions for the FILE* returned by funopen2()
+ */
+static ssize_t
+Hist_Write(void *cookie, const void *buf, size_t len)
+{
+ if (cookie != (void *)&History_fd) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return write(History_fd, buf, len);
+}
+
+static int
+Hist_Close(void *cookie)
+{
+ if (cookie == (void *)&History_fd) {
+ sh_close(History_fd);
+ History_fd = -1;
+ return 0;
+ }
+
+ VTRACE(DBG_HISTORY, ("HistClose(%p) != %p\n", cookie, &History_fd));
+
+ errno = EINVAL;
+ return -1;
+}
+
+static off_t
+Hist_Seek(void *cookie, off_t pos, int whence)
+{
+ if (cookie != (void *)&History_fd) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return lseek(History_fd, pos, whence);
+}
+
+/*
+ * a variant of open() for history files.
+ */
+static int
+open_history_file(const char *name, int mode)
+{
+ int fd;
+ struct stat statb;
+
+ fd = open(name, mode, S_IWUSR|S_IRUSR);
+
+ VTRACE(DBG_HISTORY, ("open_history_file(\"%s\", %#x) -> %d\n",
+ name, mode, fd));
+
+ if (fd == -1)
+ return -1;
+
+ if (fstat(fd, &statb) == -1) {
+ VTRACE(DBG_HISTORY, ("history file fstat(%d) failed [%d]\n",
+ fd, errno));
+ close(fd);
+ return -1;
+ }
+
+ if (statb.st_uid != getuid()) {
+ VTRACE(DBG_HISTORY,
+ ("history file wrong user (uid=%d file=%d)\n",
+ getuid(), statb.st_uid));
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+static FILE *
+Hist_File_Open(const char *name)
+{
+ FILE *fd;
+ int n;
+
+ INTOFF;
+
+ n = open_history_file(name, O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC);
+
+ VTRACE(DBG_HISTORY, ("History_File_Open(\"%s\") -> %d", name, n));
+ if (n == -1) {
+ VTRACE(DBG_HISTORY, (" [%d]\n", errno));
+ INTON;
+ return NULL;
+ }
+
+ n = to_upper_fd(n);
+ (void) lseek(n, 0, SEEK_END);
+ VTRACE(DBG_HISTORY, (" -> %d", n));
+
+ History_fd = n;
+ register_sh_fd(n, History_FD_Renumbered);
+
+ if ((fd =
+ funopen2(&History_fd, NULL, Hist_Write, Hist_Seek, NULL,
+ Hist_Close)) == NULL) {
+
+ VTRACE(DBG_HISTORY, ("; funopen2 failed[%d]\n", errno));
+
+ sh_close(n);
+ History_fd = -1;
+ INTON;
+ return NULL;
+ }
+ setlinebuf(fd);
+
+ VTRACE(DBG_HISTORY, (" fd:%p\n", fd));
+
+ INTON;
+
+ return fd;
+}
+
+void
+save_sh_history(void)
+{
+ char *var;
+ const char *file;
+ int fd;
+ FILE *fp;
+ HistEvent he;
+
+ if (HistFP != NULL) {
+ /* don't close, just make sure nothing in buffer */
+ (void) fflush(HistFP);
+ return;
+ }
+
+ if (hist == NULL)
+ return;
+
+ var = histfileval();
+ if ((histfileflags() & VUNSET) || *var == '\0')
+ return;
+
+ file = expandvar(var, histfileflags());
+
+ VTRACE(DBG_HISTORY,
+ ("save_sh_history('%s')\n", file == NULL ? "" : file));
+
+ if (file == NULL || *file == '\0')
+ return;
+
+ INTOFF;
+ fd = open_history_file(file, O_WRONLY|O_CREAT|O_TRUNC);
+ if (fd != -1) {
+ fp = fdopen(fd, "w");
+ if (fp != NULL) {
+ (void) history(hist, &he, H_SAVE_FP, fp);
+ fclose(fp);
+ } else
+ close(fd);
+ }
+ INTON;
+}
+
+void
setterm(char *term, int flags __unused)
{
INTOFF;
@@ -278,6 +569,9 @@ setterm(char *term, int flags __unused)
INTON;
}
+/*
+ * The built-in sh commands supported by this file
+ */
int
inputrc(int argc, char **argv)
{
@@ -313,7 +607,7 @@ histcmd(volatile int argc, char ** volat
int ch;
const char * volatile editor = NULL;
HistEvent he;
- volatile int lflg = 0, nflg = 0, rflg = 0, sflg = 0;
+ volatile int lflg = 0, nflg = 0, rflg = 0, sflg = 0, zflg = 0;
int i, retval;
const char *firststr, *laststr;
int first, last, direction;
@@ -341,7 +635,7 @@ histcmd(volatile int argc, char ** volat
optreset = 1; optind = 1; /* initialize getopt */
while (not_fcnumber(argv[optind]) &&
- (ch = getopt(argc, argv, ":e:lnrs")) != -1)
+ (ch = getopt(argc, argv, ":e:lnrsz")) != -1)
switch ((char)ch) {
case 'e':
editor = optarg;
@@ -363,6 +657,10 @@ histcmd(volatile int argc, char ** volat
sflg = 1;
VTRACE(DBG_HISTORY, ("histcmd -s\n"));
break;
+ case 'z':
+ zflg = 1;
+ VTRACE(DBG_HISTORY, ("histcmd -z\n"));
+ break;
case ':':
error("option -%c expects argument", optopt);
/* NOTREACHED */
@@ -373,6 +671,15 @@ histcmd(volatile int argc, char ** volat
}
argc -= optind, argv += optind;
+ if (zflg) {
+ if (argc != 0 || (lflg|nflg|rflg|sflg) != 0)
+ error("Usage: fc -z");
+
+ history(hist, &he, H_CLEAR);
+ return 0;
+ }
+
+
/*
* If executing...
*/
@@ -446,7 +753,7 @@ histcmd(volatile int argc, char ** volat
firststr = "-16";
laststr = "-1";
} else
- firststr = laststr = "-1";
+ firststr = laststr = "-1"; /* the exact same str */
break;
case 1:
firststr = argv[0];
@@ -588,6 +895,10 @@ histcmd(volatile int argc, char ** volat
return 0;
}
+/*
+ * and finally worker functions for those built-ins
+ */
+
static const char *
fc_replace(const char *s, char *p, char *r)
{
Index: src/bin/sh/input.c
diff -u src/bin/sh/input.c:1.72 src/bin/sh/input.c:1.73
--- src/bin/sh/input.c:1.72 Tue Feb 16 15:30:26 2021
+++ src/bin/sh/input.c Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: input.c,v 1.72 2021/02/16 15:30:26 kre Exp $ */
+/* $NetBSD: input.c,v 1.73 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95";
#else
-__RCSID("$NetBSD: input.c,v 1.72 2021/02/16 15:30:26 kre Exp $");
+__RCSID("$NetBSD: input.c,v 1.73 2024/07/13 13:43:58 kre Exp $");
#endif
#endif /* not lint */
@@ -338,6 +338,10 @@ preadbuffer(void)
INTOFF;
history(hist, &he, whichprompt != 2 ? H_ENTER : H_APPEND,
parsenextc);
+ if (whichprompt != 2 && HistFP != NULL) {
+ history(hist, &he, H_NSAVE_FP, (size_t)0, HistFP);
+ fflush(HistFP);
+ }
INTON;
}
#endif
Index: src/bin/sh/myhistedit.h
diff -u src/bin/sh/myhistedit.h:1.15 src/bin/sh/myhistedit.h:1.16
--- src/bin/sh/myhistedit.h:1.15 Fri Jul 12 07:30:30 2024
+++ src/bin/sh/myhistedit.h Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: myhistedit.h,v 1.15 2024/07/12 07:30:30 kre Exp $ */
+/* $NetBSD: myhistedit.h,v 1.16 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1993
@@ -41,7 +41,13 @@ extern int displayhist;
void histedit(void);
void sethistsize(char *, int);
+void sethistfile(char *, int);
+void sethistappend(char *, int);
+void save_sh_history(void);
void setterm(char *, int);
int inputrc(int, char **);
void set_editrc(char *, int);
void set_prompt_lit(char *, int);
+
+#include <stdio.h>
+extern FILE *HistFP;
Index: src/bin/sh/mystring.c
diff -u src/bin/sh/mystring.c:1.20 src/bin/sh/mystring.c:1.21
--- src/bin/sh/mystring.c:1.20 Fri Apr 7 10:34:13 2023
+++ src/bin/sh/mystring.c Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: mystring.c,v 1.20 2023/04/07 10:34:13 kre Exp $ */
+/* $NetBSD: mystring.c,v 1.21 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: mystring.c,v 1.20 2023/04/07 10:34:13 kre Exp $");
+__RCSID("$NetBSD: mystring.c,v 1.21 2024/07/13 13:43:58 kre Exp $");
#endif
#endif /* not lint */
@@ -54,6 +54,8 @@ __RCSID("$NetBSD: mystring.c,v 1.20 2023
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
+#include <strings.h>
+
#include "shell.h"
#include "syntax.h"
#include "error.h"
@@ -138,3 +140,29 @@ is_number(const char *p)
} while (*++p != '\0');
return 1;
}
+
+/*
+ * Check a string for common representations of yes/true/...
+ * Default result is false
+ */
+
+int
+boolstr(const char *s)
+{
+ size_t len;
+
+ if (s == NULL)
+ return 0;
+
+ len = strlen(s);
+ if (len == 0)
+ return 0;
+
+ if (strncasecmp(s, "true", len) == 0 ||
+ strncasecmp(s, "yes", len) == 0 ||
+ (len == 2 && strcasecmp(s, "on") == 0) ||
+ is_digit(*s) || atoi(s) != 0)
+ return 1;
+
+ return 0;
+}
Index: src/bin/sh/mystring.h
diff -u src/bin/sh/mystring.h:1.11 src/bin/sh/mystring.h:1.12
--- src/bin/sh/mystring.h:1.11 Thu Aug 7 09:05:35 2003
+++ src/bin/sh/mystring.h Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: mystring.h,v 1.11 2003/08/07 09:05:35 agc Exp $ */
+/* $NetBSD: mystring.h,v 1.12 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -40,6 +40,7 @@ void scopyn(const char *, char *, int);
int prefix(const char *, const char *);
int number(const char *);
int is_number(const char *);
+int boolstr(const char *);
#define equal(s1, s2) (strcmp(s1, s2) == 0)
#define scopy(s1, s2) ((void)strcpy(s2, s1))
Index: src/bin/sh/sh.1
diff -u src/bin/sh/sh.1:1.261 src/bin/sh/sh.1:1.262
--- src/bin/sh/sh.1:1.261 Sat Jul 13 07:11:20 2024
+++ src/bin/sh/sh.1 Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-.\" $NetBSD: sh.1,v 1.261 2024/07/13 07:11:20 kre Exp $
+.\" $NetBSD: sh.1,v 1.262 2024/07/13 13:43:58 kre Exp $
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -31,7 +31,7 @@
.\"
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95
.\"
-.Dd April 12, 2024
+.Dd July 13, 2024
.Dt SH 1
.\" everything except c o and s (keep them ordered)
.ds flags abCEeFfhIiLlmnpquVvXx
@@ -781,8 +781,6 @@ generate are treated as quoted in this c
.\"
.\"
.Ss Dollar Single Quotes ( Li \&$'...' )
-.\"
-.Pp
Enclosing characters in a matched pair of single quotes, with the
first immediately preceded by an unquoted dollar sign
.Pq Li \&$
@@ -2904,6 +2902,8 @@ and creating it again \(en provided the
.It Ic fc Oo Fl e Ar editor Oc Op Ar first Op Ar last
.It Ic fc Fl l Oo Fl nr Oc Op Ar first Op Ar last
.It Ic fc Fl s Oo Ar old=new Oc Op Ar first
+.It Ic fc Fl z
+.Pp
The
.Ic fc
built-in lists, or edits and re-executes, commands previously entered
@@ -2951,6 +2951,9 @@ nor
.Fl s ) .
.It Fl s
Re-execute the command without invoking an editor.
+.It Fl z
+Clear the history buffer.
+No other options or arguments are permitted.
.It Ar first
.It Ar last
Select the commands to list or edit.
@@ -2989,6 +2992,14 @@ The following environment variables affe
.Bl -tag -width HISTSIZE
.It Ev FCEDIT
Name of the editor to use.
+If
+.Ev FCEDIT
+is not set,
+.Ev EDITOR
+is used, if set.
+If neither is used the
+.Ic ed
+utility is used.
.It Ev HISTSIZE
The number of previous commands that are accessible.
.El
@@ -4748,8 +4759,72 @@ If set it loses its special properties,
See the
.Ic specialvar
built-in command for remedial action.
+.It Ev HISTAPPEND
+If set to one of
+.Ql true ,
+.Ql yes ,
+.Ql on ,
+or an integral value greater than zero,
+and if
+.Ev HISTFILE
+is also set, and is a valid history file,
+then as commands are read and added to the
+history buffer, they are also written to the
+.Ev HISTFILE
+named.
+.It Ev HISTFILE
+When assigned to in an interactive shell
+the contents of the file named by expanding
+the new value of
+.Ev HISTFILE
+will, if it exists,
+can be opened for reading,
+and is a suitable
+.Nm
+history file (one previously written by
+.Nm ) ,
+be read into the history buffer,
+appending its contents to any existing history entries.
+If
+.Ev HISTFILE
+is set when
+.Nm
+exits,
+after any EXIT trap has been evaluated,
+and if
+.Ev HISTAPPEND
+is not enabled,
+or if
+.Ev HISTFILE
+is assigned when HISTAPPEND is enabled,
+or if
+.Ev HISTAPPEND
+is enabled when
+.Ev HISTFILE
+is set,
+the contents of the history buffer will be written
+to the file named after expanding this variable.
+If the file named did not previously exist, it will be created.
+If it did exist, it must be writable.
+The file will be truncated, and then if owned by the current user,
+the current history buffer will be written to it.
+.Pp
+When used for reading or writing history entries,
+variable and arithmetic expansions are performed,
+upon its value to produce a file name, and if the
+.Ev HISTFILE
+variable was set by this shell,
+rather than obtained from the environment,
+command substitutions will also be performed.
+No file will be used if an expansion error occurs,
+or if there is a command substitution in a value obtained
+from the environment.
.It Ev HISTSIZE
The number of lines in the history buffer for the shell.
+If unset, or set to an empty string, 100 lines will be used.
+Attempts to set HISTSIZE to anything other than a string of
+digits will generate an error.
+An invalid value found in the environment will be ignored.
.It Ev HOME
Set automatically by
.Xr login 1
@@ -4757,7 +4832,7 @@ from the user's login directory in the p
.Pq Xr passwd 5 .
This environment variable also functions as the default argument for the
.Ic cd
-built-in.
+built-in, and as the value of a tilde expansion without a user name.
.It Ev HOSTNAME
Set to the current hostname of the system, as returned by
.Xr gethostname 3 .
Index: src/bin/sh/trap.c
diff -u src/bin/sh/trap.c:1.56 src/bin/sh/trap.c:1.57
--- src/bin/sh/trap.c:1.56 Wed Nov 10 15:26:34 2021
+++ src/bin/sh/trap.c Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.56 2021/11/10 15:26:34 kre Exp $ */
+/* $NetBSD: trap.c,v 1.57 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
#else
-__RCSID("$NetBSD: trap.c,v 1.56 2021/11/10 15:26:34 kre Exp $");
+__RCSID("$NetBSD: trap.c,v 1.57 2024/07/13 13:43:58 kre Exp $");
#endif
#endif /* not lint */
@@ -70,6 +70,9 @@ __RCSID("$NetBSD: trap.c,v 1.56 2021/11/
#include "mystring.h"
#include "var.h"
+#ifndef SMALL
+#include "myhistedit.h"
+#endif
/*
* Sigmode records the current value of the signal handlers for the various
@@ -885,6 +888,11 @@ exitshell_savedstatus(void)
INTOFF; /* we're done, no more interrupts. */
+#ifndef SMALL
+ if (rootshell)
+ save_sh_history();
+#endif
+
if (!setjmp(loc.loc)) {
handler = &loc; /* probably unnecessary */
flushall();
Index: src/bin/sh/var.c
diff -u src/bin/sh/var.c:1.83 src/bin/sh/var.c:1.84
--- src/bin/sh/var.c:1.83 Fri Jul 12 07:30:30 2024
+++ src/bin/sh/var.c Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.83 2024/07/12 07:30:30 kre Exp $ */
+/* $NetBSD: var.c,v 1.84 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: var.c,v 1.83 2024/07/12 07:30:30 kre Exp $");
+__RCSID("$NetBSD: var.c,v 1.84 2024/07/13 13:43:58 kre Exp $");
#endif
#endif /* not lint */
@@ -107,6 +107,8 @@ struct localvar *localvars;
#ifndef SMALL
struct var vhistsize;
+struct var vhistfile;
+struct var vhistappend;
struct var vterm;
struct var editrc;
struct var ps_lit;
@@ -142,6 +144,10 @@ const struct varinit varinit[] = {
#ifndef SMALL
{ &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=",
{ .set_func= sethistsize } },
+ { &vhistfile, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE=",
+ { .set_func= sethistfile } },
+ { &vhistappend, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTAPPEND=",
+ { .set_func= sethistappend } },
#endif
{ &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n",
{ NULL } },
Index: src/bin/sh/var.h
diff -u src/bin/sh/var.h:1.40 src/bin/sh/var.h:1.41
--- src/bin/sh/var.h:1.40 Fri Jul 12 07:30:30 2024
+++ src/bin/sh/var.h Sat Jul 13 13:43:58 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: var.h,v 1.40 2024/07/12 07:30:30 kre Exp $ */
+/* $NetBSD: var.h,v 1.41 2024/07/13 13:43:58 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -99,6 +99,8 @@ extern struct var line_num;
extern struct var editrc;
extern struct var vterm;
extern struct var vtermcap;
+extern struct var vhistappend;
+extern struct var vhistfile;
extern struct var vhistsize;
extern struct var ps_lit;
extern struct var euname;
@@ -128,6 +130,10 @@ extern int funclineabs;
#ifndef SMALL
#define histsizeval() (vhistsize.text + 9)
#define histsizeflags() (vhistsize.flags)
+#define histfileval() (vhistfile.text + 9)
+#define histfileflags() (vhistfile.flags)
+#define histappval() (vhistappend.text + 11)
+#define histappflags() (vhistappend.flags)
#define termval() (vterm.text + 5)
#endif