NOTIFY(2)NOTIFY(2)NAME
notify, noted, atnotify - handle asynchronous process notification
SYNOPSIS
#include <u.h>
#include <libc.h>
int notify(void (*f)(void*, char*))
int noted(int v)
int atnotify(int (*f)(void*, char*), int in)
DESCRIPTION
When a process raises an exceptional condition such as dividing by zero
or writing on a closed pipe, a note is posted to communicate the excep‐
tion. A note may also be posted by a write (see read(2)) to the
process's /proc/n/note file or to the /proc/m/notepg file of a process
in the same process group (see proc(3)). When the note is received the
behavior of the process depends on the origin of the note. If the note
was posted by an external process, the process receiving the note
exits; if generated by the system the note string, preceded by the name
and id of the process and the string "suicide: ", is printed on the
process's standard error file and the process is suspended in the Bro‐
ken state for debugging.
These default actions may be overridden. The notify function registers
a notification handler to be called within the process when a note is
received. The argument to notify replaces the previous handler, if
any. An argument of zero cancels a previous handler, restoring the
default action. A fork(2) system call leaves the handler registered in
both the parent and the child; exec(2) restores the default behavior.
Handlers may not perform floating point operations.
After a note is posted, the handler is called with two arguments: the
first is a pointer to a Ureg structure (defined in /$obj‐
type/include/ureg.h) giving the current values of registers; the second
is a pointer to the note itself, a null-terminated string with no more
than characters in it including the terminal NUL. The Ureg argument is
usually not needed; it is provided to help recover from traps such as
floating point exceptions. Its use and layout are machine- and system-
specific.
A notification handler must finish either by exiting the program or by
calling noted; if the handler returns the behavior is undefined and
probably erroneous. Until the program calls noted, any further exter‐
nally-generated notes (e.g., hangup or alarm) will be held off, and any
further notes generated by erroneous behavior by the program (such as
divide by zero) will kill the program. The argument to noted defines
the action to take: NDFLT instructs the system to perform the default
action as if the handler had never been registered; NCONT instructs the
system to resume the process at the point it was notified. In neither
case does noted return to the handler. If the note interrupted an
incomplete system call, that call returns an error (with error string
interrupted) after the process resumes. A notification handler can
also jump out to an environment set up with setjmp using the notejmp
function (see setjmp(2)), which is implemented by modifying the saved
state and calling noted(NCONT).
Regardless of the origin of the note or the presence of a handler, if
the process is being debugged (see proc(3)) the arrival of a note puts
the process in the Stopped state and awakens the debugger.
Atnotify
Rather than using the system calls notify and noted, most programs
should use atnotify to register notification handlers. The parameter
in is non-zero to register the function f, and zero to cancel registra‐
tion. A handler must return a non-zero number if the note was recog‐
nized (and resolved); otherwise it must return zero. When the system
posts a note to the process, each handler registered with atnotify is
called with arguments as described above until one of the handlers
returns non-zero. Then noted is called with argument NCONT. If no
registered function returns non-zero, atnotify calls noted with argu‐
ment NDFLT.
APE
Noted has two other possible values for its argument. NSAVE returns
from the handler and clears the note, enabling the receipt of another,
but does not return to the program. Instead it starts a new handler
with the same stack, stack pointer, and arguments as the original, at
the address recorded in the program counter of the Ureg structure.
Typically, the program counter will be overridden by the first note
handler to be the address of a separate function; NSAVE is then a
`trampoline' to that handler. That handler may executed noted(NRSTR)
to return to the original program, usually after restoring the original
program counter. NRSTR is identical to NCONT except that it can only
be executed after an NSAVE. NSAVE and NRSTR are designed to improve
the emulation of signals by the ANSI C/POSIX environment; their use
elsewhere is discouraged.
Notes
The set of notes a process may receive is system-dependent, but there
is a common set that includes:
Note Meaning
interrupt user interrupt (DEL key)
hangup I/O connection closed
alarm alarm expired
sys: breakpoint breakpoint instruction
sys: bad address system call address argument out of range
sys: odd address system call address argument unaligned
sys: bad sys call system call number out of range
sys: odd stack system call user stack unaligned
sys: write on closed pipe write on closed pipe
sys: fp: fptrap floating point exception
sys: trap: trap other exception (see below)
The notes prefixed sys: are generated by the operating system. They
are suffixed by the user program counter in format pc=0x1234. If the
note is due to a floating point exception, just before the pc is the
address of the offending instruction in format fppc=0x1234. Notes are
limited to ERRLEN bytes; if they would be longer they are truncated but
the pc is always reported correctly.
The types and syntax of the trap and fptrap portions of the notes are
machine-dependent.
SOURCE
/sys/src/libc/9syscall
/sys/src/libc/port/atnotify.c
SEE ALSOintro(2), postnote(2), notejmp in setjmp(2)BUGS
Since exec(2) discards the notification handler, there is a window of
vulnerability to notes in a new process.
NOTIFY(2)