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

Re: Unable to read history on latest Cygwin



On Wed, Dec 16, 2009 at 7:54 AM, Wayne Davison <4wayned@xxxxxxxxx> wrote:
According to various web docs, symlinks are atomic on NFS, so that might be a good thing to use in general (replacing the use of link()).

Attached is my patch for adding preferential use of a symlink as the locking mechanism. ÂThis should interoperate just fine with a hard-link creating locker, but sadly, will have issues if another locker is using open with O_EXCL. ÂI've made the symlink name "/pid-$PID/host-$HOST" in an attempt to make a create (open) over an existing symlink fail with an error (unless the /pid-$PID dir happens to exist and is writable). ÂWe could try to add O_NOFOLLOW (when available) to the O_EXCL-open as well. ÂHowever, hopefully no system will exist where one zsh locker is trying to use open-locking and another is trying to use a link-locking idiom.

What do you think? ÂDangerous? ÂUseful?

..wayne..
index 86b08bd..81b87c5 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -2599,11 +2599,36 @@ lockhistfile(char *fn, int keep_trying)
 	struct stat sb;
 	int fd;
 	char *lockfile;
+#ifdef HAVE_SYMLINK
+	char pidbuf[32], *lnk;
+#else
 #ifdef HAVE_LINK
 	char *tmpfile;
 #endif
+#endif
 
 	lockfile = bicat(unmeta(fn), ".LOCK");
+#ifdef HAVE_SYMLINK
+	sprintf(pidbuf, "/pid-%ld/host-", (long)mypid);
+	lnk = bicat(pidbuf, getsparam("HOST"));
+	/* We'll abuse fd as our success flag. */
+	while ((fd = symlink(lnk, lockfile)) < 0) {
+	    if (errno != EEXIST || !keep_trying)
+		break;
+	    if (lstat(lockfile, &sb) < 0) {
+		if (errno == ENOENT)
+		    continue;
+		break;
+	    }
+	    if (time(NULL) - sb.st_mtime < 10)
+		sleep(1);
+	    else
+		unlink(lockfile);
+	}
+	if (fd < 0)
+	    lockhistct--;
+	free(lnk);
+#else /* not HAVE_SYMLINK */
 #ifdef HAVE_LINK
 	if ((fd = gettempfile(fn, 0, &tmpfile)) >= 0) {
 	    FILE *out = fdopen(fd, "w");
@@ -2660,6 +2685,7 @@ lockhistfile(char *fn, int keep_trying)
 		close(fd);
 	}
 #endif /* not HAVE_LINK */
+#endif /* not HAVE_SYMLINK */
 	free(lockfile);
     }
 
index 5693007..262fe5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1169,7 +1169,8 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       htons ntohs \
 	       regcomp regexec regerror regfree \
 	       gdbm_open getxattr \
-	       realpath canonicalize_file_name)
+	       realpath canonicalize_file_name \
+	       symlink)
 AC_FUNC_STRCOLL
 
 if test x$enable_cap = xyes; then


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