From: Baptiste Daroussin Date: Fri, 2 Dec 2022 12:55:17 +0000 (+0100) Subject: locking: use a more portable mechanism X-Git-Tag: RELEASE_1_4_0a1~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2af27b24d181bdbc71193268fceeffb59f792524;p=thirdparty%2Fmlmmj.git locking: use a more portable mechanism --- diff --git a/include/utils.h b/include/utils.h index f94d59ca..f2d68942 100644 --- a/include/utils.h +++ b/include/utils.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -35,36 +36,4 @@ uintmax_t strtouim(const char *, uintmax_t, uintmax_t, const char **); void exec_or_die(const char *arg, ...); int exec_and_wait(const char *arg, ...); time_t strtotimet(const char *np, const char **errpp); - -static inline int open_locked(const char *path, int flags, mode_t mode) { -#ifdef O_EXLOCK - flags |= O_EXLOCK; - return (open(path, flags, mode)); -#else - int fd = open(path, flags, mode); - if (fd != -1) { - if (flock(fd, LOCK_EX) == -1) { - close(fd); - fd = -1; - } - } - return (fd); -#endif -} - -static inline int openat_locked(int dfd, const char *path, int flags, mode_t mode) { -#ifdef O_EXLOCK - flags |= O_EXLOCK; - return (openat(dfd, path, flags, mode)); -#else - int fd = openat(dfd, path, flags, mode); - if (fd != -1) { - if (flock(fd, LOCK_EX) == -1) { - close(fd); - fd = -1; - } - } - return (fd); -#endif -} - +bool lock(int fd, bool write); diff --git a/src/incindexfile.c b/src/incindexfile.c index 96d3798f..ac522021 100644 --- a/src/incindexfile.c +++ b/src/incindexfile.c @@ -49,8 +49,8 @@ int incindexfile(const char *listdir) const char *errstr; xasprintf(&indexfilename, "%s/index", listdir); - fd = open_locked(indexfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); - if(fd == -1) { + fd = open(indexfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); + if(fd == -1 && !lock(fd, true)) { free(indexfilename); log_error(LOG_ARGS, "Error opening index file"); return 0; diff --git a/src/log_oper.c b/src/log_oper.c index 1e27f79d..82ab11dc 100644 --- a/src/log_oper.c +++ b/src/log_oper.c @@ -65,8 +65,8 @@ int log_oper(const char *prefix, const char *basename, const char *fmt, ...) free(tmp); } - fd = open_locked(logfilename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); - if(fd < 0) { + fd = open(logfilename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); + if(fd < 0 && !lock(fd, true)) { log_error(LOG_ARGS, "Could not open %s", logfilename); free(logfilename); return -1; diff --git a/src/mlmmj-maintd.c b/src/mlmmj-maintd.c index 74481e22..1ab7ad2b 100644 --- a/src/mlmmj-maintd.c +++ b/src/mlmmj-maintd.c @@ -602,8 +602,8 @@ run_digests(int dfd, const char *mlmmjsend, const char *listdir, int logfd) digestinterval = ctrltimet(dfd, "digestinterval", DIGESTINTERVAL); digestmaxmails = ctrllong(listdir, "digestmaxmail", DIGESTMAXMAILS); - fd = openat_locked(dfd, "lastdigest", O_RDWR|O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) { + fd = openat(dfd, "lastdigest", O_RDWR|O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0 && !lock(fd, true)) { log(" - Could not open or create 'lastdigest': %s\n", strerror(errno)); return (false); diff --git a/src/mlmmj-send.c b/src/mlmmj-send.c index 93488c7f..dd8d0af4 100644 --- a/src/mlmmj-send.c +++ b/src/mlmmj-send.c @@ -919,7 +919,8 @@ int main(int argc, char **argv) /* initialize file with mail to send */ - if((mailfd = open_locked(mailfilename, O_RDWR, 0644)) < 0) { + if((mailfd = open(mailfilename, O_RDWR, 0644)) < 0 && + !lock(mailfd, true)) { log_error(LOG_ARGS, "Could not open '%s'", mailfilename); exit(EXIT_FAILURE); } diff --git a/src/mlmmj-sub.c b/src/mlmmj-sub.c index 4c24c379..b72bb5e9 100644 --- a/src/mlmmj-sub.c +++ b/src/mlmmj-sub.c @@ -569,9 +569,9 @@ static void subscribe_type(char *listdir, char *listaddr, char *listdelim, subfilename = concatstr(3, listdir, subdir, chstr); - subfilefd = open_locked(subfilename, O_RDWR|O_CREAT|O_APPEND, + subfilefd = open(subfilename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|groupwritable); - if(subfilefd == -1) { + if(subfilefd == -1 && !lock(subfilefd, true)) { log_error(LOG_ARGS, "Could not open '%s'", subfilename); exit(EXIT_FAILURE); } diff --git a/src/mlmmj.c b/src/mlmmj.c index 2100f26b..c9d76974 100644 --- a/src/mlmmj.c +++ b/src/mlmmj.c @@ -187,9 +187,11 @@ unsubscribe(int listfd, const char *address, enum subtype typesub) strcmp(dp->d_name, "..") == 0) continue; - rfd = openat_locked(fd, dp->d_name, O_RDONLY, 0644); + rfd = openat(fd, dp->d_name, O_RDONLY, 0644); if (rfd == -1) continue; + if (!lock(rfd, false)) + continue; if (fstat(rfd, &st) == -1) { log_err("Impossible to determine the size of %s/%s: %s", @@ -255,9 +257,9 @@ unsubscribe(int listfd, const char *address, enum subtype typesub) } xasprintf(&wrname, "%s.new", dp->d_name); - wfd = openat_locked(fd, wrname, O_RDWR|O_CREAT|O_TRUNC, + wfd = openat(fd, wrname, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|groupwritable); - if (wfd == -1) { + if (wfd == -1 && !lock(wfd, true)) { log_err("Could not open '%s/%s': %s", subdir, wrname, strerror(errno)); munmap(start, st.st_size); diff --git a/src/utils.c b/src/utils.c index cab6f7bb..6b0677a4 100644 --- a/src/utils.c +++ b/src/utils.c @@ -20,6 +20,7 @@ * IN THE SOFTWARE. */ +#include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include "xmalloc.h" @@ -179,3 +181,25 @@ exec_and_wait(const char *arg, ...) return (WEXITSTATUS(pstat)); } + +bool +lock(int fd, bool wr) +{ + struct flock lck; + int r; + + if (fd == -1) + return (false); + lck.l_type = wr ? F_WRLCK : F_RDLCK; + lck.l_whence = SEEK_SET; + lck.l_start = 0; + lck.l_len = 0; + do { + r = fcntl(fd, F_SETLKW, &lck); + } while (r < 0 && errno != EINTR); + if (r == -1) { + close(fd); + return (false); + } + return (true); +}