about summary refs log tree commit diff
path: root/Src/builtin.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/builtin.c')
-rw-r--r--Src/builtin.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index b8fd3f3b8..3e7c1f5b1 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -69,8 +69,7 @@ static struct builtin builtins[] =
      * But that's actually not useful, so it's more consistent to
      * cause an error.
      */
-    BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEim",
-	    NULL),
+    BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEimpP", NULL),
     BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
     BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%Hghlprtux", "E"),
     BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmtuUz", NULL),
@@ -82,7 +81,7 @@ static struct builtin builtins[] =
     BUILTIN("hashinfo", 0, bin_hashinfo, 0, 0, 0, NULL, NULL),
 #endif
 
-    BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEim", "l"),
+    BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEimpP", "l"),
     BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "Hghi:%lprtux", "i"),
     BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
     BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
@@ -1308,6 +1307,43 @@ bin_fc(char *nam, char **argv, Options ops, int func)
 	zwarnnam(nam, "not interactive shell", NULL, 0);
 	return 1;
     }
+    if (OPT_ISSET(ops,'p')) {
+	char *hf = "";
+	int hs = DEFAULT_HISTSIZE;
+	int shs = 0;
+	if (*argv) {
+	    hf = *argv++;
+	    if (*argv) {
+		hs = atoi(*argv++);
+		if (*argv)
+		    shs = atoi(*argv++);
+		else
+		    shs = hs;
+		if (*argv) {
+		    zwarnnam("fc", "too many arguments", NULL, 0);
+		    return 1;
+		}
+	    } else {
+		hs = histsiz;
+		shs = savehistsiz;
+	    }
+	}
+	if (!pushhiststack(hf, hs, shs))
+	    return 1;
+	if (*hf) {
+	    struct stat st;
+	    if (stat(hf, &st) >= 0 || errno != ENOENT)
+		readhistfile(hf, 1, HFILE_USE_OPTIONS);
+	}
+	return 0;
+    }
+    if (OPT_ISSET(ops,'P')) {
+	if (*argv) {
+	    zwarnnam("fc", "too many arguments", NULL, 0);
+	    return 1;
+	}
+	return !saveandpophiststack(-1);
+    }
     /* with the -m option, the first argument is taken *
      * as a pattern that history lines have to match   */
     if (*argv && OPT_ISSET(ops,'m')) {
@@ -4073,8 +4109,10 @@ zexit(int val, int from_where)
 	killrunjobs(from_where == 1);
     }
     if (isset(RCS) && interact) {
-	if (!nohistsave)
+	if (!nohistsave) {
+	    saveandpophiststack(0);
 	    savehistfile(NULL, 1, HFILE_USE_OPTIONS);
+	}
 	if (islogin && !subsh) {
 	    sourcehome(".zlogout");
 #ifdef GLOBAL_ZLOGOUT