.TH "sema" 1 "6 March 2016" "Mark Wooding" "Toys" .SH NAME sema \- operations on (SysV-style) semaphores . .SH SYNOPSIS .B sema .RB [ \-w .IR when ] .I subcmd .RI [ args ...] .PP Subcommands: 'RS .br .B mkfile .RB [ \-x ] .RB [ \-m .IR mode ] .I name .br .B new .RB [ \-x ] .RB [ \-m .IR mode ] .I name .I value .br .B rm .RB [ \-f ] .I name .br .B get .I name .br .B set .I name .I value .br .B post .RB [ \-n .IR count ] .I name .br .B wait .RB [ \-n .IR count ] .I name .RI [ cmd .IR args ...] .RE . .SH DESCRIPTION The .B sema program performs simple operations on (System V-style) semaphores. It's not intended to be a utility for general-purpose hacking on existing semaphores, but rather a tool for doing synchronization between shell scripts or other simple programs. The two biggest limitations of .B sema are that it only ever acts on the first semaphore of a set, and it has no way to change the project-id (see .BR ftok (3)). .SS Common features Semaphores are identified by a .IR name . Currently, this is always a pathname, though additional ways of designating semaphore sets may be added in later versions, so an open-ended syntax is used: a .I name has the form .IP .RI [ type \c .BR : ] \c .I value .PP Currently defined .IR type s and the required .IR value s are as follows. .TP .B file The .I value is a pathname to a file in the filesystem. The file's inode number and other information are converted to an IPC key using .BR ftok (3) which is used to fetch a semaphore id using .BR semget (2). .PP The .I type may be omitted if it is .B file and the .I value does not contain a .RB ` : ' before its first .RB ` / ' (if any); as a result, most plain pathnames can be used directly. .PP The command-line options accepted before the subcommand name are as follows. .TP .B "\-h, \-\-help" Write a help message to standard output and exit successfully. .TP .B "\-v, \-\-version" Write a version number to standard output and exit successfully. .TP .BI "\-w, \-\-wait " duration Nearly all operations on SysV semaphores may need to block for an extended period of time. This is obvious for waiting, but, alas, semaphore initialization is poorly designed, and .I every operation which expects a properly initialized semaphore has little choice but to wait until the semaphore has been set up. .IP If .I duration is .B forever (the default) then .B sema will wait indefinitely until the thing it's waiting for happens. If .I duration is .B none or .B never then .B sema will exit immediately, with status 251, instead of waiting. Otherwise, .I duration should be a (possibly fractional \(en i.e., with a decimal point) number followed by an optional unit suffix: .RB ` s ' for seconds (the default), .RB ` m ' for minutes, .RB ` h ' for hours, and .RB ` d ' for days. .SS Exit status .IP 0 Success. .IP 251 The semaphore did not become available within the period .B sema was told to wait. .IP 252 The semaphore was not properly initialized within the period .B sema was told to wait. .IP 253 An error was detected in .BR sema 's command-line arguments. .IP 254 A system error occurred. .IP Other Exit status from the program executed by the .B wait subcommand. .PP If .B sema detects an error, it writes a human-readable description of the problem to standard error and exits with one of the above status codes. The codes have been chosen so as not to conflict with those commonly used by other programs, so that errors from .B sema itself can be distinguished from problems encountered by the program executed by the .B wait subcommand, but the available space for error codes is small and conflicts are inevitable. . .SH SUBCOMMANDS .SS mkfile Create the file designated by the semaphore .I name argument. (An error is reported if the .I name does not designate a pathname.) .PP Options are as follows. .TP .BI "\-m, \-\-mode " mode Set the permissions for the new file. The .I mode should be a numeric file permission specification, in octal, as for .BR chmod (1). The default is to allow read and write according to the process umask. .TP .B "\-x, \-\-exclusive" Fail if the file already exists. .SS new Create a new semaphore set containing a single semaphore with the given .I name and initial .IR value . Options are as follows. .TP .BI "\-m, \-\-mode " mode Set the permissions for the new file. The .I mode should be a numeric file permission specification, in octal; the read and write bits determine whether the owner, group and others can read and change the semaphore; the execute bits are ignored. The default is to allow read and write according to the process umask. .TP .B "\-x, \-\-exclusive" Fail if a semaphore set with the given .I name already exists. .SS rm Delete the semaphore set with the given .IR name . .PP Options are as follows. .TP .B "\-f, \-\-force" Don't report an error if no semaphore set exists with the given name. .SS get Fetch the current value of the semaphore with the given .I name and write it, in decimal, to standard outout, followed by a newline. .PP Because this captures a snapshot of the state of an asynchronously changing value, this command is only really useful for diagnostic purposes or when the system is known to be quiescent. .PP There are no options. .SS set Set the value of the semaphore with the given .I name to .IR value . .PP Because this modifies a the state of an asynchronously changing value, this command is only really useful when the system is known to be quiescent. .PP There are no options. .SS post Atomically increment the value of the semaphore with the given .IR name . This operation can't block (though it may still be necessary to wait until the semaphore set is initialized). .PP Options are as follows. .TP .BI "\-n, \-\-count " count Adjust the semaphore value by .IR count , which must be a positive integer, rather than 1. .SS wait Wait until the value of the semaphore with the given .I name is positive and then atomically decrement it. .PP If a .I command is provided (possibly with some .IR arguments ) then execute it and then increment the semaphore value again when it finishes. The program is executed directly by .BR execvp (3). Restoring the semaphore value is reliable: it is done by the kernel, so there's no risk of some program crashing and leaving the semaphore in an inconsistent state; though obviously if the program gets stuck it will continue to hold the semaphore until it's killed. The semaphore is released as soon as the .I command exits; if it forked child processed, the semaphore will be released and the children will continue to run. .PP Options are as follows. .TP .BI "\-n, \-\-count " count Adjust the semaphore value by .IR count , which must be a positive integer, rather than 1. .B sema will wait until semaphore value is at least .IR count , and atomically decrease it by .IR count . If there is a .I command then .B sema arranges for the semaphore value to be increased by .I count when it exits. . .SH BUGS System V semaphores are remarkably awful. POSIX semaphores are superficially much better, but actually deficient in a number of ways. Most significantly for our purposes, there's no analogue of the .B SEM_UNDO feature, so to implement the feature of .B wait which holds the semaphore during the execution of a command .B sema would have to wait for it to finish; and if .B sema is killed in the meantime then nobody will fix the semaphore. Another important deficiency is that POSIX semaphores can only be adjusted a single step at a time, so the .B \-n feature of the .B wait and .B post commands can't be implemented satisfactorily. .SH AUTHOR Mark Wooding,