From nobody Sat Apr 30 08:04:22 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id C1EC31ABE07A; Sat, 30 Apr 2022 08:04:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Kr21z1fnVz4ZjW; Sat, 30 Apr 2022 08:04:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1651305863; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XmzrIMmoSsn17C7+ZvBcxlMeFvwv4QOMltX3lwJ2xWI=; b=tRYyYUYg2xCyOPPOSZmcoFRzhAGzpQiyy/eozVlYF6WghBp2uG5OOa5CCnV/zIjYRel4lg tPjPhGhrwCL/FLZWD46A7SE7Hcd5YXbuvcF1KkRQphvk35kJY+wG07q8JqdbUUx36cWT/B NL5QC3Aj9WBj7PAOTtpaLspX8UgjoElMJ04LOxBCBMMV30Y8N0wi1BSiXmJ4cZg1AYt6en ug3NxG1TLSShFcYNSYFYFZyNk1g8yWJ3L59H2nkKLvjpn104ImFrzdccxMI35owQAOmjSZ HWv5342vZLwcuWyrsWqQfzqoBTvJ5X4cfbWxnxIMqG9i+eqW183YwnOMJ26cMA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CBF711D9FB; Sat, 30 Apr 2022 08:04:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 23U84Mlr058651; Sat, 30 Apr 2022 08:04:22 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 23U84MdW058650; Sat, 30 Apr 2022 08:04:22 GMT (envelope-from git) Date: Sat, 30 Apr 2022 08:04:22 GMT Message-Id: <202204300804.23U84MdW058650@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Piotr Pawel Stefaniak Subject: git: d9d0812bc6e9 - stable/13 - sh: implement persistent history storage List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: pstef X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: d9d0812bc6e90f6d8f85ef0939357590d34c3a4a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1651305863; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XmzrIMmoSsn17C7+ZvBcxlMeFvwv4QOMltX3lwJ2xWI=; b=FxP5DfUAzO/WJybfEXLuPg4YQ44pF7bJOynC9LCxx1dtel4XKYd13D8S4vyPklDKcH8A2i NPm96k9ciDUufl5s4jvpedhxSmUujXnAY3nXG+DSKlii5pC3KDzHZtE/3ODZPF3k3lwgnX Iu8Ip09jgKwtIQcTUlAMt/PDV2PaDi7G5YuCpiSVn5TvQvAxGp3IzxCwlVns+cfx8pCt1l 11H2okTl2E4sBE2J4h8H6expcEnnBEkKCC+zMmWCwIAkN6Ir/Z9E/ftDWrACjhC058UD8n gEZV5hBi/LZ0ePlrld6hcsNdzCJENSRtTAHdqoUYFLuord5lWG7DGLIbsEU0gg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1651305863; a=rsa-sha256; cv=none; b=gtjkP57f3TZwLD8eLvZBrL0oQIMa8nKLW3t5riSvnaEWo+LgZtA0YOOC7nSxwjisAthnbc ZvzjzvSt879S11LoaWOUilUtJkEetk2lBNHlEz1hUhZ69ohJaMGB5ABBODMUuOjhubqHHe GZV/9jcIvf3xOysJUVaJtESTjd82xvY2nhtynxoXVh629VnE9BlWDHluQjsgaDvRBAHEIr sY1owVDZH2n1v/0ymAijTvHG69lPpQgISTGqwIxwNiKUJ4yKT9Dp7d7Gwrh0J46dJ9h2ko xDTwGBZWtrS4zpWt3z9bZalVR1wui9xL2bW72vSIcxTh053+AO5BIF+fyW+rvg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by pstef: URL: https://cgit.FreeBSD.org/src/commit/?id=d9d0812bc6e90f6d8f85ef0939357590d34c3a4a commit d9d0812bc6e90f6d8f85ef0939357590d34c3a4a Author: Baptiste Daroussin AuthorDate: 2021-03-30 08:28:08 +0000 Commit: Piotr Pawel Stefaniak CommitDate: 2022-04-30 07:55:42 +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 (cherry picked from commit 988b1bb0c54e50654112f0bd649aee68307a5a80) sh: try to avoid overwriting HISTFILE produced by other shells If an attempt to load history from an existing history file was unsuccessful, do not try to save command history to that file on exit. (cherry picked from commit 1f82fb3834105fd8f1186b1c6d719d8a24738180) --- bin/sh/histedit.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/sh/main.c | 7 ++++++ bin/sh/myhistedit.h | 3 ++- bin/sh/sh.1 | 11 +++++++++- bin/sh/trap.c | 3 +++ 5 files changed, 85 insertions(+), 2 deletions(-) diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c index cf6bebad4c1a..2001b80bd8ed 100644 --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -70,6 +72,7 @@ __FBSDID("$FreeBSD$"); History *hist; /* history cookie */ EditLine *el; /* editline cookie */ int displayhist; +static int savehist; static FILE *el_in, *el_out; static bool in_command_completion; @@ -81,6 +84,66 @@ static char **sh_matches(const char *, int, int); static const char *append_char_function(const char *); 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 (!savehist || (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; + errno = 0; + if (history(hist, &he, H_LOAD, histfile) != -1 || errno == ENOENT) + savehist = 1; +} + /* * 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 &&