mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-02 10:01:11 +02:00
Add symlink-based hist-file locking.
This commit is contained in:
parent
5355700992
commit
6e317e4b96
3 changed files with 37 additions and 4 deletions
|
@ -1,3 +1,7 @@
|
|||
2009-12-18 Wayne Davison <wayned@users.sourceforge.net>
|
||||
|
||||
* users/14659: Src/hist.c: Add symlink-based hist-file locking.
|
||||
|
||||
2009-12-17 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* Greg: 27529: Completion/Unix/Command/_subversion: make URL
|
||||
|
@ -12514,5 +12518,5 @@
|
|||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.4847 $
|
||||
* $Revision: 1.4848 $
|
||||
*****************************************************
|
||||
|
|
32
Src/hist.c
32
Src/hist.c
|
@ -2600,11 +2600,38 @@ lockhistfile(char *fn, int keep_trying)
|
|||
int fd;
|
||||
char *lockfile;
|
||||
#ifdef HAVE_LINK
|
||||
# ifdef HAVE_SYMLINK
|
||||
char pidbuf[32], *lnk;
|
||||
# else
|
||||
char *tmpfile;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
lockfile = bicat(unmeta(fn), ".LOCK");
|
||||
/* NOTE: only use symlink locking on a link()-having host in order to
|
||||
* avoid a change from open()-based locking to symlink()-based. */
|
||||
#ifdef HAVE_LINK
|
||||
# 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 */
|
||||
if ((fd = gettempfile(fn, 0, &tmpfile)) >= 0) {
|
||||
FILE *out = fdopen(fd, "w");
|
||||
if (out) {
|
||||
|
@ -2618,7 +2645,7 @@ lockhistfile(char *fn, int keep_trying)
|
|||
lockfile, errno);
|
||||
else if (!keep_trying)
|
||||
;
|
||||
else if (stat(lockfile, &sb) < 0) {
|
||||
else if (lstat(lockfile, &sb) < 0) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
zerr("failed to stat lock file %s: %e", lockfile, errno);
|
||||
|
@ -2635,11 +2662,12 @@ lockhistfile(char *fn, int keep_trying)
|
|||
unlink(tmpfile);
|
||||
free(tmpfile);
|
||||
}
|
||||
# endif /* not HAVE_SYMLINK */
|
||||
#else /* not HAVE_LINK */
|
||||
while ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) {
|
||||
if (errno != EEXIST || !keep_trying)
|
||||
break;
|
||||
if (stat(lockfile, &sb) < 0) {
|
||||
if (lstat(lockfile, &sb) < 0) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
break;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue