245 lines
6.3 KiB
Text
245 lines
6.3 KiB
Text
.TH NOTIFY 2
|
|
.SH NAME
|
|
notify, noted, atnotify \- handle asynchronous process notification
|
|
.SH SYNOPSIS
|
|
.B #include <u.h>
|
|
.br
|
|
.B #include <libc.h>
|
|
.PP
|
|
.B
|
|
int notify(void (*f)(void*, char*))
|
|
.PP
|
|
.B
|
|
int noted(int v)
|
|
.PP
|
|
.B
|
|
int atnotify(int (*f)(void*, char*), int in)
|
|
.SH DESCRIPTION
|
|
When a process raises an exceptional condition such as dividing by zero
|
|
or writing on a closed pipe, a
|
|
.I note
|
|
is posted to communicate the exception.
|
|
A note may also be posted by a
|
|
.I write
|
|
(see
|
|
.IR read (2))
|
|
to the process's
|
|
.BI /proc/ n /note
|
|
file or to the
|
|
.BI /proc/ m /notepg
|
|
file of a process in the same process group (see
|
|
.IR 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
|
|
\fL"suicide: "\fP,
|
|
is printed on the process's standard error file
|
|
and the
|
|
process is suspended in the
|
|
.B Broken
|
|
state for debugging.
|
|
.PP
|
|
These default actions may be overridden.
|
|
The
|
|
.I notify
|
|
function registers a
|
|
.I "notification handler
|
|
to be called within the process when a note is received.
|
|
The argument to
|
|
.I notify
|
|
replaces the previous handler, if any.
|
|
An argument of zero cancels a previous handler,
|
|
restoring the default action.
|
|
A
|
|
.IR fork (2)
|
|
system call leaves the handler registered in
|
|
both the parent and the child;
|
|
.IR exec (2)
|
|
restores the default behavior.
|
|
Handlers may not perform floating point operations.
|
|
.PP
|
|
After a note is posted,
|
|
the handler is called with two arguments:
|
|
the first is a pointer to a
|
|
.B Ureg
|
|
structure (defined in
|
|
.BR /$objtype/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
|
|
.L ERRLEN
|
|
characters in it including the terminal NUL.
|
|
The
|
|
.B 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.
|
|
.PP
|
|
A notification handler must finish either by exiting the program or by calling
|
|
.IR noted ;
|
|
if the handler returns the behavior
|
|
is undefined and probably erroneous.
|
|
Until the program calls
|
|
.IR noted ,
|
|
any further externally-generated notes
|
|
(e.g.,
|
|
.B hangup
|
|
or
|
|
.BR 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
|
|
.I noted
|
|
defines the action to take:
|
|
.B NDFLT
|
|
instructs the system to perform the default action
|
|
as if the handler had never been registered;
|
|
.B NCONT
|
|
instructs the system to resume the process
|
|
at the point it was notified.
|
|
In neither case does
|
|
.I noted
|
|
return to the handler.
|
|
If the note interrupted an incomplete system call,
|
|
that call returns an error (with error string
|
|
.BR interrupted )
|
|
after the process resumes.
|
|
A notification handler can also jump out to an environment
|
|
set up with
|
|
.I setjmp
|
|
using the
|
|
.I notejmp
|
|
function (see
|
|
.IR setjmp (2)),
|
|
which is implemented by modifying the saved state and calling
|
|
.BR noted(NCONT) .
|
|
.PP
|
|
Regardless of the origin of the note or the presence of a handler,
|
|
if the process is being debugged
|
|
(see
|
|
.IR proc (3))
|
|
the arrival of a note puts the process in the
|
|
.B Stopped
|
|
state and awakens the debugger.
|
|
.SS Atnotify
|
|
Rather than using the system calls
|
|
.I notify
|
|
and
|
|
.IR noted ,
|
|
most programs should use
|
|
.I atnotify
|
|
to register notification handlers.
|
|
The parameter
|
|
.I in
|
|
is non-zero to register the function
|
|
.IR f ,
|
|
and zero to cancel registration.
|
|
A handler must return a non-zero number
|
|
if the note was recognized (and resolved);
|
|
otherwise it must return zero.
|
|
When the system posts a note to the process,
|
|
each handler registered with
|
|
.I atnotify
|
|
is called with arguments as
|
|
described above
|
|
until one of the handlers returns non-zero.
|
|
Then
|
|
.I noted
|
|
is called with argument
|
|
.BR NCONT .
|
|
If no registered function returns non-zero,
|
|
.I atnotify
|
|
calls
|
|
.I noted
|
|
with argument
|
|
.BR NDFLT .
|
|
.SS APE
|
|
.I Noted
|
|
has two other possible values for its argument.
|
|
.B 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
|
|
.B Ureg
|
|
structure. Typically, the program counter will be overridden by the
|
|
first note handler to be the address of a separate function;
|
|
.B NSAVE
|
|
is then a `trampoline' to that handler.
|
|
That handler may executed
|
|
.B noted(NRSTR)
|
|
to return to the original program, usually after restoring the original program
|
|
counter.
|
|
.B NRSTR
|
|
is identical to
|
|
.BR NCONT
|
|
except that it can only be executed after an
|
|
.BR NSAVE .
|
|
.B NSAVE
|
|
and
|
|
.B NRSTR
|
|
are designed to improve the emulation of signals by the ANSI C/POSIX
|
|
environment; their use elsewhere is discouraged.
|
|
.SS Notes
|
|
The set of notes a process may receive is system-dependent, but there
|
|
is a common set that includes:
|
|
.PP
|
|
.RS 3n
|
|
.nf
|
|
.ta \w'\fLsys: write on closed pipe \fP'u
|
|
\fINote\fP \fIMeaning\fP
|
|
\fLinterrupt\fP user interrupt (DEL key)
|
|
\fLhangup\fP I/O connection closed
|
|
\fLalarm\fP alarm expired
|
|
\fLsys: breakpoint\fP breakpoint instruction
|
|
\fLsys: bad address\fP system call address argument out of range
|
|
\fLsys: odd address\fP system call address argument unaligned
|
|
\fLsys: bad sys call\fP system call number out of range
|
|
\fLsys: odd stack\fP system call user stack unaligned
|
|
\fLsys: write on closed pipe\fP write on closed pipe
|
|
\fLsys: fp: \fIfptrap\f1 floating point exception
|
|
\fLsys: trap: \fItrap\f1 other exception (see below)
|
|
.fi
|
|
.RE
|
|
.PP
|
|
The notes prefixed
|
|
.B sys:
|
|
are generated by the operating system.
|
|
They are suffixed by the user program counter in format
|
|
.BR pc=0x1234 .
|
|
If the note is due to a floating point exception, just before the
|
|
.BR pc
|
|
is the address of the offending instruction in format
|
|
.BR fppc=0x1234 .
|
|
Notes are limited to
|
|
.B ERRLEN
|
|
bytes; if they would be longer they are truncated but the
|
|
.B pc
|
|
is always reported correctly.
|
|
.PP
|
|
The types and syntax of the
|
|
.I trap
|
|
and
|
|
.I fptrap
|
|
portions of the notes are machine-dependent.
|
|
.SH SOURCE
|
|
.B /sys/src/libc/9syscall
|
|
.br
|
|
.B /sys/src/libc/port/atnotify.c
|
|
.SH SEE ALSO
|
|
.IR postnote (2),
|
|
.IR intro (2),
|
|
.I notejmp
|
|
in
|
|
.IR setjmp (2)
|
|
.SH BUGS
|
|
Since
|
|
.IR exec (2)
|
|
discards the notification handler, there is a window
|
|
of vulnerability to notes in a new process.
|