home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume15 / lp-onionskin / lock.c next >
C/C++ Source or Header  |  1988-05-24  |  3KB  |  138 lines

  1. #ifndef LINT
  2. static char SccsId[] = "@(#)lock.c    1.1 U of T Physics 12/15/87";
  3. #endif
  4.  
  5. /*
  6.  * Standard lp creates lockfiles to suspend a second request.
  7.  * This leaves a small window of vulnerability if 2 users
  8.  * are using the program at one time.
  9.  *
  10.  * This file contains:
  11.  *    lockproc() - which locks so other user can use
  12.  *            the program.
  13.  *    unlockproc() - which unlocks for other users.
  14.  *
  15.  * It uses the semaphore facility and is highly system dependent.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <sys/ipc.h>
  21. #include <sys/sem.h>
  22. #include <errno.h>
  23.  
  24. /*
  25.  * The following are the way to get a key out of ftok()
  26.  */
  27. #define PATH     "/usr/bin/real_lp"
  28. #define ID    'a'
  29.  
  30. #define UNLOCK    (1)
  31. #define LOCK    (-1)    /* impossible, so will lock */
  32.  
  33. #define MODE    (0666)  /* rw by the world */
  34.  
  35. /*
  36.  * If the owner removes the facility while a 2nd process is 
  37.  * waiting to lock it, the second process will receive an
  38.  * error from semop(2).  Thus, we try TRIES times to lock
  39.  * the process.
  40.  */
  41. #define TRIES    5    
  42.  
  43. #define YES    1
  44. #define NO    0
  45.  
  46. static int sid;        /* semaphore id number */
  47. static short creator;    /* == YES if this process created */
  48.  
  49. extern char *progname;
  50.  
  51. lockproc()
  52. {
  53.     int sem_flg, numbad;
  54.     key_t key, ftok();
  55.     struct sembuf sb;
  56.  
  57.     numbad = 0;
  58.  
  59. retry:
  60.  
  61.     if((key = ftok(PATH,ID)) == -1) 
  62.         Lock_Error("Cannot get ipc key");
  63.  
  64.  
  65.     errno = 0;
  66.     creator = NO;
  67.  
  68.     if(numbad >= TRIES) {
  69.         if(creator == YES)
  70.             semctl(sid, IPC_RMID, 0);
  71.         Lock_Error("Lock error");
  72.     }
  73.  
  74.     sem_flg = MODE | IPC_CREAT | IPC_EXCL;
  75.  
  76.     sid = semget(key, 1, sem_flg);
  77.     if(sid == -1 && errno == EEXIST) {
  78.         /*
  79.          * In use by another user.
  80.          */
  81.         sem_flg = MODE;
  82.         (void) fflush(stdout);
  83.         sid = semget(key, 1, sem_flg);
  84.         /* it will get here, but then block */
  85.     } else {
  86.         creator = YES;
  87.         if(semctl(sid, 0, SETVAL, UNLOCK) == -1) {
  88.             semctl(sid, 0, IPC_RMID, 0);
  89.             Lock_Error("Cannot create semaphore");
  90.         }
  91.     }
  92.  
  93.     sb.sem_num = 0;        /* 1st semaphore */
  94.     sb.sem_op = LOCK;    /* we are locking the semaphore */
  95.     sb.sem_flg = SEM_UNDO;    /* auto reverse */
  96.  
  97.     if (semop(sid, &sb, 1) == -1) {
  98.         if( errno == EINTR || errno == EIDRM) {
  99.             numbad++;
  100.             goto retry;
  101.         } else {
  102.             Lock_Error("Cannot semop()");
  103.         }
  104.     }
  105. }
  106.  
  107. unlockproc()
  108. {
  109.     struct sembuf sb;
  110.  
  111.     if(creator == YES) {
  112.         if(semctl(sid, IPC_RMID, 0) != 0) {
  113.             Lock_Error("Cannot remove lock");
  114.         }
  115.     } else {
  116.         sb.sem_num = 0;
  117.         sb.sem_op = UNLOCK;
  118.         sb.sem_flg = SEM_UNDO;
  119.  
  120.         if(semop(sid, &sb, 1) == -1)
  121.             Lock_Error("Cannot unlock");
  122.     }
  123. }
  124.  
  125. Lock_Error(s)
  126. char *s;
  127. {
  128.     void exit();
  129.     extern char *progname;
  130.  
  131.     fprintf(stderr,"%s: please notify your system administrator\n",
  132.         progname);
  133.     fprintf(stderr,"that you received the following error message:\n");
  134.     fprintf(stderr," ***** %s *****\n", s);
  135.     fprintf(stderr,"Your print job has aborted.\n");
  136.     exit(1);
  137. }
  138.