1*32769Sbostic # include	"../hdr/macros.h"
2*32769Sbostic # include	"errno.h"
3*32769Sbostic SCCSID(@(#)lockit	2.1);
4*32769Sbostic /*
5*32769Sbostic 	Process semaphore.
6*32769Sbostic 	Try repeatedly (`count' times) to create `lockfile' mode 444.
7*32769Sbostic 	Sleep 10 seconds between tries.
8*32769Sbostic 	If `lockfile' is successfully created, write the process ID
9*32769Sbostic 	`pid' in `lockfile' (in binary), and return 0.
10*32769Sbostic 	If `lockfile' exists and it hasn't been modified within the last
11*32769Sbostic 	minute, and either the file is empty or the process ID contained
12*32769Sbostic 	in the file is not the process ID of any existing process,
13*32769Sbostic 	`lockfile' is removed and it tries again to make `lockfile'.
14*32769Sbostic 	After `count' tries, or if the reason for the create failing
15*32769Sbostic 	is something other than EACCES, return xmsg().
16*32769Sbostic 
17*32769Sbostic 	Unlockit will return 0 if the named lock exists, contains
18*32769Sbostic 	the given pid, and is successfully removed; -1 otherwise.
19*32769Sbostic */
20*32769Sbostic 
21*32769Sbostic 
22*32769Sbostic lockit(lockfile,count,pid)
23*32769Sbostic register char *lockfile;
24*32769Sbostic register unsigned count;
25*32769Sbostic unsigned pid;
26*32769Sbostic {
27*32769Sbostic 	register int fd;
28*32769Sbostic 	unsigned opid;
29*32769Sbostic 	long ltime;
30*32769Sbostic 	extern int errno;
31*32769Sbostic 
32*32769Sbostic 	for (++count; --count; sleep(10)) {
33*32769Sbostic 		if ((fd=creat(lockfile,0444)) >= 0) {
34*32769Sbostic 			write(fd,&pid,sizeof(pid));
35*32769Sbostic 			close(fd);
36*32769Sbostic 			return(0);
37*32769Sbostic 		}
38*32769Sbostic 		if (errno == ENFILE) {
39*32769Sbostic 			unlink(lockfile);
40*32769Sbostic 			++count;
41*32769Sbostic 			continue;
42*32769Sbostic 		}
43*32769Sbostic 		if (errno != EACCES)
44*32769Sbostic 			return(xmsg(lockfile,"lockit"));
45*32769Sbostic 		if (exists(lockfile)) {
46*32769Sbostic 			time(&ltime);
47*32769Sbostic 			ltime =- Statbuf.st_mtime;
48*32769Sbostic 			if ((fd = open(lockfile,0)) < 0)
49*32769Sbostic 				continue;
50*32769Sbostic 			if (ltime < 60L)
51*32769Sbostic 				sleep(60);
52*32769Sbostic 			if (read(fd,&opid,sizeof(opid)) != sizeof(opid)) {
53*32769Sbostic 				close(fd);
54*32769Sbostic 				unlink(lockfile);
55*32769Sbostic 				continue;
56*32769Sbostic 			}
57*32769Sbostic 			close(fd);
58*32769Sbostic 			if (kill(opid,0) == -1 && errno == ESRCH) {
59*32769Sbostic 				unlink(lockfile);
60*32769Sbostic 				continue;
61*32769Sbostic 			}
62*32769Sbostic 		}
63*32769Sbostic 	}
64*32769Sbostic 	return(-1);
65*32769Sbostic }
66*32769Sbostic 
67*32769Sbostic 
68*32769Sbostic unlockit(lockfile,pid)
69*32769Sbostic register char *lockfile;
70*32769Sbostic unsigned pid;
71*32769Sbostic {
72*32769Sbostic 	register int fd, n;
73*32769Sbostic 	unsigned opid;
74*32769Sbostic 
75*32769Sbostic 	if ((fd = open(lockfile,0)) < 0)
76*32769Sbostic 		return(-1);
77*32769Sbostic 	n = read(fd,&opid,sizeof(opid));
78*32769Sbostic 	close(fd);
79*32769Sbostic 	if (n == sizeof(opid) && opid == pid)
80*32769Sbostic 		return(unlink(lockfile));
81*32769Sbostic 	else
82*32769Sbostic 		return(-1);
83*32769Sbostic }
84