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;
}