home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / modempool / part01 / lock.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  5KB  |  242 lines

  1. /*******************************************************************
  2.  * 
  3.  * Module: @(#)lock.c    4.2 92/04/16
  4.  *
  5.  * Description:
  6.  *    Handle various lockfile functions.
  7.  *
  8.  * Revision:
  9.  *    Date    By            Reason    
  10.  *    ----    --            ------    
  11.  *    920306    Lars Berntzon        Created
  12.  *
  13.  *******************************************************************/
  14. static char SccsId[] = "@(#)lock.c    4.2 92/04/16";
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <unistd.h>
  19. #include <fcntl.h>
  20. #include <assert.h>
  21. #include <stdarg.h>
  22.  
  23. #include "modempool.h"
  24. /*******************************************************************
  25.  *        L O C K _ L I N E
  26.  *        -----------------
  27.  *
  28.  * Description:
  29.  *    Lock a tty-port the old UNIX way.
  30.  *
  31.  * Arguments:
  32.  *    line    - Name of tty device.
  33.  *
  34.  *******************************************************************/
  35. int
  36. lock_line(char *line, int pid)
  37. {
  38.     char fname[NAME_SIZE];
  39.     char id[NAME_SIZE];
  40.     int fd;
  41.  
  42.     sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
  43.  
  44.     /*
  45.      * Check that lockdirectory is writeable.
  46.      */
  47.     if (access(LOCKDIR, O_WRONLY) != 0) {
  48.     logerr("lock_line: lock directory not writeable");
  49.     return E_FAIL;
  50.     }
  51.  
  52.     /*
  53.      * First try to create own lockfile.
  54.      */
  55.     while(1)
  56.     {
  57.         if ((fd = open(fname, O_RDWR | O_CREAT | O_EXCL, 0666)) >= 0) 
  58.     {
  59.         /* Succeded, break out of retry loop */
  60.         break;
  61.     }
  62.         else
  63.         {
  64.             /*
  65.              * File allready existed, try to open it without creation.
  66.          */
  67.             if ((fd = open(fname, O_RDONLY)) < 0) {
  68.         logerr("lock_line: can't read file '%s'", fname);
  69.         return E_LOCK;
  70.         }
  71.  
  72.         id[0] = 0;
  73.             if (read(fd, id, sizeof id) < 0)
  74.             {
  75.                 close(fd);
  76.         debug("lock_line: failed to read");
  77.                 return E_READ;
  78.             }
  79.             close(fd); 
  80.  
  81.         /*
  82.          * If I own the lock, it's all right.
  83.          */
  84.         if (atoi(id) == pid) {
  85.         debug("lock_line: i allready owned the lock");
  86.         break;
  87.         }
  88.  
  89.             /*
  90.          * Process owning lock does exists so i can't use the line.
  91.          */
  92.             if (kill(atoi(id), 0) >= 0)
  93.             {
  94.         debug("lock_line: process exists");
  95.                 return E_PROC_EXIST;
  96.             }
  97.             if (unlink(fname) < 0)
  98.             {
  99.         debug("lock_line: failed to unlink");
  100.             return E_UNLINK;
  101.             }
  102.         }
  103.     }
  104.  
  105.     /*
  106.      * Here our own lock file has been created.
  107.      */
  108.     lseek(fd, 0, 0);
  109.     sprintf(id, "%10d\n", pid);
  110.     write(fd, id, strlen(id));
  111.     close(fd);
  112.  
  113.     debug("lock_line: ok");
  114.  
  115.     return E_OK;
  116. }
  117.  
  118. /*******************************************************************
  119.  *        R E L O C K _ L I N E
  120.  *        ---------------------
  121.  *
  122.  * Description:
  123.  *    Relock the line
  124.  *
  125.  * Arguments:
  126.  *    line    - Name of tty device.
  127.  *
  128.  *******************************************************************/
  129. int
  130. relock_line(char *line)
  131. {
  132.     char fname[NAME_SIZE];
  133.     char id[NAME_SIZE];
  134.     int fd;
  135.  
  136.     sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
  137.  
  138.     /* Open lockfile */
  139.     if ((fd = open(fname, O_WRONLY | O_TRUNC)) < 0) return E_OPEN;
  140.  
  141.     /* Write pid to lockfile */
  142.     sprintf(id, "%10d\n", getpid());
  143.     if (write(fd, id, strlen(id)) < 0) {
  144.     return E_WRITE;
  145.     }
  146.  
  147.     close(fd);
  148.     return E_OK;
  149. }
  150.  
  151. /*******************************************************************
  152.  *        U N L O C K _ L I N E
  153.  *        ---------------------
  154.  *
  155.  * Description:
  156.  *    Unlock line.
  157.  *
  158.  * Arguments:
  159.  *    line    - Name of tty device.
  160.  *
  161.  *******************************************************************/
  162. int
  163. unlock_line(char *line)
  164. {
  165.     char fname[NAME_SIZE];
  166.     sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
  167.     unlink(fname);
  168.     return E_OK;
  169. }
  170.  
  171. /*******************************************************************
  172.  *        L O C K _ W A I T
  173.  *        -----------------
  174.  *
  175.  * Description:
  176.  *    Wait until lock goes away.
  177.  *
  178.  *******************************************************************/
  179. int
  180. lock_wait(char *line)
  181. {
  182.     int fd = -1;
  183.     char fname[NAME_SIZE], id[NAME_SIZE];
  184.  
  185.     if (line == NULL) {
  186.     logerr("lock_wait: programming error: line = NULL");
  187.     return E_FAIL;
  188.     }
  189.  
  190.     sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
  191.  
  192.     /* 
  193.      * This one never times out when line is locked.
  194.      */
  195.     while(1)
  196.     {
  197.     /*
  198.      * Check if lockfile exists.
  199.      */
  200.     if (access(fname, F_OK) != 0) {
  201.         return E_OK;
  202.     }
  203.  
  204.     /*
  205.      * Open lockfile.
  206.      */
  207.     if ((fd = open(fname, O_RDONLY)) < 0) {
  208.         fatal("lockfile not readable");
  209.     }
  210.  
  211.     id[0] = 0;
  212.     if (read(fd, id, sizeof id) < 0) {
  213.         logerr("lock_wait: failed to read lockfile");
  214.         close(fd);
  215.         return E_FAIL;
  216.     }
  217.  
  218.     /*
  219.      * If I hold the lock, remove it and return.
  220.      */
  221.     if (atoi(id) == getpid()) {
  222.         debug("lock_wait: i owned the lock");
  223.         unlock_line(line);
  224.         close(fd);
  225.         return E_OK;
  226.     }
  227.  
  228.     /*
  229.      * If no owner of lock, remove it and return.
  230.      */
  231.     if (kill(atoi(id), 0) != 0) {
  232.         debug("lock_wait: no owner of lock");
  233.         unlock_line(line);
  234.         close(fd);
  235.         return E_OK;
  236.     }
  237.  
  238.     close(fd);
  239.     sleep(5);
  240.     }
  241. }
  242.