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(<ime);
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