The branch main has been updated by bapt:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=988b1bb0c54e50654112f0bd649aee68307a5a80

commit 988b1bb0c54e50654112f0bd649aee68307a5a80
Author:     Baptiste Daroussin <[email protected]>
AuthorDate: 2021-03-30 08:28:08 +0000
Commit:     Baptiste Daroussin <[email protected]>
CommitDate: 2021-05-10 16:57:13 +0000

    sh: implement persistent history storage
    
    Implement persistent history storage:
    the strategy is simple at start: loads the existing .sh_history file
    at exit dump it.
    
    The implementation respects the HISTFILE variable and its POSIX
    definition: ~/.sh_history is used if HISTFILE is not set.
    
    to avoid sh to create the history file, set HISTSIZE to 0 or HISTFILE to
    en empty value
    
    Co-authored-by: pstef
    Reviewed by:    jilles
    Differential Revision:  https://reviews.freebsd.org/D29493
---
 bin/sh/histedit.c   | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 bin/sh/main.c       |  7 +++++++
 bin/sh/myhistedit.h |  3 ++-
 bin/sh/sh.1         | 11 +++++++++-
 bin/sh/trap.c       |  3 +++
 5 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
index ba2bec357181..596145790f31 100644
--- a/bin/sh/histedit.c
+++ b/bin/sh/histedit.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <dirent.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
@@ -78,6 +79,64 @@ static int comparator(const void *, const void *, void *);
 static char **sh_matches(const char *, int, int);
 static unsigned char sh_complete(EditLine *, int);
 
+static const char *
+get_histfile(void)
+{
+       const char *histfile;
+
+       /* don't try to save if the history size is 0 */
+       if (hist == NULL || histsizeval() == 0)
+               return (NULL);
+       histfile = expandstr("${HISTFILE-${HOME-}/.sh_history}");
+
+       if (histfile[0] == '\0')
+               return (NULL);
+       return (histfile);
+}
+
+void
+histsave(void)
+{
+       HistEvent he;
+       char *histtmpname = NULL;
+       const char *histfile;
+       int fd;
+       FILE *f;
+
+       if ((histfile = get_histfile()) == NULL)
+               return;
+       INTOFF;
+       asprintf(&histtmpname, "%s.XXXXXXXXXX", histfile);
+       if (histtmpname == NULL) {
+               INTON;
+               return;
+       }
+       fd = mkstemp(histtmpname);
+       if (fd == -1 || (f = fdopen(fd, "w")) == NULL) {
+               free(histtmpname);
+               INTON;
+               return;
+       }
+       if (history(hist, &he, H_SAVE_FP, f) < 1 ||
+           rename(histtmpname, histfile) == -1)
+               unlink(histtmpname);
+       fclose(f);
+       free(histtmpname);
+       INTON;
+
+}
+
+void
+histload(void)
+{
+       const char *histfile;
+       HistEvent he;
+
+       if ((histfile = get_histfile()) == NULL)
+               return;
+       history(hist, &he, H_LOAD, histfile);
+}
+
 /*
  * Set history and editing status.  Called whenever the status may
  * have changed (figures out what to do).
diff --git a/bin/sh/main.c b/bin/sh/main.c
index cbe026e13640..b0a5fac6fd4e 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -75,6 +75,9 @@ __FBSDID("$FreeBSD$");
 #include "cd.h"
 #include "redir.h"
 #include "builtins.h"
+#ifndef NO_HISTORY
+#include "myhistedit.h"
+#endif
 
 int rootpid;
 int rootshell;
@@ -157,6 +160,10 @@ state2:
                        read_profile(shinit);
                }
        }
+#ifndef NO_HISTORY
+       if (iflag)
+               histload();
+#endif
 state3:
        state = 4;
        popstackmark(&smark2);
diff --git a/bin/sh/myhistedit.h b/bin/sh/myhistedit.h
index 968d23c9c1f8..1f513f0ae206 100644
--- a/bin/sh/myhistedit.h
+++ b/bin/sh/myhistedit.h
@@ -43,4 +43,5 @@ extern int displayhist;
 void histedit(void);
 void sethistsize(const char *);
 void setterm(const char *);
-
+void histload(void);
+void histsave(void);
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 76335cfaa2cd..ca3faeff13af 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
 .\"    from: @(#)sh.1  8.6 (Berkeley) 5/4/95
 .\" $FreeBSD$
 .\"
-.Dd July 6, 2020
+.Dd May 10, 2021
 .Dt SH 1
 .Os
 .Sh NAME
@@ -1351,6 +1351,15 @@ If not set, the default editor is
 The default editor used with the
 .Ic fc
 built-in.
+.It Va HISTFILE
+File used for persistent history storage.
+If unset
+.Pa ~/.sh_history
+will be used.
+If set but empty or
+.Va HISTSIZE
+is set to 0
+the shell will not load and save the history.
 .It Va HISTSIZE
 The number of previous commands that are accessible.
 .It Va HOME
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index d7ef40274270..2dd394035ca4 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -535,6 +535,9 @@ exitshell_savedstatus(void)
                flushall();
 #if JOBS
                setjobctl(0);
+#endif
+#ifndef NO_HISTORY
+               histsave();
 #endif
        }
        if (sig != 0 && sig != SIGSTOP && sig != SIGTSTP && sig != SIGTTIN &&
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to