2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * Copyright (c) 1983 Regents of the University of California.
8 * All rights reserved. The Berkeley software License Agreement
9 * specifies the terms and conditions for redistribution.
12 #pragma ident "%Z%%M% %I% %E% SMI"
15 * defs that come from uucp.h
20 #define SLCKTIME (8*60*60) /* device timeout (LCK.. files) in seconds */
22 #define ASSERT(e, f, v) if (!(e)) {\
23 (void) fprintf(stderr, "AERROR - (%s) ", #e); \
24 (void) fprintf(stderr, f, v); \
28 #define ASSERT(e, f, v) if (!(e)) {\
29 (void) fprintf(stderr, "AERROR - (%s) ", "e"); \
30 (void) fprintf(stderr, f, v); \
34 #define SIZEOFPID 10 /* maximum number of digits in a pid */
36 #define LOCKDIR "/var/spool/locks"
40 * This code is taken almost directly from uucp and follows the same
41 * conventions. This is important since uucp and tip should
42 * respect each others locks.
45 #include <sys/types.h>
47 #include <sys/mkdev.h>
58 static void stlock(char *);
59 static int onelock(char *, char *, char *);
60 static int checkLock(char *);
62 extern void finish(int);
69 * ulockf - this routine will create a lock file (file).
70 * If one already exists, send a signal 0 to the process--if
71 * it fails, then unlink it and make a new one.
74 * file - name of the lock file
75 * atime - is unused, but we keep it for lint compatibility
78 * return codes: 0 | FAIL
82 ulockf(char *file
, time_t atime
)
84 static char pid
[SIZEOFPID
+2] = { '\0' }; /* +2 for '\n' and NULL */
85 static char tempfile
[NAMESIZE
];
88 (void) snprintf(pid
, sizeof (pid
), "%*d\n", SIZEOFPID
,
90 (void) snprintf(tempfile
, sizeof (tempfile
),
91 "%s/LTMP.%d", LOCKDIR
, getpid());
93 if (onelock(pid
, tempfile
, file
) == -1) {
94 /* lock file exists */
95 (void) unlink(tempfile
);
99 if (onelock(pid
, tempfile
, file
)) {
100 (void) unlink(tempfile
);
110 * check to see if the lock file exists and is still active
111 * - use kill(pid, 0) - (this only works on ATTSV and some hacked
112 * BSD systems at this time)
114 * 0 -> success (lock file removed - no longer active)
115 * FAIL -> lock file still active
118 checkLock(char *file
)
122 char alpid
[SIZEOFPID
+2]; /* +2 for '\n' and NULL */
127 if (errno
== ENOENT
) /* file does not exist -- OK */
131 ret
= read(fd
, (char *)alpid
, SIZEOFPID
+1); /* +1 for '\n' */
133 if (ret
!= (SIZEOFPID
+1))
136 if ((ret
= kill(lpid
, 0)) == 0 || errno
== EPERM
)
140 if (unlink(file
) != 0)
145 #define MAXLOCKS 10 /* maximum number of lock files */
146 char *Lockfile
[MAXLOCKS
];
150 * stlock(name) put name in list of lock files
162 for (i
= 0; i
< Nlocks
; i
++) {
163 if (Lockfile
[i
] == NULL
)
166 ASSERT(i
< MAXLOCKS
, "TOO MANY LOCKS %d", i
);
169 p
= calloc(strlen(name
) + 1, sizeof (char));
170 ASSERT(p
!= NULL
, "CAN NOT ALLOCATE FOR %s", name
);
171 (void) strcpy(p
, name
);
176 * rmlock(name) remove all lock files in list
177 * char *name; or name
187 for (i
= 0; i
< Nlocks
; i
++) {
188 if (Lockfile
[i
] == NULL
)
190 if (name
== NULL
|| strcmp(name
, Lockfile
[i
]) == SAME
) {
191 (void) unlink(Lockfile
[i
]);
199 onelock(char *pid
, char *tempfile
, char *name
)
202 static int first
= 1;
204 fd
= creat(tempfile
, 0444);
207 if (errno
== EACCES
) {
208 (void) fprintf(stderr
,
209 "tip: can't create files in lock file directory %s\n",
211 } else if (access(LOCKDIR
, 0) < 0) {
212 (void) fprintf(stderr
,
213 "tip: lock file directory %s: ",
219 if (errno
== EMFILE
|| errno
== ENFILE
)
220 (void) unlink(tempfile
);
224 if (write(fd
, pid
, SIZEOFPID
+1) != (SIZEOFPID
+1)) {
225 (void) fprintf(stderr
,
226 "tip: can't write to files in lock file directory %s: %s\n",
227 LOCKDIR
, strerror(errno
));
228 (void) unlink(tempfile
);
231 (void) fchmod(fd
, 0444);
233 if (link(tempfile
, name
) < 0) {
234 (void) unlink(tempfile
);
237 (void) unlink(tempfile
);
242 * delock(sys) remove a lock file
250 char lname
[NAMESIZE
];
252 if (stat(sys
, &sb
) < 0)
254 (void) snprintf(lname
, sizeof (lname
), "%s/%s.%3.3lu.%3.3lu.%3.3lu",
256 (unsigned long)major(sb
.st_dev
),
257 (unsigned long)major(sb
.st_rdev
),
258 (unsigned long)minor(sb
.st_rdev
));
263 * tip_mlock(sys) create system lock
266 * return codes: 0 | FAIL
273 char lname
[NAMESIZE
];
275 if (stat(sys
, &sb
) < 0)
277 (void) snprintf(lname
, sizeof (lname
), "%s/%s.%3.3lu.%3.3lu.%3.3lu",
279 (unsigned long)major(sb
.st_dev
),
280 (unsigned long)major(sb
.st_rdev
),
281 (unsigned long)minor(sb
.st_rdev
));
282 return (ulockf(lname
, (time_t)SLCKTIME
) < 0 ? FAIL
: 0);