zsh-users
 help / color / mirror / code / Atom feed
From: Wayne Davison <wayned@users.sourceforge.net>
To: zsh-users@sunsite.dk
Subject: Re: History corruption (over NFS)
Date: Mon, 14 Feb 2005 10:57:05 -0800	[thread overview]
Message-ID: <20050214185705.GC6444@blorf.net> (raw)
In-Reply-To: <20050214155630.GB6395@ay.vinc17.org>

[-- Attachment #1: Type: text/plain, Size: 1158 bytes --]

On Mon, Feb 14, 2005 at 04:56:30PM +0100, Vincent Lefevre wrote:
> Then the current zsh instances went on writing to the history file
> without noticing that it had been truncated, hence the null bytes.

I think this is an NFS problem, since the zsh instances do not keep the
history file open -- they just open the file for appending, and add an
item to the end.  When the file is rewritten, it is opened for writing
with O_TRUNC, and the new contents output.

A little while ago I wrote a patch that caused zsh to change its
rewriting strategy to use a HISTORY_FILE.new file and then rename it
into place.  The purpose of this patch is to avoid losing any history if
zsh gets interrupted during the writing of the new history file.
However, it should also be a friendlier update strategy for NFS dirs
because the inode of the file changes.  The downside is that it can undo
some user's use of symlinks, hardlinks, or special group permissions on
their history file (because it is replacing the history file instead of
rewriting it in-place).  Perhaps this algorithm should be made optional?

I've attached a diff in case you want to try it out.

..wayne..

[-- Attachment #2: hist-dot-new.patch --]
[-- Type: text/plain, Size: 1528 bytes --]

--- orig/hist.c	2005-01-28 02:16:20 -0800
+++ hist.c	2004-10-18 15:21:54 -0700
@@ -2004,7 +2004,7 @@
 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,14 @@
 	    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 {
-	out = fdopen(open(unmeta(fn),
-			 O_CREAT | O_WRONLY | O_TRUNC | O_NOCTTY, 0600), "w");
+	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 +2093,11 @@
 	    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 +2117,13 @@
 	    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);
 }

  parent reply	other threads:[~2005-02-14 18:57 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-10 16:54 Vincent Lefevre
2005-02-10 18:41 ` Bart Schaefer
2005-02-10 23:54   ` Vincent Lefevre
2005-02-14 15:56   ` Vincent Lefevre
2005-02-14 16:24     ` Bart Schaefer
2005-02-15  9:50       ` Vincent Lefevre
2005-02-15 16:15         ` Bart Schaefer
2005-02-14 18:57     ` Wayne Davison [this message]
2005-02-14 21:06       ` Seth Kurtzberg
2005-02-14 22:33         ` Wayne Davison
2005-02-15  9:58       ` Vincent Lefevre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050214185705.GC6444@blorf.net \
    --to=wayned@users.sourceforge.net \
    --cc=zsh-users@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).