code: plan9front

Download patch

ref: 9c1dff3fa9928dd66114f3899d8ede99fad2cd53
parent: 1473e5d437e12c7312a859bcdfc167284ca99a4e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jun 13 11:01:02 EDT 2015

lock: reopen lockfile after changing mode to make lock effective

lock is acquired on open/create when file has DMEXCL set in mode,
so we need to reopen the file after setting the bit with wstat.

--- a/sys/src/cmd/lock.c
+++ b/sys/src/cmd/lock.c
@@ -41,14 +41,12 @@
 static int
 openlock(char *lock)
 {
-	int lckfd;
+	int lckfd, didwstat = 0;
 	Dir *dir;
 
-	if (lockwait)
-		while ((lckfd = open(lock, ORDWR)) < 0)
-			sleep(1000);
-	else
-		lckfd = open(lock, ORDWR);
+Reopen:
+	while ((lckfd = open(lock, ORDWR)) < 0 && lockwait)
+		sleep(1000);
 	if (lckfd < 0)
 		sysfatal("can't open %s read/write: %r", lock);
 	dir = dirfstat(lckfd);
@@ -55,10 +53,16 @@
 	if (dir == nil)
 		sysfatal("can't fstat %s: %r", lock);
 	if (!(dir->mode & DMEXCL)) {
+		if(didwstat++)
+			sysfatal("exclusive bit does not stick for %s", lock);
 		dir->mode |= DMEXCL;
 		dir->qid.type |= QTEXCL;
 		if (dirfwstat(lckfd, dir) < 0)
 			sysfatal("can't make %s exclusive access: %r", lock);
+		/* reopen for lock to be effective */
+		free(dir);
+		close(lckfd);
+		goto Reopen;
 	}
 	free(dir);
 	return lckfd;