[net.unix-wizards] mutual exclusion between processes

jwp (01/05/83)

Randy Bentson (csu-cs!bentson) points out, correctly, that using
"creat(LOCKFILE, 0)" fails to guarantee exclusion since the 'creat' works
for the superuser even if LOCKFILE already exists and has mode 0.

The following does not have that problem:

	myfile = mktemp(TEMPLATE);	/* mktemp() guarantees a unique */
					/* file name for each invocation */
					/* of the program */
	creat(myfile, ANYDESIREDMODE);

	if(link(myfile, LOCKFILE) == 0)	/* LOCKFILE is a name known by */
		{			/* all invocations of the program. */
		<whatever>		/* The link will fail if LOCKFILE */
		unlink(LOCKFILE);	/* exists even if the process is */
		}			/* being run with uid == 0. */
	else
		{
		<other whatever>
		}
	unlink(myfile);

I use this in a variety of places, one of them being a sort of general
purpose "spool stuff up for this device/file" program where the alogrithm
is essentially:

	Get temporary file name
	Copy input to the temporary file name
	Try to link temporary file name to lockfile name
	If the link succeeds, start daemon and exit
	If the link fails, exit (the daemon is already running)

			John Pierce, Chemistry, UC San Diego
			{ucbvax, philabs}!sdcsvax!sdchema!jwp

plw (01/07/83)

	Using 'access(LOCKFILE, 0)' also works, especially well for root
because root would not be denied search permission in any directory component
of the path 'LOCKFILE'.

CHUQUI@MIT-MC (03/05/83)

From:  Charles F. Von Rospach <CHUQUI @ MIT-MC>

That works fine, unless the Daemon runs setuid root, which I was doing
with lpd for a while. Anytime something runs setuid root, locking is going
to have a problem. What I ended up doing was install the MKTEMP and LINK, 
and have lpd setuid to run under an account called 'daemon' with group 1,
uid 1.

chuck

guy (03/31/83)

USG UNIX (and, I believe, 4.2BSD)has a cute trick for this; if you do an "open"
with the O_CREAT and O_EXCL bits on in the second argument (note; you can do
a create and have the resulting descriptor open for writing *and* reading -
it's about time!), if the file already exists an EEXIST error will be returned,
and the file will be untouched - even if you are the super-user.

					Guy Harris
					RLG Corporation
					{seismo,mcnc,we13}!rlgvax!guy