1 /* lock.c - universal locking routines */
3 static char ident[] = "@(#)$Id: lock.c,v 2.2 1990/04/05 15:32:41 sources Exp shettich $";
12 #include "../h/strings.h"
23 #include <sys/types.h>
30 #define NULLCP ((char *) 0)
34 #define rindex strrchr
42 char *lockldir = "/usr/spool/locks";
51 int lkopen (file, access)
59 return f_lkopen (file, access);
63 return b_lkopen (file, access);
69 static int b_lkopen (file, access)
80 if (stat (file, &st) == NOTOK)
82 lockname (curlock, tmplock, file, (int) st.st_dev, (int) st.st_ino);
85 switch (lockit (tmplock, curlock)) {
87 if ((i = open (file, access)) == NOTOK) {
89 (void) unlink (curlock);
96 if (stat (curlock, &st) == NOTOK) {
104 (void) time (&curtime);
105 if (curtime < st.st_ctime + 60L)
108 (void) unlink (curlock);
114 static int lockit (tmp, file)
120 if ((fd = creat (tmp, 0400)) == NOTOK)
124 fd = link (tmp, file);
127 return (fd != NOTOK ? OK : NOTOK);
132 static lockname (curlock, tmplock, file, dev, ino)
133 register char *curlock,
143 if ((cp = rindex (file, '/')) == NULL || *++cp == NULL)
145 if (lockldir == NULL || *lockldir == NULL) {
147 (void) sprintf (bp, "%.*s", cp - file, file);
152 (void) sprintf (bp, "%s/", lockldir);
159 (void) sprintf (bp, "%s.lock", cp);
163 (void) sprintf (bp, "LCK%05d.%05d", dev, ino);
168 if ((cp = rindex (curlock, '/')) == NULL || *++cp == NULL)
169 (void) strcpy (tmplock, ",LCK.XXXXXX");
171 (void) sprintf (tmplock, "%.*s,LCK.XXXXXX",
172 cp - curlock, curlock);
173 (void) unlink (mktemp (tmplock));
181 #include <sys/file.h>
183 #include <sys/fcntl.h>
186 static int f_lkopen (file, access)
194 for (i = 0; i < 5; i++) {
197 access &= ! O_APPEND; /* make sure we open at the beginning */
199 if ((fd = open (file, access | O_NDELAY)) == NOTOK)
202 if (flock (fd, LOCK_EX | LOCK_NB) != NOTOK)
205 if (lockf (fd, F_TLOCK, 0L) != NOTOK) {
206 /* see if we should be at the end */
207 if (j & O_APPEND) lseek (fd, 0L, L_XTND);
210 /* Fix errno - lockf screws it */
211 if (errno == EACCES) errno = EWOULDBLOCK;
229 int lkclose (fd, file)
233 char curlock[BUFSIZ];
244 lseek (fd, 0L, L_SET); /* make sure we unlock the whole thing */
245 lockf (fd, F_ULOCK, 0L);
251 if (fstat (fd, &st) != NOTOK) {
252 lockname (curlock, NULLCP, file, (int) st.st_dev, (int) st.st_ino);
253 (void) unlink (curlock);
264 FILE *lkfopen (file, mode)
271 if ((fd = lkopen (file, strcmp (mode, "r") ? 2 : 0)) == NOTOK)
274 if ((fp = fdopen (fd, mode)) == NULL) {
285 int lkfclose (fp, file)
289 char curlock[BUFSIZ];
299 flock (fileno(fp), LOCK_UN);
301 fseek (fp, 0L, 0); /* make sure we unlock the whole thing */
302 lockf (fileno(fp), F_ULOCK, 0L);
308 if (fstat (fileno (fp), &st) != NOTOK) {
309 lockname (curlock, NULLCP, file, (int) st.st_dev, (int) st.st_ino);
310 (void) unlink (curlock);
314 return (fclose (fp));
321 #define NSECS ((unsigned) 20)
329 #define NULLP ((struct lock *) 0)
331 static struct lock *l_top = NULLP;
341 register struct lock *lp;
344 (void) signal (SIGALRM, alrmser);
347 for (lp = l_top; lp; lp = lp -> l_next)
348 if (*(cp = lp -> l_lock) && (j = creat (cp, 0400)) != NOTOK)
351 (void) alarm (NSECS);
356 static timerON (lock, fd)
360 register struct lock *lp;
362 if ((lp = (struct lock *) malloc ((unsigned) (sizeof *lp))) == NULLP)
366 if ((lp -> l_lock = malloc ((unsigned) (strlen (lock) + 1))) == NULLCP) {
370 (void) strcpy (lp -> l_lock, lock);
371 lp -> l_next = NULLP;
374 lp -> l_next = l_top -> l_next;
376 (void) signal (SIGALRM, alrmser);/* perhaps SIGT{STP,TIN,TOU} */
377 (void) alarm (NSECS);
386 register struct lock *pp,
392 for (pp = lp = l_top; lp; pp = lp, lp = lp -> l_next)
393 if (lp -> l_fd == fd)
397 l_top = lp -> l_next;
399 pp -> l_next = lp -> l_next;
407 (void) alarm (NSECS);