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 2018 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                 return (LSTYLE_LAST);
 105         }
 106 }
 107 
 108 
 109 char *
 110 flock_stylestr(lock_style_t style)
 111 {
 112         switch (style) {
 113         case LSTYLE_POSIX:
 114                 return ("posix");
 115         case LSTYLE_OFD:
 116                 return ("ofd");
 117         case LSTYLE_FLOCK:
 118                 return ("flock");
 119         default:
 120                 abort();
 121                 return ("<unreachable>");
 122         }
 123 }
 124 
 125 
 126 char *
 127 flock_stylename(lock_style_t style)
 128 {
 129         switch (style) {
 130         case LSTYLE_POSIX:
 131                 return ("fcntl(2) POSIX");
 132         case LSTYLE_OFD:
 133                 return ("fcntl(2) OFD");
 134         case LSTYLE_FLOCK:
 135                 return ("flock(3C)");
 136         default:
 137                 abort();
 138                 return ("<unreachable>");
 139         }
 140 }
 141 
 142 
 143 void
 144 flock_reinit(struct flock *flp, int ltype)
 145 {
 146         bzero(flp, sizeof (*flp));
 147         flp->l_type = ltype;
 148 }
 149 
 150 
 151 char *
 152 flock_cmdname(int cmd)
 153 {
 154         switch (cmd) {
 155         case F_SETLK:
 156                 return ("F_SETLK");
 157         case F_OFD_SETLK:
 158                 return ("F_OFD_SETLK");
 159         case F_SETLKW:
 160                 return ("F_SETLKW");
 161         case F_OFD_SETLKW:
 162                 return ("F_OFD_SETLKW");
 163         case F_GETLK:
 164                 return ("F_GETLK");
 165         case F_OFD_GETLK:
 166                 return ("F_OFD_GETLK");
 167         case F_FLOCK:
 168                 return ("F_FLOCK");
 169         case F_FLOCKW:
 170                 return ("F_FLOCKW");
 171 #if !defined(_LP64)
 172         case F_OFD_SETLK64:
 173                 return ("F_OFD_SETLK64");
 174         case F_OFD_SETLKW64:
 175                 return ("F_OFD_SETLKW64");
 176         case F_OFD_GETLK64:
 177                 return ("F_OFD_GETLK64");
 178 #endif
 179         default:
 180                 abort();
 181                 return ("<unreachable>");
 182         }
 183 }