This is an interactive exerciser for the semctl(2), semget(2) and semop(2) system calls of System V UNIX. You can use it to experiment with the semaphore features in order to understand them better. It includes on-line help.
Calls that might cause semex to block (semop(2) with negative operation values) are handed to a forked copy of semex. Semex's children emit reports just before they block and when they unblock, to enable the user to track what's going on.
Semex can also be used as a semaphores interface for scripts. Command prompting is suppressed if stdin isn't a tty; so are the verbose descriptions of actions performed that it normally emits, and the process-forking described above.
All arguments of every command are optional; the code tries to give reasonable defaults to any you leave off. Anytime a `semid' or `semnum' argument is given, the default semid or semnum for future commands is set to it.
c(reate) key nsems -[ce] perms -- create semaphore group
This calls semget(2). The `key' argument should be a long, the `nsems' argument an int. The third (flags) argument of the semget(2) call is created from the third and fourth arguments of this command; flags `c' and `e' stand for IPC_CREAT and IPC_EXCL respectively and `perms' should be at least three digits of octal permission mask.
The `current semaphore group id' (semid) is set to the return value of this command.
The default arguments are `0L 1 - 0660' (note that 0L = IPC_PRIVATE).
f(ind) semid -- select a semaphore group by id
This changes semex's notion of the current semaphore group id. If the argument is omitted, the current value is simply printed out.
i(ndex) semnum -- select a semaphore index
This changes semex's notion of the current semaphore index. If the argument is omitted, the current value is simply printed out.
d(o) op -[un] -- do a semaphore operation
This command does a semop(2) call. The first argument of the call will be the currently selected semaphore id. The third argument (number of operations) will be 1. The (struct sembuf *) second argument will point to a single operation structure.
The sem_num field of this structure is set to the `current semaphore index' value set by the `n' command (normally 1). The sem_op field is set to the value of the `op' command argument (which should be an integer). The sem_flg field is set according to the flags in the third command argument; `u' stands for SEM_UNDO, `n' for IPC_NOWAIT.
The argument defaults are `0 -'.
v(alue) semid semnum -- query a semaphore's semval
This command displays the return of a semctl(semid, semnum, GETVAL). If semnum is omitted it defaults to the currently selected semaphore index. If semid is omitted it defaults to the currently selected semaphore id.
p(id) semid semnum -- query a semaphore's sempid
This command displays the return of a semctl(semid, semnum, GETPID). If semnum is omitted it defaults to the currently selected semaphore index. If semid is omitted it defaults to the currently selected semaphore id.
n(cnt) semid semnum -- query a semaphore's semncnt
This command displays the return of a semctl(semid, semnum, GETNCNT). If semnum is omitted it defaults to the currently selected semaphore index. If semid is omitted it defaults to the currently selected semaphore id.
z(cnt) semid semnum -- query a semaphore's semzcnt
This command displays the return of a semctl(semid, semnum, GETZCNT). If semnum is omitted it defaults to the currently selected semaphore index. If semid is omitted it defaults to the currently selected semaphore id.
s(et) semval -- set the value of a semaphore
This command does a semop(2) call using the SETVAL command to set the value of the currently selected semaphore. The first argument of the call will be the currently selected semaphore id. The second argument of the call will be the currently selected semaphore index. The fourth (value) argument will be the semval argument of the command (which defaults to 0 if omitted).
m(mask) semid uid gid mode -- query/set a semaphore's mode
The m command with no arguments displays the uid, gid and mode of the currently selected semaphore group. With one argument, it displays this information for the given semaphore group. With two or more arguments it sets whatever portions of the mode and ownership data are given; uid and gid should be decimal integers and mode at least three digits of octal.
r(emove) semid -- remove a semaphore group
Do a semctl(2) to remove a semaphore group. If the semid argument is omitted, the currently selected semaphore group will be removed.
l(ist) -- run ipcs -sbopt
This is just a convenience. It displays data on active semaphores.
x(it) -- exit
Exit semex. Child semex processes created by 'd' commands will get SIGHUP and die gracefully.
! cmd -- execute a shell command
Escape to a shell.
? -- print this help message
In addition, typing a newline will simply display the value of the currently selected semaphore (newline is a synonym for the `v' command).
The 'p' and 'v' commands are not Dyskstra's P and V operations.
There is no way for semex to specify more than one semaphore op at once in semop(2).
There is no support for exercising the GETALL or SETALL modes of semctl(2).
Eric S. Raymond <esr@snark.thyrsus.com>. You may
find updates and related resources at http://www.catb.org/~esr/.