]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/zotnet/mts/lock.c
1 /* lock.c - universal locking routines */
3 static char ident
[] = "@(#)$Id: lock.c,v 2.19 1993/08/25 17:33:09 jromine Exp $";
5 /* compile-time priority:
7 * FCNTL use if SYS5 defined and LOCKF not defined
8 * FLOCK use if BSD42 defined and LOCKF and SYS5 not defined
18 #include "../h/strings.h"
25 #else /* not MMDFONLY */
27 #endif /* not MMDFONLY */
29 #include <sys/types.h>
36 #include <sys/errno.h>
42 #include <sys/fcntl.h>
46 #if defined(_AIX) || defined(AUX)
51 #define u_short ushort
56 #if defined(SYS5) && !defined(_AIX)
58 #define rindex strrchr
61 #define FLOCK /* LOCKF will override this, if defined */
68 char *lockldir
= "/usr/spool/locks";
69 #endif /* not MMDFONLY */
72 static int b_lkopen(), lockit(), f_lkopen();
73 static lockname(), timerON(), timerOFF();
79 int lkopen (file
, access
)
86 #if defined (FLOCK) || defined(LOCKF) || defined(FCNTL)
87 return f_lkopen (file
, access
);
91 return b_lkopen (file
, access
);
97 static int b_lkopen (file
, access
)
104 char curlock
[BUFSIZ
],
108 if (stat (file
, &st
) == NOTOK
)
110 lockname (curlock
, tmplock
, file
, (int) st
.st_dev
, (int) st
.st_ino
);
113 switch (lockit (tmplock
, curlock
)) {
115 if ((i
= open (file
, access
)) == NOTOK
) {
117 (void) unlink (curlock
);
120 timerON (curlock
, i
);
124 if (stat (curlock
, &st
) == NOTOK
) {
132 (void) time (&curtime
);
133 if (curtime
< st
.st_ctime
+ 60L)
136 (void) unlink (curlock
);
142 static int lockit (tmp
, file
)
148 if ((fd
= creat (tmp
, 0400)) == NOTOK
)
150 #if defined(hpux) || defined(ncr)
151 write(fd
, "MH lock\n",8);
155 fd
= link (tmp
, file
);
158 return (fd
!= NOTOK
? OK
: NOTOK
);
163 static lockname (curlock
, tmplock
, file
, dev
, ino
)
164 register char *curlock
,
174 if ((cp
= rindex (file
, '/')) == NULL
|| *++cp
== 0)
176 if (lockldir
== NULL
|| *lockldir
== 0) {
178 (void) sprintf (bp
, "%.*s", cp
- file
, file
);
183 (void) sprintf (bp
, "%s/", lockldir
);
190 (void) sprintf (bp
, "%s.lock", cp
);
194 (void) sprintf (bp
, "LCK%05d.%05d", dev
, ino
);
199 if ((cp
= rindex (curlock
, '/')) == NULL
|| *++cp
== 0)
200 (void) strcpy (tmplock
, ",LCK.XXXXXX");
202 (void) sprintf (tmplock
, "%.*s,LCK.XXXXXX",
203 cp
- curlock
, curlock
);
204 (void) unlink (mktemp (tmplock
));
210 #if defined(FLOCK) || defined(LOCKF) || defined(FCNTL)
212 #if defined(BSD42) || defined(SVR4)
213 #include <sys/file.h>
214 #if defined(SUN40) || defined(SVR4)
215 #include <sys/fcntl.h>
223 static int f_lkopen (file
, access
)
234 for (i
= 0; i
< 5; i
++) {
235 #if defined(LOCKF) || defined(FCNTL)
237 access
&= ~O_APPEND
; /* make sure we open at the beginning */
238 if ((access
& 03) == O_RDONLY
) {
239 /* We MUST have write permission or lockf/fcntl() won't work */
244 #endif /* LOCKF || FCNTL */
245 if ((fd
= open (file
, access
| O_NDELAY
)) == NOTOK
)
250 /* should be an error? */
252 buf
.l_type
= F_WRLCK
;
256 if (fcntl (fd
, F_SETLK
, &buf
) != NOTOK
)
260 if (flock (fd
, LOCK_EX
| LOCK_NB
) != NOTOK
)
264 if (lockf (fd
, F_TLOCK
, 0L) != NOTOK
) {
265 /* see if we should be at the end */
268 lseek (fd
, (off_t
)0, SEEK_END
);
270 lseek (fd
, (off_t
)0, L_XTND
);
274 /* Fix errno - lockf screws it */
288 #endif /* FLOCK || LOCKF || FCNTL */
294 int lkclose (fd
, file
)
298 char curlock
[BUFSIZ
];
311 /* should be an error? */
313 buf
.l_type
= F_UNLCK
;
317 fcntl(fd
, F_SETLK
, &buf
);
325 lseek (fd
, (off_t
)0, L_SET
); /* make sure we unlock the whole thing */
326 lockf (fd
, F_ULOCK
, 0L);
331 if (fstat (fd
, &st
) != NOTOK
) {
332 lockname (curlock
, NULLCP
, file
, (int) st
.st_dev
, (int) st
.st_ino
);
333 (void) unlink (curlock
);
344 FILE *lkfopen (file
, mode
)
351 if ((fd
= lkopen (file
, strcmp (mode
, "r") ? 2 : 0)) == NOTOK
)
354 if ((fp
= fdopen (fd
, mode
)) == NULL
) {
365 int lkfclose (fp
, file
)
369 char curlock
[BUFSIZ
];
383 /* should be an error? */
385 buf
.l_type
= F_UNLCK
;
389 fcntl(fileno(fp
), F_SETLK
, &buf
);
393 flock (fileno(fp
), LOCK_UN
);
397 fseek (fp
, 0L, 0); /* make sure we unlock the whole thing */
398 lockf (fileno(fp
), F_ULOCK
, 0L);
403 if (fstat (fileno (fp
), &st
) != NOTOK
) {
404 lockname (curlock
, NULLCP
, file
, (int) st
.st_dev
, (int) st
.st_ino
);
405 (void) unlink (curlock
);
409 return (fclose (fp
));
416 #define NSECS ((unsigned) 20)
424 #define NULLP ((struct lock *) 0)
426 static struct lock
*l_top
= NULLP
;
431 static TYPESIG
alrmser (sig
)
436 register struct lock
*lp
;
439 (void) signal (SIGALRM
, alrmser
);
442 for (lp
= l_top
; lp
; lp
= lp
-> l_next
)
443 if (*(cp
= lp
-> l_lock
) && (j
= creat (cp
, 0400)) != NOTOK
)
446 (void) alarm (NSECS
);
451 static timerON (lock
, fd
)
455 register struct lock
*lp
;
457 if ((lp
= (struct lock
*) malloc ((unsigned) (sizeof *lp
))) == NULLP
)
461 if ((lp
-> l_lock
= malloc ((unsigned) (strlen (lock
) + 1))) == NULLCP
) {
465 (void) strcpy (lp
-> l_lock
, lock
);
466 lp
-> l_next
= NULLP
;
469 lp
-> l_next
= l_top
-> l_next
;
471 (void) signal (SIGALRM
, alrmser
);/* perhaps SIGT{STP,TIN,TOU} */
472 (void) alarm (NSECS
);
481 register struct lock
*pp
,
487 for (pp
= lp
= l_top
; lp
; pp
= lp
, lp
= lp
-> l_next
)
488 if (lp
-> l_fd
== fd
)
492 l_top
= lp
-> l_next
;
494 pp
-> l_next
= lp
-> l_next
;
502 (void) alarm (NSECS
);