diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2023-03-09 12:59:09 +0100 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2023-03-21 15:19:33 +0100 |
commit | aea3ca36135aeb74ea38e7538c710d92b37f479d (patch) | |
tree | ec315249081da1eda7f0bf2c59dd6cb740c06c72 /src/basic/lock-util.c | |
parent | 2415a0c7aa1801c6080ba1b8e8d584d5eb0a8c01 (diff) | |
download | systemd-aea3ca36135aeb74ea38e7538c710d92b37f479d.tar.gz |
lock-util: Add make_lock_file_at()
Diffstat (limited to 'src/basic/lock-util.c')
-rw-r--r-- | src/basic/lock-util.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/basic/lock-util.c b/src/basic/lock-util.c index 13e4c12237..46391bb5cc 100644 --- a/src/basic/lock-util.c +++ b/src/basic/lock-util.c @@ -15,17 +15,25 @@ #include "missing_fcntl.h" #include "path-util.h" -int make_lock_file(const char *p, int operation, LockFile *ret) { - _cleanup_close_ int fd = -EBADF; +int make_lock_file_at(int dir_fd, const char *p, int operation, LockFile *ret) { + _cleanup_close_ int fd = -EBADF, dfd = -EBADF; _cleanup_free_ char *t = NULL; int r; + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(p); assert(IN_SET(operation & ~LOCK_NB, LOCK_EX, LOCK_SH)); assert(ret); + if (isempty(p)) + return -EINVAL; + /* We use UNPOSIX locks as they have nice semantics, and are mostly compatible with NFS. */ + dfd = fd_reopen(dir_fd, O_CLOEXEC|O_PATH|O_DIRECTORY); + if (dfd < 0) + return dfd; + t = strdup(p); if (!t) return -ENOMEM; @@ -33,7 +41,7 @@ int make_lock_file(const char *p, int operation, LockFile *ret) { for (;;) { struct stat st; - fd = open(p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600); + fd = openat(dfd, p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600); if (fd < 0) return -errno; @@ -54,6 +62,7 @@ int make_lock_file(const char *p, int operation, LockFile *ret) { } *ret = (LockFile) { + .dir_fd = TAKE_FD(dfd), .path = TAKE_PTR(t), .fd = TAKE_FD(fd), .operation = operation, @@ -100,11 +109,12 @@ void release_lock_file(LockFile *f) { f->operation = LOCK_EX|LOCK_NB; if ((f->operation & ~LOCK_NB) == LOCK_EX) - (void) unlink(f->path); + (void) unlinkat(f->dir_fd, f->path, 0); f->path = mfree(f->path); } + f->dir_fd = safe_close(f->dir_fd); f->fd = safe_close(f->fd); f->operation = 0; } |