123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- .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.
- .PP
- 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 .
- .PP
- .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.
- .PP
- 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 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.
|