132769Sbostic # include	"../hdr/macros.h"
232769Sbostic # include	"errno.h"
332769Sbostic SCCSID(@(#)lockit	2.1);
432769Sbostic /*
532769Sbostic 	Process semaphore.
632769Sbostic 	Try repeatedly (`count' times) to create `lockfile' mode 444.
732769Sbostic 	Sleep 10 seconds between tries.
832769Sbostic 	If `lockfile' is successfully created, write the process ID
932769Sbostic 	`pid' in `lockfile' (in binary), and return 0.
1032769Sbostic 	If `lockfile' exists and it hasn't been modified within the last
1132769Sbostic 	minute, and either the file is empty or the process ID contained
1232769Sbostic 	in the file is not the process ID of any existing process,
1332769Sbostic 	`lockfile' is removed and it tries again to make `lockfile'.
1432769Sbostic 	After `count' tries, or if the reason for the create failing
1532769Sbostic 	is something other than EACCES, return xmsg().
1632769Sbostic 
1732769Sbostic 	Unlockit will return 0 if the named lock exists, contains
1832769Sbostic 	the given pid, and is successfully removed; -1 otherwise.
1932769Sbostic */
2032769Sbostic 
2132769Sbostic 
lockit(lockfile,count,pid)2232769Sbostic lockit(lockfile,count,pid)
2332769Sbostic register char *lockfile;
2432769Sbostic register unsigned count;
2532769Sbostic unsigned pid;
2632769Sbostic {
2732769Sbostic 	register int fd;
2832769Sbostic 	unsigned opid;
2932769Sbostic 	long ltime;
3032769Sbostic 	extern int errno;
3132769Sbostic 
3232769Sbostic 	for (++count; --count; sleep(10)) {
3332769Sbostic 		if ((fd=creat(lockfile,0444)) >= 0) {
3432769Sbostic 			write(fd,&pid,sizeof(pid));
3532769Sbostic 			close(fd);
3632769Sbostic 			return(0);
3732769Sbostic 		}
3832769Sbostic 		if (errno == ENFILE) {
3932769Sbostic 			unlink(lockfile);
4032769Sbostic 			++count;
4132769Sbostic 			continue;
4232769Sbostic 		}
4332769Sbostic 		if (errno != EACCES)
4432769Sbostic 			return(xmsg(lockfile,"lockit"));
4532769Sbostic 		if (exists(lockfile)) {
4632769Sbostic 			time(&ltime);
47*32770Sbostic 			ltime -= Statbuf.st_mtime;
4832769Sbostic 			if ((fd = open(lockfile,0)) < 0)
4932769Sbostic 				continue;
5032769Sbostic 			if (ltime < 60L)
5132769Sbostic 				sleep(60);
5232769Sbostic 			if (read(fd,&opid,sizeof(opid)) != sizeof(opid)) {
5332769Sbostic 				close(fd);
5432769Sbostic 				unlink(lockfile);
5532769Sbostic 				continue;
5632769Sbostic 			}
5732769Sbostic 			close(fd);
5832769Sbostic 			if (kill(opid,0) == -1 && errno == ESRCH) {
5932769Sbostic 				unlink(lockfile);
6032769Sbostic 				continue;
6132769Sbostic 			}
6232769Sbostic 		}
6332769Sbostic 	}
6432769Sbostic 	return(-1);
6532769Sbostic }
6632769Sbostic 
6732769Sbostic 
unlockit(lockfile,pid)6832769Sbostic unlockit(lockfile,pid)
6932769Sbostic register char *lockfile;
7032769Sbostic unsigned pid;
7132769Sbostic {
7232769Sbostic 	register int fd, n;
7332769Sbostic 	unsigned opid;
7432769Sbostic 
7532769Sbostic 	if ((fd = open(lockfile,0)) < 0)
7632769Sbostic 		return(-1);
7732769Sbostic 	n = read(fd,&opid,sizeof(opid));
7832769Sbostic 	close(fd);
7932769Sbostic 	if (n == sizeof(opid) && opid == pid)
8032769Sbostic 		return(unlink(lockfile));
8132769Sbostic 	else
8232769Sbostic 		return(-1);
8332769Sbostic }
84