| .TH NOTIFY 3 |
| .SH NAME |
| notify, noted, atnotify, noteenable, notedisable, notifyon, notifyoff \- 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) |
| .PP |
| .B |
| int noteenable(char *msg) |
| .br |
| .B |
| int notedisable(char *msg) |
| .PP |
| .B |
| int notifyon(char *msg) |
| .br |
| .B |
| int notifyoff(char *msg) |
| .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 another process |
| via |
| .IR postnote (3). |
| On Unix, notes are implemented as signals. |
| .PP |
| When a note is received, the action taken depends on the note. |
| See |
| .IR signal (7) |
| for the full description of the defaults. |
| .PP |
| The 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 (3) |
| 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 unimplemented and should not be used |
| (on Plan 9 |
| it is a |
| .B Ureg |
| structure |
| giving the current values of registers); |
| the second is a pointer to the note itself, |
| a null-terminated string. |
| .\" 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 (3)). |
| .PP |
| Unix provides a fixed set of notes (typically there are 32) called |
| .IR signals . |
| It also allows a process to block certain notes from being delivered |
| (see |
| .IR sigprocmask (2)) |
| and to ignore certain notes by setting the signal hander to the special value |
| .B SIG_IGN |
| (see |
| .IR signal (2)). |
| .I Noteenable |
| and |
| .I notedisable |
| enable or disable receipt of a particular note by changing the current process's blocked signal mask. |
| Receipt of a disabled note will be postponed until it is reenabled. |
| .I Notifyon |
| and |
| .I notifyoff |
| enable or disable whether the notification handler |
| is called upon receipt of the note; if the handler is not called, the note is discarded. |
| .PP |
| Regardless of the origin of the note or the presence of a handler, |
| if the process is being debugged |
| (see |
| .IR ptrace (2)) |
| 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 |
| .I Notify |
| and |
| .I atnotify |
| return \-1 on error and 0 on success. |
| .I Noted |
| returns \-1 on error; successful calls to |
| .I noted |
| do not return. |
| .I Noteenable |
| and |
| .I notedisable |
| .RI ( notitfyon |
| and |
| .IR notifyoff ) |
| return \-1 on error, 0 if the note was previously disabled (not notified), |
| and 1 if the note was previously enabled (notified). |
| .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: segmentation violation \fP'u +\w'process requested to exit 'u |
| \fINote\fP \fIMeaning\fP \fIUnix signal\fP |
| \fLinterrupt\fP user interrupt (DEL key) SIGINTR |
| \fLhangup\fP I/O connection closed SIGHUP |
| \fLalarm\fP alarm expired SIGLARM |
| \fLquit\fP quit from keyboard SIGQUIT |
| \fLkill\fP process requested to exit SIGTERM |
| \fLsys: kill\fP process forced to exit SIGKILL |
| \fLsys: bus error\fP bus error SIGBUS |
| \fLsys: segmentation violation\fP segmentation violation SIGSEGV |
| \fLsys: write on closed pipe\fP write on closed pipe SIGPIPE |
| \fLsys: child\fP child wait status change SIGCHLD |
| .fi |
| .RE |
| .PP |
| See |
| .B \*9/src/lib9/await.c |
| (sic) |
| for the full list. |
| .PP |
| The notes prefixed |
| .B sys: |
| are usually generated by the operating system. |
| .SH SOURCE |
| .B \*9/src/lib9/notify.c |
| .br |
| .B \*9/src/lib9/atnotify.c |
| .SH SEE ALSO |
| .IR intro (3), |
| .I notejmp |
| in |
| .IR setjmp (3) |