home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume15
/
lp-onionskin
/
lock.c
next >
Wrap
C/C++ Source or Header
|
1988-05-24
|
3KB
|
138 lines
#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);
}