1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2019 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * Utility functions for use in both acquire-lock and runtests.
  18  */
  19 
  20 #include "util.h"
  21 #include <err.h>
  22 #include <errno.h>
  23 #include <poll.h>
  24 #include <stdarg.h>
  25 #include <stdio.h>
  26 #include <stdlib.h>
  27 #include <strings.h>
  28 #include <unistd.h>
  29 
  30 
  31 boolean_t LOG = B_FALSE;
  32 
  33 
  34 void
  35 flock_log(const char *format, ...)
  36 {
  37         va_list ap;
  38         if (!LOG) {
  39                 return;
  40         }
  41 
  42         va_start(ap, format);
  43         (void) vfprintf(stderr, format, ap);
  44         va_end(ap);
  45 }
  46 
  47 
  48 boolean_t
  49 flock_nodata(int fd)
  50 {
  51         struct pollfd pfd = { fd, POLLIN, 0 };
  52         int ret = poll(&pfd, 1, 1000);
  53 
  54         if (ret == -1) {
  55                 err(EXIT_FAILURE, "poll failed");
  56         }
  57 
  58         return (ret == 0);
  59 }
  60 
  61 
  62 void
  63 flock_block(int fd)
  64 {
  65         char buf[1];
  66         int ret = 0;
  67         while (ret < 1) {
  68                 ret = read(fd, buf, 1);
  69                 if (ret == -1) {
  70                         if (errno == EINTR)
  71                                 continue;
  72                         err(EXIT_FAILURE, "read failed");
  73                 }
  74         }
  75 }
  76 
  77 
  78 void
  79 flock_alert(int fd)
  80 {
  81         int ret = 0;
  82         while (ret < 1) {
  83                 ret = write(fd, "1", 1);
  84                 if (ret == -1) {
  85                         if (errno == EINTR)
  86                                 continue;
  87                         err(EXIT_FAILURE, "write failed");
  88                 }
  89         }
  90 }
  91 
  92 
  93 lock_style_t
  94 flock_styleenum(char *stylestr)
  95 {
  96         if (strcmp(stylestr, "posix") == 0) {
  97                 return (LSTYLE_POSIX);
  98         } else if (strcmp(stylestr, "ofd") == 0) {
  99                 return (LSTYLE_OFD);
 100         } else if (strcmp(stylestr, "flock") == 0) {
 101                 return (LSTYLE_FLOCK);
 102         } else {
 103                 errx(EXIT_FAILURE, BAD_LOCK_MESSAGE);
 104         }
 105 }
 106 
 107 
 108 char *
 109 flock_stylestr(lock_style_t style)
 110 {
 111         switch (style) {
 112         case LSTYLE_POSIX:
 113                 return ("posix");
 114         case LSTYLE_OFD:
 115                 return ("ofd");
 116         case LSTYLE_FLOCK:
 117                 return ("flock");
 118         default:
 119                 abort();
 120         }
 121 }
 122 
 123 
 124 char *
 125 flock_stylename(lock_style_t style)
 126 {
 127         switch (style) {
 128         case LSTYLE_POSIX:
 129                 return ("fcntl(2) POSIX");
 130         case LSTYLE_OFD:
 131                 return ("fcntl(2) OFD");
 132         case LSTYLE_FLOCK:
 133                 return ("flock(3C)");
 134         default:
 135                 abort();
 136         }
 137 }
 138 
 139 
 140 void
 141 flock_reinit(struct flock *flp, int ltype)
 142 {
 143         bzero(flp, sizeof (*flp));
 144         flp->l_type = ltype;
 145 }
 146 
 147 
 148 char *
 149 flock_cmdname(int cmd)
 150 {
 151         switch (cmd) {
 152         case F_SETLK:
 153                 return ("F_SETLK");
 154         case F_OFD_SETLK:
 155                 return ("F_OFD_SETLK");
 156         case F_SETLKW:
 157                 return ("F_SETLKW");
 158         case F_OFD_SETLKW:
 159                 return ("F_OFD_SETLKW");
 160         case F_GETLK:
 161                 return ("F_GETLK");
 162         case F_OFD_GETLK:
 163                 return ("F_OFD_GETLK");
 164         case F_FLOCK:
 165                 return ("F_FLOCK");
 166         case F_FLOCKW:
 167                 return ("F_FLOCKW");
 168 #if !defined(_LP64)
 169         case F_OFD_SETLK64:
 170                 return ("F_OFD_SETLK64");
 171         case F_OFD_SETLKW64:
 172                 return ("F_OFD_SETLKW64");
 173         case F_OFD_GETLK64:
 174                 return ("F_OFD_GETLK64");
 175 #endif
 176         default:
 177                 abort();
 178         }
 179 }