zsh-workers
 help / color / mirror / code / Atom feed
From: Wayne Davison <wayned@users.sourceforge.net>
To: zsh-workers@sunsite.dk
Subject: Re: [PATCH] history locking with fcntl
Date: Thu, 17 Apr 2008 09:23:07 -0700	[thread overview]
Message-ID: <20080417162307.GB22594@blorf.net> (raw)
In-Reply-To: <20080415153120.GE1223@prunille.vinc17.org>

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

On Tue, Apr 15, 2008 at 05:31:20PM +0200, Vincent Lefevre wrote:
> I no longer get the error
> 
> zsh: failed to write history file /home/vlefevre/.zhistory: bad file descriptor

I fixed the bogus "bad file descriptor" part of that error back on March
6th, as well as making some minor improvements to the errors.  I'd like
to see what the real error is when your flock patch is not present.

I personally think this patch goes too far.  There is a lockhistfile()
call that is done to give a particular shell exclusive control over the
history files.  I'd prefer to see nay extra locking done there.

Attached is an alternative patch for the Src/utils.c file that
implements this (it is easier to see what I've done than diffing it
against the file with the current fcntl changes).  Let me know what
you think.

Additional discussion:  I think the option name should be made more
generic so that it can be made to support more types of file locking,
such as the flock() call.  Perhaps call it HIST_EXTRA_LOCKING?

..wayne..

[-- Attachment #2: fcntl.patch --]
[-- Type: text/x-diff, Size: 1719 bytes --]

--- Src/hist.c	14 Apr 2008 13:42:53 -0000	1.74
+++ Src/hist.c	17 Apr 2008 16:12:04 -0000
@@ -2330,6 +2330,36 @@ savehistfile(char *fn, int err, int writ
     unlockhistfile(fn);
 }
 
+#ifdef HAVE_FCNTL_H
+static int flock_fd = -1;
+
+static int
+flockhistfile(char *fn, int keep_trying)
+{
+    struct flock lck;
+    int ctr = keep_trying ? 9 : 0;
+
+    if ((flock_fd = open(unmeta(fn), O_RDWR | O_NOCTTY)) < 0)
+	return errno == ENOENT; /* "successfully" locked missing file */
+
+    lck.l_type = F_WRLCK;
+    lck.l_whence = SEEK_SET;
+    lck.l_start = 0;
+    lck.l_len = 0;  /* lock the whole file */
+
+    while (fcntl(flock_fd, F_SETLKW, &lck) == -1) {
+	if (--ctr < 0) {
+	    close(flock_fd);
+	    flock_fd = -1;
+	    return 0;
+	}
+	sleep(1);
+    }
+
+    return 1;
+}
+#endif
+
 static int lockhistct;
 
 /**/
@@ -2340,6 +2370,12 @@ lockhistfile(char *fn, int keep_trying)
 
     if (!fn && !(fn = getsparam("HISTFILE")))
 	return 0;
+
+#ifdef HAVE_FCNTL_H
+    if (isset(HISTFCNTLLOCK) && !lockhistct && !flockhistfile(fn, keep_trying))
+	return 0;
+#endif
+
     if (!lockhistct++) {
 	struct stat sb;
 	int fd;
@@ -2404,7 +2440,15 @@ lockhistfile(char *fn, int keep_trying)
 #endif /* not HAVE_LINK */
 	free(lockfile);
     }
-    return ct != lockhistct;
+
+    if (ct == lockhistct) {
+#ifdef HAVE_FCNTL_H
+	close(flock_fd);
+	flock_fd = -1;
+#endif
+	return 0;
+    }
+    return 1;
 }
 
 /* Unlock the history file if this corresponds to the last nested lock
@@ -2428,6 +2472,12 @@ unlockhistfile(char *fn)
 	sprintf(lockfile, "%s.LOCK", fn);
 	unlink(lockfile);
 	free(lockfile);
+#ifdef HAVE_FCNTL_H
+	if (flock_fd >= 0) {
+	    close(flock_fd);
+	    flock_fd = -1;
+	}
+#endif
     }
 }
 

  parent reply	other threads:[~2008-04-17 16:22 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-15 15:31 Vincent Lefevre
2008-04-17  9:40 ` Peter Stephenson
2008-04-17 13:58   ` Bart Schaefer
2008-04-18  0:49     ` Vincent Lefevre
2008-04-18  1:24       ` Bart Schaefer
2008-04-17 16:23 ` Wayne Davison [this message]
2008-04-17 16:35   ` Peter Stephenson
2008-04-18  0:59   ` Vincent Lefevre
2008-04-19  2:31     ` Wayne Davison
2008-04-19  5:23       ` Bart Schaefer
2008-04-19 18:35         ` Wayne Davison
2008-04-21 13:19       ` Vincent Lefevre
2008-05-05  1:25         ` Wayne Davison
2009-01-01  4:01           ` Vincent Lefevre
2009-01-01  4:12             ` 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=20080417162307.GB22594@blorf.net \
    --to=wayned@users.sourceforge.net \
    --cc=zsh-workers@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).