From: Ian Jackson Date: Sat, 20 Aug 2022 10:39:52 +0000 (+0100) Subject: prefork-interp: locking: require same inode X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=8acd6705563dabfb61ec38bcdbf9339c68752254;p=chiark-utils.git prefork-interp: locking: require same inode Signed-off-by: Ian Jackson --- 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; }