| 1 | .TH "sema" 1 "6 March 2016" "Mark Wooding" "Toys" |
| 2 | .SH NAME |
| 3 | sema \- operations on (SysV-style) semaphores |
| 4 | . |
| 5 | .SH SYNOPSIS |
| 6 | .B sema |
| 7 | .RB [ \-w |
| 8 | .IR when ] |
| 9 | .I subcmd |
| 10 | .RI [ args ...] |
| 11 | .PP |
| 12 | Subcommands: |
| 13 | 'RS |
| 14 | .br |
| 15 | .B mkfile |
| 16 | .RB [ \-x ] |
| 17 | .RB [ \-m |
| 18 | .IR mode ] |
| 19 | .I name |
| 20 | .br |
| 21 | .B new |
| 22 | .RB [ \-x ] |
| 23 | .RB [ \-m |
| 24 | .IR mode ] |
| 25 | .I name |
| 26 | .I value |
| 27 | .br |
| 28 | .B rm |
| 29 | .RB [ \-f ] |
| 30 | .I name |
| 31 | .br |
| 32 | .B get |
| 33 | .I name |
| 34 | .br |
| 35 | .B set |
| 36 | .I name |
| 37 | .I value |
| 38 | .br |
| 39 | .B post |
| 40 | .RB [ \-n |
| 41 | .IR count ] |
| 42 | .I name |
| 43 | .br |
| 44 | .B wait |
| 45 | .RB [ \-n |
| 46 | .IR count ] |
| 47 | .I name |
| 48 | .RI [ cmd |
| 49 | .IR args ...] |
| 50 | .RE |
| 51 | . |
| 52 | .SH DESCRIPTION |
| 53 | The |
| 54 | .B sema |
| 55 | program performs simple operations |
| 56 | on (System V-style) semaphores. |
| 57 | It's not intended to be a utility for |
| 58 | general-purpose hacking on |
| 59 | existing semaphores, |
| 60 | but rather a tool for doing synchronization |
| 61 | between shell scripts or other simple programs. |
| 62 | The two biggest limitations of |
| 63 | .B sema |
| 64 | are that it only ever acts on the first semaphore of a set, |
| 65 | and it has no way to change the project-id |
| 66 | (see |
| 67 | .BR ftok (3)). |
| 68 | .SS Common features |
| 69 | Semaphores are identified by a |
| 70 | .IR name . |
| 71 | Currently, this is always a pathname, |
| 72 | though additional ways of designating semaphore sets |
| 73 | may be added in later versions, |
| 74 | so an open-ended syntax is used: |
| 75 | a |
| 76 | .I name |
| 77 | has the form |
| 78 | .IP |
| 79 | .RI [ type \c |
| 80 | .BR : ] \c |
| 81 | .I value |
| 82 | .PP |
| 83 | Currently defined |
| 84 | .IR type s |
| 85 | and the required |
| 86 | .IR value s |
| 87 | are as follows. |
| 88 | .TP |
| 89 | .B file |
| 90 | The |
| 91 | .I value |
| 92 | is a pathname to a file in the filesystem. |
| 93 | The file's inode number and other information |
| 94 | are converted to an IPC key using |
| 95 | .BR ftok (3) |
| 96 | which is used to fetch a semaphore id using |
| 97 | .BR semget (2). |
| 98 | .PP |
| 99 | The |
| 100 | .I type |
| 101 | may be omitted if it is |
| 102 | .B file |
| 103 | and the |
| 104 | .I value |
| 105 | does not contain a |
| 106 | .RB ` : ' |
| 107 | before its first |
| 108 | .RB ` / ' |
| 109 | (if any); |
| 110 | as a result, |
| 111 | most plain pathnames can be used directly. |
| 112 | .PP |
| 113 | The command-line options accepted before the subcommand name |
| 114 | are as follows. |
| 115 | .TP |
| 116 | .B "\-h, \-\-help" |
| 117 | Write a help message to standard output |
| 118 | and exit successfully. |
| 119 | .TP |
| 120 | .B "\-v, \-\-version" |
| 121 | Write a version number to standard output |
| 122 | and exit successfully. |
| 123 | .TP |
| 124 | .BI "\-w, \-\-wait " duration |
| 125 | Nearly all operations on SysV semaphores may need to block |
| 126 | for an extended period of time. |
| 127 | This is obvious for waiting, but, alas, |
| 128 | semaphore initialization is poorly designed, |
| 129 | and |
| 130 | .I every |
| 131 | operation which expects a properly initialized semaphore |
| 132 | has little choice but to wait until the semaphore has been set up. |
| 133 | .IP |
| 134 | If |
| 135 | .I duration |
| 136 | is |
| 137 | .B forever |
| 138 | (the default) |
| 139 | then |
| 140 | .B sema |
| 141 | will wait indefinitely until the thing it's waiting for happens. |
| 142 | If |
| 143 | .I duration |
| 144 | is |
| 145 | .B none |
| 146 | or |
| 147 | .B never |
| 148 | then |
| 149 | .B sema |
| 150 | will exit immediately, |
| 151 | with status 251, |
| 152 | instead of waiting. |
| 153 | Otherwise, |
| 154 | .I |
| 155 | duration |
| 156 | should be a |
| 157 | (possibly fractional \(en i.e., with a decimal point) |
| 158 | number followed by an optional unit suffix: |
| 159 | .RB ` s ' |
| 160 | for seconds (the default), |
| 161 | .RB ` m ' |
| 162 | for minutes, |
| 163 | .RB ` h ' |
| 164 | for hours, and |
| 165 | .RB ` d ' |
| 166 | for days. |
| 167 | .SS Exit status |
| 168 | .IP 0 |
| 169 | Success. |
| 170 | .IP 251 |
| 171 | The semaphore did not become available |
| 172 | within the period |
| 173 | .B sema |
| 174 | was told to wait. |
| 175 | .IP 252 |
| 176 | The semaphore was not properly initialized |
| 177 | within the period |
| 178 | .B sema |
| 179 | was told to wait. |
| 180 | .IP 253 |
| 181 | An error was detected in |
| 182 | .BR sema 's |
| 183 | command-line arguments. |
| 184 | .IP 254 |
| 185 | A system error occurred. |
| 186 | .IP Other |
| 187 | Exit status from the program executed by the |
| 188 | .B wait |
| 189 | subcommand. |
| 190 | .PP |
| 191 | If |
| 192 | .B sema |
| 193 | detects an error, |
| 194 | it writes a human-readable description of the problem |
| 195 | to standard error and exits with one of the above status codes. |
| 196 | The codes have been chosen so as not to conflict |
| 197 | with those commonly used by other programs, |
| 198 | so that errors from |
| 199 | .B sema |
| 200 | itself can be distinguished from problems encountered |
| 201 | by the program executed by the |
| 202 | .B wait |
| 203 | subcommand, |
| 204 | but the available space for error codes is small |
| 205 | and conflicts are inevitable. |
| 206 | . |
| 207 | .SH SUBCOMMANDS |
| 208 | .SS mkfile |
| 209 | Create the file designated by the semaphore |
| 210 | .I name |
| 211 | argument. |
| 212 | (An error is reported if the |
| 213 | .I name |
| 214 | does not designate a pathname.) |
| 215 | .PP |
| 216 | Options are as follows. |
| 217 | .TP |
| 218 | .BI "\-m, \-\-mode " mode |
| 219 | Set the permissions for the new file. |
| 220 | The |
| 221 | .I mode |
| 222 | should be a numeric file permission specification, in octal, |
| 223 | as for |
| 224 | .BR chmod (1). |
| 225 | The default is to allow read and write according to the process umask. |
| 226 | .TP |
| 227 | .B "\-x, \-\-exclusive" |
| 228 | Fail if the file already exists. |
| 229 | .SS new |
| 230 | Create a new semaphore set containing a single semaphore |
| 231 | with the given |
| 232 | .I name |
| 233 | and initial |
| 234 | .IR value . |
| 235 | Options are as follows. |
| 236 | .TP |
| 237 | .BI "\-m, \-\-mode " mode |
| 238 | Set the permissions for the new file. |
| 239 | The |
| 240 | .I mode |
| 241 | should be a numeric file permission specification, in octal; |
| 242 | the read and write bits determine whether the owner, group and others |
| 243 | can read and change the semaphore; |
| 244 | the execute bits are ignored. |
| 245 | The default is to allow read and write according to the process umask. |
| 246 | .TP |
| 247 | .B "\-x, \-\-exclusive" |
| 248 | Fail if a semaphore set with the given |
| 249 | .I name |
| 250 | already exists. |
| 251 | .SS rm |
| 252 | Delete the semaphore set with the given |
| 253 | .IR name . |
| 254 | .PP |
| 255 | Options are as follows. |
| 256 | .TP |
| 257 | .B "\-f, \-\-force" |
| 258 | Don't report an error if no semaphore set exists with the given name. |
| 259 | .SS get |
| 260 | Fetch the current value of the semaphore with the given |
| 261 | .I name |
| 262 | and |
| 263 | write it, in decimal, to standard outout, followed by a newline. |
| 264 | .PP |
| 265 | Because this captures a snapshot of the state |
| 266 | of an asynchronously changing value, |
| 267 | this command is only really useful for diagnostic purposes |
| 268 | or when the system is known to be quiescent. |
| 269 | .PP |
| 270 | There are no options. |
| 271 | .SS set |
| 272 | Set the value of the semaphore with the given |
| 273 | .I name |
| 274 | to |
| 275 | .IR value . |
| 276 | .PP |
| 277 | Because this modifies a the state |
| 278 | of an asynchronously changing value, |
| 279 | this command is only really useful |
| 280 | when the system is known to be quiescent. |
| 281 | .PP |
| 282 | There are no options. |
| 283 | .SS post |
| 284 | Atomically increment the value of the semaphore with the given |
| 285 | .IR name . |
| 286 | This operation can't block |
| 287 | (though it may still be necessary to wait |
| 288 | until the semaphore set is initialized). |
| 289 | .PP |
| 290 | Options are as follows. |
| 291 | .TP |
| 292 | .BI "\-n, \-\-count " count |
| 293 | Adjust the semaphore value by |
| 294 | .IR count , |
| 295 | which must be a positive integer, |
| 296 | rather than 1. |
| 297 | .SS wait |
| 298 | Wait until the value of the semaphore with the given |
| 299 | .I name |
| 300 | is positive and then atomically decrement it. |
| 301 | .PP |
| 302 | If a |
| 303 | .I command |
| 304 | is provided |
| 305 | (possibly with some |
| 306 | .IR arguments ) |
| 307 | then execute it and then increment the semaphore value again |
| 308 | when it finishes. |
| 309 | The program is executed directly by |
| 310 | .BR execvp (3). |
| 311 | Restoring the semaphore value is reliable: |
| 312 | it is done by the kernel, |
| 313 | so there's no risk of some program crashing and |
| 314 | leaving the semaphore in an inconsistent state; |
| 315 | though obviously if the program gets stuck |
| 316 | it will continue to hold the semaphore until it's killed. |
| 317 | The semaphore is released as soon as the |
| 318 | .I command |
| 319 | exits; |
| 320 | if it forked child processed, |
| 321 | the semaphore will be released |
| 322 | and the children will continue to run. |
| 323 | .PP |
| 324 | Options are as follows. |
| 325 | .TP |
| 326 | .BI "\-n, \-\-count " count |
| 327 | Adjust the semaphore value by |
| 328 | .IR count , |
| 329 | which must be a positive integer, |
| 330 | rather than 1. |
| 331 | .B sema |
| 332 | will wait until semaphore value is at least |
| 333 | .IR count , |
| 334 | and atomically decrease it by |
| 335 | .IR count . |
| 336 | If there is a |
| 337 | .I command |
| 338 | then |
| 339 | .B sema |
| 340 | arranges for the semaphore value to be increased by |
| 341 | .I count |
| 342 | when it exits. |
| 343 | . |
| 344 | .SH BUGS |
| 345 | System V semaphores are remarkably awful. |
| 346 | POSIX semaphores are superficially much better, |
| 347 | but actually deficient in a number of ways. |
| 348 | Most significantly for our purposes, |
| 349 | there's no analogue of the |
| 350 | .B SEM_UNDO |
| 351 | feature, |
| 352 | so to implement the feature of |
| 353 | .B wait |
| 354 | which holds the semaphore during the execution of a command |
| 355 | .B sema |
| 356 | would have to wait for it to finish; |
| 357 | and if |
| 358 | .B sema |
| 359 | is killed in the meantime then nobody will fix the semaphore. |
| 360 | Another important deficiency is that |
| 361 | POSIX semaphores can only be adjusted a single step at a time, |
| 362 | so the |
| 363 | .B \-n |
| 364 | feature of the |
| 365 | .B wait |
| 366 | and |
| 367 | .B post |
| 368 | commands can't be implemented satisfactorily. |
| 369 | .SH AUTHOR |
| 370 | Mark Wooding, <mdw@distorted.org.uk> |