home *** CD-ROM | disk | FTP | other *** search
/ pc.louisiana.edu/pub/unix/ / Louisiana_UNIX.tar / Louisiana_UNIX / lockfile.c < prev    next >
C/C++ Source or Header  |  1995-09-18  |  4KB  |  193 lines

  1. /*
  2.  * LOCKFILE
  3.  *
  4.  * Create files for locking purposes.
  5.  *
  6.  * Usage: lockfile [-nuv] [-t <timeout>] <file>
  7.  *     -n    Don't block indefinitely waiting for a locked file.  Only
  8.  *        tries the lock once.
  9.  *    -u    Unlock (remove) the lock file.
  10.  *    -v    Verbose.
  11.  *    -t <timeout>    If the lock file alredy exists and is older than
  12.  *            <timeout> seconds, assume it is stale and remove it.
  13.  *            The default timeout is 300 seconds.
  14.  * 
  15.  * Exit code is 0 if the lock succeeds, -1 otherwise.
  16.  *
  17.  * Created 9/95 by Lane Robert (lar@usl.edu)
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <fcntl.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <unistd.h>
  26. #include <sys/time.h>
  27. #include <errno.h>
  28.  
  29. #define EXIT_ERROR -1
  30. #define EXIT_OK 0
  31.  
  32. #define USAGE fprintf(stderr, "%s: Usage: \"%s [-nuv][-t <timeout>] <file>\"\n", me, me)
  33.  
  34. extern int optind;
  35. extern char *optarg;
  36.  
  37. extern int errno;
  38. extern char *sys_errlist[];
  39.  
  40. char *me;
  41.  
  42. main (int argc, char **argv)
  43. {
  44.      int noblock, timeout, unlock, verbose, ch;
  45.      char *fname;
  46.  
  47.      noblock = 0;
  48.      timeout = 300;
  49.      unlock = 0;
  50.      verbose = 0;
  51.      me = argv[0];
  52.  
  53.      while ((ch = getopt(argc, argv, "nt:uv")) != -1) {
  54.        switch(ch) {
  55.        case 'n':
  56.         noblock = 1;
  57.         break;
  58.        case 't':
  59.         timeout = atoi(optarg);
  60.         if (timeout <= 0) {
  61.              fprintf(stderr, "%s: Invalid timeout value \"%s\"\n",
  62.              me, optarg);
  63.          exit(EXIT_ERROR);
  64.         }
  65.         break;
  66.        case 'u':
  67.         unlock = 1;
  68.         break;
  69.        case 'v':
  70.         verbose = 1;
  71.         break;
  72.        default:
  73.         USAGE;
  74.         exit(EXIT_ERROR);
  75.        }
  76.      }
  77.  
  78.        if (optind >= argc) {
  79.         USAGE;
  80.         exit(EXIT_ERROR);
  81.        }
  82.        else fname = argv[optind];
  83.  
  84.        /* UNLOCK */
  85.        if (unlock) {
  86.         if (unlink(fname) != 0) {
  87.          if (errno == ENOENT) {
  88.               if (verbose) {
  89.                fprintf(stderr,
  90.             "%s: Warning: Cannot remove %s: file does not exist\n",
  91.                    me, fname);
  92.               }
  93.          }
  94.          else {
  95.               fprintf(stderr, "%s: Cannot remove %s: %s\n", me, fname,
  96.                   sys_errlist[errno]);
  97.               exit(EXIT_ERROR);
  98.          }
  99.         }
  100.         else {
  101.          if (verbose)
  102.               fprintf(stderr, "%s: Lock file %s removed.\n", me,
  103.                   fname);
  104.         }
  105.        }
  106.        else {
  107.         /* LOCK */
  108.         while (1) {
  109.          struct stat statbuf;
  110.          time_t now;
  111.  
  112.          if (stat(fname, &statbuf) != 0) {
  113.               if (errno == ENOENT) {
  114.                int fd;
  115.  
  116.                /* File doesn't exist; create it. */
  117.                if ((fd = open(fname, O_WRONLY|O_EXCL|O_CREAT, 0666))
  118.                    < 0) {
  119.                 if (errno == EEXIST) {
  120.                      if (verbose)
  121.                       fprintf(stderr,
  122.                           "%s: Creation of %s failed.\n",
  123.                           fname, me);
  124.                 }
  125.                 else {
  126.                      fprintf(stderr,
  127.                          "%s: Creation of %s failed: %s\n",
  128.                          me, fname, sys_errlist[errno]);
  129.                      exit(EXIT_ERROR);
  130.                 }
  131.                 if (noblock)
  132.                      exit(EXIT_ERROR);
  133.                 else {
  134.                      if (verbose)
  135.                       fprintf(stderr, "%s: Retrying.\n",
  136.                           me);
  137.                      sleep(15);
  138.                      continue;
  139.                 }
  140.                }
  141.                else {
  142.                 if (verbose)
  143.                      fprintf(stderr,
  144.                          "%s: Lock file %s created.\n", me,
  145.                          fname);
  146.                 close(fd);
  147.                 exit(EXIT_OK);
  148.                }
  149.               }
  150.               else {
  151.                fprintf(stderr, "%s: Cannot create %s: %s\n", me,
  152.                    fname, sys_errlist[errno]);
  153.                exit(EXIT_ERROR);
  154.               }
  155.          }
  156.          /* Lock file exists.  Is it stale? */
  157.          now = time((time_t *)NULL);
  158.          if (now - statbuf.st_mtime >= timeout) {
  159.               /* It's stale.  Remove it. */
  160.               if (verbose)
  161.                fprintf(stderr,
  162.                    "%s: Lock file %s is old.  Removing it.\n",
  163.                    me, fname);
  164.               if (unlink(fname) != 0 && errno != ENOENT) {
  165.                fprintf(stderr,
  166.                    "%s: Cannot remove old file %s: %s\n", me,
  167.                    fname, sys_errlist[errno]);
  168.                exit(EXIT_ERROR);
  169.               }
  170.               if (verbose)
  171.                fprintf(stderr, "%s: Retrying lock of %s.\n", me,
  172.                    fname);
  173.               continue;
  174.          }
  175.          /*
  176.           * Lock file exists and is not stale.
  177.           * Unless we are in nonblock mode, sleep
  178.           * for a short time and retry.
  179.           */
  180.          if (verbose)
  181.               fprintf(stderr,
  182.                   "%s: Creation of lock file %s failed.\n",
  183.                   me, fname);
  184.          if (noblock)
  185.               exit(EXIT_ERROR);
  186.          if (verbose)
  187.               fprintf(stderr, "%s: Retrying lock of %s.\n", me, fname);
  188.          sleep(15);
  189.         }
  190.        }
  191.      exit(EXIT_OK);
  192. }
  193.