.TH NOTIFY 2 .SH NAME notify, noted, atnotify \- handle asynchronous process notification .SH SYNOPSIS .B #include .br .B #include .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 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.