home *** CD-ROM | disk | FTP | other *** search
- #ifndef LINT
- static char SccsId[] = "@(#)lock.c 1.1 U of T Physics 12/15/87";
- #endif
-
- /*
- * Standard lp creates lockfiles to suspend a second request.
- * This leaves a small window of vulnerability if 2 users
- * are using the program at one time.
- *
- * This file contains:
- * lockproc() - which locks so other user can use
- * the program.
- * unlockproc() - which unlocks for other users.
- *
- * It uses the semaphore facility and is highly system dependent.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <errno.h>
-
- /*
- * The following are the way to get a key out of ftok()
- */
- #define PATH "/usr/bin/real_lp"
- #define ID 'a'
-
- #define UNLOCK (1)
- #define LOCK (-1) /* impossible, so will lock */
-
- #define MODE (0666) /* rw by the world */
-
- /*
- * If the owner removes the facility while a 2nd process is
- * waiting to lock it, the second process will receive an
- * error from semop(2). Thus, we try TRIES times to lock
- * the process.
- */
- #define TRIES 5
-
- #define YES 1
- #define NO 0
-
- static int sid; /* semaphore id number */
- static short creator; /* == YES if this process created */
-
- extern char *progname;
-
- lockproc()
- {
- int sem_flg, numbad;
- key_t key, ftok();
- struct sembuf sb;
-
- numbad = 0;
-
- retry:
-
- if((key = ftok(PATH,ID)) == -1)
- Lock_Error("Cannot get ipc key");
-
-
- errno = 0;
- creator = NO;
-
- if(numbad >= TRIES) {
- if(creator == YES)
- semctl(sid, IPC_RMID, 0);
- Lock_Error("Lock error");
- }
-
- sem_flg = MODE | IPC_CREAT | IPC_EXCL;
-
- sid = semget(key, 1, sem_flg);
- if(sid == -1 && errno == EEXIST) {
- /*
- * In use by another user.
- */
- sem_flg = MODE;
- (void) fflush(stdout);
- sid = semget(key, 1, sem_flg);
- /* it will get here, but then block */
- } else {
- creator = YES;
- if(semctl(sid, 0, SETVAL, UNLOCK) == -1) {
- semctl(sid, 0, IPC_RMID, 0);
- Lock_Error("Cannot create semaphore");
- }
- }
-
- sb.sem_num = 0; /* 1st semaphore */
- sb.sem_op = LOCK; /* we are locking the semaphore */
- sb.sem_flg = SEM_UNDO; /* auto reverse */
-
- if (semop(sid, &sb, 1) == -1) {
- if( errno == EINTR || errno == EIDRM) {
- numbad++;
- goto retry;
- } else {
- Lock_Error("Cannot semop()");
- }
- }
- }
-
- unlockproc()
- {
- struct sembuf sb;
-
- if(creator == YES) {
- if(semctl(sid, IPC_RMID, 0) != 0) {
- Lock_Error("Cannot remove lock");
- }
- } else {
- sb.sem_num = 0;
- sb.sem_op = UNLOCK;
- sb.sem_flg = SEM_UNDO;
-
- if(semop(sid, &sb, 1) == -1)
- Lock_Error("Cannot unlock");
- }
- }
-
- Lock_Error(s)
- char *s;
- {
- void exit();
- extern char *progname;
-
- fprintf(stderr,"%s: please notify your system administrator\n",
- progname);
- fprintf(stderr,"that you received the following error message:\n");
- fprintf(stderr," ***** %s *****\n", s);
- fprintf(stderr,"Your print job has aborted.\n");
- exit(1);
- }
-