Index: bin/sh/histedit.c =================================================================== --- bin/sh/histedit.c +++ bin/sh/histedit.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,75 @@ static char **sh_matches(const char *, int, int); static unsigned char sh_complete(EditLine *, int); +void +histsave(void) +{ + HistEvent he; + const char *home; + char histfile[] = ".sh_history.XXXXX"; + int dfd, fd; + + /* don't try to save if the history size is 0 */ + if (histsizeval() == 0) + return; + home = expandstr("${HOME-}"); + if (home == NULL) + return; + if ((dfd = open(home, O_DIRECTORY)) == -1) + return; + fd = mkostempsat(dfd, histfile, 5, O_EXLOCK|O_CLOEXEC); + if (fd < 0) { + close(dfd); + return; + } + + history(hist, &he, H_FIRST); + for (int ret = history(hist, &he, H_FIRST); ret >= 0; + ret = history(hist, &he, H_NEXT)) + dprintf(fd, "%s", he.str); + + close(fd); + if (renameat(dfd, histfile, dfd, ".sh_history") == -1) + unlinkat(dfd, histfile, 0); + close(dfd); +} + +static void +histload(void) +{ + const char *home; + char *line = NULL; + ssize_t linelen; + size_t linecap = 0; + int dfd, fd; + FILE *f; + HistEvent he; + + /* don't try to save if the history size is 0 */ + if (histsizeval() == 0) + return; + home = expandstr("${HOME-}"); + if ((dfd = open(home, O_DIRECTORY)) == -1) + return; + if ((fd = openat(dfd, ".sh_history", O_RDONLY)) == -1) { + close(dfd); + return; + } + close(dfd); + if ((f = fdopen(fd, "r")) == NULL) { + close(fd); + return; + } + + while ((linelen = getline(&line, &linecap, f)) > 0) { + if (line[linelen -1] == '\n') + line[linelen -1] = '\0'; + history(hist, &he, H_ENTER, line); + } + free(line); + fclose(f); +} + /* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). @@ -101,6 +171,8 @@ sethistsize(histsizeval()); else out2fmt_flush("sh: can't initialize history\n"); + /* Load the history */ + histload(); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* Index: bin/sh/myhistedit.h =================================================================== --- bin/sh/myhistedit.h +++ bin/sh/myhistedit.h @@ -43,4 +43,4 @@ void histedit(void); void sethistsize(const char *); void setterm(const char *); - +void histsave(void); Index: bin/sh/trap.c =================================================================== --- bin/sh/trap.c +++ bin/sh/trap.c @@ -539,6 +539,9 @@ flushall(); #if JOBS setjobctl(0); +#endif +#ifndef NO_HISTORY + histsave(); #endif } if (sig != 0 && sig != SIGSTOP && sig != SIGTSTP && sig != SIGTTIN &&