10 date 90.04.05.15.32.41; author sources; state Exp;
15 date 90.04.05.14.50.19; author sources; state Exp;
20 date 89.11.17.15.57.47; author sources; state Exp;
25 date 89.11.17.15.49.06; author sources; state Exp;
39 @/* lock.c - universal locking routines */
41 static char ident[] = "@@(#)$Id:$";
50 #include "../h/strings.h"
61 #include <sys/types.h>
68 #define NULLCP ((char *) 0)
72 #define rindex strrchr
80 char *lockldir = "/usr/spool/locks";
89 int lkopen (file, access)
97 return f_lkopen (file, access);
101 return b_lkopen (file, access);
107 static int b_lkopen (file, access)
114 char curlock[BUFSIZ],
118 if (stat (file, &st) == NOTOK)
120 lockname (curlock, tmplock, file, (int) st.st_dev, (int) st.st_ino);
123 switch (lockit (tmplock, curlock)) {
125 if ((i = open (file, access)) == NOTOK) {
127 (void) unlink (curlock);
130 timerON (curlock, i);
134 if (stat (curlock, &st) == NOTOK) {
142 (void) time (&curtime);
143 if (curtime < st.st_ctime + 60L)
146 (void) unlink (curlock);
152 static int lockit (tmp, file)
158 if ((fd = creat (tmp, 0400)) == NOTOK)
162 fd = link (tmp, file);
165 return (fd != NOTOK ? OK : NOTOK);
170 static lockname (curlock, tmplock, file, dev, ino)
171 register char *curlock,
181 if ((cp = rindex (file, '/')) == NULL || *++cp == NULL)
183 if (lockldir == NULL || *lockldir == NULL) {
185 (void) sprintf (bp, "%.*s", cp - file, file);
190 (void) sprintf (bp, "%s/", lockldir);
197 (void) sprintf (bp, "%s.lock", cp);
201 (void) sprintf (bp, "LCK%05d.%05d", dev, ino);
206 if ((cp = rindex (curlock, '/')) == NULL || *++cp == NULL)
207 (void) strcpy (tmplock, ",LCK.XXXXXX");
209 (void) sprintf (tmplock, "%.*s,LCK.XXXXXX",
210 cp - curlock, curlock);
211 (void) unlink (mktemp (tmplock));
219 #include <sys/file.h>
221 #include <sys/fcntl.h>
224 static int f_lkopen (file, access)
232 for (i = 0; i < 5; i++) {
235 access &= ! O_APPEND; /* make sure we open at the beginning */
237 if ((fd = open (file, access | O_NDELAY)) == NOTOK)
240 if (flock (fd, LOCK_EX | LOCK_NB) != NOTOK)
243 if (lockf (fd, F_TLOCK, 0L) != NOTOK) {
244 /* see if we should be at the end */
245 if (j & O_APPEND) lseek (fd, 0L, L_XTND);
248 /* Fix errno - lockf screws it */
249 if (errno == EACCES) errno = EWOULDBLOCK;
267 int lkclose (fd, file)
271 char curlock[BUFSIZ];
282 lseek (fd, 0L, L_SET); /* make sure we unlock the whole thing */
283 lockf (fd, F_ULOCK, 0L);
289 if (fstat (fd, &st) != NOTOK) {
290 lockname (curlock, NULLCP, file, (int) st.st_dev, (int) st.st_ino);
291 (void) unlink (curlock);
302 FILE *lkfopen (file, mode)
309 if ((fd = lkopen (file, strcmp (mode, "r") ? 2 : 0)) == NOTOK)
312 if ((fp = fdopen (fd, mode)) == NULL) {
323 int lkfclose (fp, file)
327 char curlock[BUFSIZ];
337 flock (fileno(fp), LOCK_UN);
339 fseek (fp, 0L, 0); /* make sure we unlock the whole thing */
340 lockf (fileno(fp), F_ULOCK, 0L);
346 if (fstat (fileno (fp), &st) != NOTOK) {
347 lockname (curlock, NULLCP, file, (int) st.st_dev, (int) st.st_ino);
348 (void) unlink (curlock);
352 return (fclose (fp));
359 #define NSECS ((unsigned) 20)
367 #define NULLP ((struct lock *) 0)
369 static struct lock *l_top = NULLP;
379 register struct lock *lp;
382 (void) signal (SIGALRM, alrmser);
385 for (lp = l_top; lp; lp = lp -> l_next)
386 if (*(cp = lp -> l_lock) && (j = creat (cp, 0400)) != NOTOK)
389 (void) alarm (NSECS);
394 static timerON (lock, fd)
398 register struct lock *lp;
400 if ((lp = (struct lock *) malloc ((unsigned) (sizeof *lp))) == NULLP)
404 if ((lp -> l_lock = malloc ((unsigned) (strlen (lock) + 1))) == NULLCP) {
408 (void) strcpy (lp -> l_lock, lock);
409 lp -> l_next = NULLP;
412 lp -> l_next = l_top -> l_next;
414 (void) signal (SIGALRM, alrmser);/* perhaps SIGT{STP,TIN,TOU} */
415 (void) alarm (NSECS);
424 register struct lock *pp,
430 for (pp = lp = l_top; lp; pp = lp, lp = lp -> l_next)
431 if (lp -> l_fd == fd)
435 l_top = lp -> l_next;
437 pp -> l_next = lp -> l_next;
445 (void) alarm (NSECS);
457 static char ident[] = "$Id:";
463 @changes for SUN40 shared libraries and NNTP under bbc