Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/test/os-tests/tests/file-locking/acquire-lock.c
          +++ new/usr/src/test/os-tests/tests/file-locking/acquire-lock.c
   1    1  /*
   2    2   * This file and its contents are supplied under the terms of the
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2016 Joyent, Inc.
  14   14   */
  15   15  
  16   16  /*
  17   17   * Acquire the specified kind of lock with the specified parameters. After
  18   18   * acquiring the lock, a byte will be written to stdout. The program will
  19   19   * then wait for a byte to be written to stdin before exiting.
  20   20   *
  21   21   * Usage: <posix|ofd|flock> <shared|exclusive> <path>
  22   22   */
  23   23  
  24   24  #include "util.h"
  25   25  #include <err.h>
  26   26  #include <errno.h>
  27   27  #include <fcntl.h>
  28   28  #include <stdio.h>
  29   29  #include <stdlib.h>
  30   30  #include <strings.h>
  31   31  #include <sys/file.h>
  32   32  #include <unistd.h>
  33   33  
  34   34  
  35   35  static  void    acq_fcntl(int, int, int);
  36   36  static  void    acq_flock(int fd, int mode);
  37   37  static  void    acq_run(int, lock_style_t, boolean_t);
  38   38  
  39   39  
  40   40  static void
  41   41  acq_fcntl(int fd, int cmd, int mode)
  42   42  {
  43   43          struct flock fl;
  44   44          int ret, i;
  45   45  
  46   46          /*
  47   47           * Acquire the lock, and then try reacquiring it several times. Once we
  48   48           * have acquired the lock, trying to acquire it again should succeed,
  49   49           * and shouldn't upgrade, downgrade or free the lock.
  50   50           */
  51   51          for (i = 0; i < 3; i++) {
  52   52                  flock_reinit(&fl, mode);
  53   53                  flock_log("Acquiring lock (fcntl)...\n");
  54   54                  ret = fcntl(fd, cmd, &fl);
  55   55                  if (ret == -1) {
  56   56                          err(EXIT_FAILURE, "fcntl failed");
  57   57                  }
  58   58          }
  59   59  
  60   60  
  61   61          /* Let the parent know we have the lock and wait */
  62   62          flock_log("Waiting (fcntl)...\n");
  63   63          flock_alert(1);
  64   64          flock_block(0);
  65   65  
  66   66          /* Now unlock */
  67   67          flock_reinit(&fl, F_UNLCK);
  68   68          flock_log("Releasing lock (fcntl)...\n");
  69   69          ret = fcntl(fd, cmd, &fl);
  70   70          if (ret == -1) {
  71   71                  err(EXIT_FAILURE, "fcntl failed");
  72   72          }
  73   73  }
  74   74  
  75   75  
  76   76  static void
  77   77  acq_flock(int fd, int mode)
  78   78  {
  79   79          int ret, i;
  80   80  
  81   81          /*
  82   82           * Acquire the lock, and then try reacquiring it several times. Once we
  83   83           * have acquired the lock, trying to acquire it again should succeed,
  84   84           * and shouldn't upgrade, downgrade or free the lock.
  85   85           */
  86   86          for (i = 0; i < 3; i++) {
  87   87                  flock_log("Acquiring lock (flock)...\n");
  88   88                  ret = flock(fd, mode);
  89   89                  if (ret == -1) {
  90   90                          err(EXIT_FAILURE, "flock failed");
  91   91                  }
  92   92          }
  93   93  
  94   94          /* Wait to be okayed to unlock */
  95   95          flock_log("Waiting (flock)...\n");
  96   96          flock_alert(1);
  97   97          flock_block(0);
  98   98  
  99   99          /* Release lock */
 100  100          flock_log("Releasing lock (flock)...\n");
 101  101          ret = flock(fd, LOCK_UN);
 102  102          if (ret == -1) {
 103  103                  err(EXIT_FAILURE, "flock failed");
 104  104          }
 105  105  }
 106  106  
 107  107  
 108  108  static void
 109  109  acq_run(int fd, lock_style_t style, boolean_t is_exclusive)
 110  110  {
 111  111          switch (style) {
 112  112          case LSTYLE_POSIX:
 113  113                  acq_fcntl(fd, F_SETLKW, is_exclusive ? F_WRLCK : F_RDLCK);
 114  114                  break;
 115  115          case LSTYLE_OFD:
 116  116                  acq_fcntl(fd, F_OFD_SETLKW, is_exclusive ? F_WRLCK : F_RDLCK);
 117  117                  break;
 118  118          case LSTYLE_FLOCK:
 119  119                  acq_flock(fd, is_exclusive ? LOCK_EX : LOCK_SH);
 120  120                  break;
 121  121          default:
 122  122                  abort();
 123  123          }
 124  124  }
 125  125  
 126  126  
 127  127  int
 128  128  main(int argc, char *argv[])
 129  129  {
 130  130          char *modestr, *path;
 131  131          lock_style_t style;
 132  132          boolean_t is_exclusive;
 133  133          int fd;
 134  134  
 135  135          if (argc < 4) {
 136  136                  errx(EXIT_FAILURE, BAD_ARGS_MESSAGE, argc - 1);
 137  137          }
 138  138  
 139  139          modestr = argv[2];
 140  140          path = argv[3];
 141  141  
 142  142          style = flock_styleenum(argv[1]);
 143  143  
 144  144          if (strcmp(modestr, "shared") == 0) {
 145  145                  is_exclusive = B_FALSE;
 146  146          } else if (strcmp(modestr, "exclusive") == 0) {
 147  147                  is_exclusive = B_TRUE;
 148  148          } else {
 149  149                  errx(EXIT_FAILURE, BAD_MODE_MESSAGE);
 150  150          }
 151  151  
 152  152          boolean_t rdonly = style == LSTYLE_FLOCK || !is_exclusive;
 153  153          fd = open(path, rdonly ? O_RDONLY : O_WRONLY);
 154  154          if (fd == -1) {
 155  155                  err(EXIT_FAILURE, "Failed to open %s", path);
 156  156          }
 157  157  
 158  158          acq_run(fd, style, is_exclusive);
 159  159  
 160  160          return (0);
 161  161  }
  
    | 
      ↓ open down ↓ | 
    161 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX