home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / flock / flock.c next >
Encoding:
C/C++ Source or Header  |  1995-06-18  |  2.0 KB  |  114 lines

  1. #include <fcntl.h>
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <signal.h>
  5.  
  6. char *progname;
  7.  
  8. Usage() {
  9.     fprintf(stderr, "Usage: %s [-rw] <filename>\n", progname);
  10.     exit(1);
  11.     /* NOTREACHED */
  12. }
  13.  
  14.  
  15. int child_pid;
  16. int child_status;
  17.  
  18. main(int argc, char **argv) {
  19.     int fd;
  20.     int opt;
  21.     int    pipe_fds[2];
  22.     static struct flock lck = {
  23.         0,
  24.         0,
  25.         0,
  26.         0,
  27.     };
  28.     extern int optind, opterr;
  29.     
  30.     progname = argv[0];
  31.     
  32.     opterr = 0;
  33.     while ((opt = getopt(argc, argv, "rw")) != -1) {
  34.         switch (opt) {
  35.         case 'r':
  36.         case 'w':
  37.             if (lck.l_type != 0) {
  38.                 fprintf(stderr, "%s: Only one lock type may be specified\n", progname);
  39.                 exit(1);
  40.             }
  41.             lck.l_type = (opt == 'r') ? F_RDLCK : F_WRLCK;
  42.             break;
  43.  
  44.         case '?':
  45.             Usage();
  46.             /* NOTREACHED */
  47.         } /* switch */
  48.     } /* while */
  49.  
  50.     if (lck.l_type == 0) {
  51.         /* default is exclusive */
  52.         lck.l_type = F_WRLCK;
  53.     }
  54.     
  55.     if (argc - optind > 1) {
  56.         Usage();
  57.     }
  58.  
  59.     if (pipe(pipe_fds) == -1) {
  60.         perror("pipe");
  61.         exit(errno);
  62.     }
  63.     
  64.     switch (child_pid = fork()) {
  65.     case 0:
  66.         /* The child */
  67.         fclose(stdin);
  68.         fclose(stdout);
  69.         fclose(stderr);
  70.         close(pipe_fds[0]);
  71.         if ((fd = open(argv[optind], 2)) == -1) {
  72.             child_status = errno;
  73.             write(pipe_fds[1], &errno, sizeof(errno));
  74.             exit(child_status);
  75.         }
  76.         if (fcntl(fd, F_SETLK, &lck) != 0) {
  77.             child_status = errno;
  78.             write(pipe_fds[1], &errno, sizeof(errno));
  79.             exit(child_status);
  80.         }
  81.         errno = 0;
  82.         write(pipe_fds[1], &errno, sizeof(errno));
  83.         close(pipe_fds[1]);
  84.         pause();
  85.         /*
  86.          * The only way for pause to return is on an signal, but we
  87.          * don't do anything with signals, so it will just die.
  88.          * The file will be closed on exit, and the lock will
  89.          * disappear.
  90.          */
  91.         /* NOTREACHED */
  92.  
  93.     case -1:
  94.         /* fork failed */
  95.         perror("fork");
  96.         exit(errno);
  97.         /* NOTREACHED */
  98.  
  99.     default:
  100.         /* The Parent */
  101.         close(pipe_fds[1]);
  102.         read(pipe_fds[0], &child_status, sizeof(child_status));
  103.         if (child_status == 0)
  104.             printf("%d\n", child_pid);
  105.         else {
  106.             errno = child_status;
  107.             perror("flock");
  108.         }
  109.     } /* switch */
  110.  
  111.     exit(child_status);
  112.     /* NOTREACHED */
  113. }
  114.