From 8acd6705563dabfb61ec38bcdbf9339c68752254 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 20 Aug 2022 11:39:52 +0100 Subject: [PATCH] prefork-interp: locking: require same inode Signed-off-by: Ian Jackson --- cprogs/prefork.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/cprogs/prefork.c b/cprogs/prefork.c index 5c1d5bf..21c4b7a 100644 --- a/cprogs/prefork.c +++ b/cprogs/prefork.c @@ -187,14 +187,31 @@ void find_socket_path(void) { int acquire_lock(void) { int r; int lockfd = -1; + struct stat stab_fd; + struct stat stab_path; lock_path = m_asprintf("%s/l%s",run_base,ident); - lockfd = open(lock_path, O_CREAT|O_RDWR, 0600); - if (lockfd<0) diee("create lock (%s)", lock_path); + for (;;) { + if (lockfd >= 0) { close(lockfd); lockfd = -1; } - r = flock(lockfd, LOCK_EX); - if (r) diee("lock lock (%s)", lock_path); + lockfd = open(lock_path, O_CREAT|O_RDWR, 0600); + if (lockfd<0) diee("create lock (%s)", lock_path); + + r = flock(lockfd, LOCK_EX); + if (r && errno == EINTR) continue; + if (r) diee("lock lock (%s)", lock_path); + + r = fstat(lockfd, &stab_fd); + if (r) diee("fstat locked lock"); + + r = stat(lock_path, &stab_path); + if (!r) { + if (stabs_same_inode(&stab_path, &stab_fd)) break; + } else { + if (!(errno == ENOENT)) diee("re-stat locked lock (%s)", lock_path); + } + } return lockfd; } -- 2.30.2