Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH 3/3] Delay closing the history file until the fcntl-lock is released.
Closes are not delayed if zsh is not compiled with fcntl() lock or if
the histfcntllock option isn't set.
---
Src/hist.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 93 insertions(+), 4 deletions(-)
diff --git a/Src/hist.c b/Src/hist.c
index 981316674..2d0b3eb0f 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -2527,6 +2527,63 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in)
#ifdef HAVE_FCNTL_H
static int flock_fd = -1;
+#define FLOCK_MAX_FILES_TO_CLOSE 10
+static int flock_fds_to_close[FLOCK_MAX_FILES_TO_CLOSE] = { -1 };
+static FILE* flock_files_to_close[FLOCK_MAX_FILES_TO_CLOSE];
+
+static int
+closehistfd(int fd) {
+ int i;
+
+ if (flock_fd < 0) {
+ return close(fd);
+ }
+
+ for (i=0; i < FLOCK_MAX_FILES_TO_CLOSE; ++i) {
+ if (flock_fds_to_close[i] < 0) {
+ break;
+ }
+ }
+
+ if (i >= FLOCK_MAX_FILES_TO_CLOSE) {
+ zerr("Ran out of flock_fds_to_close, increase the "
+ "FLOCK_MAX_FILES_TO_CLOSE limit (currently at %d) in hist.c.",
+ FLOCK_MAX_FILES_TO_CLOSE);
+ /* Close if we can't postpone */
+ return close(fd);
+ }
+
+ flock_fds_to_close[i] = fd;
+
+ return 0;
+}
+
+static int
+closehistfile(FILE* fp) {
+ int i;
+
+ if (flock_fd < 0) {
+ return fclose(fp);
+ }
+
+ for (i=0; i < FLOCK_MAX_FILES_TO_CLOSE; ++i) {
+ if (! flock_files_to_close[i]) {
+ break;
+ }
+ }
+
+ if (i >= FLOCK_MAX_FILES_TO_CLOSE) {
+ zerr("Ran out of flock_files_to_close, increase the "
+ "FLOCK_MAX_FILES_TO_CLOSE limit (currently at %d) in hist.c.",
+ FLOCK_MAX_FILES_TO_CLOSE);
+ /* Close if we can't postpone */
+ return fclose(fp);
+ }
+
+ flock_files_to_close[i] = fp;
+
+ return 0;
+}
/*
* Lock file using fcntl(). Return 0 on success, 1 on failure of
@@ -2539,10 +2596,18 @@ flockhistfile(char *fn, int keep_trying)
struct flock lck;
long sleep_us = 0x10000; /* about 67 ms */
time_t end_time;
+ int i;
if (flock_fd >= 0)
return 0; /* already locked */
+ /* Clear out the list of fds/file descriptors which will be closed
+ upon relinquising the lock */
+ memset(flock_files_to_close, 0, sizeof(flock_files_to_close[0])*FLOCK_MAX_FILES_TO_CLOSE);
+ for (i=0; i < FLOCK_MAX_FILES_TO_CLOSE; ++i) {
+ flock_fds_to_close[i] = -1;
+ }
+
if ((flock_fd = open(unmeta(fn), O_RDWR | O_NOCTTY)) < 0)
return errno == ENOENT ? 0 : 2; /* "successfully" locked missing file */
@@ -2575,12 +2640,36 @@ flockhistfile(char *fn, int keep_trying)
static void
funlockhistfile()
{
+ int i;
+
if (flock_fd >= 0) {
close(flock_fd);
flock_fd = -1;
}
+
+ for (i=0; i < FLOCK_MAX_FILES_TO_CLOSE; ++i) {
+ if (flock_files_to_close[i]) {
+ fclose(flock_files_to_close[i]);
+ flock_files_to_close[i] = NULL;
+ } else {
+ break;
+ }
+ }
+
+ for (i=0; i < FLOCK_MAX_FILES_TO_CLOSE; ++i) {
+ if (flock_fds_to_close[i] >= 0) {
+ close(flock_fds_to_close[i]);
+ flock_fds_to_close[i] = -1;
+ } else {
+ break;
+ }
+ }
}
-#endif
+
+#else /* ! HAVE_FCNTL_H */
+# define closehistfd(x) close(x)
+# define closehistfile(x) fclose(x)
+#endif /* ! HAVE_FCNTL_H */
/**/
void
@@ -2768,7 +2857,7 @@ readhistfile(char *fn, int err, int readflags)
zfree(buf, bufsiz);
popheap();
- fclose(in);
+ closehistfile(in);
} else if (err)
zerr("can't read history file %s", fn);
@@ -2860,7 +2949,7 @@ savehistfile(char *fn, int err, int writeflags)
if (fd >=0) {
out = fdopen(fd, "w");
if (!out)
- close(fd);
+ closehistfd(fd);
} else
out = NULL;
}
@@ -2948,7 +3037,7 @@ savehistfile(char *fn, int err, int writeflags)
lasthist.text = ztrdup(start);
}
}
- if (fclose(out) < 0 && ret >= 0)
+ if (closehistfile(out) < 0 && ret >= 0)
ret = -1;
if (ret >= 0) {
if (tmpfile) {
--
2.20.1
Messages sorted by:
Reverse Date,
Date,
Thread,
Author