Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

revisiting history-file rewriting



On Wed, Mar 16, 2005 at 11:13:49AM +0000, Peter Stephenson wrote:
> some time around (western-style) Easter we should probably produce
> 4.2.5.

This makes me want to get approval on a better version of my history-
rewriting patch and get it into 4.2.5.  If some folks would take a look
at this and let me know: (1) do you like the patch for 4.3.0? and (2) do
you like the idea of putting it into 4.2.5 as well.

This patch adds the option HIST_OVERWRITE that is off by default.  This
changes the default history-rewriting strategy to one that uses the name
$HISTFILE.new for writing out the history lines, and then renaming it
over $HISTFILE when it is done (both actions happen with the history
file locked).  If the user chooses to set the HIST_OVERWRITE option, zsh
goes back to the current algorithm of directly re-writing the history
lines to the history file (also while locked).

The reason I chose to change the default is that it is safer to not
truncate the history file when rewriting it.

..wayne..
--- Doc/Zsh/options.yo	12 Jan 2005 13:42:13 -0000	1.36
+++ Doc/Zsh/options.yo	16 Mar 2005 20:34:27 -0000
@@ -557,6 +557,14 @@ Note that the command lingers in the int
 command is entered before it vanishes, allowing you to briefly reuse
 or edit the line.
 )
+pindex(HIST_OVERWRITE)
+item(tt(HIST_OVERWRITE))(
+When the history file is rewritten, we normally write out a new file
+and rename it over the old one.  If this option is set, we instead
+overwrite the old history file directly.  Use this only if you have
+special needs, as it is possible to lose history entries if zsh gets
+interrupted during the history-file writing with this option set.
+)
 pindex(HIST_REDUCE_BLANKS)
 item(tt(HIST_REDUCE_BLANKS))(
 Remove superfluous blanks from each command line
--- Src/hist.c	22 Jan 2005 04:03:15 -0000	1.58
+++ Src/hist.c	16 Mar 2005 20:34:27 -0000
@@ -2004,7 +2004,7 @@ readhistfile(char *fn, int err, int read
 void
 savehistfile(char *fn, int err, int writeflags)
 {
-    char *t, *start = NULL;
+    char *t, *tmpfile, *start = NULL;
     FILE *out;
     Histent he;
     zlong xcurhist = curhist - !!(histactive & HA_ACTIVE);
@@ -2041,12 +2041,17 @@ savehistfile(char *fn, int err, int writ
 	    extended_history = 1;
     }
     if (writeflags & HFILE_APPEND) {
+	tmpfile = NULL;
 	out = fdopen(open(unmeta(fn),
 			O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600), "a");
-    }
-    else {
+    } else if (isset(HISTOVERWRITE)) {
+	tmpfile = NULL;
 	out = fdopen(open(unmeta(fn),
 			 O_CREAT | O_WRONLY | O_TRUNC | O_NOCTTY, 0600), "w");
+    } else {
+	tmpfile = bicat(unmeta(fn), ".new");
+	unlink(tmpfile);
+	out = fdopen(open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600), "w");
     }
     if (out) {
 	for (; he && he->histnum <= xcurhist; he = down_histent(he)) {
@@ -2091,6 +2096,11 @@ savehistfile(char *fn, int err, int writ
 	    lasthist.text = ztrdup(start);
 	}
 	fclose(out);
+	if (tmpfile) {
+	    if (rename(tmpfile, unmeta(fn)) < 0)
+		zerr("can't rename %s.new to $HISTFILE", fn, 0);
+	    free(tmpfile);
+	}
 
 	if (writeflags & HFILE_SKIPOLD
 	 && !(writeflags & (HFILE_FAST | HFILE_NO_REWRITE))) {
@@ -2110,8 +2120,13 @@ savehistfile(char *fn, int err, int writ
 	    pophiststack();
 	    histactive = remember_histactive;
 	}
-    } else if (err)
-	zerr("can't write history file %s", fn, 0);
+    } else if (err) {
+	if (tmpfile) {
+	    zerr("can't write history file %s.new", fn, 0);
+	    free(tmpfile);
+	} else
+	    zerr("can't write history file %s", fn, 0);
+    }
 
     unlockhistfile(fn);
 }
--- Src/options.c	3 Sep 2004 09:47:49 -0000	1.21
+++ Src/options.c	16 Mar 2005 20:34:27 -0000
@@ -137,6 +137,7 @@ static struct optname optns[] = {
 {NULL, "histignorespace",     0,			 HISTIGNORESPACE},
 {NULL, "histnofunctions",     0,			 HISTNOFUNCTIONS},
 {NULL, "histnostore",	      0,			 HISTNOSTORE},
+{NULL, "histoverwrite",       0,			 HISTOVERWRITE},
 {NULL, "histreduceblanks",    0,			 HISTREDUCEBLANKS},
 {NULL, "histsavenodups",      0,			 HISTSAVENODUPS},
 {NULL, "histverify",	      0,			 HISTVERIFY},
--- Src/zsh.h	25 Feb 2005 10:21:02 -0000	1.70
+++ Src/zsh.h	16 Mar 2005 20:34:28 -0000
@@ -1513,6 +1513,7 @@ enum {
     HISTIGNORESPACE,
     HISTNOFUNCTIONS,
     HISTNOSTORE,
+    HISTOVERWRITE,
     HISTREDUCEBLANKS,
     HISTSAVENODUPS,
     HISTVERIFY,


Messages sorted by: Reverse Date, Date, Thread, Author