From: Philippe Troin <phil+github-commits@fifi.org>
To: Zsh hackers list <zsh-workers@zsh.org>
Cc: Philippe Troin <phil+github-commits@fifi.org>
Subject: [PATCH 3/3] Delay closing the history file until the fcntl-lock is released.
Date: Fri, 8 Mar 2019 16:54:42 -0800 [thread overview]
Message-ID: <20190309005442.944477-3-phil+github-commits@fifi.org> (raw)
In-Reply-To: <20190309005442.944477-1-phil+github-commits@fifi.org>
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
next prev parent reply other threads:[~2019-03-09 0:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-27 18:30 Issues with fcntl() history file locking Philippe Troin
2019-02-27 21:27 ` Bart Schaefer
2019-02-28 6:36 ` Philippe Troin
2019-03-09 0:53 ` Philippe Troin
2019-03-09 0:54 ` [PATCH 1/3] Move readhistfile() after flockhistfile() Philippe Troin
2019-03-09 0:54 ` [PATCH 2/3] Factorize the code that unlock the fcntl() lock into funlockhistfile() Philippe Troin
2019-03-09 0:54 ` Philippe Troin [this message]
[not found] ` <CAH+w=7aUD11M_GYy-FOC5MPGpGXb+o9O_q855OTC32fnSnpshQ@mail.gmail.com>
[not found] ` <82f4a6db638fbfce396e64a45029424185863068.camel@fifi.org>
[not found] ` <CAH+w=7ZS=ke8xHuBaO+hu0-RTtW=GYnG-0MENfBtTsyyp9joyg@mail.gmail.com>
[not found] ` <3228a3e68f2580fc25a9fda9bf7ccf5ce9a73689.camel@fifi.org>
2019-03-10 1:19 ` [PATCH 1/3] Move readhistfile() after flockhistfile() Bart Schaefer
2019-03-11 21:04 ` Jason L Tibbitts III
2019-03-12 7:55 ` Jun T
2019-03-12 9:52 ` Peter Stephenson
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=20190309005442.944477-3-phil+github-commits@fifi.org \
--to=phil+github-commits@fifi.org \
--cc=zsh-workers@zsh.org \
/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).