home *** CD-ROM | disk | FTP | other *** search
- /*
- * lock.c -- deal with file locking on various architectures and UNIXs.
- * dot_lock() creates a file with the same name as the parameter passed
- * with the appendage ".lock" -- this is to be compatible with certain
- * systems that don't use flock or lockf or whatever they have available
- * that they don't use.
- */
-
- #ifdef USG
- #include <unistd.h>
- #endif /* USG */
- #include "mush.h"
- #if defined(SYSV) && !defined(USG)
- #include <sys/locking.h>
- #endif /* SYSV && !USG */
-
- #ifdef DOT_LOCK
- extern int sgid;
- #ifdef BSD
- extern int rgid;
- #endif /* BSD */
-
- dot_lock(filename)
- char *filename;
- {
- char buf[MAXPATHLEN];
- int lockfd, cnt = 0;
- SIGRET (*oldint)(), (*oldquit)();
-
- #ifdef SYSV
- /* Only the spoolfile needs to be dot_locked -- other files are
- * handled by lock_fopen, below. To avoid collisions with 14-char
- * file name limits, we allow dot_locking ONLY of the spoolfile.
- */
- if (strcmp(spoolfile, filename) != 0)
- return 0;
- #endif
- #ifdef BSD
- setregid(rgid, sgid);
- #else /* BSD */
- setgid(sgid);
- #endif /* BSD */
- #ifdef M_XENIX
- (void) sprintf(buf, "/tmp/%.10s.mlk", login);
- #else /* M_XENIX */
- (void) sprintf(buf, "%s.lock", filename);
- #endif /* M_XENIX */
- on_intr();
- while ((lockfd = open(buf, O_CREAT|O_WRONLY|O_EXCL, 0444)) == -1) {
- if (errno != EEXIST) {
- error("unable to lock %s", filename);
- break;
- }
- if (cnt++ == 0)
- print("%s already locked, waiting", filename);
- else
- print_more(".");
- sleep(1);
- if (ison(glob_flags, WAS_INTR)) {
- print_more("\nAborted.\n");
- break;
- }
- }
- off_intr();
- if (lockfd != -1) {
- if (cnt)
- print("done.\n");
- (void) close(lockfd);
- }
- #ifdef BSD
- setregid(sgid, rgid);
- #else
- setgid(getgid());
- #endif /* BSD */
- return lockfd == -1? -1 : 0;
- }
- #endif /* DOT_LOCK */
-
- #ifdef SYSV
-
- /*
- * Define some BSD names for the SYSV world
- */
- #ifdef USG
- #define LOCK_SH F_RDLCK
- #define LOCK_EX F_WRLCK
- #define LOCK_UN F_UNLCK
- #else /* USG */
- #define LOCK_SH LK_LOCK
- #define LOCK_EX LK_LOCK
- #define LOCK_UN LK_UNLCK
- #endif /* USG */
- #define LOCK_NB 0 /* Always non-blocking in this case */
-
- #ifdef HPUX
- #undef EWOULDBLOCK
- #endif /* HPUX */
- #define EWOULDBLOCK EAGAIN
-
- flock(fd, op)
- int fd, op;
- {
- #ifndef USG
- (void) locking(fd, op, 0); /* old xenix (sys III) */
- return 0;
- #else
- struct flock l;
-
- l.l_len = 0L;
- l.l_start = 0L;
- l.l_whence = 1;
- l.l_type = op;
-
- return fcntl(fd, F_SETLK, &l);
- #endif /* USG */
- }
-
- #endif /* SYSV */
-
- FILE *
- lock_fopen(filename, mode)
- char *filename;
- char *mode;
- {
- FILE *mail_fp = NULL_FILE;
- #ifndef LCKDFLDIR
- int fd, lk;
- int cnt = 0;
- SIGRET (*oldint)(), (*oldquit)();
- #else /* LCKDFLDIR */
- extern FILE *lk_fopen();
- #endif /* !LCKDFLDIR */
-
- if (debug && do_set(set_options, "deadlock")) {
- (void) un_set(&set_options, "deadlock");
- return NULL_FILE;
- }
-
- #ifdef LCKDFLDIR
- return lk_fopen(filename, mode, NULL, NULL, 0);
- #else /* !LCKDFLDIR */
-
- #ifdef DOT_LOCK
- if (dot_lock(filename) == 0)
- #endif /* DOT_LOCK */
- mail_fp = mask_fopen(filename, mode);
- if (!mail_fp)
- return NULL_FILE;
- fd = fileno(mail_fp);
-
- if (mode[0] != 'r' || mode[1] == '+')
- lk = LOCK_EX | LOCK_NB;
- else
- lk = LOCK_SH | LOCK_NB;
-
- on_intr();
- while (isoff(glob_flags, WAS_INTR) && flock(fd, lk)) {
- if (errno == EWOULDBLOCK) {
- if (isoff(glob_flags, REDIRECT))
- if (!cnt++)
- print("\nwaiting to lock");
- else
- print(".");
- } else {
- error("Unable to lock \"%s\"", filename);
- (void) fclose(mail_fp);
- off_intr();
- return NULL_FILE;
- }
- (void) fflush(stdout);
- sleep(1);
- }
- if (cnt)
- print("\n");
- cnt = (ison(glob_flags, WAS_INTR) != 0);
- off_intr();
- if (cnt) {
- (void) fclose(mail_fp);
- return NULL_FILE;
- }
- return mail_fp;
- #endif /* LCKDFLDIR */
- }
-
- /*ARGSUSED*/
- close_lock(filename, fp)
- char *filename;
- FILE *fp;
- #ifdef LCKDFLDIR
- {
- return lk_fclose(fp, filename, NULL, NULL);
- }
- #else /* !LCKDFLDIR */
- {
- #ifdef DOT_LOCK
- char buf[MAXPATHLEN];
- #endif /* DOT_LOCK */
-
- fflush(fp);
- #ifdef DOT_LOCK
- #ifdef BSD
- setregid(rgid, sgid);
- #else
- setgid(sgid);
- #endif /* BSD */
- #ifdef SYSV
- if (strcmp(spoolfile, filename) == 0)
- #endif /* SYSV */
- #ifdef M_XENIX
- (void) unlink(sprintf(buf, "/tmp/%.10s.mlk", login));
- #else /* M_XENIX */
- (void) unlink(sprintf(buf, "%s.lock", filename));
- #endif /* M_XENIX */
- #ifdef BSD
- setregid(sgid, rgid);
- #else
- setgid(getgid());
- #endif /* BSD */
- #endif /* DOT_LOCK */
-
- (void) flock(fileno(fp), LOCK_UN);
- return fclose(fp);
- }
- #endif /* LCKDFLDIR */
-