summaryrefslogtreecommitdiff
path: root/sys/man/2
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 16:49:47 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 16:49:47 +0300
commitb41b9034225ab3e49980d9de55c141011b6383b0 (patch)
tree891014b4c2e803e01ac7a1fd2b60819fbc5a6e73 /sys/man/2
parentc558a99e0be506a9abdf677f0ca4490644e05fc1 (diff)
Import sources from 2011-03-30 iso image - sys/man
Diffstat (limited to 'sys/man/2')
-rwxr-xr-xsys/man/2/0intro457
-rwxr-xr-xsys/man/2/9p788
-rwxr-xr-xsys/man/2/9pcmdbuf120
-rwxr-xr-xsys/man/2/9pfid207
-rwxr-xr-xsys/man/2/9pfile223
-rwxr-xr-xsys/man/2/INDEX1514
-rwxr-xr-xsys/man/2/INDEX.html637
-rwxr-xr-xsys/man/2/abort18
-rwxr-xr-xsys/man/2/abs33
-rwxr-xr-xsys/man/2/access60
-rwxr-xr-xsys/man/2/addpt188
-rwxr-xr-xsys/man/2/aes101
-rwxr-xr-xsys/man/2/allocimage348
-rwxr-xr-xsys/man/2/arg126
-rwxr-xr-xsys/man/2/arith3268
-rwxr-xr-xsys/man/2/assert25
-rwxr-xr-xsys/man/2/atof144
-rwxr-xr-xsys/man/2/auth394
-rwxr-xr-xsys/man/2/authsrv238
-rwxr-xr-xsys/man/2/avl147
-rwxr-xr-xsys/man/2/bin99
-rwxr-xr-xsys/man/2/bind236
-rwxr-xr-xsys/man/2/bio361
-rwxr-xr-xsys/man/2/blowfish52
-rwxr-xr-xsys/man/2/brk62
-rwxr-xr-xsys/man/2/cachechars313
-rwxr-xr-xsys/man/2/chdir32
-rwxr-xr-xsys/man/2/cleanname34
-rwxr-xr-xsys/man/2/color56
-rwxr-xr-xsys/man/2/complete105
-rwxr-xr-xsys/man/2/control1948
-rwxr-xr-xsys/man/2/cputime60
-rwxr-xr-xsys/man/2/ctime129
-rwxr-xr-xsys/man/2/ctype160
-rwxr-xr-xsys/man/2/debugger386
-rwxr-xr-xsys/man/2/des149
-rwxr-xr-xsys/man/2/dial333
-rwxr-xr-xsys/man/2/dirread103
-rwxr-xr-xsys/man/2/disk172
-rwxr-xr-xsys/man/2/draw821
-rwxr-xr-xsys/man/2/dsa139
-rwxr-xr-xsys/man/2/dup42
-rwxr-xr-xsys/man/2/elgamal125
-rwxr-xr-xsys/man/2/encode85
-rwxr-xr-xsys/man/2/encrypt76
-rwxr-xr-xsys/man/2/errstr85
-rwxr-xr-xsys/man/2/event384
-rwxr-xr-xsys/man/2/exec200
-rwxr-xr-xsys/man/2/exits81
-rwxr-xr-xsys/man/2/exp62
-rwxr-xr-xsys/man/2/fauth66
-rwxr-xr-xsys/man/2/fcall357
-rwxr-xr-xsys/man/2/fd2path57
-rwxr-xr-xsys/man/2/fgetc213
-rwxr-xr-xsys/man/2/flate207
-rwxr-xr-xsys/man/2/floor58
-rwxr-xr-xsys/man/2/fmtinstall372
-rwxr-xr-xsys/man/2/fopen354
-rwxr-xr-xsys/man/2/fork166
-rwxr-xr-xsys/man/2/fprintf506
-rwxr-xr-xsys/man/2/frame362
-rwxr-xr-xsys/man/2/frexp47
-rwxr-xr-xsys/man/2/fscanf404
-rwxr-xr-xsys/man/2/fversion72
-rwxr-xr-xsys/man/2/getcallerpc38
-rwxr-xr-xsys/man/2/getenv44
-rwxr-xr-xsys/man/2/getfcr119
-rwxr-xr-xsys/man/2/getfields99
-rwxr-xr-xsys/man/2/getpid42
-rwxr-xr-xsys/man/2/getuser37
-rwxr-xr-xsys/man/2/getwd37
-rwxr-xr-xsys/man/2/graphics642
-rwxr-xr-xsys/man/2/html1420
-rwxr-xr-xsys/man/2/httpd307
-rwxr-xr-xsys/man/2/hypot21
-rwxr-xr-xsys/man/2/intmap126
-rwxr-xr-xsys/man/2/ioproc178
-rwxr-xr-xsys/man/2/iounit37
-rwxr-xr-xsys/man/2/ip364
-rwxr-xr-xsys/man/2/isalpharune54
-rwxr-xr-xsys/man/2/keyboard104
-rwxr-xr-xsys/man/2/lock313
-rwxr-xr-xsys/man/2/mach393
-rwxr-xr-xsys/man/2/malloc230
-rwxr-xr-xsys/man/2/matrix350
-rwxr-xr-xsys/man/2/memdraw448
-rwxr-xr-xsys/man/2/memlayer305
-rwxr-xr-xsys/man/2/memory126
-rwxr-xr-xsys/man/2/mktemp40
-rwxr-xr-xsys/man/2/mouse249
-rwxr-xr-xsys/man/2/mp610
-rwxr-xr-xsys/man/2/muldiv31
-rwxr-xr-xsys/man/2/nan52
-rwxr-xr-xsys/man/2/ndb498
-rwxr-xr-xsys/man/2/notify244
-rwxr-xr-xsys/man/2/object150
-rwxr-xr-xsys/man/2/open148
-rwxr-xr-xsys/man/2/perror92
-rwxr-xr-xsys/man/2/pipe74
-rwxr-xr-xsys/man/2/plumb240
-rwxr-xr-xsys/man/2/pool356
-rwxr-xr-xsys/man/2/postnote49
-rwxr-xr-xsys/man/2/prime100
-rwxr-xr-xsys/man/2/print452
-rwxr-xr-xsys/man/2/privalloc36
-rwxr-xr-xsys/man/2/proto131
-rwxr-xr-xsys/man/2/pushssl45
-rwxr-xr-xsys/man/2/pushtls254
-rwxr-xr-xsys/man/2/qball75
-rwxr-xr-xsys/man/2/qsort33
-rwxr-xr-xsys/man/2/quaternion151
-rwxr-xr-xsys/man/2/quote167
-rwxr-xr-xsys/man/2/rand175
-rwxr-xr-xsys/man/2/rc455
-rwxr-xr-xsys/man/2/read96
-rwxr-xr-xsys/man/2/readcolmap76
-rwxr-xr-xsys/man/2/readv82
-rwxr-xr-xsys/man/2/regexp212
-rwxr-xr-xsys/man/2/remove31
-rwxr-xr-xsys/man/2/rendezvous58
-rwxr-xr-xsys/man/2/rsa219
-rwxr-xr-xsys/man/2/rune193
-rwxr-xr-xsys/man/2/runestrcat67
-rwxr-xr-xsys/man/2/scribble162
-rwxr-xr-xsys/man/2/scsi186
-rwxr-xr-xsys/man/2/sechash203
-rwxr-xr-xsys/man/2/seek46
-rwxr-xr-xsys/man/2/segattach168
-rwxr-xr-xsys/man/2/segbrk66
-rwxr-xr-xsys/man/2/segflush42
-rwxr-xr-xsys/man/2/semacquire106
-rwxr-xr-xsys/man/2/setjmp98
-rwxr-xr-xsys/man/2/sin64
-rwxr-xr-xsys/man/2/sinh23
-rwxr-xr-xsys/man/2/sleep45
-rwxr-xr-xsys/man/2/stat326
-rwxr-xr-xsys/man/2/strcat269
-rwxr-xr-xsys/man/2/string236
-rwxr-xr-xsys/man/2/stringsize69
-rwxr-xr-xsys/man/2/subfont235
-rwxr-xr-xsys/man/2/symbol436
-rwxr-xr-xsys/man/2/thread642
-rwxr-xr-xsys/man/2/time44
-rwxr-xr-xsys/man/2/tmpfile60
-rwxr-xr-xsys/man/2/usb460
-rwxr-xr-xsys/man/2/usbfs341
-rwxr-xr-xsys/man/2/venti72
-rwxr-xr-xsys/man/2/venti-cache246
-rwxr-xr-xsys/man/2/venti-client190
-rwxr-xr-xsys/man/2/venti-conn200
-rwxr-xr-xsys/man/2/venti-fcall275
-rwxr-xr-xsys/man/2/venti-file325
-rwxr-xr-xsys/man/2/venti-log136
-rwxr-xr-xsys/man/2/venti-mem68
-rwxr-xr-xsys/man/2/venti-packet281
-rwxr-xr-xsys/man/2/venti-server122
-rwxr-xr-xsys/man/2/venti-zero56
-rwxr-xr-xsys/man/2/wait122
-rwxr-xr-xsys/man/2/window244
159 files changed, 34206 insertions, 0 deletions
diff --git a/sys/man/2/0intro b/sys/man/2/0intro
new file mode 100755
index 000000000..ad5ea1c4a
--- /dev/null
+++ b/sys/man/2/0intro
@@ -0,0 +1,457 @@
+.TH INTRO 2
+.SH NAME
+intro \- introduction to library functions
+.SH SYNOPSIS
+.nf
+.B #include <u.h>
+.PP
+.B #include <libc.h>
+.PP
+.B #include <auth.h>
+.PP
+.B #include <bio.h>
+.PP
+.B #include <draw.h>
+.PP
+.B #include <fcall.h>
+.PP
+.B #include <frame.h>
+.PP
+.B #include <mach.h>
+.PP
+.B #include <ndb.h>
+.PP
+.B #include <regexp.h>
+.PP
+.B #include <stdio.h>
+.PP
+.B #include <thread.h>
+.fi
+.SH DESCRIPTION
+This section describes functions
+in various libraries.
+For the most part, each library is defined by a single C include
+file, such as those listed above, and a single archive file containing
+the library proper. The name of the archive is
+.BI /$objtype/lib/lib x .a \f1,
+where
+.I x
+is the base of the include file name, stripped of a leading
+.B lib
+if present.
+For example,
+.B <draw.h>
+defines the contents of library
+.BR /$objtype/lib/libdraw.a ,
+which may be abbreviated when named to the loader as
+.BR -ldraw .
+In practice, each include file contains a
+.B #pragma
+that directs the loader to pick up the associated archive
+automatically, so it is rarely necessary to tell the loader
+which
+libraries a program needs.
+.PP
+The library to which a function belongs is defined by the
+header file that defines its interface.
+The `C library',
+.IR libc ,
+contains most of the basic subroutines such
+as
+.IR strlen .
+Declarations for all of these functions are
+in
+.BR <libc.h> ,
+which must be preceded by
+.RI ( needs )
+an include of
+.BR <u.h> .
+The graphics library,
+.IR draw ,
+is defined by
+.BR <draw.h> ,
+which needs
+.B <libc.h>
+and
+.BR <u.h> .
+The Buffered I/O library,
+.IR libbio ,
+is defined by
+.BR <bio.h> ,
+which needs
+.B <libc.h>
+and
+.BR <u.h> .
+The ANSI C Standard I/O library,
+.IR libstdio ,
+is defined by
+.BR <stdio.h> ,
+which needs
+.BR <u.h> .
+There are a few other, less commonly used libraries defined on
+individual pages of this section.
+.PP
+The include file
+.BR <u.h> ,
+a prerequisite of several other include files,
+declares the architecture-dependent and -independent types, including:
+.IR uchar ,
+.IR ushort ,
+.IR uint ,
+and
+.IR ulong ,
+the unsigned integer types;
+.IR schar ,
+the signed char type;
+.I vlong
+and
+.IR uvlong ,
+the signed and unsigned very long integral types;
+.IR Rune ,
+the Unicode character type;
+.IR u8int ,
+.IR u16int ,
+.IR u32int ,
+and
+.IR u64int ,
+the unsigned integral types with specific widths;
+.IR uintptr ,
+the unsigned integral type with the same width as a pointer;
+.IR jmp_buf ,
+the type of the argument to
+.I setjmp
+and
+.IR longjmp ,
+plus macros that define the layout of
+.IR jmp_buf
+(see
+.IR setjmp (2));
+definitions of the bits in the floating-point control register
+as used by
+.IR getfcr (2);
+and
+the macros
+.B va_arg
+and friends for accessing arguments of variadic functions (identical to the
+macros defined in
+.B <stdarg.h>
+in ANSI C).
+.SS "Name space
+Files are collected into a hierarchical organization called a
+.I "file tree
+starting in a
+.I directory
+called the
+.IR root .
+File names, also called
+.IR paths ,
+consist of a number of
+.BR / -separated
+.I "path elements"
+with the slashes corresponding to directories.
+A path element must contain only printable
+characters (those outside the control spaces of
+.SM ASCII
+and Latin-1).
+A path element cannot contain a slash.
+.PP
+When a process presents a file name to Plan 9, it is
+.I evaluated
+by the following algorithm.
+Start with a directory that depends on the first
+character of the path:
+.L /
+means the root of the main hierarchy,
+.L #
+means the separate root of a kernel device's file tree (see Section 3),
+and anything else means the process's current working directory.
+Then for each path element, look up the element
+in the directory, advance to that directory,
+do a possible translation (see below), and repeat.
+The last step may yield a directory or regular file.
+The collection of files reachable from the root is called the
+.I "name space
+of a process.
+.PP
+A program can use
+.I bind
+or
+.I mount
+(see
+.IR bind (2))
+to say that whenever a specified file is reached during evaluation,
+evaluation instead continues from a second specified file.
+Also, the same system calls create
+.IR "union directories" ,
+which are concatenations of ordinary directories
+that are searched sequentially until the desired element is found.
+Using
+.I bind
+and
+.I mount
+to do name space adjustment affects only
+the current process group (see below).
+Certain conventions about the layout of the name space should
+be preserved; see
+.IR namespace (4).
+.SS "File I/O"
+Files are opened for input or output
+by
+.I open
+or
+.I create
+(see
+.IR open (2)).
+These calls return an integer called a
+.IR "file descriptor"
+which identifies the file
+to subsequent I/O calls,
+notably
+.IR read (2)
+and
+.IR write .
+The system allocates the numbers by selecting the lowest unused descriptor.
+They are allocated dynamically; there is no visible limit to the number of file
+descriptors a process may have open.
+They may be reassigned using
+.IR dup (2).
+File descriptors are indices into a
+kernel resident
+.IR "file descriptor table" .
+Each process has an associated file descriptor table.
+In some cases (see
+.I rfork
+in
+.IR fork (2))
+a file descriptor table may be shared by several processes.
+.PP
+By convention,
+file descriptor 0 is the standard input,
+1 is the standard output,
+and 2 is the standard error output.
+With one exception, the operating system is unaware of these conventions;
+it is permissible to close file 0,
+or even to replace it by a file open only for writing,
+but many programs will be confused by such chicanery.
+The exception is that the system prints messages about broken processes
+to file descriptor 2.
+.PP
+Files are normally read or written in sequential order.
+The I/O position in the file is called the
+.IR "file offset"
+and may be set arbitrarily using the
+.IR seek (2)
+system call.
+.PP
+Directories may be opened and read much like regular files.
+They contain an integral number of records, called
+.IR "directory entries" .
+Each entry is a machine-independent representation of
+the information about an existing file in the directory,
+including the name, ownership,
+permission,
+access dates,
+and so on.
+The entry
+corresponding to an arbitrary file can be retrieved by
+.IR stat (2)
+or
+.IR fstat ;
+.I wstat
+and
+.I fwstat
+write back entries, thus changing the properties of a file.
+An entry may be translated into a more convenient, addressable
+form called a
+.B Dir
+structure;
+.IR dirstat ,
+.IR dirfstat,
+.IR dirwstat ,
+and
+.I dirfwstat
+execute the appropriate translations (see
+.IR stat (2)).
+.PP
+New files are made with
+.I create
+(see
+.IR open (2))
+and deleted with
+.IR remove (2).
+Directories may not directly be written;
+.IR create ,
+.IR remove ,
+.IR wstat ,
+and
+.I fwstat
+alter them.
+.PP
+The operating system kernel records the file name used to access each open file or directory.
+If the file is opened by a local name (one that does not begin
+.B /
+or
+.BR # ),
+the system makes the stored name absolute by prefixing
+the string associated with the current directory.
+Similar lexical adjustments are made for path names containing
+.B .
+(dot) or
+.B ..
+(dot-dot).
+By this process, the system maintains a record of the route by which each file was accessed.
+Although there is a possibility for error\(emthe name is not maintained after the file is opened,
+so removals and renamings can confound it\(emthis simple method usually
+permits the system to return, via the
+.IR fd2path (2)
+system call and related calls such as
+.IR getwd (2),
+a valid name that may be used to find a file again.
+This is also the source of the names reported in the name space listing of
+.IR ns (1)
+or
+.B /dev/ns
+(see
+.IR proc (3)).
+.PP
+.IR Pipe (2)
+creates a connected pair of file descriptors,
+useful for bidirectional local communication.
+.SS "Process execution and control"
+A new process is created
+when an existing one calls
+.I rfork
+with the
+.B RFPROC
+bit set, usually just by calling
+.IR fork (2).
+The new (child) process starts out with
+copies of the address space and most other attributes
+of the old (parent) process.
+In particular,
+the child starts out running
+the same program as the parent;
+.IR exec (2)
+will bring in a different one.
+.PP
+Each process has a unique integer process id;
+a set of open files, indexed by file descriptor;
+and a current working directory
+(changed by
+.IR chdir (2)).
+.PP
+Each process has a set of attributes \(em memory, open files,
+name space, etc. \(em that may be shared or unique.
+Flags to
+.IR rfork
+control the sharing of these attributes.
+.PP
+The memory of a process is divided into
+.IR segments .
+Every program has at least a
+.I text
+(instruction) and
+.I stack
+segment.
+Most also have an initialized
+.I data
+segment and a segment of zero-filled data called
+.IR bss .
+Processes may
+.IR segattach (2)
+other segments for special purposes.
+.PP
+A process terminates by calling
+.IR exits (2).
+A parent process may call
+.IR wait (2)
+to wait for some child to terminate.
+A string of status information
+may be passed from
+.I exits
+to
+.IR wait .
+A process can go to sleep for a specified time by calling
+.IR sleep (2).
+.PP
+There is a
+.I notification
+mechanism for telling a process about events such as address faults,
+floating point faults, and messages from other processes.
+A process uses
+.IR notify (2)
+to register the function to be called (the
+.IR "notification handler" )
+when such events occur.
+.SS Multithreading
+By calling
+.I rfork
+with the
+.B RFMEM
+bit set, a program may create several independently executing processes sharing the same
+memory (except for the stack segment, which is unique to each process).
+Where possible according to the ANSI C standard,
+the main C library works properly in multiprocess programs;
+.IR malloc ,
+.IR print ,
+and the other routines use locks (see
+.IR lock (2))
+to synchronize access to their data structures.
+The graphics library defined in
+.B <draw.h>
+is also multi-process capable; details are in
+.IR graphics (2).
+In general, though, multiprocess programs should use some form of synchronization
+to protect shared data.
+.PP
+The thread library, defined in
+.BR <thread.h> ,
+provides support for multiprocess programs.
+It includes a data structure called a
+.B Channel
+that can be used to send messages between processes,
+and coroutine-like
+.IR threads ,
+which enable multiple threads of control within a single process.
+The threads within a process are scheduled by the library, but there is
+no pre-emptive scheduling within a process; thread switching occurs
+only at communication or synchronization points.
+.PP
+Most programs using the thread library
+comprise multiple processes
+communicating over channels, and within some processes,
+multiple threads. Since Plan 9 I/O calls may block, a system
+call may block all the threads in a process.
+Therefore, a program that shouldn't block unexpectedly will use a process
+to serve the I/O request, passing the result to the main processes
+over a channel when the request completes.
+For examples of this design, see
+.IR ioproc (2)
+or
+.IR mouse (2).
+.SH SEE ALSO
+.IR nm (1),
+.IR 2l (1),
+.IR 2c (1)
+.SH DIAGNOSTICS
+Math functions in
+.I libc
+return
+special values when the function is undefined for the
+given arguments or when the value is not representable
+(see
+.IR nan (2)).
+.PP
+Some of the functions in
+.I libc
+are system calls and many others employ system calls in their implementation.
+All system calls return integers,
+with \-1 indicating that an error occurred;
+.IR errstr (2)
+recovers a string describing the error.
+Some user-level library functions also use the
+.I errstr
+mechanism to report errors.
+Functions that may affect the value of the error string are said to ``set
+.IR errstr '';
+it is understood that the error string is altered only if an error occurs.
diff --git a/sys/man/2/9p b/sys/man/2/9p
new file mode 100755
index 000000000..5ec62552f
--- /dev/null
+++ b/sys/man/2/9p
@@ -0,0 +1,788 @@
+.TH 9P 2
+.SH NAME
+Srv,
+dirread9p,
+emalloc9p,
+erealloc9p,
+estrdup9p,
+listensrv,
+postfd,
+postmountsrv,
+readbuf,
+readstr,
+respond,
+responderror,
+threadlistensrv,
+threadpostmountsrv,
+srv \- 9P file service
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fL1234'u +\w'\fLTree* 'u
+typedef struct Srv {
+ Tree* tree;
+
+ void (*attach)(Req *r);
+ void (*auth)(Req *r);
+ void (*open)(Req *r);
+ void (*create)(Req *r);
+ void (*read)(Req *r);
+ void (*write)(Req *r);
+ void (*remove)(Req *r);
+ void (*flush)(Req *r);
+ void (*stat)(Req *r);
+ void (*wstat)(Req *r);
+ void (*walk)(Req *r);
+
+ char* (*walk1)(Fid *fid, char *name, Qid *qid);
+ char* (*clone)(Fid *oldfid, Fid *newfid);
+
+ void (*destroyfid)(Fid *fid);
+ void (*destroyreq)(Req *r);
+ void (*end)(Srv *s);
+ void* aux;
+
+ int infd;
+ int outfd;
+ int srvfd;
+ int nopipe;
+} Srv;
+.fi
+.PP
+.nf
+.ft L
+.ta \w'\fLvoid* 'u
+int srv(Srv *s)
+void postmountsrv(Srv *s, char *name, char *mtpt, int flag)
+void threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag)
+void listensrv(Srv *s, char *addr)
+void threadlistensrv(Srv *s, char *addr)
+int postfd(char *srvname, int fd)
+void respond(Req *r, char *error)
+void responderror(Req*)
+void readstr(Req *r, char *src)
+void readbuf(Req *r, void *src, long nsrc)
+typedef int Dirgen(int n, Dir *dir, void *aux)
+void dirread9p(Req *r, Dirgen *gen, void *aux)
+void walkandclone(Req *r, char *(*walk1)(Fid *old, char *name, void *v),
+ char *(*clone)(Fid *old, Fid *new, void *v), void *v)
+.fi
+.PP
+.nf
+.ft L
+.ta \w'\fLvoid* 'u
+void* emalloc9p(ulong n)
+void* erealloc9p(void *v, ulong n)
+char* estrdup9p(char *s)
+.fi
+.PP
+.nf
+.ft L
+extern int chatty9p;
+.fi
+.SH DESCRIPTION
+The function
+.I srv
+serves a 9P session by reading requests from
+.BR s->infd ,
+dispatching them to the function pointers kept in
+.BR Srv ,
+and
+writing the responses to
+.BR s->outfd .
+(Typically,
+.I postmountsrv
+or
+.I threadpostmountsrv
+initializes the
+.B infd
+and
+.B outfd
+structure members. See the description below.)
+.PP
+.B Req
+and
+.B Fid
+structures are allocated one-to-one with uncompleted
+requests and active fids, and are described in
+.IR 9pfid (2).
+.PP
+The behavior of
+.I srv
+depends on whether there is a file tree
+(see
+.IR 9pfile (2))
+associated with the server, that is,
+whether the
+.B tree
+element is nonzero.
+The differences are made explicit in the
+discussion of the service loop below.
+The
+.B aux
+element is the client's, to do with as it pleases.
+.PP
+.I Srv
+does not return until the 9P conversation is finished.
+Since it is usually run in a separate process so that
+the caller can exit, the service loop has little chance
+to return gracefully on out of memory errors.
+It calls
+.IR emalloc9p ,
+.IR erealloc9p ,
+and
+.I estrdup9p
+to obtain its memory.
+The default implementations of these functions
+act as
+.IR malloc ,
+.IR realloc ,
+and
+.I strdup
+but abort the program if they run out of memory.
+If alternate behavior is desired, clients can link against
+alternate implementations of these functions.
+.PP
+.I Postmountsrv
+and
+.I threadpostmountsrv
+are wrappers that create a separate process in which to run
+.IR srv .
+They do the following:
+.IP
+If
+.IB s -> nopipe
+is zero (the common case),
+initialize
+.IB s -> infd
+and
+.IB s -> outfd
+to be one end of a freshly allocated pipe,
+with
+.IB s -> srvfd
+initialized as the other end.
+.IP
+If
+.B name
+is non-nil, call
+.BI postfd( s -> srvfd ,
+.IB name )
+to post
+.IB s -> srvfd
+as
+.BI /srv/ name .
+.IP
+Fork a child process via
+.I rfork
+(see
+.IR fork (2))
+or
+.I procrfork
+(see
+.IR thread (2)),
+using the
+.BR RFFDG ,
+.RR RFNOTEG ,
+.BR RFNAMEG ,
+and
+.BR RFMEM
+flags.
+The child process
+calls
+.IB close( s -> srvfd )
+and then
+.IB srv( s ) \fR;
+it will exit once
+.I srv
+returns.
+.IP
+If
+.I mtpt
+is non-nil,
+call
+.BI amount( s -> srvfd,
+.IB mtpt ,
+.IB flag ,
+\fB"")\fR;
+otherwise, close
+.IB s -> srvfd \fR.
+.IP
+The parent returns to the caller.
+.LP
+If any error occurs during
+this process, the entire process is terminated by calling
+.I sysfatal
+(see
+.IR perror (2)).
+.PP
+.I Listensrv
+and
+.I threadlistensrv
+create a separate process to announce as
+.IR addr .
+The process listens for incoming connections,
+creating a new process to serve each.
+Using these functions results in
+.I srv
+and the service functions
+being run in multiple processes simultaneously.
+The library locks its own data structures as necessary;
+the client may need to lock data it shares between
+the multiple connections.
+.SS Service functions
+The functions in a
+.B Srv
+structure named after 9P transactions
+are called to satisfy requests as they arrive.
+If a function is provided, it
+.I must
+arrange for
+.I respond
+to be called when the request is satisfied.
+The only parameter of each service function
+is a
+.B Req*
+parameter (say
+.IR r ).
+The incoming request parameters are stored in
+.IB r -> ifcall \fR;
+.IB r -> fid
+and
+.IB r -> newfid
+are pointers to
+.B Fid
+structures corresponding to the
+numeric fids in
+.IB r -> ifcall \fR;
+similarly,
+.IB r -> oldreq
+is the
+.B Req
+structure corresponding to
+.IB r -> ifcall.oldtag \fR.
+The outgoing response data should be stored in
+.IB r -> ofcall \fR.
+The one exception to this rule is that
+.I stat
+should fill in
+.IB r -> d
+rather than
+.IB r -> ofcall.stat \fR:
+the library will convert the structure into the machine-independent
+wire representation.
+Similarly,
+.I wstat
+may consult
+.IB r -> d
+rather than decoding
+.IB r -> ifcall . stat
+itself.
+When a request has been handled,
+.I respond
+should be called with
+.I r
+and an error string.
+If the request was satisfied successfully, the error
+string should be a nil pointer.
+Note that it is permissible for a function to return
+without itself calling
+.IR respond ,
+as long as it has arranged for
+.I respond
+to be called at some point in the future
+by another proc sharing its address space,
+but see the discussion of
+.I flush
+below.
+Once
+.I respond
+has been called, the
+.B Req*
+as well as any pointers it once contained must
+be considered freed and not referenced.
+.PP
+.I Responderror
+calls
+.I respond
+with the system error string
+(see
+.IR errstr (2)).
+.PP
+If the service loop detects an error in a request
+(e.g., an attempt to reuse an extant fid, an open of
+an already open fid, a read from a fid opened for write, etc.)
+it will reply with an error without consulting
+the service functions.
+.PP
+The service loop provided by
+.I srv
+(and indirectly by
+.I postmountsrv
+and
+.IR threadpostmountsrv )
+is single-threaded.
+If it is expected that some requests might
+block, arranging for alternate processes
+to handle them is suggested.
+.PP
+The constraints on the service functions are as follows.
+These constraints are checked while the server executes.
+If a service function fails to do something it ought to have,
+.I srv
+will call
+.I endsrv
+and then abort.
+.TP
+.I Auth
+If authentication is desired,
+the
+.I auth
+function should record that
+.IB r -> afid
+is the new authentication fid and
+set
+.IB r -> afid -> qid
+and
+.IR ofcall.qid .
+.I Auth
+may be nil, in which case it will be treated as having
+responded with the error
+.RI `` "argv0: authentication not required" ,''
+where
+.I argv0
+is the program name variable as set by
+.I ARGBEGIN
+(see
+.IR arg (2)).
+.TP
+.I Attach
+The
+.I attach
+function should check the authentication state of
+.I afid
+if desired,
+and set
+.IB r -> fid -> qid
+and
+.I ofcall.qid
+to the qid of the file system root.
+.I Attach
+may be nil only if file trees are in use;
+in this case, the qid will be filled from the root
+of the tree, and no authentication will be done.
+.TP
+.I Walk
+If file trees are in use,
+.I walk
+is handled internally, and
+.IB srv -> walk
+is never called.
+.IP
+If file trees are not in use,
+.I walk
+should consult
+.IB r -> ifcall . wname
+and
+.IB r -> ifcall . nwname \fR,
+filling in
+.IB ofcall . qid
+and
+.IB ofcall . nqid \fR,
+and also copying any necessary
+.I aux
+state from
+.IB r -> fid
+to
+.IB r -> newfid
+when the two are different.
+As long as
+.I walk
+sets
+.IB ofcall . nqid
+appropriately, it can
+.I respond
+with a nil error string even when 9P
+demands an error
+.RI ( e.g. ,
+in the case of a short walk);
+the library detects error conditions and handles them appropriately.
+.IP
+Because implementing the full walk message is intricate and
+prone to error, the helper routine
+.I walkandclone
+will handle the request given pointers to two functions
+.I walk1
+and (optionally)
+.I clone .
+.IR Clone ,
+if non-nil, is called to signal the creation of
+.I newfid
+from
+.IR oldfid .
+Typically a
+.I clone
+routine will copy or increment a reference count in
+.IR oldfid 's
+.I aux
+element.
+.I Walk1
+should walk
+.I fid
+to
+.IR name ,
+initializing
+.IB fid -> qid
+to the new path's qid.
+Both should return nil
+on success or an error message on error.
+.I Walkandclone
+will call
+.I respond
+after handling the request.
+.TP
+.I Walk1\fR, \fPClone
+If the client provides functions
+.IB srv -> walk1
+and (optionally)
+.IB srv -> clone \fR,
+the 9P service loop will call
+.I walkandclone
+with these functions to handle the request.
+Unlike the
+.I walk1
+above,
+.IB srv -> walk1
+must fill in both
+.IB fid -> qid
+and
+.BI * qid
+with the new qid on a successful walk.
+.TP
+.I Open
+If file trees are in use, the file
+metadata will be consulted on open, create, remove, and wstat
+to see if the requester has the appropriate permissions.
+If not, an error will be sent back without consulting a service function.
+.IP
+If not using file trees or the user has the appropriate permissions,
+.I open
+is called with
+.IB r -> ofcall . qid
+already initialized to the one stored in the
+.B Fid
+structure (that is, the one returned in the previous walk).
+If the qid changes, both should be updated.
+.TP
+.I Create
+The
+.I create
+function must fill in
+both
+.IB r -> fid -> qid
+and
+.IB r -> ofcall . qid
+on success.
+When using file trees,
+.I create
+should allocate a new
+.B File
+with
+.IR createfile ;
+note that
+.I createfile
+may return nil (because, say, the file already exists).
+If the
+.I create
+function is nil,
+.I srv
+behaves as though it were a function that always responded
+with the error ``create prohibited''.
+.TP
+.I Remove
+.I Remove
+should mark the file as removed, whether
+by calling
+.I removefile
+when using file trees, or by updating an internal data structure.
+In general it is not a good idea to clean up the
+.I aux
+information associated with the corresponding
+.B File
+at this time, to avoid memory errors if other
+fids have references to that file.
+Instead, it is suggested that
+.I remove
+simply mark the file as removed (so that further
+operations on it know to fail) and wait until the
+file tree's destroy function is called to reclaim the
+.I aux
+pointer.
+If not using file trees, it is prudent to take the
+analogous measures.
+If
+.I remove
+is not provided, all remove requests will draw
+``remove prohibited'' errors.
+.TP
+.I Read
+The
+.I read
+function must be provided; it fills
+.IB r -> ofcall . data
+with at most
+.IB r -> ifcall . count
+bytes of data from offset
+.IB r -> ifcall . offset
+of the file.
+It also sets
+.IB r -> ofcall . count
+to the number of bytes being returned.
+If using file trees,
+.I srv
+will handle reads of directories internally, only
+calling
+.I read
+for requests on files.
+.I Readstr
+and
+.I readbuf
+are useful for satisfying read requests on a string or buffer.
+Consulting the request in
+.IB r -> ifcall \fR,
+they fill
+.IB r -> ofcall . data
+and set
+.IB r -> ofcall . count \fR;
+they do not call
+.IB respond .
+Similarly,
+.I dirread9p
+can be used to handle directory reads in servers
+not using file trees.
+The passed
+.I gen
+function will be called as necessary to
+fill
+.I dir
+with information for the
+.IR n th
+entry in the directory.
+The string pointers placed in
+.I dir
+should be fresh copies
+made with
+.IR estrdup9p ;
+they will be freed by
+.I dirread9p
+after each successful call to
+.IR gen .
+.I Gen
+should return zero if it successfully filled
+.IR dir ,
+minus one on end of directory.
+.TP
+.I Write
+The
+.I write
+function is similar but need not be provided.
+If it is not, all writes will draw
+``write prohibited'' errors.
+Otherwise,
+.I write
+should attempt to write the
+.IB r -> ifcall . count
+bytes of
+.IB r -> ifcall . data
+to offset
+.IB r -> ifcall . offset
+of the file, setting
+.IB r -> ofcall . count
+to the number of bytes actually written.
+Most programs consider it an error to
+write less than the requested amount.
+.TP
+.I Stat
+.I Stat
+should fill
+.IB r -> d
+with the stat information for
+.IB r -> fid \fR.
+If using file trees,
+.IB r -> d
+will have been initialized with the stat info from
+the tree, and
+.I stat
+itself may be nil.
+.TP
+.I Wstat
+The
+.I wstat
+consults
+.IB r -> d
+in changing the metadata for
+.IB r -> fid
+as described in
+.IR stat (5).
+When using file trees,
+.I srv
+will take care to check that the request satisfies
+the permissions outlined in
+.IR stat (5).
+Otherwise
+.I wstat
+should take care to enforce permissions
+where appropriate.
+.TP
+.I Flush
+Servers that always call
+.I respond
+before returning from the service functions
+need not provide a
+.I flush
+implementation:
+.I flush
+is only necessary in programs
+that arrange for
+.I respond
+to be called asynchronously.
+.I Flush
+should cause the request
+.IB r -> oldreq
+to be cancelled or hurried along.
+If
+.I oldreq
+is cancelled, this should be signalled by calling
+.I respond
+on
+.I oldreq
+with error string
+.RB ` interrupted '.
+.I Flush
+must respond to
+.I r
+with a nil error string.
+.I Flush
+may respond to
+.I r
+before forcing a response to
+.IB r -> oldreq \fR.
+In this case, the library will delay sending
+the
+.I Rflush
+message until the response to
+.IB r -> oldreq
+has been sent.
+.PD
+.PP
+.IR Destroyfid ,
+.IR destroyreq ,
+and
+.I end
+are auxiliary functions, not called in direct response to 9P requests.
+.TP
+.I Destroyfid
+When a
+.BR Fid 's
+reference count drops to zero
+.RI ( i.e.,
+it has been clunked and there are no outstanding
+requests referring to it),
+.I destroyfid
+is called to allow the program to dispose
+of the
+.IB fid -> aux
+pointer.
+.TP
+.I Destroyreq
+Similarly, when a
+.BR Req 's
+reference count drops to zero
+.RI ( i.e. ,
+it has been handled via
+.I respond
+and other outstanding pointers to it have been closed),
+.I destroyreq
+is called to allow the program to dispose of the
+.IB r -> aux
+pointer.
+.TP
+.I End
+Once the 9P service loop has finished
+(end of file been reached on the service pipe
+or a bad message has been read),
+.I end
+is called (if provided) to allow any final cleanup.
+For example, it was used by the Palm Pilot synchronization
+file system (never finished) to gracefully terminate the serial conversation once
+the file system had been unmounted.
+After calling
+.IR end ,
+the service loop (which runs in a separate process
+from its caller) terminates using
+.I _exits
+(see
+.IR exits (2)).
+.PD
+.PP
+If the
+.B chatty9p
+flag is at least one,
+a transcript of the 9P session is printed
+on standard error.
+If the
+.B chatty9p
+flag is greater than one,
+additional unspecified debugging output is generated.
+By convention, servers written using this library
+accept the
+.B -D
+option to increment
+.BR chatty9p .
+.SH EXAMPLES
+.IR Archfs (4),
+.IR cdfs (4),
+.IR nntpfs (4),
+.IR snap (4),
+and
+.B /sys/src/lib9p/ramfs.c
+are good examples of simple single-threaded file servers.
+.IR Webfs (4)
+and
+.I sshnet
+(see
+.IR ssh (1))
+are good examples of multithreaded file servers.
+.PP
+In general, the
+.B File
+interface is appropriate for maintaining arbitrary file trees (as in
+.IR ramfs ).
+The
+.B File
+interface is best avoided when the
+tree structure is easily generated as necessary;
+this is true when the tree is highly structured (as in
+.I cdfs
+and
+.IR nntpfs )
+or is maintained elsewhere.
+.SH SOURCE
+.B /sys/src/lib9p
+.SH SEE ALSO
+.IR 9pfid (2),
+.IR 9pfile (2),
+.IR srv (3),
+.IR intro (5)
+.SH BUGS
+The switch to 9P2000 was taken as an opportunity to tidy
+much of the interface; we promise to avoid such gratuitous change
+in the future.
diff --git a/sys/man/2/9pcmdbuf b/sys/man/2/9pcmdbuf
new file mode 100755
index 000000000..83dcef887
--- /dev/null
+++ b/sys/man/2/9pcmdbuf
@@ -0,0 +1,120 @@
+.TH 9PCMDBUF 2
+.SH NAME
+Cmdbuf, parsecmd, respondcmderror, lookupcmd \- control message parsing
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fL1234'u +\w'\fL12345678'u
+typedef struct Cmdbuf
+{
+ char *buf;
+ char **f;
+ int nf;
+} Cmdbuf;
+
+typedef struct Cmdtab
+{
+ int index;
+ char *cmd;
+ int narg;
+};
+
+Cmdbuf *parsecmd(char *p, int n)
+Cmdtab *lookupcmd(Cmdbuf *cb, Cmdtab *tab, int ntab)
+void respondcmderror(Req *r, Cmdbuf *cb, char *fmt, ...)
+.fi
+.SH DESCRIPTION
+These data structures and functions provide parsing of textual control messages.
+.PP
+.I Parsecmd
+treats the
+.I n
+bytes at
+.I p
+(which need not be NUL-terminated) as a UTF string and splits it
+using
+.I tokenize
+(see
+.IR getfields (2)).
+It returns a
+.B Cmdbuf
+structure holding pointers to each field in the message.
+It is the caller's responsibility to
+free this structure when it is no longer needed.
+.PP
+.I Lookupcmd
+walks through the array
+.IR ctab ,
+which has
+.I ntab
+entries,
+looking for the first
+.B Cmdtab
+that matches the parsed command.
+(If the parsed command is empty,
+.I lookupcmd
+returns nil immediately.)
+A
+.B Cmdtab
+matches the command if
+.I cmd
+is equal to
+.IB cb -> f [0]
+or if
+.I cmd
+is
+.LR * .
+Once a matching
+.B Cmdtab
+has been found, if
+.I narg
+is not zero, then the parsed command
+must have exactly
+.I narg
+fields (including the command string itself).
+If the command has the wrong number of arguments,
+.I lookupcmd
+returns nil.
+Otherwise, it returns a pointer to the
+.B Cmdtab
+entry.
+If
+.I lookupcmd
+does not find a matching command at all,
+it returns nil.
+Whenever
+.I lookupcmd
+returns nil, it sets the system error string.
+.PP
+.I Respondcmderror
+resoponds to request
+.I r
+with an error of the form
+`\fIfmt\fB:\fI cmd\fR,'
+where
+.I fmt
+is the formatted string and
+.I cmd
+is a reconstruction of the parsed command.
+Fmt
+is often simply
+.B "%r" .
+.SH EXAMPLES
+This interface is not used in any distributed 9P servers.
+It was lifted from the Plan 9 kernel.
+Almost any kernel driver
+.RB ( /sys/src/9/*/dev*.c )
+is a good example.
+.SH SOURCE
+.B /sys/src/lib9p/parse.c
+.SH SEE ALSO
+.IR 9p (2)
diff --git a/sys/man/2/9pfid b/sys/man/2/9pfid
new file mode 100755
index 000000000..6ad79aa85
--- /dev/null
+++ b/sys/man/2/9pfid
@@ -0,0 +1,207 @@
+.TH 9PFID 2
+.SH NAME
+Fid, Fidpool, allocfidpool, freefidpool, allocfid, closefid, lookupfid, removefid,
+Req, Reqpool, allocreqpool, freereqpool, allocreq, closereq, lookupreq, removereq \- 9P fid, request tracking
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fL 'u +\w'\fLulong 'u
+typedef struct Fid
+{
+ ulong fid;
+ char omode; /* -1 if not open */
+ char *uid;
+ Qid qid;
+ File *file;
+ void *aux;
+ \fI...\fP
+} Fid;
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fL 'u +\w'\fLulong 'u
+typedef struct Req
+{
+ ulong tag;
+ Fcall ifcall;
+ Fcall ofcall;
+ Req *oldreq;
+ void *aux;
+ Fid *fid;
+ Fid *afid;
+ Fid *newfid;
+ \fI...\fP
+} Req;
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fLFidpool* 'u
+Fidpool* allocfidpool(void (*destroy)(Fid*))
+void freefidpool(Fidpool *p)
+Fid* allocfid(Fidpool *p, ulong fid)
+Fid* lookupfid(Fidpool *p, ulong fid)
+Fid* removefid(Fidpool *p, ulong fid);
+void closefid(Fid *f)
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fLReqpool* 'u
+Reqpool* allocreqpool(void (*destroy)(Req*))
+void freereqpool(Reqpool *p)
+Req* allocreq(Reqpool *p, ulong tag)
+Req* lookupreq(Reqpool *p, ulong tag)
+Req* removereq(Reqpool *p, ulong tag);
+void closereq(Req *f)
+.fi
+.SH DESCRIPTION
+These routines provide management of
+.B Fid
+and
+.B Req
+structures from
+.BR Fidpool s
+and
+.BR Reqpool s.
+They are primarily used by the 9P server loop
+described in
+.IR 9p (2).
+.PP
+.B Fid
+structures are intended to represent
+active fids in a 9P connection, as
+.B Chan
+structures do in the Plan 9 kernel.
+The
+.B fid
+element is the integer fid used in the 9P
+connection.
+.B Omode
+is the mode under which the fid was opened, or
+.B -1
+if this fid has not been opened yet.
+Note that in addition to the values
+.BR OREAD ,
+.BR OWRITE ,
+and
+.BR ORDWR ,
+.B omode
+can contain the various flags permissible in
+an open call.
+To ignore the flags, use
+.BR omode&OMASK .
+.B Omode
+should not be changed by the client.
+The fid derives from a successful authentication by
+.BR uid .
+.B Qid
+contains the qid returned in the last successful
+.B walk
+or
+.B create
+transaction involving the fid.
+In a file tree-based server, the
+.BR Fid 's
+.B file
+element points at a
+.B File
+structure
+(see
+.IR 9pfile (2))
+corresponding to the fid.
+The
+.B aux
+member is intended for use by the
+client to hold information specific to a particular
+.BR Fid .
+With the exception of
+.BR aux ,
+these elements should be treated
+as read-only by the client.
+.PP
+.I Allocfidpool
+creates a new
+.BR Fidpool .
+.I Freefidpool
+destroys such a pool.
+.I Allocfid
+returns a new
+.B Fid
+whose fid number is
+.IR fid .
+There must not already be an extant
+.B Fid
+with that number in the pool.
+Once a
+.B Fid
+has been allocated, it can be looked up by
+fid number using
+.IR lookupfid .
+.BR Fid s
+are reference counted: both
+.I allocfid
+and
+.I lookupfid
+increment the reference count on the
+.B Fid
+structure before
+returning.
+When a reference to a
+.B Fid
+is no longer needed,
+.I closefid
+should be called to note the destruction of the reference.
+When the last reference to a
+.B Fid
+is removed, if
+.I destroy
+(supplied when creating the fid pool)
+is not zero, it is called with the
+.B Fid
+as a parameter.
+It should perform whatever cleanup is necessary
+regarding the
+.B aux
+element.
+.I Removefid
+is equivalent to
+.I lookupfid
+but also removes the
+.B Fid
+from the pool.
+Note that due to lingering references,
+the return of
+.I removefid
+may not mean that
+.I destroy
+has been called.
+.PP
+.IR Allocreqpool ,
+.IR freereqpool ,
+.IR allocreq ,
+.IR lookupreq ,
+.IR closereq ,
+and
+.I removereq
+are analogous but
+operate on
+.BR Reqpool s
+and
+.B Req
+structures.
+.SH SOURCE
+.B /sys/src/lib9p
+.SH SEE ALSO
+.IR 9p (2),
+.IR 9pfile (2)
diff --git a/sys/man/2/9pfile b/sys/man/2/9pfile
new file mode 100755
index 000000000..668d61689
--- /dev/null
+++ b/sys/man/2/9pfile
@@ -0,0 +1,223 @@
+.TH 9PFILE 2
+.SH NAME
+Tree, alloctree, freetree,
+File, createfile, closefile, removefile, walkfile,
+opendirfile, readdirfile, closedirfile, hasperm \- in-memory file hierarchy
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fLFile 'u
+typedef struct File
+{
+ Ref;
+ Dir;
+ void *aux;
+ \fI...\fP
+} File;
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fLTree 'u
+typedef struct Tree
+{
+ File *root;
+ \fI...\fP
+} Tree;
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fLReaddir* 'u +4n +4n
+Tree* alloctree(char *uid, char *gid, ulong mode,
+ void (*destroy)(File*))
+void freetree(Tree *tree)
+File* createfile(File *dir, char *name, char *uid,
+ ulong mode, void *aux)
+int removefile(File *file)
+void closefile(File *file)
+File* walkfile(File *dir, char *path)
+Readdir* opendirfile(File *dir)
+long readdirfile(Readdir *rdir, uchar *buf, long n)
+void closedirfile(Readdir *rdir)
+int hasperm(File *file, char *uid, int p)
+.fi
+.SH DESCRIPTION
+.BR File s
+and
+.BR Tree s
+provide an in-memory file hierarchy
+intended for use in 9P file servers.
+.PP
+.I Alloctree
+creates a new tree of files, and
+.I freetree
+destroys it.
+The root of the tree
+(also the
+.B root
+element in the structure)
+will have mode
+.I mode
+and be owned by user
+.I uid
+and group
+.IR gid .
+.I Destroy
+is used when freeing
+.B File
+structures and is described later.
+.PP
+.BR File s
+(including directories)
+other than the root are created using
+.IR createfile ,
+which attempts to create a file named
+.I name
+in the directory
+.IR dir .
+If created, the file will have owner
+.I uid
+and have a group inherited from
+the directory.
+.I Mode
+and the permissions of
+.I dir
+are used to calculate the permission bits for
+the file as described in
+.IR open (5).
+It is permissible for
+.I name
+to be a slash-separated path rather than a single element.
+.PP
+.I Removefile
+removes a file from the file tree.
+The file will not be freed until the last
+reference to it has been removed.
+Directories may only be removed when empty.
+.I Removefile
+returns zero on success, \-1 on error.
+It is correct to consider
+.I removefile
+to be
+.I closefile
+with the side effect of removing the file
+when possible.
+.PP
+.I Walkfile
+evaluates
+.I path
+relative to the directory
+.IR dir ,
+returning the resulting file,
+or zero if the named file or any intermediate element
+does not exist.
+.PP
+The
+.B File
+structure's
+.B aux
+pointer may be used by the client
+for
+.RB per- File
+storage.
+.BR File s
+are reference-counted: if not zero,
+.I destroy
+(specified in the call to
+.IR alloctree )
+will be called for each file when its
+last reference is removed or when the tree is freed.
+.I Destroy
+should take care of any necessary cleanup related to
+.BR aux .
+When creating new file references by copying pointers,
+call
+.I incref
+(see
+.IR lock (2))
+to update the reference count.
+To note the removal of a reference to a file, call
+.IR closefile .
+.I Createfile
+and
+.I walkfile
+return new references.
+.IR Removefile ,
+.IR closefile ,
+and
+.I walkfile
+(but not
+.IR createfile )
+consume the passed reference.
+.PP
+Directories may be read, yielding a directory entry structure
+(see
+.IR stat (5))
+for each file in the directory.
+In order to allow concurrent reading of directories,
+clients must obtain a
+.B Readdir
+structure by calling
+.I opendirfile
+on a directory.
+Subsequent calls to
+.I readdirfile
+will each yield an integral number of machine-independent
+stat buffers, until end of directory.
+When finished, call
+.I closedirfile
+to free the
+.BR Readdir .
+.PP
+.I Hasperm
+does simplistic permission checking; it assumes only
+one-user groups named by uid and returns non-zero if
+.I uid
+has permission
+.I p
+(a bitwise-or of
+.BR AREAD ,
+.BR AWRITE
+and
+.BR AEXEC )
+according to
+.IB file ->mode \fR.
+9P servers written using
+.B File
+trees will do standard permission checks automatically;
+.I hasperm
+may be called explicitly to do additional checks.
+A 9P server may link against a different
+.I hasperm
+implementation to provide more complex groups.
+.SH EXAMPLE
+The following code correctly handles references
+when elementwise walking a path and creating a file.
+.IP
+.EX
+f = tree->root;
+incref(f);
+for(i=0; i<n && f!=nil; i++)
+ f = walkfile(f, elem[i]);
+if(f == nil)
+ return nil;
+nf = createfile(f, "foo", "nls", 0666, nil);
+closefile(f);
+return nf;
+.EE
+.SH SOURCE
+.B /sys/src/lib9p/file.c
+.SH SEE ALSO
+.IR 9p (2)
+.SH BUGS
+The reference counting is cumbersome.
diff --git a/sys/man/2/INDEX b/sys/man/2/INDEX
new file mode 100755
index 000000000..c417683a6
--- /dev/null
+++ b/sys/man/2/INDEX
@@ -0,0 +1,1514 @@
+0intro 0intro
+intro 0intro
+9p 9p
+Srv 9p
+dirread9p 9p
+emalloc9p 9p
+erealloc9p 9p
+estrdup9p 9p
+listensrv 9p
+postfd 9p
+postmountsrv 9p
+readbuf 9p
+readstr 9p
+respond 9p
+responderror 9p
+srv 9p
+threadlistensrv 9p
+threadpostmountsrv 9p
+9pcmdbuf 9pcmdbuf
+Cmdbuf 9pcmdbuf
+lookupcmd 9pcmdbuf
+parsecmd 9pcmdbuf
+respondcmderror 9pcmdbuf
+9pfid 9pfid
+Fid 9pfid
+Fidpool 9pfid
+Req 9pfid
+Reqpool 9pfid
+allocfid 9pfid
+allocfidpool 9pfid
+allocreq 9pfid
+allocreqpool 9pfid
+closefid 9pfid
+closereq 9pfid
+freefidpool 9pfid
+freereqpool 9pfid
+lookupfid 9pfid
+lookupreq 9pfid
+removefid 9pfid
+removereq 9pfid
+9pfile 9pfile
+File 9pfile
+Tree 9pfile
+alloctree 9pfile
+closedirfile 9pfile
+closefile 9pfile
+createfile 9pfile
+freetree 9pfile
+hasperm 9pfile
+opendirfile 9pfile
+readdirfile 9pfile
+removefile 9pfile
+walkfile 9pfile
+abort abort
+abs abs
+labs abs
+access access
+Dx addpt
+Dy addpt
+Pt addpt
+Rect addpt
+Rpt addpt
+addpt addpt
+canonrect addpt
+combinerect addpt
+divpt addpt
+eqpt addpt
+eqrect addpt
+insetrect addpt
+mulpt addpt
+ptinrect addpt
+rectXrect addpt
+rectaddpt addpt
+rectclip addpt
+rectinrect addpt
+rectsubpt addpt
+subpt addpt
+aes aes
+aesCBCdecrypt aes
+aesCBCencrypt aes
+aesCTRdecrypt aes
+aesCTRencrypt aes
+aesXCBCmac aes
+setupAESXCBCstate aes
+setupAESstate aes
+allocimage allocimage
+allocimagemix allocimage
+bytesperline allocimage
+cloadimage allocimage
+freeimage allocimage
+loadimage allocimage
+namedimage allocimage
+nameimage allocimage
+readimage allocimage
+setalpha allocimage
+unloadimage allocimage
+wordsperline allocimage
+writeimage allocimage
+ARGBEGIN arg
+ARGC arg
+ARGEND arg
+ARGF arg
+EARGF arg
+arg arg
+add3 arith3
+add4 arith3
+arith3 arith3
+closept3 arith3
+cross3 arith3
+dist3 arith3
+div3 arith3
+dot3 arith3
+eqpt3 arith3
+fff2p3 arith3
+len3 arith3
+lerp3 arith3
+midpt3 arith3
+mul3 arith3
+nearseg3 arith3
+neg3 arith3
+pdiv4 arith3
+pldist3 arith3
+pn2f3 arith3
+ppp2f3 arith3
+reflect3 arith3
+sub3 arith3
+sub4 arith3
+unit3 arith3
+vdiv3 arith3
+vrem3 arith3
+assert assert
+atof atof
+atoi atof
+atol atof
+atoll atof
+charstod atof
+strtod atof
+strtol atof
+strtoll atof
+strtoul atof
+strtoull atof
+addns auth
+amount auth
+amount_getkey auth
+auth auth
+auth_allocrpc auth
+auth_challenge auth
+auth_chuid auth
+auth_freeAI auth
+auth_freechal auth
+auth_freerpc auth
+auth_getinfo auth
+auth_getkey auth
+auth_getuserpasswd auth
+auth_proxy auth
+auth_respond auth
+auth_response auth
+auth_rpc auth
+auth_userpasswd auth
+fauth_proxy auth
+login auth
+newns auth
+noworld auth
+_asgetticket authsrv
+_asrdresp authsrv
+authdial authsrv
+authsrv authsrv
+convA2M authsrv
+convM2A authsrv
+convM2PR authsrv
+convM2T authsrv
+convM2TR authsrv
+convPR2M authsrv
+convT2M authsrv
+convTR2M authsrv
+nvcsum authsrv
+passtokey authsrv
+readnvram authsrv
+avl avl
+avlnext avl
+avlprev avl
+avlwalk avl
+deleteavl avl
+endwalk avl
+insertavl avl
+lookupavl avl
+mkavltree avl
+bin bin
+binalloc bin
+binfree bin
+bingrow bin
+bind bind
+mount bind
+unmount bind
+Bbuffered bio
+Bfildes bio
+Bflush bio
+Bgetc bio
+Bgetd bio
+Bgetrune bio
+Binit bio
+Binits bio
+Blinelen bio
+Boffset bio
+Bopen bio
+Bprint bio
+Bputc bio
+Bputrune bio
+Brdline bio
+Brdstr bio
+Bread bio
+Bseek bio
+Bterm bio
+Bungetc bio
+Bungetrune bio
+Bvprint bio
+Bwrite bio
+bio bio
+bfCBCdecrypt blowfish
+bfCBCencrypt blowfish
+bfECBdecrypt blowfish
+bfECBencrypt blowfish
+blowfish blowfish
+setupBFstate blowfish
+brk brk
+sbrk brk
+Font cachechars
+Fontchar cachechars
+Subfont cachechars
+agefont cachechars
+cachechars cachechars
+loadchar cachechars
+chdir chdir
+cleanname cleanname
+cmap2rgb color
+cmap2rgba color
+color color
+rgb2cmap color
+complete complete
+Control control
+Controlset control
+activate control
+closecontrol control
+closecontrolset control
+control control
+controlcalled control
+controlwire control
+createbox control
+createboxbox control
+createbutton control
+createcolumn control
+createentry control
+createkeyboard control
+createlabel control
+createmenu control
+createradiobutton control
+createrow control
+createscribble control
+createslider control
+createstack control
+createtab control
+createtext control
+createtextbutton control
+ctlerror control
+ctlmalloc control
+ctlprint control
+ctlrealloc control
+ctlstrdup control
+deactivate control
+freectlfont control
+freectlimage control
+initcontrols control
+namectlfont control
+namectlimage control
+newcontrolset control
+resizecontrolset control
+cputime cputime
+cycles cputime
+times cputime
+asctime ctime
+ctime ctime
+gmtime ctime
+localtime ctime
+timezone ctime
+tm2sec ctime
+_tolower ctype
+_toupper ctype
+ctype ctype
+isalnum ctype
+isalpha ctype
+isascii ctype
+iscntrl ctype
+isdigit ctype
+isgraph ctype
+islower ctype
+isprint ctype
+ispunct ctype
+isspace ctype
+isupper ctype
+isxdigit ctype
+toascii ctype
+tolower ctype
+toupper ctype
+beieee80ftos debugger
+beieeedftos debugger
+beieeesftos debugger
+ciscframe debugger
+cisctrace debugger
+debugger debugger
+fpformat debugger
+ieeedftos debugger
+ieeesftos debugger
+leieee80ftos debugger
+leieeedftos debugger
+leieeesftos debugger
+localaddr debugger
+riscframe debugger
+risctrace debugger
+symoff debugger
+block_cipher des
+des des
+des3CBCdecrypt des
+des3CBCencrypt des
+des3ECBdecrypt des
+des3ECBencrypt des
+des56to64 des
+des64to56 des
+desCBCdecrypt des
+desCBCencrypt des
+desECBdecrypt des
+desECBencrypt des
+des_key_setup des
+key_setup des
+setupDES3state des
+setupDESstate des
+triple_block_cipher des
+accept dial
+announce dial
+dial dial
+freenetconninfo dial
+getnetconninfo dial
+hangup dial
+listen dial
+netmkaddr dial
+reject dial
+setnetmtpt dial
+dirread dirread
+dirreadall dirread
+Disk disk
+disk disk
+opendisk disk
+ARROW draw
+Image draw
+_string draw
+arc draw
+bezier draw
+bezspline draw
+border draw
+draw draw
+drawrepl draw
+drawreplxy draw
+drawsetdebug draw
+ellipse draw
+fillarc draw
+fillbezier draw
+fillbezspline draw
+fillellipse draw
+fillpoly draw
+gendraw draw
+icossin draw
+icossin2 draw
+line draw
+poly draw
+replclipr draw
+runestring draw
+runestringbg draw
+runestringn draw
+runestringnbg draw
+string draw
+stringbg draw
+stringn draw
+stringnbg draw
+dsa dsa
+dsagen dsa
+dsaprivalloc dsa
+dsaprivfree dsa
+dsaprivtopub dsa
+dsapuballoc dsa
+dsapubfree dsa
+dsasigalloc dsa
+dsasigfree dsa
+dsasign dsa
+dsaverify dsa
+dup dup
+egdecrypt elgamal
+egencrypt elgamal
+eggen elgamal
+egprivalloc elgamal
+egprivfree elgamal
+egprivtopub elgamal
+egpuballoc elgamal
+egpubfree elgamal
+egsigalloc elgamal
+egsigfree elgamal
+egsign elgamal
+egverify elgamal
+elgamal elgamal
+dec16 encode
+dec32 encode
+dec64 encode
+enc16 encode
+enc32 encode
+enc64 encode
+encode encode
+encodefmt encode
+decrypt encrypt
+encrypt encrypt
+netcrypt encrypt
+errstr errstr
+rerrstr errstr
+werrstr errstr
+Event event
+Menu event
+Mouse event
+eatomouse event
+ecankbd event
+ecanmouse event
+ecanread event
+edrawgetrect event
+egetrect event
+einit event
+ekbd event
+emenuhit event
+emouse event
+emoveto event
+eread event
+ereadmouse event
+eresized event
+esetcursor event
+estart event
+estartfn event
+etimer event
+event event
+_nprivates exec
+_privates exec
+_tos exec
+exec exec
+execl exec
+_exits exits
+atexit exits
+atexitdont exits
+exits exits
+terminate exits
+exp exp
+log exp
+log10 exp
+pow exp
+pow10 exp
+sqrt exp
+fauth fauth
+Fcall fcall
+convD2M fcall
+convM2D fcall
+convM2S fcall
+convS2M fcall
+dirfmt fcall
+dirmodefmt fcall
+fcall fcall
+fcallfmt fcall
+read9pmsg fcall
+sizeD2M fcall
+sizeS2M fcall
+statcheck fcall
+fd2path fd2path
+fgetc fgetc
+fgets fgetc
+fputc fgetc
+fputs fgetc
+fread fgetc
+fwrite fgetc
+getc fgetc
+getchar fgetc
+gets fgetc
+putc fgetc
+putchar fgetc
+puts fgetc
+ungetc fgetc
+adler32 flate
+blockcrc flate
+deflate flate
+deflateblock flate
+deflateinit flate
+deflatezlib flate
+deflatezlibblock flate
+flate flate
+flateerr flate
+inflate flate
+inflateblock flate
+inflateinit flate
+inflatezlib flate
+inflatezlibblock flate
+mkcrctab flate
+ceil floor
+fabs floor
+floor floor
+fmod floor
+dofmt fmtinstall
+dorfmt fmtinstall
+errfmt fmtinstall
+fmtfdflush fmtinstall
+fmtfdinit fmtinstall
+fmtinstall fmtinstall
+fmtprint fmtinstall
+fmtrune fmtinstall
+fmtrunestrcpy fmtinstall
+fmtstrcpy fmtinstall
+fmtstrflush fmtinstall
+fmtstrinit fmtinstall
+fmtvprint fmtinstall
+runefmtstrflush fmtinstall
+runefmtstrinit fmtinstall
+clearerr fopen
+fclose fopen
+fdopen fopen
+feof fopen
+ferror fopen
+fflush fopen
+fgetpos fopen
+fileno fopen
+fopen fopen
+freopen fopen
+fseek fopen
+fsetpos fopen
+ftell fopen
+rewind fopen
+sclose fopen
+setbuf fopen
+setvbuf fopen
+sopenr fopen
+sopenw fopen
+fork fork
+rfork fork
+fprintf fprintf
+printf fprintf
+snprintf fprintf
+sprintf fprintf
+vfprintf fprintf
+vprintf fprintf
+vsnprintf fprintf
+vsprintf fprintf
+frame frame
+frcharofpt frame
+frclear frame
+frdelete frame
+frdrawsel frame
+frdrawsel0 frame
+frgetmouse frame
+frinit frame
+frinittick frame
+frinsert frame
+frptofchar frame
+frselect frame
+frselectpaint frame
+frsetrects frame
+frtick frame
+frexp frexp
+ldexp frexp
+modf frexp
+fscanf fscanf
+scanf fscanf
+sscanf fscanf
+vfscanf fscanf
+fversion fversion
+getcallerpc getcallerpc
+getenv getenv
+putenv getenv
+getfcr getfcr
+getfsr getfcr
+setfcr getfcr
+setfsr getfcr
+getfields getfields
+gettokens getfields
+tokenize getfields
+getpid getpid
+getppid getpid
+getuser getuser
+sysname getuser
+getwd getwd
+Cursor graphics
+Display graphics
+Pfmt graphics
+Point graphics
+Rectangle graphics
+Rfmt graphics
+bufimage graphics
+buildfont graphics
+chantodepth graphics
+chantostr graphics
+closedisplay graphics
+drawerror graphics
+flushimage graphics
+freefont graphics
+gengetwindow graphics
+geninitdraw graphics
+getdefont graphics
+getwindow graphics
+graphics graphics
+initdisplay graphics
+initdraw graphics
+lockdisplay graphics
+openfont graphics
+strtochan graphics
+unlockdisplay graphics
+dimenkind html
+dimenspec html
+freedocinfo html
+freeitems html
+fromStr html
+html html
+parsehtml html
+printitems html
+targetid html
+targetname html
+toStr html
+validitems html
+HConnect httpd
+HContent httpd
+HContents httpd
+HETag httpd
+HFields httpd
+HRange httpd
+HSPairs httpd
+Hio httpd
+Htmlesc httpd
+HttpHead httpd
+HttpReq httpd
+halloc httpd
+hbodypush httpd
+hbuflen httpd
+hcheckcontent httpd
+hclose httpd
+hdate2sec httpd
+hdatefmt httpd
+hfail httpd
+hflush httpd
+hgetc httpd
+hgethead httpd
+hinit httpd
+hiserror httpd
+hload httpd
+hlower httpd
+hmkcontent httpd
+hmkhfields httpd
+hmkmimeboundary httpd
+hmkspairs httpd
+hmoved httpd
+hmydomain httpd
+hokheaders httpd
+hparseheaders httpd
+hparsequery httpd
+hparsereq httpd
+hprint httpd
+hputc httpd
+hreadbuf httpd
+hredirected httpd
+hreqcleanup httpd
+hrevhfields httpd
+hrevspairs httpd
+hstrdup httpd
+htmlesc httpd
+http11 httpd
+httpd httpd
+httpfmt httpd
+httpunesc httpd
+hunallowed httpd
+hungetc httpd
+hunload httpd
+hurlfmt httpd
+hurlunesc httpd
+hversion httpd
+hvprint httpd
+hwrite httpd
+hxferenc httpd
+hypot hypot
+Intmap intmap
+allocmap intmap
+caninsertkey intmap
+deletekey intmap
+freemap intmap
+insertkey intmap
+intmap intmap
+lookupkey intmap
+closeioproc ioproc
+iocall ioproc
+ioclose ioproc
+iodial ioproc
+iointerrupt ioproc
+ioopen ioproc
+ioproc ioproc
+ioread ioproc
+ioreadn ioproc
+iowrite ioproc
+iounit iounit
+defmask ip
+eipfmt ip
+equivip4 ip
+equivip6 ip
+hnputl ip
+hnputs ip
+hnputv ip
+ip ip
+isv4 ip
+maskip ip
+myetheraddr ip
+myipaddr ip
+nhgetl ip
+nhgets ip
+nhgetv ip
+parseether ip
+parseip ip
+parseipmask ip
+ptclbsum ip
+readipifc ip
+v4parsecidr ip
+v4parseip ip
+v4tov6 ip
+v6tov4 ip
+isalpharune isalpharune
+islowerrune isalpharune
+isspacerune isalpharune
+istitlerune isalpharune
+isupperrune isalpharune
+tolowerrune isalpharune
+totitlerune isalpharune
+toupperrune isalpharune
+closekeyboard keyboard
+ctlkeyboard keyboard
+initkeyboard keyboard
+keyboard keyboard
+canlock lock
+canqlock lock
+canrlock lock
+canwlock lock
+decref lock
+incref lock
+lock lock
+qlock lock
+qunlock lock
+rlock lock
+rsleep lock
+runlock lock
+rwakeup lock
+rwakeupall lock
+unlock lock
+wlock lock
+wunlock lock
+attachproc mach
+beswab mach
+beswal mach
+beswav mach
+crackhdr mach
+findseg mach
+get1 mach
+get2 mach
+get4 mach
+get8 mach
+leswab mach
+leswal mach
+leswav mach
+loadmap mach
+mach mach
+machbyname mach
+machbytype mach
+newmap mach
+put1 mach
+put2 mach
+put4 mach
+put8 mach
+setmap mach
+unusemap mach
+calloc malloc
+free malloc
+getmalloctag malloc
+getrealloctag malloc
+malloc malloc
+mallocalign malloc
+malloctopoolblock malloc
+mallocz malloc
+msize malloc
+realloc malloc
+setmalloctag malloc
+setrealloctag malloc
+adjoint matrix
+determinant matrix
+ident matrix
+invertmat matrix
+ixform matrix
+look matrix
+matmul matrix
+matmulr matrix
+matrix matrix
+move matrix
+persp matrix
+popmat matrix
+pushmat matrix
+qrot matrix
+rot matrix
+scale matrix
+viewport matrix
+xform matrix
+xformplane matrix
+xformpoint matrix
+xformpointd matrix
+Memdata memdraw
+Memdrawparam memdraw
+Memimage memdraw
+allocmemimage memdraw
+allocmemimaged memdraw
+allocmemsubfont memdraw
+byteaddr memdraw
+cloadmemimage memdraw
+creadmemimage memdraw
+drawclip memdraw
+freememimage memdraw
+freememsubfont memdraw
+getmemdefont memdraw
+hwdraw memdraw
+iprint memdraw
+loadmemimage memdraw
+memarc memdraw
+memdraw memdraw
+memellipse memdraw
+memfillcolor memdraw
+memfillpoly memdraw
+memimagedraw memdraw
+memimageinit memdraw
+memimageline memdraw
+memimagemove memdraw
+memimagestring memdraw
+memlinebbox memdraw
+memlineendsize memdraw
+mempoly memdraw
+memsetchan memdraw
+memsubfontwidth memdraw
+openmemsubfont memdraw
+readmemimage memdraw
+unloadmemimage memdraw
+wordaddr memdraw
+writememimage memdraw
+memdraw memlayer
+memlalloc memlayer
+memlayer memlayer
+memldelete memlayer
+memlexpose memlayer
+memlfree memlayer
+memlhide memlayer
+memline memlayer
+memlnorefresh memlayer
+memload memlayer
+memlorigin memlayer
+memlsetrefresh memlayer
+memltofront memlayer
+memltofrontn memlayer
+memltorear memlayer
+memltorearn memlayer
+memunload memlayer
+memccpy memory
+memchr memory
+memcmp memory
+memcpy memory
+memmove memory
+memory memory
+memset memory
+mktemp mktemp
+closemouse mouse
+drawgetrect mouse
+getrect mouse
+initmouse mouse
+menuhit mouse
+mouse mouse
+moveto mouse
+readmouse mouse
+setcursor mouse
+betomp mp
+crtin mp
+crtout mp
+crtpre mp
+crtprefree mp
+crtresfree mp
+itomp mp
+letomp mp
+mp mp
+mpadd mp
+mpassign mp
+mpbits mp
+mpcmp mp
+mpcopy mp
+mpdigdiv mp
+mpdiv mp
+mpexp mp
+mpextendedgcd mp
+mpfmt mp
+mpfree mp
+mpinvert mp
+mpleft mp
+mplowbits0 mp
+mpmagadd mp
+mpmagcmp mp
+mpmagsub mp
+mpmod mp
+mpmul mp
+mpnew mp
+mpnorm mp
+mprand mp
+mpright mp
+mpsetminbits mp
+mpsignif mp
+mpsub mp
+mptoa mp
+mptobe mp
+mptoi mp
+mptole mp
+mptoui mp
+mptouv mp
+mptov mp
+mpvecadd mp
+mpveccmp mp
+mpvecdigmuladd mp
+mpvecdigmulsub mp
+mpvecmul mp
+mpvecsub mp
+strtomp mp
+uitomp mp
+uvtomp mp
+vtomp mp
+muldiv muldiv
+umuldiv muldiv
+Inf nan
+NaN nan
+isInf nan
+isNaN nan
+nan nan
+csgetval ndb
+csgetvalue ndb
+csipinfo ndb
+dnsquery ndb
+ipattr ndb
+ndb ndb
+ndbcat ndb
+ndbchanged ndb
+ndbclose ndb
+ndbconcatenate ndb
+ndbdiscard ndb
+ndbfindattr ndb
+ndbfree ndb
+ndbgetipaddr ndb
+ndbgetval ndb
+ndbgetvalue ndb
+ndbhash ndb
+ndbipinfo ndb
+ndblookval ndb
+ndbopen ndb
+ndbparse ndb
+ndbreopen ndb
+ndbreorder ndb
+ndbsearch ndb
+ndbsnext ndb
+ndbsubstitute ndb
+atnotify notify
+noted notify
+notify notify
+isar object
+nextar object
+object object
+objtraverse object
+objtype object
+readar object
+readobj object
+close open
+create open
+open open
+perror perror
+sysfatal perror
+syslog perror
+pipe pipe
+Plumbmsg plumb
+eplumb plumb
+plumb plumb
+plumbaddattr plumb
+plumbdelattr plumb
+plumbfree plumb
+plumblookup plumb
+plumbopen plumb
+plumbpack plumb
+plumbpackattr plumb
+plumbrecv plumb
+plumbsend plumb
+plumbsendtext plumb
+plumbunpack plumb
+plumbunpackattr plumb
+plumbunpackpartial plumb
+pool pool
+poolalloc pool
+poolallocalign pool
+poolblockcheck pool
+poolcheck pool
+poolcompact pool
+pooldump pool
+poolfree pool
+poolmsize pool
+poolrealloc pool
+postnote postnote
+DSAprimes prime
+genprime prime
+gensafeprime prime
+genstrongprime prime
+prime prime
+probably_prime prime
+smallprimetest prime
+fprint print
+print print
+runeseprint print
+runesmprint print
+runesnprint print
+runesprint print
+runevseprint print
+runevsmprint print
+runevsnprint print
+seprint print
+smprint print
+snprint print
+sprint print
+vfprint print
+vseprint print
+vsmprint print
+vsnprint print
+privalloc privalloc
+privfree privalloc
+proto proto
+rdproto proto
+pushssl pushssl
+freeThumbprints pushtls
+initThumbprints pushtls
+okThumbprint pushtls
+pushtls pushtls
+readcert pushtls
+readcertchain pushtls
+tlsClient pushtls
+tlsServer pushtls
+qball qball
+qsort qsort
+mtoq quaternion
+qadd quaternion
+qdiv quaternion
+qinv quaternion
+qlen quaternion
+qmid quaternion
+qmul quaternion
+qneg quaternion
+qsqrt quaternion
+qsub quaternion
+qtom quaternion
+quaternion quaternion
+qunit quaternion
+slerp quaternion
+doquote quote
+needsrcquote quote
+quote quote
+quotefmtinstall quote
+quoterunestrdup quote
+quoterunestrfmt quote
+quotestrdup quote
+quotestrfmt quote
+unquoterunestrdup quote
+unquotestrdup quote
+fastrand rand
+frand rand
+genrandom rand
+lnrand rand
+lrand rand
+nfastrand rand
+nrand rand
+ntruerand rand
+prng rand
+rand rand
+srand rand
+truerand rand
+rc4 rc4
+rc4back rc4
+rc4skip rc4
+setupRC4state rc4
+pread read
+pwrite read
+read read
+readn read
+write read
+RGB readcolmap
+readcolmap readcolmap
+writecolmap readcolmap
+preadv readv
+pwritev readv
+readv readv
+writev readv
+regcomp regexp
+regcomplit regexp
+regcompnl regexp
+regerror regexp
+regexec regexp
+regexp regexp
+regsub regexp
+rregexec regexp
+rregsub regexp
+remove remove
+rendezvous rendezvous
+X509gen rsa
+X509toRSApub rsa
+X509verify rsa
+asn1dump rsa
+asn1toRSApriv rsa
+decodePEM rsa
+rsa rsa
+rsadecrypt rsa
+rsaencrypt rsa
+rsagen rsa
+rsaprivalloc rsa
+rsaprivfree rsa
+rsaprivtopub rsa
+rsapuballoc rsa
+rsapubfree rsa
+chartorune rune
+fullrune rune
+rune rune
+runelen rune
+runenlen rune
+runetochar rune
+utfecpy rune
+utflen rune
+utfnlen rune
+utfrrune rune
+utfrune rune
+utfutf rune
+runestrcat runestrcat
+runestrchr runestrcat
+runestrcmp runestrcat
+runestrcpy runestrcat
+runestrdup runestrcat
+runestrecpy runestrcat
+runestrlen runestrcat
+runestrncat runestrcat
+runestrncmp runestrcat
+runestrncpy runestrcat
+runestrrchr runestrcat
+runestrstr runestrcat
+recognize scribble
+scribble scribble
+scribblealloc scribble
+closescsi scsi
+openscsi scsi
+scsi scsi
+scsicmd scsi
+scsierror scsi
+scsiready scsi
+aes sechash
+hmac_aes sechash
+hmac_md5 sechash
+hmac_sha1 sechash
+hmac_sha2_224 sechash
+hmac_sha2_256 sechash
+hmac_sha2_384 sechash
+hmac_sha2_512 sechash
+hmac_x sechash
+md4 sechash
+md5 sechash
+md5pickle sechash
+md5unpickle sechash
+sechash sechash
+sha1 sechash
+sha1pickle sechash
+sha1unpickle sechash
+sha2_224 sechash
+sha2_256 sechash
+sha2_384 sechash
+sha2_512 sechash
+seek seek
+segattach segattach
+segdetach segattach
+segfree segattach
+segbrk segbrk
+segflush segflush
+semacquire semacquire
+semrelease semacquire
+longjmp setjmp
+notejmp setjmp
+setjmp setjmp
+acos sin
+asin sin
+atan sin
+atan2 sin
+cos sin
+sin sin
+tan sin
+cosh sinh
+sinh sinh
+tanh sinh
+alarm sleep
+sleep sleep
+dirfstat stat
+dirfwstat stat
+dirstat stat
+dirwstat stat
+fstat stat
+fwstat stat
+nulldir stat
+stat stat
+wstat stat
+cistrcmp strcat
+cistrncmp strcat
+cistrstr strcat
+strcat strcat
+strchr strcat
+strcmp strcat
+strcpy strcat
+strcspn strcat
+strdup strcat
+strecpy strcat
+strlen strcat
+strncat strcat
+strncmp strcat
+strncpy strcat
+strpbrk strcat
+strrchr strcat
+strspn strcat
+strstr strcat
+strtok strcat
+s_alloc string
+s_append string
+s_array string
+s_copy string
+s_error string
+s_free string
+s_getline string
+s_grow string
+s_incref string
+s_memappend string
+s_nappend string
+s_new string
+s_newalloc string
+s_parse string
+s_putc string
+s_read string
+s_read_line string
+s_reset string
+s_restart string
+s_terminate string
+s_tolower string
+s_unique string
+string string
+runestringnwidth stringsize
+runestringsize stringsize
+runestringwidth stringsize
+stringnwidth stringsize
+stringsize stringsize
+stringwidth stringsize
+allocsubfont subfont
+freesubfont subfont
+installsubfont subfont
+lookupsubfont subfont
+mkfont subfont
+readsubfont subfont
+readsubfonti subfont
+stringsubfont subfont
+strsubfontwidth subfont
+subfont subfont
+subfontname subfont
+uninstallsubfont subfont
+writesubfont subfont
+file2pc symbol
+fileelem symbol
+fileline symbol
+filesym symbol
+findlocal symbol
+findsym symbol
+fnbound symbol
+getauto symbol
+getsym symbol
+globalsym symbol
+line2addr symbol
+localsym symbol
+lookup symbol
+pc2line symbol
+pc2sp symbol
+symbase symbol
+symbol symbol
+syminit symbol
+textseg symbol
+textsym symbol
+alt thread
+chanclose thread
+chanclosing thread
+chancreate thread
+chanfree thread
+chaninit thread
+chanprint thread
+mainstacksize thread
+nbrecv thread
+nbrecvp thread
+nbrecvul thread
+nbsend thread
+nbsendp thread
+nbsendul thread
+proccreate thread
+procdata thread
+procexec thread
+procexecl thread
+procrfork thread
+recv thread
+recvp thread
+recvul thread
+send thread
+sendp thread
+sendul thread
+thread thread
+threadcreate thread
+threaddata thread
+threadexits thread
+threadexitsall thread
+threadgetgrp thread
+threadgetname thread
+threadid thread
+threadint thread
+threadintgrp thread
+threadkill thread
+threadkillgrp thread
+threadmain thread
+threadnotify thread
+threadpid thread
+threadsetgrp thread
+threadsetname thread
+threadwaitchan thread
+yield thread
+nsec time
+time time
+tmpfile tmpfile
+tmpnam tmpfile
+CSP usb
+class usb
+classname usb
+closedev usb
+configdev usb
+devctl usb
+finddevs usb
+loaddevstr usb
+matchdevcsp usb
+opendev usb
+opendevdata usb
+openep usb
+proto usb
+startdevs usb
+subclass usb
+unstall usb
+usb usb
+usbcmd usb
+usbdirfs usbfs
+usbdirread usbfs
+usbfs usbfs
+usbfsadd usbfs
+usbfsdel usbfs
+usbfsinit usbfs
+usbreadbuf usbfs
+venti venti
+VtBlock venti-cache
+VtCache venti-cache
+venti-cache venti-cache
+vtblockcopy venti-cache
+vtblockdirty venti-cache
+vtblockduplock venti-cache
+vtblockput venti-cache
+vtblockwrite venti-cache
+vtcachealloc venti-cache
+vtcacheallocblock venti-cache
+vtcacheblocksize venti-cache
+vtcachefree venti-cache
+vtcacheglobal venti-cache
+vtcachelocal venti-cache
+vtcachesetwrite venti-cache
+vtglobaltolocal venti-cache
+vtlocaltoglobal venti-cache
+venti-client venti-client
+ventidoublechecksha1 venti-client
+vtconnect venti-client
+vthello venti-client
+vtping venti-client
+vtread venti-client
+vtreadpacket venti-client
+vtrpc venti-client
+vtsync venti-client
+vtwrite venti-client
+vtwritepacket venti-client
+VtConn venti-conn
+venti-conn venti-conn
+vtconn venti-conn
+vtdebug venti-conn
+vtdial venti-conn
+vtfreeconn venti-conn
+vthangup venti-conn
+vtrecv venti-conn
+vtsend venti-conn
+vtversion venti-conn
+VtEntry venti-fcall
+VtFcall venti-fcall
+VtRoot venti-fcall
+venti-fcall venti-fcall
+vtentrypack venti-fcall
+vtentryunpack venti-fcall
+vtfcallclear venti-fcall
+vtfcallfmt venti-fcall
+vtfcallpack venti-fcall
+vtfcallunpack venti-fcall
+vtfromdisktype venti-fcall
+vtgetstring venti-fcall
+vtparsescore venti-fcall
+vtputstring venti-fcall
+vtrootpack venti-fcall
+vtrootunpack venti-fcall
+vtscorefmt venti-fcall
+vttodisktype venti-fcall
+VtFile venti-file
+venti-file venti-file
+vtfileblock venti-file
+vtfileblockscore venti-file
+vtfileclose venti-file
+vtfilecreate venti-file
+vtfilecreateroot venti-file
+vtfileflush venti-file
+vtfileflushbefore venti-file
+vtfilegetdirsize venti-file
+vtfilegetentry venti-file
+vtfilegetsize venti-file
+vtfileincref venti-file
+vtfilelock venti-file
+vtfilelock2 venti-file
+vtfileopen venti-file
+vtfileopenroot venti-file
+vtfileread venti-file
+vtfileremove venti-file
+vtfilesetdirsize venti-file
+vtfilesetentry venti-file
+vtfilesetsize venti-file
+vtfiletruncate venti-file
+vtfileunlock venti-file
+vtfilewrite venti-file
+VtLog venti-log
+VtLogChunk venti-log
+venti-log venti-log
+ventilogging venti-log
+vtlog venti-log
+vtlogclose venti-log
+vtlogdump venti-log
+vtlognames venti-log
+vtlogopen venti-log
+vtlogprint venti-log
+vtlogremove venti-log
+venti-mem venti-mem
+vtbrk venti-mem
+vtfree venti-mem
+vtmalloc venti-mem
+vtmallocz venti-mem
+vtrealloc venti-mem
+vtstrdup venti-mem
+Packet venti-packet
+packetalloc venti-packet
+packetappend venti-packet
+packetasize venti-packet
+packetcmp venti-packet
+packetconcat venti-packet
+packetconsume venti-packet
+packetcopy venti-packet
+packetdup venti-packet
+packetforeign venti-packet
+packetfragments venti-packet
+packetfree venti-packet
+packetheader venti-packet
+packetpeek venti-packet
+packetprefix venti-packet
+packetsha1 venti-packet
+packetsize venti-packet
+packetsplit venti-packet
+packetstats venti-packet
+packettrailer venti-packet
+packettrim venti-packet
+venti-packet venti-packet
+venti-server venti-server
+vtgetreq venti-server
+vtlisten venti-server
+vtrespond venti-server
+vtsrvhello venti-server
+venti-zero venti-zero
+vtzeroextend venti-zero
+vtzeroscore venti-zero
+vtzerotruncate venti-zero
+await wait
+wait wait
+waitpid wait
+Screen window
+allocscreen window
+allocwindow window
+bottomnwindows window
+bottomwindow window
+freescreen window
+originwindow window
+publicscreen window
+topnwindows window
+topwindow window
+window window
diff --git a/sys/man/2/INDEX.html b/sys/man/2/INDEX.html
new file mode 100755
index 000000000..5951bcff0
--- /dev/null
+++ b/sys/man/2/INDEX.html
@@ -0,0 +1,637 @@
+<HEAD>
+<TITLE>plan 9 man section 2</TITLE>
+</HEAD>
+<BODY>
+<B>[<A HREF="/sys/man/index.html">manual index</A>]</B>
+<H2>Plan 9 from Bell Labs - Section 2 - System and Library Calls</H2>
+<HR>
+<DL>
+<DT><A HREF="/magic/man2html/2/0intro">0intro</A>
+- introduction to library functions
+<DD><TT> intro</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/9p">9p</A>
+- 9P file service
+<DD><TT> Srv, dirread9p, emalloc9p, erealloc9p, estrdup9p, listensrv, postfd, postmountsrv, readbuf, readstr, respond, responderror, threadlistensrv, threadpostmountsrv, srv</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/9pcmdbuf">9pcmdbuf</A>
+- control message parsing
+<DD><TT> Cmdbuf, parsecmd, respondcmderror, lookupcmd</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/9pfid">9pfid</A>
+- 9P fid, request tracking
+<DD><TT> Fid, Fidpool, allocfidpool, freefidpool, allocfid, closefid, lookupfid, removefid, Req, Reqpool, allocreqpool, freereqpool, allocreq, closereq, lookupreq, removereq</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/9pfile">9pfile</A>
+- in-memory file hierarchy
+<DD><TT> Tree, alloctree, freetree, File, createfile, closefile, removefile, walkfile, opendirfile, readdirfile, closedirfile, hasperm</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/abort">abort</A>
+- generate a fault
+<DD><TT> abort</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/abs">abs</A>
+- integer absolute values
+<DD><TT> abs, labs</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/access">access</A>
+- determine accessibility of file
+<DD><TT> access</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/addpt">addpt</A>
+- arithmetic on points and rectangles
+<DD><TT> addpt, subpt, mulpt, divpt, rectaddpt, rectsubpt, insetrect, canonrect, eqpt, eqrect, ptinrect, rectinrect, rectXrect, rectclip, combinerect, Dx, Dy, Pt, Rect, Rpt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/aes">aes</A>
+- advanced encryption standard (rijndael)
+<DD><TT> setupAESstate, aesCBCencrypt, aesCBCdecrypt, aesCTRencrypt, aesCTRdecrypt, setupAESXCBCstate, aesXCBCmac</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/allocimage">allocimage</A>
+- allocating, freeing, reading, writing images
+<DD><TT> allocimage, allocimagemix, freeimage, nameimage, namedimage, setalpha, loadimage, cloadimage, unloadimage, readimage, writeimage, bytesperline, wordsperline</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/arg">arg</A>
+- process option letters from argv
+<DD><TT> ARGBEGIN, ARGEND, ARGC, ARGF, EARGF</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/arith3">arith3</A>
+- operations on 3-d points and planes
+<DD><TT> add3, sub3, neg3, div3, mul3, eqpt3, closept3, dot3, cross3, len3, dist3, unit3, midpt3, lerp3, reflect3, nearseg3, pldist3, vdiv3, vrem3, pn2f3, ppp2f3, fff2p3, pdiv4, add4, sub4</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/assert">assert</A>
+- check program invariants
+<DD><TT> assert</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/atof">atof</A>
+- convert text to numbers
+<DD><TT> atof, atoi, atol, atoll, charstod, strtod, strtol, strtoll, strtoul, strtoull</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/auth">auth</A>
+- routines for authenticating users
+<DD><TT> amount, newns, addns, login, noworld, auth_proxy, fauth_proxy, auth_allocrpc, auth_freerpc, auth_rpc, auth_getkey, amount_getkey, auth_freeAI, auth_chuid, auth_challenge, auth_response, auth_freechal, auth_respond, auth_userpasswd, auth_getuserpasswd, auth_getinfo</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/authsrv">authsrv</A>
+- routines for communicating with authentication servers
+<DD><TT> authdial, passtokey, nvcsum, readnvram, convT2M, convM2T, convTR2M, convM2TR, convA2M, convM2A, convPR2M, convM2PR, _asgetticket, _asrdresp</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/avl">avl</A>
+- AVL tree routines
+<DD><TT> mkavltree, insertavl, lookupavl, deleteavl, avlwalk, avlnext, avlprev, endwalk</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/bin">bin</A>
+- grouped memory allocation
+<DD><TT> binalloc, bingrow, binfree</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/bind">bind</A>
+- change name space
+<DD><TT> bind, mount, unmount</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/bio">bio</A>
+- buffered input/output
+<DD><TT> Bopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetrune, Bgetd, Bungetc, Bungetrune, Bread, Bseek, Boffset, Bfildes, Blinelen, Bputc, Bputrune, Bprint, Bvprint, Bwrite, Bflush, Bterm, Bbuffered</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/blowfish">blowfish</A>
+- blowfish encryption
+<DD><TT> setupBFstate, bfCBCencrypt, bfCBCdecrypt, bfECBencrypt, bfECBdecrypt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/brk">brk</A>
+- change memory allocation
+<DD><TT> brk, sbrk</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/cachechars">cachechars</A>
+- font utilities
+<DD><TT> cachechars, agefont, loadchar, Subfont, Fontchar, Font</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/chdir">chdir</A>
+- change working directory
+<DD><TT> chdir</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/cleanname">cleanname</A>
+- clean a path name
+<DD><TT> cleanname</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/color">color</A>
+- colors and color maps
+<DD><TT> cmap2rgb, cmap2rgba, rgb2cmap</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/complete">complete</A>
+- file name completion
+<DD><TT> complete</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/control">control</A>
+- interactive graphical controls
+<DD><TT> Control, Controlset, activate, closecontrol, closecontrolset, controlcalled, controlwire, createbox, createboxbox, createbutton, createcolumn, createentry, createkeyboard, createlabel, createmenu, createradiobutton, createrow, createscribble, createslider, createstack, createtab, createtext, createtextbutton, ctlerror, ctlmalloc, ctlrealloc, ctlstrdup, ctlprint, deactivate, freectlfont, freectlimage, initcontrols, namectlfont, namectlimage, newcontrolset, resizecontrolset</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/cputime">cputime</A>
+- cpu time in this process and children
+<DD><TT> cputime, times, cycles</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/ctime">ctime</A>
+- convert date and time
+<DD><TT> ctime, localtime, gmtime, asctime, tm2sec, timezone</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/ctype">ctype</A>
+- ASCII character classification
+<DD><TT> isalpha, isupper, islower, isdigit, isxdigit, isalnum, isspace, ispunct, isprint, isgraph, iscntrl, isascii, toascii, _toupper, _tolower, toupper, tolower</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/debugger">debugger</A>
+- machine-independent debugger functions
+<DD><TT> cisctrace, risctrace, ciscframe, riscframe, localaddr, symoff, fpformat, beieee80ftos, beieeesftos, beieeedftos, leieee80ftos, leieeesftos, leieeedftos, ieeesftos, ieeedftos</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/des">des</A>
+- single and triple digital encryption standard
+<DD><TT> setupDESstate, des_key_setup, block_cipher, desCBCencrypt, desCBCdecrypt, desECBencrypt, desECBdecrypt, des3CBCencrypt, des3CBCdecrypt, des3ECBencrypt, des3ECBdecrypt, key_setup, des56to64, des64to56, setupDES3state, triple_block_cipher</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/dial">dial</A>
+- make and break network connections
+<DD><TT> dial, hangup, announce, listen, accept, reject, netmkaddr, setnetmtpt, getnetconninfo, freenetconninfo</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/dirread">dirread</A>
+- read directory
+<DD><TT> dirread, dirreadall</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/disk">disk</A>
+- generic disk device interface
+<DD><TT> opendisk, Disk</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/draw">draw</A>
+- graphics functions PB L
+<DD><TT> Image, draw, gendraw, drawreplxy, drawrepl, replclipr, line, poly, fillpoly, bezier, bezspline, fillbezier, fillbezspline, ellipse, fillellipse, arc, fillarc, icossin, icossin2, border, string, stringn, runestring, runestringn, stringbg, stringnbg, runestringbg, runestringnbg, _string, ARROW, drawsetdebug</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/dsa">dsa</A>
+- digital signature algorithm
+<DD><TT> dsagen, dsasign, dsaverify, dsapuballoc, dsapubfree, dsaprivalloc, dsaprivfree, dsasigalloc, dsasigfree, dsaprivtopub</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/dup">dup</A>
+- duplicate an open file descriptor
+<DD><TT> dup</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/elgamal">elgamal</A>
+- elgamal encryption
+<DD><TT> eggen, egencrypt, egdecrypt, egsign, egverify, egpuballoc, egpubfree, egprivalloc, egprivfree, egsigalloc, egsigfree, egprivtopub</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/encode">encode</A>
+- encoding byte arrays as strings
+<DD><TT> dec64, enc64, dec32, enc32, dec16, enc16, encodefmt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/encrypt">encrypt</A>
+- DES encryption
+<DD><TT> encrypt, decrypt, netcrypt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/errstr">errstr</A>
+- description of last system call error
+<DD><TT> errstr, rerrstr, werrstr</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/event">event</A>
+- graphics events
+<DD><TT> event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, ereadmouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, emoveto, esetcursor, Event, Mouse, Menu</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/exec">exec</A>
+- execute a file
+<DD><TT> exec, execl, _privates, _nprivates, _tos</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/exits">exits</A>
+- terminate process, process cleanup
+<DD><TT> exits, _exits, atexit, atexitdont, terminate</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/exp">exp</A>
+- exponential, logarithm, power, square root
+<DD><TT> exp, log, log10, pow, pow10, sqrt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fauth">fauth</A>
+- set up authentication on a file descriptor to a file server
+<DD><TT> fauth</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fcall">fcall</A>
+- interface to Plan 9 File protocol
+<DD><TT> Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt, dirmodefmt, read9pmsg, statcheck, sizeS2M, sizeD2M</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fd2path">fd2path</A>
+- return file name associated with file descriptor
+<DD><TT> fd2path</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fgetc">fgetc</A>
+- Stdio input and output
+<DD><TT> fgetc, getc, getchar, fputc, putc, putchar, ungetc, fgets, gets, fputs, puts, fread, fwrite</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/flate">flate</A>
+- deflate compression
+<DD><TT> deflateinit, deflate, deflatezlib, deflateblock, deflatezlibblock, inflateinit, inflate, inflatezlib, inflateblock, inflatezlibblock, flateerr, mkcrctab, blockcrc, adler32</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/floor">floor</A>
+- absolute value, remainder, floor, ceiling functions
+<DD><TT> fabs, fmod, floor, ceil</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fmtinstall">fmtinstall</A>
+- support for user-defined print formats and output routines
+<DD><TT> fmtinstall, dofmt, dorfmt, fmtprint, fmtvprint, fmtrune, fmtstrcpy, fmtrunestrcpy, fmtfdinit, fmtfdflush, fmtstrinit, fmtstrflush, runefmtstrinit, runefmtstrflush, errfmt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fopen">fopen</A>
+- standard buffered input/output package
+<DD><TT> fopen, freopen, fdopen, fileno, fclose, sopenr, sopenw, sclose, fflush, setvbuf, setbuf, fgetpos, ftell, fsetpos, fseek, rewind, feof, ferror, clearerr</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fork">fork</A>
+- manipulate process resources
+<DD><TT> fork, rfork</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fprintf">fprintf</A>
+- print formatted output
+<DD><TT> fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf, vsnprintf</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/frame">frame</A>
+- frames of text
+<DD><TT> frinit, frsetrects, frinittick, frclear, frcharofpt, frptofchar, frinsert, frdelete, frselect, frtick, frselectpaint, frdrawsel, frdrawsel0, frgetmouse</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/frexp">frexp</A>
+- split into mantissa and exponent
+<DD><TT> frexp, ldexp, modf</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fscanf">fscanf</A>
+- scan formatted input
+<DD><TT> fscanf, scanf, sscanf, vfscanf</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/fversion">fversion</A>
+- initialize 9P connection and negotiate version
+<DD><TT> fversion</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getcallerpc">getcallerpc</A>
+- fetch return PC of current function
+<DD><TT> getcallerpc</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getenv">getenv</A>
+- access environment variables
+<DD><TT> getenv, putenv</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getfcr">getfcr</A>
+- control floating point
+<DD><TT> getfcr, setfcr, getfsr, setfsr</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getfields">getfields</A>
+- break a string into fields
+<DD><TT> getfields, gettokens, tokenize</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getpid">getpid</A>
+- get process ids
+<DD><TT> getpid, getppid</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getuser">getuser</A>
+- get user or system name
+<DD><TT> getuser, sysname</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/getwd">getwd</A>
+- get current directory
+<DD><TT> getwd</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/graphics">graphics</A>
+- interactive graphics
+<DD><TT> Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getdefont, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, openfont, buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/html">html</A>
+- HTML parser
+<DD><TT> parsehtml, printitems, validitems, freeitems, freedocinfo, dimenkind, dimenspec, targetid, targetname, fromStr, toStr</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/httpd">httpd</A>
+- routines for creating an http server
+<DD><TT> HConnect, HContent, HContents, HETag, HFields, Hio, Htmlesc, HttpHead, HttpReq, HRange, HSPairs, hmydomain, hversion, htmlesc, halloc, hbodypush, hbuflen, hcheckcontent, hclose, hdate2sec, hdatefmt, hfail, hflush, hgetc, hgethead, hinit, hiserror, hload, hlower, hmkcontent, hmkhfields, hmkmimeboundary, hmkspairs, hmoved, hokheaders, hparseheaders, hparsequery, hparsereq, hprint, hputc, hreadbuf, hredirected, hreqcleanup, hrevhfields, hrevspairs, hstrdup, http11, httpfmt, httpunesc, hunallowed, hungetc, hunload, hurlfmt, hurlunesc, hvprint, hwrite, hxferenc,</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/hypot">hypot</A>
+- Euclidean distance
+<DD><TT> hypot</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/intmap">intmap</A>
+- integer to data structure maps
+<DD><TT> Intmap, allocmap, freemap, insertkey, caninsertkey, lookupkey, deletekey</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/ioproc">ioproc</A>
+- slave I/O processes for threaded programs
+<DD><TT> closeioproc, iocall, ioclose, iointerrupt, iodial, ioopen, ioproc, ioread, ioreadn, iowrite</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/iounit">iounit</A>
+- return size of atomic I/O unit for file descriptor
+<DD><TT> iounit</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/ip">ip</A>
+- Internet Protocol addressing
+<DD><TT> eipfmt, parseip, parseipmask, v4parseip, v4parsecidr, parseether, myipaddr, myetheraddr, maskip, equivip4, equivip6, defmask, isv4, v4tov6, v6tov4, nhgetv, nhgetl, nhgets, hnputv, hnputl, hnputs, ptclbsum, readipifc</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/isalpharune">isalpharune</A>
+- Unicode character classes and cases
+<DD><TT> isalpharune, islowerrune, isspacerune, istitlerune, isupperrune, tolowerrune, totitlerune, toupperrune</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/keyboard">keyboard</A>
+- keyboard control
+<DD><TT> initkeyboard, ctlkeyboard, closekeyboard</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/lock">lock</A>
+- spin locks, queueing rendezvous locks, reader-writer locks, rendezvous points, and reference counts
+<DD><TT> lock, canlock, unlock, qlock, canqlock, qunlock, rlock, canrlock, runlock, wlock, canwlock, wunlock, rsleep, rwakeup, rwakeupall, incref, decref</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/mach">mach</A>
+- machine-independent access to executable files
+<DD><TT> crackhdr, machbytype, machbyname, newmap, setmap, findseg, unusemap, loadmap, attachproc, get1, get2, get4, get8, put1, put2, put4, put8, beswab, beswal, beswav, leswab, leswal, leswav</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/malloc">malloc</A>
+- memory allocator
+<DD><TT> malloc, mallocalign, mallocz, free, realloc, calloc, msize, setmalloctag, setrealloctag, getmalloctag, getrealloctag, malloctopoolblock</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/matrix">matrix</A>
+- Geometric transformations
+<DD><TT> ident, matmul, matmulr, determinant, adjoint, invertmat, xformpoint, xformpointd, xformplane, pushmat, popmat, rot, qrot, scale, move, xform, ixform, persp, look, viewport</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/memdraw">memdraw</A>
+- drawing routines for memory-resident images
+<DD><TT> Memimage, Memdata, Memdrawparam, memimageinit, wordaddr, byteaddr, memimagemove, allocmemimage, allocmemimaged, readmemimage, creadmemimage, writememimage, freememimage, memsetchan, loadmemimage, cloadmemimage, unloadmemimage, memfillcolor, memarc, mempoly, memellipse, memfillpoly, memimageline, memimagedraw, drawclip, memlinebbox, memlineendsize, allocmemsubfont, openmemsubfont, freememsubfont, memsubfontwidth, getmemdefont, memimagestring, iprint, hwdraw</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/memlayer">memlayer</A>
+- windows of memory-resident images
+<DD><TT> memdraw, memlalloc, memldelete, memlexpose, memlfree, memlhide, memline, memlnorefresh, memload, memunload, memlorigin, memlsetrefresh, memltofront, memltofrontn, memltorear, memltorearn</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/memory">memory</A>
+- memory operations
+<DD><TT> memccpy, memchr, memcmp, memcpy, memmove, memset</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/mktemp">mktemp</A>
+- make a unique file name
+<DD><TT> mktemp</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/mouse">mouse</A>
+- mouse control
+<DD><TT> initmouse, readmouse, closemouse, moveto, getrect, drawgetrect, menuhit, setcursor</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/mp">mp</A>
+- extended precision arithmetic
+<DD><TT> mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, strtomp, mpfmt,mptoa, betomp, mptobe, letomp, mptole, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/muldiv">muldiv</A>
+- high-precision multiplication and division
+<DD><TT> muldiv, umuldiv</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/nan">nan</A>
+- not-a-number and infinity functions
+<DD><TT> NaN, Inf, isNaN, isInf</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/ndb">ndb</A>
+- network database
+<DD><TT> ndbopen, ndbcat, ndbchanged, ndbclose, ndbreopen, ndbsearch, ndbsnext, ndbgetvalue, ndbfree, ipattr, ndbgetipaddr, ndbipinfo, csipinfo, ndbhash, ndbparse, csgetvalue, ndbfindattr, dnsquery, ndbdiscard, ndbconcatenate, ndbreorder, ndbsubstitute, ndbgetval, csgetval, ndblookval</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/notify">notify</A>
+- handle asynchronous process notification
+<DD><TT> notify, noted, atnotify</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/object">object</A>
+- object file interpretation functions
+<DD><TT> objtype, readobj, objtraverse, isar, nextar, readar</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/open">open</A>
+- open a file for reading or writing, create file
+<DD><TT> open, create, close</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/perror">perror</A>
+- system error messages
+<DD><TT> perror, syslog, sysfatal</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/pipe">pipe</A>
+- create an interprocess channel
+<DD><TT> pipe</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/plumb">plumb</A>
+- plumb messages
+<DD><TT> eplumb, plumbfree, plumbopen, plumbsend, plumbsendtext, plumblookup, plumbpack, plumbpackattr, plumbaddattr, plumbdelattr, plumbrecv, plumbunpack, plumbunpackpartial, plumbunpackattr, Plumbmsg</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/pool">pool</A>
+- general memory management routines
+<DD><TT> poolalloc, poolallocalign, poolfree, poolmsize, poolrealloc, poolcompact, poolcheck, poolblockcheck, pooldump</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/postnote">postnote</A>
+- send a note to a process or process group
+<DD><TT> postnote</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/prime">prime</A>
+- prime number generation
+<DD><TT> genprime, gensafeprime, genstrongprime, DSAprimes, probably_prime, smallprimetest</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/print">print</A>
+- print formatted output
+<DD><TT> print, fprint, sprint, snprint, seprint, smprint, runesprint, runesnprint, runeseprint, runesmprint, vfprint, vsnprint, vseprint, vsmprint, runevsnprint, runevseprint, runevsmprint</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/privalloc">privalloc</A>
+- per-process private storage management
+<DD><TT> privalloc, privfree</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/proto">proto</A>
+- parse and process a proto file listing
+<DD><TT> rdproto</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/pushssl">pushssl</A>
+- attach SSL version 2 encryption to a communication channel
+<DD><TT> pushssl</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/pushtls">pushtls</A>
+- attach TLS1 or SSL3 encryption to a communication channel
+<DD><TT> pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, readcert, readcertchain</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/qball">qball</A>
+- 3-d rotation controller
+<DD><TT> qball</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/qsort">qsort</A>
+- quicker sort
+<DD><TT> qsort</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/quaternion">quaternion</A>
+- Quaternion arithmetic
+<DD><TT> qtom, mtoq, qadd, qsub, qneg, qmul, qdiv, qunit, qinv, qlen, slerp, qmid, qsqrt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/quote">quote</A>
+- quoted character strings
+<DD><TT> quotestrdup, quoterunestrdup, unquotestrdup, unquoterunestrdup, quotestrfmt, quoterunestrfmt, quotefmtinstall, doquote, needsrcquote</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/rand">rand</A>
+- random number generators
+<DD><TT> rand, lrand, frand, nrand, lnrand, srand, truerand, ntruerand, genrandom, prng, fastrand, nfastrand</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/rc4">rc4</A>
+- alleged rc4 encryption
+<DD><TT> setupRC4state, rc4, rc4skip, rc4back</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/read">read</A>
+- read or write file
+<DD><TT> read, readn, write, pread, pwrite</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/readcolmap">readcolmap</A>
+- access display color map
+<DD><TT> RGB, readcolmap, writecolmap</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/readv">readv</A>
+- scatter/gather read and write
+<DD><TT> readv, writev, preadv, pwritev</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/regexp">regexp</A>
+- regular expression
+<DD><TT> regcomp, regcomplit, regcompnl, regexec, regsub, rregexec, rregsub, regerror</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/remove">remove</A>
+- remove a file
+<DD><TT> remove</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/rendezvous">rendezvous</A>
+- user level process synchronization
+<DD><TT> rendezvous</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/rsa">rsa</A>
+- RSA encryption algorithm
+<DD><TT> asn1dump, asn1toRSApriv, decodePEM, rsadecrypt, rsaencrypt, rsagen, rsaprivalloc, rsaprivfree, rsaprivtopub, rsapuballoc, rsapubfree, X509toRSApub, X509gen, X509verify</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/rune">rune</A>
+- rune/UTF conversion
+<DD><TT> runetochar, chartorune, runelen, runenlen, fullrune, utfecpy, utflen, utfnlen, utfrune, utfrrune, utfutf</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/runestrcat">runestrcat</A>
+- rune string operations
+<DD><TT> runestrcat, runestrncat, runestrcmp, runestrncmp, runestrcpy, runestrncpy, runestrecpy, runestrlen, runestrchr, runestrrchr, runestrdup, runestrstr</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/scribble">scribble</A>
+- character recognition
+<DD><TT> scribblealloc, recognize</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/scsi">scsi</A>
+- SCSI device operations
+<DD><TT> openscsi, closescsi, scsiready, scsi, scsicmd, scsierror</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/sechash">sechash</A>
+- cryptographically secure hashes
+<DD><TT> md4, md5, sha1, sha2_224, sha2_256, sha2_384, sha2_512, aes, hmac_x, hmac_md5, hmac_sha1, hmac_sha2_224, hmac_sha2_256, hmac_sha2_384, hmac_sha2_512, hmac_aes, md5pickle, md5unpickle, sha1pickle, sha1unpickle</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/seek">seek</A>
+- change file offset
+<DD><TT> seek</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/segattach">segattach</A>
+- map/unmap a segment in virtual memory
+<DD><TT> segattach, segdetach, segfree</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/segbrk">segbrk</A>
+- change memory allocation
+<DD><TT> segbrk</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/segflush">segflush</A>
+- flush instruction and data caches
+<DD><TT> segflush</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/semacquire">semacquire</A>
+- user level semaphores
+<DD><TT> semacquire, semrelease</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/setjmp">setjmp</A>
+- non-local goto
+<DD><TT> setjmp, longjmp, notejmp</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/sin">sin</A>
+- trigonometric functions
+<DD><TT> sin, cos, tan, asin, acos, atan, atan2</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/sinh">sinh</A>
+- hyperbolic functions
+<DD><TT> sinh, cosh, tanh</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/sleep">sleep</A>
+- delay, ask for delayed note
+<DD><TT> sleep, alarm</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/stat">stat</A>
+- get and put file status
+<DD><TT> stat, fstat, wstat, fwstat, dirstat, dirfstat, dirwstat, dirfwstat, nulldir</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/strcat">strcat</A>
+- string operations
+<DD><TT> strcat, strncat, strcmp, strncmp, cistrcmp, cistrncmp, strcpy, strncpy, strecpy, strlen, strchr, strrchr, strpbrk, strspn, strcspn, strtok, strdup, strstr, cistrstr</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/string">string</A>
+- extensible strings
+<DD><TT> s_alloc, s_append, s_array, s_copy, s_error, s_free, s_incref, s_memappend, s_nappend, s_new, s_newalloc, s_parse, s_reset, s_restart, s_terminate, s_tolower, s_putc, s_unique, s_grow, s_read, s_read_line, s_getline</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/stringsize">stringsize</A>
+- graphical size of strings
+<DD><TT> stringsize, stringwidth, stringnwidth, runestringsize, runestringwidth, runestringnwidth</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/subfont">subfont</A>
+- subfont manipulation
+<DD><TT> allocsubfont, freesubfont, installsubfont, lookupsubfont, uninstallsubfont, subfontname, readsubfont, readsubfonti, writesubfont, stringsubfont, strsubfontwidth, mkfont</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/symbol">symbol</A>
+- symbol table access functions
+<DD><TT> syminit, getsym, symbase, pc2sp, pc2line, textseg, line2addr, lookup, findlocal, getauto, findsym, localsym, globalsym, textsym, file2pc, fileelem, filesym, fileline, fnbound</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/thread">thread</A>
+- thread and proc management
+<DD><TT> alt, chanclose, chancreate, chanfree, chaninit, chanclosing, chanprint, mainstacksize, proccreate, procdata, procexec, procexecl, procrfork, recv, recvp, recvul, send, sendp, sendul, nbrecv, nbrecvp, nbrecvul, nbsend, nbsendp, nbsendul, threadcreate, threaddata, threadexits, threadexitsall, threadgetgrp, threadgetname, threadint, threadintgrp, threadkill, threadkillgrp, threadmain, threadnotify, threadid, threadpid, threadsetgrp, threadsetname, threadwaitchan, yield</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/time">time</A>
+- time in seconds and nanoseconds since epoch
+<DD><TT> time, nsec</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/tmpfile">tmpfile</A>
+- Stdio temporary files
+<DD><TT> tmpfile, tmpnam</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/usb">usb</A>
+- USB device driver library
+<DD><TT> usbcmd, classname, closedev, configdev, devctl, finddevs, loaddevstr, matchdevcsp, opendev, opendevdata, openep, startdevs, unstall, class, subclass, proto, CSP</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/usbfs">usbfs</A>
+- USB device driver file system library
+<DD><TT> usbreadbuf, usbfsadd, usbfsdel, usbdirread, usbfsinit, usbdirfs, usbfs</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti">venti</A>
+- archival storage server
+<DD><TT> venti</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-cache">venti-cache</A>
+- Venti block cache
+<DD><TT> VtBlock, VtCache, vtblockcopy, vtblockdirty, vtblockduplock, vtblockput, vtblockwrite, vtcachealloc, vtcacheallocblock, vtcacheblocksize, vtcachefree, vtcacheglobal, vtcachelocal, vtcachesetwrite, vtglobaltolocal, vtlocaltoglobal</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-client">venti-client</A>
+- Venti client
+<DD><TT> vtconnect, vthello, vtread, vtwrite, vtreadpacket, vtwritepacket, vtsync, vtping, vtrpc, ventidoublechecksha1</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-conn">venti-conn</A>
+- Venti network connections
+<DD><TT> VtConn, vtconn, vtdial, vtfreeconn, vtsend, vtrecv, vtversion, vtdebug, vthangup</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-fcall">venti-fcall</A>
+- venti data formats
+<DD><TT> VtEntry, VtFcall, VtRoot, vtentrypack, vtentryunpack, vtfcallclear, vtfcallfmt, vtfcallpack, vtfcallunpack, vtfromdisktype, vttodisktype, vtgetstring, vtputstring, vtrootpack, vtrootunpack, vtparsescore, vtscorefmt</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-file">venti-file</A>
+- Venti files
+<DD><TT> VtFile, vtfileblock, vtfileblockscore, vtfileclose, vtfilecreate, vtfilecreateroot, vtfileflush, vtfileflushbefore, vtfilegetdirsize, vtfilegetentry, vtfilegetsize, vtfileincref, vtfilelock, vtfilelock2, vtfileopen, vtfileopenroot, vtfileread, vtfileremove, vtfilesetdirsize, vtfilesetentry, vtfilesetsize, vtfiletruncate, vtfileunlock, vtfilewrite</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-log">venti-log</A>
+- Venti logs
+<DD><TT> VtLog, VtLogChunk, vtlog, vtlogclose, vtlogdump, vtlognames, vtlogopen, vtlogprint, vtlogremove, vtlogopen, ventilogging</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-mem">venti-mem</A>
+- error-checking memory allocators
+<DD><TT> vtbrk, vtmalloc, vtmallocz, vtrealloc, vtstrdup, vtfree</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-packet">venti-packet</A>
+- zero-copy network buffers
+<DD><TT> Packet, packetalloc, packetappend, packetasize, packetcmp, packetconcat, packetconsume, packetcopy, packetdup, packetforeign, packetfragments, packetfree, packetheader, packetpeek, packetprefix, packetsha1, packetsize, packetsplit, packetstats, packettrailer, packettrim</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-server">venti-server</A>
+- Venti server
+<DD><TT> vtsrvhello, vtlisten, vtgetreq, vtrespond</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/venti-zero">venti-zero</A>
+- Venti block truncation
+<DD><TT> vtzerotruncate, vtzeroextend, vtzeroscore</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/wait">wait</A>
+- wait for a process to exit
+<DD><TT> await, wait, waitpid</TT>
+</DT>
+<DT><A HREF="/magic/man2html/2/window">window</A>
+- window management
+<DD><TT> Screen, allocscreen, publicscreen, freescreen, allocwindow, bottomwindow, bottomnwindows, topwindow, topnwindows, originwindow</TT>
+</DT>
+</DL>
diff --git a/sys/man/2/abort b/sys/man/2/abort
new file mode 100755
index 000000000..feec9d856
--- /dev/null
+++ b/sys/man/2/abort
@@ -0,0 +1,18 @@
+.TH ABORT 2
+.SH NAME
+abort \- generate a fault
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+void abort(void)
+.fi
+.SH DESCRIPTION
+.I Abort
+causes an access fault, causing the current process to enter the `Broken' state.
+The process can then be inspected by a debugger.
+.SH SOURCE
+.B /sys/src/libc/9sys/abort.c
diff --git a/sys/man/2/abs b/sys/man/2/abs
new file mode 100755
index 000000000..b2df7fba6
--- /dev/null
+++ b/sys/man/2/abs
@@ -0,0 +1,33 @@
+.TH ABS 2
+.SH NAME
+abs, labs \- integer absolute values
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int abs(int a)
+.PP
+.B
+long labs(long a)
+.SH DESCRIPTION
+.I Abs
+returns
+the absolute value of integer
+.IR a ,
+and
+.I labs
+does the same for a long.
+.SH SOURCE
+.B /sys/src/libc/port/abs.c
+.SH SEE ALSO
+.IR floor (2)
+for
+.I fabs
+.SH DIAGNOSTICS
+.I Abs
+and
+.I labs
+return
+the most negative integer or long when the true result is unrepresentable.
diff --git a/sys/man/2/access b/sys/man/2/access
new file mode 100755
index 000000000..25c368320
--- /dev/null
+++ b/sys/man/2/access
@@ -0,0 +1,60 @@
+.TH ACCESS 2
+.SH NAME
+access \- determine accessibility of file
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int access(char *name, int mode)
+.SH DESCRIPTION
+.I Access
+evaluates the given
+file
+.I name
+for accessibility.
+If \fImode\fL&4\fR
+is nonzero,
+read permission is expected;
+if \fImode\fL&2\fR,
+write permission;
+if \fImode\fL&1\fR,
+execute permission.
+If \fImode\fL==0\fR,
+the file merely need exist.
+In any case
+all directories leading to the file
+must permit searches.
+Zero is returned if the desired access is permitted,
+\-1 if not.
+.PP
+Only access for open is checked.
+A file may look executable, but
+.IR exec (2)
+will fail unless it is in proper format.
+.PP
+The include file
+.F <libc.h>
+defines
+.BR AEXIST =0,
+.BR AEXEC =1,
+.BR AWRITE =2,
+and
+.BR AREAD =4.
+.PP
+.SH SOURCE
+.B /sys/src/libc/9sys/access.c
+.SH SEE ALSO
+.IR stat (2)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
+.SH BUGS
+Since file permissions are checked by the server and group information
+is not known to the client,
+.I access
+must open the file to check permissions.
+(It calls
+.IR stat (2)
+to check simple existence.)
diff --git a/sys/man/2/addpt b/sys/man/2/addpt
new file mode 100755
index 000000000..9738c51bf
--- /dev/null
+++ b/sys/man/2/addpt
@@ -0,0 +1,188 @@
+.TH ADDPT 2
+.SH NAME
+addpt, subpt, mulpt, divpt, rectaddpt, rectsubpt, insetrect, canonrect, eqpt, eqrect, ptinrect, rectinrect, rectXrect, rectclip, combinerect, Dx, Dy, Pt, Rect, Rpt \- arithmetic on points and rectangles
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <draw.h>
+.PP
+.B
+Point addpt(Point p, Point q)
+.PP
+.B
+Point subpt(Point p, Point q)
+.PP
+.B
+Point mulpt(Point p, int a)
+.PP
+.B
+Point divpt(Point p, int a)
+.PP
+.B
+Rectangle rectaddpt(Rectangle r, Point p)
+.PP
+.B
+Rectangle rectsubpt(Rectangle r, Point p)
+.PP
+.B
+Rectangle insetrect(Rectangle r, int n)
+.PP
+.B
+Rectangle canonrect(Rectangle r)
+.PP
+.B
+int eqpt(Point p, Point q)
+.PP
+.B
+int eqrect(Rectangle r, Rectangle s)
+.PP
+.B
+int ptinrect(Point p, Rectangle r)
+.PP
+.B
+int rectinrect(Rectangle r, Rectangle s)
+.PP
+.B
+int rectXrect(Rectangle r, Rectangle s)
+.PP
+.B
+int rectclip(Rectangle *rp, Rectangle b)
+.PP
+.B
+void combinerect(Rectangle *rp, Rectangle b)
+.PP
+.B
+int Dx(Rectangle r)
+.PP
+.B
+int Dy(Rectangle r)
+.PP
+.B
+Point Pt(int x, int y)
+.PP
+.B
+Rectangle Rect(int x0, int y0, int x1, int y1)
+.PP
+.B
+Rectangle Rpt(Point p, Point q)
+.SH DESCRIPTION
+The functions
+.IR Pt ,
+.I Rect
+and
+.I Rpt
+construct geometrical data types from their components.
+.PP
+.I Addpt
+returns the Point
+sum of its arguments:
+.BI Pt( p .x+ q .x,
+.IB p .y+ q .y) \f1.
+.I Subpt
+returns the Point
+difference of its arguments:
+.BI Pt( p .x- q .x,
+.IB p .y- q .y) \f1.
+.I Mulpt
+returns the Point
+.BI Pt( p .x* a ,
+.IB p .y* a ) \f1.
+.I Divpt
+returns the Point
+.BI Pt( p .x/ a ,
+.IB p .y/ a ) \f1.
+.PP
+.I Rectaddpt
+returns the Rectangle
+.BI Rect(add( r .min,
+.IB p ) \f1,
+.BI add( r .max,
+.IB p )) \f1;
+.I rectsubpt
+returns the Rectangle
+.BI Rpt(sub( r .min,
+.IB p ),
+.BI sub( r .max,
+.IB p ))\fR.
+.PP
+.I Insetrect
+returns the Rectangle
+.BI Rect( r .min.x+ n \f1,
+.IB r .min.y+ n \f1,
+.IB r .max.x- n \f1,
+.IB r .max.y- n ) \f1.
+.PP
+.I Canonrect
+returns a rectangle with the same extent as
+.IR r ,
+canonicalized so that
+.B min.x
+≤
+.BR max.x ,
+and
+.B min.y
+≤
+.BR max.y .
+.PP
+.I Eqpt
+compares its argument Points and returns
+0 if unequal,
+1 if equal.
+.I Eqrect
+does the same for its argument Rectangles.
+.PP
+.I Ptinrect
+returns 1 if
+.I p
+is a point within
+.IR r ,
+and 0 otherwise.
+.PP
+.I Rectinrect
+returns 1 if all the pixels in
+.I r
+are also in
+.IR s ,
+and 0 otherwise.
+.PP
+.I RectXrect
+returns 1 if
+.I r
+and
+.I s
+share any point, and 0 otherwise.
+.PP
+.I Rectclip
+clips in place
+the Rectangle pointed to by
+.I rp
+so that it is completely contained within
+.IR b .
+The return value is 1 if any part of
+.RI * rp
+is within
+.IR b .
+Otherwise, the return value is 0 and
+.RI * rp
+is unchanged.
+.PP
+.I Combinerect
+overwrites
+.B *rp
+with the smallest rectangle sufficient to cover all the pixels of
+.B *rp
+and
+.BR b .
+.PP
+The functions
+.I Dx
+and
+.I Dy
+give the width (Δx) and height (Δy) of a Rectangle.
+They are implemented as macros.
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2)
diff --git a/sys/man/2/aes b/sys/man/2/aes
new file mode 100755
index 000000000..caae33630
--- /dev/null
+++ b/sys/man/2/aes
@@ -0,0 +1,101 @@
+.TH AES 2
+.SH NAME
+setupAESstate, aesCBCencrypt, aesCBCdecrypt, aesCTRencrypt, aesCTRdecrypt, setupAESXCBCstate, aesXCBCmac - advanced encryption standard (rijndael)
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.in +0.5i
+.ti -0.5i
+.B
+void aes_encrypt(ulong rk[], int Nr, uchar pt[16], uchar ct[16]);
+.PP
+.B
+void aes_decrypt(ulong rk[], int Nr, uchar ct[16], uchar pt[16]);
+.PP
+.B
+void setupAESstate(AESstate *s, uchar key[], int keybytes, uchar *ivec)
+.PP
+.B
+void aesCBCencrypt(uchar *p, int len, AESstate *s)
+.PP
+.B
+void aesCBCdecrypt(uchar *p, int len, AESstate *s)
+.PP
+.B
+void aesCTRencrypt(uchar *p, int len, AESstate *s)
+.PP
+.B
+void aesCTRdecrypt(uchar *p, int len, AESstate *s)
+.PP
+.B
+void setupAESXCBCstate(AESstate *s)
+.PP
+.B
+void aesXCBCmac(uchar *p, int len, AESstate *s)
+.SH DESCRIPTION
+AES (a.k.a. Rijndael) has replaced DES as the preferred
+block cipher.
+.I Aes_encrypt
+and
+.I aes_decrypt
+are the block ciphers, corresponding to
+.IR des (2)'s
+.IR block_cipher .
+.IR SetupAESstate ,
+.IR aesCBCencrypt ,
+and
+.I aesCBCdecrypt
+implement cipher-block-chaining encryption.
+.I AesCTRencrypt
+and
+.I aesCTRdecrypt
+implement counter mode, per RFC 3686;
+they are identical operations.
+.I setupAESXCBCstate
+and
+.I aesXCBCmac
+implement AES XCBC message authentication, per RFC 3566.
+All ciphering is performed in place.
+.I Keybytes
+should be 16, 24, or 32.
+The initialization vector
+.I ivec
+of
+.I AESbsize
+bytes should be random enough to be unlikely to be reused
+but does not need to be
+cryptographically strongly unpredictable.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.I aescbc
+in
+.IR secstore (1),
+.IR mp (2),
+.IR blowfish (2),
+.IR des (2),
+.IR dsa (2),
+.IR elgamal (2),
+.IR rc4 (2),
+.IR rsa (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2)
+.br
+.B http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+.SH BUGS
+The functions
+.IR aes_encrypt ,
+.IR aes_decrypt ,
+.IR aesCTRencrypt ,
+.IR aesCTRdecrypt ,
+.IR setupAESXCBCstate ,
+and
+.IR aesXCBCmac
+have not yet been verified by running test vectors through them.
diff --git a/sys/man/2/allocimage b/sys/man/2/allocimage
new file mode 100755
index 000000000..2a584c143
--- /dev/null
+++ b/sys/man/2/allocimage
@@ -0,0 +1,348 @@
+.TH ALLOCIMAGE 2
+.SH NAME
+allocimage, allocimagemix, freeimage, nameimage, namedimage, setalpha, loadimage, cloadimage, unloadimage, readimage, writeimage, bytesperline, wordsperline \- allocating, freeing, reading, writing images
+.SH SYNOPSIS
+.nf
+.PP
+.B
+#include <u.h>
+.B
+#include <libc.h>
+.B
+#include <draw.h>
+.PP
+.ta \w'\fLImage 'u
+.B
+Image *allocimage(Display *d, Rectangle r,
+.br
+.B
+ ulong chan, int repl, int col)
+.PP
+.B
+Image *allocimagemix(Display *d, ulong one, ulong three)
+.PP
+.B
+void freeimage(Image *i)
+.PP
+.B
+int nameimage(Image *i, char *name, int in)
+.PP
+.B
+Image *namedimage(Display *d, char *name)
+.PP
+.B
+ulong setalpha(ulong color, uchar alpha)
+.PP
+.B
+int loadimage(Image *i, Rectangle r, uchar *data, int ndata)
+.PP
+.B
+int cloadimage(Image *i, Rectangle r, uchar *data, int ndata)
+.PP
+.B
+int unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
+.PP
+.B
+Image *readimage(Display *d, int fd, int dolock)
+.PP
+.B
+int writeimage(int fd, Image *i, int dolock)
+.PP
+.B
+int bytesperline(Rectangle r, int d)
+.PP
+.B
+int wordsperline(Rectangle r, int d)
+.PP
+.nf
+.B
+enum
+.nf
+.ft L
+.ta +4n +20
+{
+ DOpaque = 0xFFFFFFFF,
+ DTransparent = 0x00000000,
+ DBlack = 0x000000FF,
+ DWhite = 0xFFFFFFFF,
+ DRed = 0xFF0000FF,
+ DGreen = 0x00FF00FF,
+ DBlue = 0x0000FFFF,
+ DCyan = 0x00FFFFFF,
+ DMagenta = 0xFF00FFFF,
+ DYellow = 0xFFFF00FF,
+ DPaleyellow = 0xFFFFAAFF,
+ DDarkyellow = 0xEEEE9EFF,
+ DDarkgreen = 0x448844FF,
+ DPalegreen = 0xAAFFAAFF,
+ DMedgreen = 0x88CC88FF,
+ DDarkblue = 0x000055FF,
+ DPalebluegreen = 0xAAFFFFFF,
+ DPaleblue = 0x0000BBFF,
+ DBluegreen = 0x008888FF,
+ DGreygreen = 0x55AAAAFF,
+ DPalegreygreen = 0x9EEEEEFF,
+ DYellowgreen = 0x99994CFF,
+ DMedblue = 0x000099FF,
+ DGreyblue = 0x005DBBFF,
+ DPalegreyblue = 0x4993DDFF,
+ DPurpleblue = 0x8888CCFF,
+
+ DNotacolor = 0xFFFFFF00,
+ DNofill = DNotacolor,
+
+};
+.fi
+.SH DESCRIPTION
+A new
+.B Image
+on
+.B Display
+.B d
+is allocated with
+.BR allocimage ;
+it will have the rectangle, pixel channel format,
+and replication flag
+given by its arguments.
+Convenient pixel channels like
+.BR GREY1 ,
+.BR GREY2 ,
+.BR CMAP8 ,
+.BR RGB16 ,
+.BR RGB24 ,
+and
+.BR RGBA32
+are predefined.
+All the new image's pixels will have initial value
+.IR col .
+If
+.I col
+is
+.BR DNofill ,
+no initialization is done.
+Representative useful values of color are predefined:
+.BR DBlack ,
+.BR DWhite ,
+.BR DRed ,
+and so on.
+Colors are specified by 32-bit numbers comprising,
+from most to least significant byte,
+8-bit values for red, green, blue, and alpha.
+The values correspond to illumination, so 0 is black and 255 is white.
+Similarly, for alpha 0 is transparent and 255 is opaque.
+The
+.I id
+field will have been set to the identifying number used by
+.B /dev/draw
+(see
+.IR draw (3)),
+and the
+.I cache
+field will be zero.
+If
+.I repl
+is true, the clip rectangle is set to a very large region; if false, it is set to
+.IR r .
+The
+.I depth
+field will be set to the number of bits per pixel specified
+by the channel descriptor
+(see
+.IR image (6)).
+.I Allocimage
+returns 0 if the server has run out of image memory.
+.PP
+.I Allocimagemix
+is used to allocate background colors.
+On 8-bit color-mapped displays, it
+returns a 2×2 replicated image with one pixel colored
+the color
+.I one
+and the other three with
+.IR three .
+(This simulates a wider range of tones than can be represented by a single pixel
+value on a color-mapped display.)
+On true color displays, it returns a 1×1 replicated image
+whose pixel is the result of mixing the two colors in
+a one to three ratio.
+.PP
+.I Freeimage
+frees the resources used by its argument image.
+.PP
+.I Nameimage
+publishes in the server the image
+.I i
+under the given
+.IR name .
+If
+.I in
+is non-zero, the image is published; otherwise
+.I i
+must be already named
+.I name
+and it is withdrawn from publication.
+.I Namedimage
+returns a reference to the image published under the given
+.I name
+on
+.B Display
+.IR d .
+These routines permit unrelated applications sharing a display to share an image;
+for example they provide the mechanism behind
+.B getwindow
+(see
+.IR graphics (2)).
+.PP
+The RGB values in a color are
+.I premultiplied
+by the alpha value; for example, a 50% red is
+.B 0x7F00007F
+not
+.BR 0xFF00007F .
+The function
+.I setalpha
+performs the alpha computation on a given
+.BR color ,
+ignoring its initial alpha value, multiplying the components by the supplied
+.BR alpha .
+For example, to make a 50% red color value, one could execute
+.B setalpha(DRed,
+.BR 0x7F) .
+.PP
+The remaining functions deal with moving groups of pixel
+values between image and user space or external files.
+There is a fixed format for the exchange and storage of
+image data
+(see
+.IR image (6)).
+.PP
+.I Unloadimage
+reads a rectangle of pixels from image
+.I i
+into
+.IR data ,
+whose length is specified by
+.IR ndata .
+It is an error if
+.I ndata
+is too small to accommodate the pixels.
+.PP
+.I Loadimage
+replaces the specified rectangle in image
+.I i
+with the
+.I ndata
+bytes of
+.IR data .
+.PP
+The pixels are presented one horizontal line at a time,
+starting with the top-left pixel of
+.IR r .
+In the data processed by these routines, each scan line starts with a new byte in the array,
+leaving the last byte of the previous line partially empty, if necessary.
+Pixels are packed as tightly as possible within
+.IR data ,
+regardless of the rectangle being extracted.
+Bytes are filled from most to least significant bit order,
+as the
+.I x
+coordinate increases, aligned so
+.IR x =0
+would appear as the leftmost pixel of its byte.
+Thus, for
+.B depth
+1, the pixel at
+.I x
+offset 165 within the rectangle will be in a
+.I data
+byte at bit-position
+.B 0x04
+regardless of the overall
+rectangle: 165 mod 8 equals 5, and
+.B "0x80\ >>\ 5"
+equals
+.BR 0x04 .
+.PP
+.B Cloadimage
+does the same as
+.IR loadimage ,
+but for
+.I ndata
+bytes of compressed image
+.I data
+(see
+.IR image (6)).
+On each call to
+.IR cloadimage,
+the
+.I data
+must be at the beginning of a compressed data block, in particular,
+it should start with the
+.B y
+coordinate and data length for the block.
+.PP
+.IR Loadimage ,
+.IR cloadimage ,
+and
+.I unloadimage
+return the number of bytes copied.
+.PP
+.I Readimage
+creates an image from data contained in an external file (see
+.IR image (6)
+for the file format);
+.I fd
+is a file descriptor obtained by opening such a file for reading.
+The returned image is allocated using
+.IR allocimage .
+The
+.I dolock
+flag specifies whether the
+.B Display
+should be synchronized for multithreaded access; single-threaded
+programs can leave it zero.
+.PP
+.I Writeimage
+writes image
+.I i
+onto file descriptor
+.IR fd ,
+which should be open for writing.
+The format is as described for
+.IR readimage .
+.PP
+.I Readimage
+and
+.I writeimage
+do not close
+.IR fd .
+.PP
+.I Bytesperline
+and
+.I wordsperline
+return the number of bytes or words occupied in memory by one scan line of rectangle
+.I r
+in an image with
+.I d
+bits per pixel.
+.SH EXAMPLE
+To allocate a single-pixel replicated image that may be used to paint a region red,
+.EX
+ red = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DRed);
+.EE
+.SH SOURCE
+.B /sys/src/libdraw
+.SH "SEE ALSO"
+.IR graphics (2),
+.IR draw (2),
+.IR draw (3),
+.IR image (6)
+.SH DIAGNOSTICS
+These functions return pointer 0 or integer \-1 on failure, usually due to insufficient
+memory.
+.PP
+May set
+.IR errstr .
+.SH BUGS
+.B Depth
+must be a divisor or multiple of 8.
diff --git a/sys/man/2/arg b/sys/man/2/arg
new file mode 100755
index 000000000..e54394310
--- /dev/null
+++ b/sys/man/2/arg
@@ -0,0 +1,126 @@
+.TH ARG 2
+.SH NAME
+ARGBEGIN, ARGEND, ARGC, ARGF, EARGF \- process option letters from argv
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B ARGBEGIN {
+.B char *ARGF();
+.B char *EARGF(code);
+.B Rune ARGC();
+.B } ARGEND
+.PP
+.B extern char *argv0;
+.SH DESCRIPTION
+These macros assume the names
+.I argc
+and
+.I argv
+are in scope; see
+.IR exec (2).
+.I ARGBEGIN
+and
+.I ARGEND
+surround code for processing program options.
+The code
+should be the cases of a C switch on
+option characters;
+it is executed once for each option character.
+Options end after an argument
+.BR -- ,
+before an argument
+.BR - ,
+or before an argument that doesn't begin with
+.BR - .
+.PP
+The function macro
+.I ARGC
+returns the current option character, as an integer.
+.PP
+The function macro
+.I ARGF
+returns the current option argument:
+a pointer to the rest of the option string if not empty,
+or the next argument in
+.I argv
+if any, or 0.
+.I ARGF
+must be called just once for each option
+argument.
+The macro
+.I EARGF
+is like
+.I ARGF
+but instead of returning zero
+runs
+.I code
+and, if that returns, calls
+.IR abort (2).
+A typical value for
+.I code
+is
+.BR usage() ,
+as in
+.BR EARGF(usage()) .
+.PP
+After
+.IR ARGBEGIN ,
+.I argv0
+is a copy of
+.BR argv[0]
+(conventionally the name of the program).
+.PP
+After
+.IR ARGEND ,
+.I argv
+points at a zero-terminated list of the remaining
+.I argc
+arguments.
+.SH EXAMPLE
+This C program can take option
+.B b
+and option
+.BR f ,
+which requires an argument.
+.IP
+.EX
+.ta \w'12345678'u +\w'12345678'u +\w'12345678'u +\w'12345678'u +\w'12345678'u
+#include <u.h>
+#include <libc.h>
+void
+main(int argc, char *argv[])
+{
+ char *f;
+ print("%s", argv[0]);
+ ARGBEGIN {
+ case 'b':
+ print(" -b");
+ break;
+ case 'f':
+ print(" -f(%s)", (f=ARGF())? f: "no arg");
+ break;
+ default:
+ print(" badflag('%c')", ARGC());
+ } ARGEND
+ print(" %d args:", argc);
+ while(*argv)
+ print(" '%s'", *argv++);
+ print("\en");
+ exits(nil);
+}
+.EE
+.PP
+Here is the output from running the command
+.B
+prog -bffile1 -r -f file2 arg1 arg2
+.IP
+.B
+prog -b -f(file1) badflag('r') -f(file2) 2 args: 'arg1' 'arg2'
+.PP
+.SH SOURCE
+.B /sys/include/libc.h
+.SH SEE ALSO
+.IR getflags (8)
diff --git a/sys/man/2/arith3 b/sys/man/2/arith3
new file mode 100755
index 000000000..d2c4acb08
--- /dev/null
+++ b/sys/man/2/arith3
@@ -0,0 +1,268 @@
+.TH ARITH3 2
+.SH NAME
+add3, sub3, neg3, div3, mul3, eqpt3, closept3, dot3, cross3, len3, dist3, unit3, midpt3, lerp3, reflect3, nearseg3, pldist3, vdiv3, vrem3, pn2f3, ppp2f3, fff2p3, pdiv4, add4, sub4 \- operations on 3-d points and planes
+.SH SYNOPSIS
+.B
+#include <draw.h>
+.br
+.B
+#include <geometry.h>
+.PP
+.B
+Point3 add3(Point3 a, Point3 b)
+.PP
+.B
+Point3 sub3(Point3 a, Point3 b)
+.PP
+.B
+Point3 neg3(Point3 a)
+.PP
+.B
+Point3 div3(Point3 a, double b)
+.PP
+.B
+Point3 mul3(Point3 a, double b)
+.PP
+.B
+int eqpt3(Point3 p, Point3 q)
+.PP
+.B
+int closept3(Point3 p, Point3 q, double eps)
+.PP
+.B
+double dot3(Point3 p, Point3 q)
+.PP
+.B
+Point3 cross3(Point3 p, Point3 q)
+.PP
+.B
+double len3(Point3 p)
+.PP
+.B
+double dist3(Point3 p, Point3 q)
+.PP
+.B
+Point3 unit3(Point3 p)
+.PP
+.B
+Point3 midpt3(Point3 p, Point3 q)
+.PP
+.B
+Point3 lerp3(Point3 p, Point3 q, double alpha)
+.PP
+.B
+Point3 reflect3(Point3 p, Point3 p0, Point3 p1)
+.PP
+.B
+Point3 nearseg3(Point3 p0, Point3 p1, Point3 testp)
+.PP
+.B
+double pldist3(Point3 p, Point3 p0, Point3 p1)
+.PP
+.B
+double vdiv3(Point3 a, Point3 b)
+.PP
+.B
+Point3 vrem3(Point3 a, Point3 b)
+.PP
+.B
+Point3 pn2f3(Point3 p, Point3 n)
+.PP
+.B
+Point3 ppp2f3(Point3 p0, Point3 p1, Point3 p2)
+.PP
+.B
+Point3 fff2p3(Point3 f0, Point3 f1, Point3 f2)
+.PP
+.B
+Point3 pdiv4(Point3 a)
+.PP
+.B
+Point3 add4(Point3 a, Point3 b)
+.PP
+.B
+Point3 sub4(Point3 a, Point3 b)
+.SH DESCRIPTION
+These routines do arithmetic on points and planes in affine or projective 3-space.
+Type
+.B Point3
+is
+.IP
+.EX
+.ta 6n
+typedef struct Point3 Point3;
+struct Point3{
+ double x, y, z, w;
+};
+.EE
+.PP
+Routines whose names end in
+.B 3
+operate on vectors or ordinary points in affine 3-space, represented by their Euclidean
+.B (x,y,z)
+coordinates.
+(They assume
+.B w=1
+in their arguments, and set
+.B w=1
+in their results.)
+.TF reflect3
+.TP
+Name
+Description
+.TP
+.B add3
+Add the coordinates of two points.
+.TP
+.B sub3
+Subtract coordinates of two points.
+.TP
+.B neg3
+Negate the coordinates of a point.
+.TP
+.B mul3
+Multiply coordinates by a scalar.
+.TP
+.B div3
+Divide coordinates by a scalar.
+.TP
+.B eqpt3
+Test two points for exact equality.
+.TP
+.B closept3
+Is the distance between two points smaller than
+.IR eps ?
+.TP
+.B dot3
+Dot product.
+.TP
+.B cross3
+Cross product.
+.TP
+.B len3
+Distance to the origin.
+.TP
+.B dist3
+Distance between two points.
+.TP
+.B unit3
+A unit vector parallel to
+.IR p .
+.TP
+.B midpt3
+The midpoint of line segment
+.IR pq .
+.TP
+.B lerp3
+Linear interpolation between
+.I p
+and
+.IR q .
+.TP
+.B reflect3
+The reflection of point
+.I p
+in the segment joining
+.I p0
+and
+.IR p1 .
+.TP
+.B nearseg3
+The closest point to
+.I testp
+on segment
+.IR "p0 p1" .
+.TP
+.B pldist3
+The distance from
+.I p
+to segment
+.IR "p0 p1" .
+.TP
+.B vdiv3
+Vector divide \(em the length of the component of
+.I a
+parallel to
+.IR b ,
+in units of the length of
+.IR b .
+.TP
+.B vrem3
+Vector remainder \(em the component of
+.I a
+perpendicular to
+.IR b .
+Ignoring roundoff, we have
+.BR "eqpt3(add3(mul3(b, vdiv3(a, b)), vrem3(a, b)), a)" .
+.PD
+.PP
+The following routines convert amongst various representations of points
+and planes. Planes are represented identically to points, by duality;
+a point
+.B p
+is on a plane
+.B q
+whenever
+.BR p.x*q.x+p.y*q.y+p.z*q.z+p.w*q.w=0 .
+Although when dealing with affine points we assume
+.BR p.w=1 ,
+we can't make the same assumption for planes.
+The names of these routines are extra-cryptic. They contain an
+.B f
+(for `face') to indicate a plane,
+.B p
+for a point and
+.B n
+for a normal vector.
+The number
+.B 2
+abbreviates the word `to.'
+The number
+.B 3
+reminds us, as before, that we're dealing with affine points.
+Thus
+.B pn2f3
+takes a point and a normal vector and returns the corresponding plane.
+.TF reflect3
+.TP
+Name
+Description
+.TP
+.B pn2f3
+Compute the plane passing through
+.I p
+with normal
+.IR n .
+.TP
+.B ppp2f3
+Compute the plane passing through three points.
+.TP
+.B fff2p3
+Compute the intersection point of three planes.
+.PD
+.PP
+The names of the following routines end in
+.B 4
+because they operate on points in projective 4-space,
+represented by their homogeneous coordinates.
+.TP
+pdiv4
+Perspective division. Divide
+.B p.w
+into
+.IR p 's
+coordinates, converting to affine coordinates.
+If
+.B p.w
+is zero, the result is the same as the argument.
+.TP
+add4
+Add the coordinates of two points.
+.PD
+.TP
+sub4
+Subtract the coordinates of two points.
+.SH SOURCE
+.B /sys/src/libgeometry
+.SH "SEE ALSO
+.IR matrix (2)
diff --git a/sys/man/2/assert b/sys/man/2/assert
new file mode 100755
index 000000000..56e092f86
--- /dev/null
+++ b/sys/man/2/assert
@@ -0,0 +1,25 @@
+.TH ASSERT 2
+.SH NAME
+assert \- check program invariants
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+#define assert(cond) if(cond);else _assert("cond")
+.PP
+.B
+void _assert(char* cond)
+.SH DESCRIPTION
+.I Assert
+is a preprocessor macro that
+(via
+.IR _assert )
+prints a message and calls
+.I abort
+when
+.I cond
+is false.
+.SH SOURCE
+.B /sys/src/libc/port/_assert.c
diff --git a/sys/man/2/atof b/sys/man/2/atof
new file mode 100755
index 000000000..cf7a88fde
--- /dev/null
+++ b/sys/man/2/atof
@@ -0,0 +1,144 @@
+.TH ATOF 2
+.SH NAME
+atof, atoi, atol, atoll, charstod, strtod, strtol, strtoll, strtoul, strtoull \- convert text to numbers
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.ta \w'\fLdouble 'u
+.B
+double atof(char *nptr)
+.PP
+.B
+int atoi(char *nptr)
+.PP
+.B
+long atol(char *nptr)
+.PP
+.B
+vlong atoll(char *nptr)
+.PP
+.B
+double charstod(int (*f)(void *), void *a)
+.PP
+.B
+double strtod(char *nptr, char **rptr)
+.PP
+.B
+long strtol(char *nptr, char **rptr, int base)
+.PP
+.B
+vlong strtoll(char *nptr, char **rptr, int base)
+.PP
+.B
+ulong strtoul(char *nptr, char **rptr, int base)
+.PP
+.B
+uvlong strtoull(char *nptr, char **rptr, int base)
+.fi
+.SH DESCRIPTION
+.IR Atof ,
+.IR atoi ,
+.IR atol ,
+and
+.I atoll
+convert a string pointed to by
+.I nptr
+to floating, integer, long integer, and long long integer
+.RB ( vlong )
+representation respectively.
+The first unrecognized character ends the string.
+Leading C escapes are understood, as in
+.I strtol
+with
+.I base
+zero (described below).
+.PP
+.I Atof
+recognizes an optional string of tabs and spaces,
+then an optional sign, then
+a string of digits optionally containing a decimal
+point, then an optional
+.L e
+or
+.L E
+followed
+by an optionally signed integer.
+.PP
+.I Atoi
+and
+.I atol
+recognize an optional string of tabs and spaces,
+then an optional sign, then a string of
+decimal digits.
+.PP
+.IR Strtod ,
+.IR strtol ,
+.IR strtoll ,
+.IR strtoul ,
+and
+.I strtoull
+behave similarly to
+.I atof
+and
+.I atol
+and, if
+.I rptr
+is not zero, set
+.I *rptr
+to point to the input character
+immediately after the string converted.
+.PP
+.IR Strtol ,
+.IR strtoll ,
+.IR strtoul ,
+and
+.IR strtoull
+interpret the digit string in the specified
+.IR base ,
+from 2 to 36,
+each digit being less than the base.
+Digits with value over 9 are represented by letters,
+a-z or A-Z.
+If
+.I base
+is 0, the input is interpreted as an integral constant in
+the style of C (with no suffixed type indicators):
+numbers are octal if they begin with
+.LR 0 ,
+hexadecimal if they begin with
+.L 0x
+or
+.LR 0X ,
+otherwise decimal.
+.PP
+.I Charstod
+interprets floating point numbers in the manner of
+.IR atof ,
+but gets successive characters by calling
+.BR (*\fIf\fP)(a) .
+The last call to
+.I f
+terminates the scan, so it must have returned a character that
+is not a legal continuation of a number.
+Therefore, it may be necessary to back up the input stream one character
+after calling
+.IR charstod .
+.SH SOURCE
+.B /sys/src/libc/port
+.SH SEE ALSO
+.IR fscanf (2)
+.SH DIAGNOSTICS
+Zero is returned if the beginning of the input string is not
+interpretable as a number; even in this case,
+.I rptr
+will be updated.
+.SH BUGS
+.I Atoi,
+.I atol,
+and
+.I atoll
+accept octal and hexadecimal numbers in the style of C,
+contrary to the ANSI specification.
diff --git a/sys/man/2/auth b/sys/man/2/auth
new file mode 100755
index 000000000..f2aee745d
--- /dev/null
+++ b/sys/man/2/auth
@@ -0,0 +1,394 @@
+.TH AUTH 2
+.SH NAME
+amount, newns, addns, login, noworld, auth_proxy, fauth_proxy, auth_allocrpc, auth_freerpc, auth_rpc, auth_getkey, amount_getkey, auth_freeAI, auth_chuid, auth_challenge, auth_response, auth_freechal, auth_respond, auth_userpasswd, auth_getuserpasswd, auth_getinfo \- routines for authenticating users
+.SH SYNOPSIS
+.nf
+.PP
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+.fi
+.ta 11n +4n +4n +4n +4n +4n +4n
+.PP
+.B
+int newns(char *user, char *nsfile);
+.PP
+.B
+int addns(char *user, char *nsfile);
+.PP
+.B
+int amount(int fd, char *old, int flag, char *aname);
+.PP
+.B
+int login(char *user, char *password, char *namespace);
+.PP
+.B
+int noworld(char *user);
+.PP
+.B
+AuthInfo* auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...);
+.PP
+.B
+AuthInfo* fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey,
+.br
+.B char *params);
+.PP
+.B
+AuthRpc* auth_allocrpc(int afd);
+.PP
+.B
+void auth_freerpc(AuthRpc *rpc);
+.PP
+.B
+uint auth_rpc(AuthRpc *rpc, char *verb, void *a, int n);
+.PP
+.B
+int auth_getkey(char *proto, char *dom);
+.PP
+.B
+int (*amount_getkey)(char*, char*);
+.PP
+.B
+void auth_freeAI(AuthInfo *ai);
+.PP
+.B
+int auth_chuid(AuthInfo *ai, char *ns);
+.PP
+.B
+Chalstate* auth_challenge(char *fmt, ...);
+.PP
+.B
+AuthInfo* auth_response(Chalstate*);
+.PP
+.B
+void auth_freechal(Chalstate*);
+.PP
+.B
+int auth_respond(void *chal, uint nchal, char *user, uint nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...);
+.PP
+.B
+AuthInfo* auth_userpasswd(char*user, char*password);
+.PP
+.B
+UserPasswd* auth_getuserpasswd(AuthGetkey *getkey, char*fmt, ...);
+.PP
+.B
+AuthInfo* auth_getinfo(int fd);
+.SH DESCRIPTION
+.PP
+This library, in concert with
+.IR factotum (4),
+is used to authenticate users.
+It provides the primary interface to
+.IR factotum .
+.PP
+.I Newns
+builds a name space for
+.IR user .
+It opens the file
+.I nsfile
+.RB ( /lib/namespace
+is used if
+.I nsfile
+is null),
+copies the old environment, erases the current name space,
+sets the environment variables
+.B user
+and
+.BR home ,
+and interprets the commands in
+.IR nsfile .
+The format of
+.I nsfile
+is described in
+.IR namespace (6).
+.PP
+.I Addns
+also interprets and executes the commands in
+.IR nsfile .
+Unlike
+.I newns
+it applies the command to the current name space
+rather than starting from scratch.
+.PP
+.I Amount
+is like
+.I mount
+but performs any authentication required.
+It should be used instead of
+.I mount
+whenever the file server being mounted requires authentication.
+See
+.IR bind (2)
+for a definition of the arguments to
+.I mount
+and
+.IR amount .
+.PP
+.I Login
+changes the user id of the process
+.I user
+and recreates the namespace using the file
+.I namespace
+(default
+.BR /lib/namespace ).
+It uses
+.I auth_userpasswd
+and
+.IR auth_chuid .
+.PP
+.I Noworld
+returns 1 if the user is in the group
+.B noworld
+in
+.BR /adm/users .
+Otherwise, it returns 0.
+.I Noworld
+is used by telnetd and ftpd to provide sandboxed
+access for some users.
+.PP
+The following routines use the
+.B AuthInfo
+structure returned after a successful authentication by
+.IR factotum (4).
+.IP
+.ne 8
+.EX
+.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n
+typedef struct
+{
+ char *cuid; /* caller id */
+ char *suid; /* server id */
+ char *cap; /* capability */
+ int nsecret; /* length of secret */
+ uchar *secret; /* secret */
+} AuthInfo;
+.EE
+.PP
+The fields
+.B cuid
+and
+.B suid
+point to the authenticated ids of the client and server.
+.B Cap
+is a capability returned only to the server.
+It can be passed to the
+.IR cap (3)
+device to change the user id of the process.
+.B Secret
+is an
+.BR nsecret -byte
+shared secret that can be used by the client and server to
+create encryption and hashing keys for the rest of the
+conversation.
+.PP
+.I Auth_proxy
+proxies an authentication conversation between a remote
+server reading and writing
+.I fd
+and a
+.I factotum
+file. The
+.I factotum
+file used is
+.BR /mnt/factotum/rpc .
+An
+.B sprint
+(see
+.IR print (2))
+of
+.I fmt
+and the variable arg list yields a key template (see
+.IR factotum (4))
+specifying the key to use.
+The template must specify at least the protocol (
+.BI proto= xxx )
+and the role (either
+.B role=client
+or
+.BR role=server ).
+.I Auth_proxy
+either returns an allocated
+.B AuthInfo
+structure, or sets the error string and
+returns nil.
+.PP
+.I Fauth_proxy
+can be used instead of
+.I auth_proxy
+if a single connection to
+.I factotum
+will be used for multiple authentications.
+This is necessary, for example, for
+.I newns
+which must open the
+.I factotum
+file before wiping out the namespace.
+.I Fauth_proxy
+takes as an argument a pointer to an
+.B AuthRPC
+structure which contains an fd for an open connection to
+.I factotum
+in addition to storage and state information for
+the protocol.
+An
+.B AuthRPC
+structure is obtained by calling
+.I auth_allocrpc
+with the fd of an open
+.I factotum
+connection.
+It is freed using
+.IR auth_freerpc .
+Individual commands can be sent to
+.IR factotum (4)
+by invoking
+.IR auth_rpc .
+.PP
+Both
+.I auth_proxy
+and
+.I fauth_proxy
+take a pointer to a routine,
+.IR getkey ,
+to invoke should
+.I factotum
+not posess a key for the authentication. If
+.I getkey
+is nil, the authentication fails.
+.I Getkey
+is called with a key template for the desired
+key.
+We have provided a generic routine,
+.IR auth_getkey ,
+which queries the user for
+the key information and passes it to
+.IR factotum .
+This is the default for the global variable,
+.IR amount_getkey ,
+which holds a pointer to the key prompting routine used by
+.IR amount .
+.PP
+.I Auth_chuid
+uses the
+.B cuid
+and
+.B cap
+fields of an
+.B AuthInfo
+structure to change the user id of the current
+process and uses
+.IR ns ,
+default
+.BR /lib/namespace ,
+to build it a new name space.
+.PP
+.I Auth_challenge
+and
+.I auth_response
+perform challenge/response protocols with
+.IR factotum .
+State between the challenge and response phase are
+kept in the
+.B Chalstate
+structure:
+.IP
+.EX
+struct Chalstate
+{
+ char *user;
+ char chal[MAXCHLEN];
+ int nchal;
+ void *resp;
+ int nresp;
+
+/* for implementation only */
+ int afd;
+ AuthRpc *rpc;
+ char userbuf[MAXNAMELEN];
+ int userinchal;
+};
+.EE
+.PP
+.I Auth_challenge
+requires a key template generated by an
+.B sprint
+of
+.I fmt
+and the variable arguments. It must contain the protocol
+(\fLproto=\fIxxx\fR)
+and depending on the protocol, the user name (\c
+.BI user= xxx \fR).\fP
+.B P9cr
+and
+.B vnc
+expect the user specified as an attribute in
+the key template and
+.BR apop ,
+.BR cram ,
+and
+.BR chap
+expect it in the
+.B user
+field of the arg to
+.IR auth_response .
+For all protocols, the response is returned
+to
+.I auth_response
+in the
+.I resp
+field of the
+.BR Chalstate .
+.I Chalstate.nresp
+must be the length of the response.
+.PP
+Supply to
+.I auth_respond
+a challenge string and the fmt and args specifying a key,
+and it will use
+.I factotum
+to return the proper user and response.
+.PP
+.I Auth_userpasswd
+verifies a simple user/password pair.
+.I Auth_getuserpasswd
+retrieves a user/password pair from
+.I factotum
+if permitted:
+.IP
+.ne 8
+.EX
+.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n
+typedef struct UserPasswd {
+ char *user;
+ char *passwd;
+} UserPasswd;
+.EE
+.PP
+.I Auth_getinfo
+reads an
+.B AuthInfo
+message from
+.I fd
+and converts it into a structure. It is only
+used by the other routines in this library when
+communicating with
+.IR factotum .
+.PP
+.I Auth_freeAI
+is used to free an
+.B AuthInfo
+structure returned by one of these routines.
+Similary
+.I auth_freechal
+frees a challenge/response state.
+.SH SOURCE
+.B /sys/src/libauth
+.SH SEE ALSO
+.IR factotum (4),
+.IR authsrv (2),
+.IR bind (2)
+.SH DIAGNOSTICS
+These routines set
+.IR errstr .
diff --git a/sys/man/2/authsrv b/sys/man/2/authsrv
new file mode 100755
index 000000000..9eec0a426
--- /dev/null
+++ b/sys/man/2/authsrv
@@ -0,0 +1,238 @@
+.TH AUTHSRV 2
+.SH NAME
+authdial, passtokey, nvcsum, readnvram, convT2M, convM2T, convTR2M, convM2TR, convA2M, convM2A, convPR2M, convM2PR, _asgetticket, _asrdresp \- routines for communicating with authentication servers
+.SH SYNOPSIS
+.nf
+.PP
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <authsrv.h>
+.fi
+.ta 8n +4n +4n +4n +4n +4n +4n
+.PP
+.B
+int authdial(char *netroot, char *ad);
+.PP
+.B
+int passtokey(char key[DESKEYLEN], char *password)
+.PP
+.B
+uchar nvcsum(void *mem, int len)
+.PP
+.B
+int readnvram(Nvrsafe *nv, int flag);
+.PPP
+.B
+int convT2M(Ticket *t, char *msg, char *key)
+.PP
+.B
+void convM2T(char *msg, Ticket *t, char *key)
+.PP
+.B
+int convA2M(Authenticator *a, char *msg, char *key)
+.PP
+.B
+void convM2A(char *msg, Authenticator *a, char *key)
+.PP
+.B
+int convTR2M(Ticketreq *tr, char *msg)
+.PP
+.B
+void convM2TR(char *msg, Ticketreq *tr)
+.PP
+.B
+int convPR2M(Passwordreq *pr, char *msg, char *key)
+.PP
+.B
+void convM2PR(char *msg, Passwordreq *pr, char *key)
+.PP
+.B
+int _asgetticket(int fd, char *trbuf, char *tbuf);
+.PP
+.B
+int _asrdresp(int fd, char *buf, int len);
+.SH DESCRIPTION
+.I Authdial
+dials an authentication server over the
+network rooted at
+.IR net ,
+default
+.BR /net .
+The authentication domain,
+.IR ad ,
+specifies which server to call.
+If
+.I ad
+is non-nil,
+the connection server
+.B cs
+(see
+.IR ndb (8))
+is queried for an entry which contains
+.B authdom=\fIad\fP
+or
+.BR dom=\fIad\fP ,
+the former having precedence,
+and which also contains an
+.B auth
+attribute.
+If it finds neither, it tries
+.BI p9auth. ad
+in DNS as the authentication server.
+The string dialed is then
+.I netroot\fP!\fIserver\fP!ticket
+where
+.I server
+is the value of the
+.B auth
+attribute.
+If no entry is found, the error string is
+set to ``no authentication server found''
+and -1 is returned.
+If
+.I authdom
+is nil, the string
+.IB netroot !$auth! ticket
+is used to make the call.
+.PP
+.I Passtokey
+converts
+.I password
+into a DES key and stores the result in
+.IR key .
+It returns 0 if
+.I password
+could not be converted,
+and 1 otherwise.
+.PP
+.I Readnvram
+reads authentication information into the structure:
+.PP
+.EX
+.ta 4n +4n +8n +4n +4n +4n +4n
+struct Nvrsafe
+{
+ char machkey[DESKEYLEN]; /* was file server's authid's des key */
+ uchar machsum;
+ char authkey[DESKEYLEN]; /* authid's des key from password */
+ uchar authsum;
+ /*
+ * file server config string of device holding full configuration;
+ * secstore key on non-file-servers.
+ */
+ char config[CONFIGLEN];
+ uchar configsum;
+ char authid[ANAMELEN]; /* auth userid, e.g., bootes */
+ uchar authidsum;
+ char authdom[DOMLEN]; /* auth domain, e.g., cs.bell-labs.com */
+ uchar authdomsum;
+};
+.EE
+.PP
+On Sparc, MIPS, and SGI machines this information is
+in non-volatile ram, accessible in the file
+.BR #r/nvram .
+On x86s and Alphas
+.I readnvram
+successively opens the following areas stopping with the
+first to succeed:
+.PP
+\- the partition named by the
+.B $nvram
+environment variable
+(commonly set via
+.IR plan9.ini (8))
+.br
+\- the partition
+.B #S/sdC0/nvram
+.br
+\- a file called
+.B plan9.nvr
+in the partition
+.B #S/sdC0/9fat
+.br
+\- the partition
+.B #S/sd00/nvram
+.br
+\- a file called
+.B plan9.nvr
+in the partition
+.B #S/sd00/9fat
+.br
+\- a file called
+.B plan9.nvr
+on a DOS floppy in drive 0
+.br
+\- a file called
+.B plan9.nvr
+on a DOS floppy in drive 1
+.PP
+The
+.IR nvcsum s
+of the fields
+.BR machkey ,
+.BR authid ,
+and
+.B authdom
+must match their respective checksum or that field is zeroed.
+If
+.I flag
+is
+.B NVwrite
+or at least one checksum fails and
+.I flag
+is
+.BR NVwriteonerr ,
+.I readnvram
+will prompt for new values on
+.B #c/cons
+and then write them back to the storage area.
+If
+.I flag
+is
+.BR NVwritemem ,
+.I readnvram
+will write the values in
+.I *nv
+back to the storage area.
+.PP
+.IR ConvT2M ,
+.IR convA2M ,
+.IR convTR2M ,
+and
+.I convPR2M
+convert tickets, authenticators, ticket requests, and password change request
+structures into transmittable messages.
+.IR ConvM2T ,
+.IR convM2A ,
+.IR convM2TR ,
+and
+.I convM2PR
+are used to convert them back.
+.I Key
+is used for encrypting the message before transmission and decrypting
+after reception.
+.PP
+The routine
+.I _asgetresp
+receives either a character array or an error string.
+On error, it sets errstr and returns -1. If successful,
+it returns the number of bytes received.
+.PP
+The routine
+.I _asgetticket
+sends a ticket request message and then uses
+.I _asgetresp
+to recieve an answer.
+.SH SOURCE
+.B /sys/src/libauthsrv
+.SH SEE ALSO
+.IR passwd (1),
+.IR cons (3),
+.IR dial (2),
+.IR authsrv (6),
+.SH DIAGNOSTICS
+These routines set
+.IR errstr .
+Integer-valued functions return -1 on error.
diff --git a/sys/man/2/avl b/sys/man/2/avl
new file mode 100755
index 000000000..681f1dcc3
--- /dev/null
+++ b/sys/man/2/avl
@@ -0,0 +1,147 @@
+.TH AVL 2
+.SH NAME
+mkavltree, insertavl, lookupavl, deleteavl, avlwalk, avlnext, avlprev, endwalk - AVL tree routines
+.SH SYNOPSIS
+.\" .ta 0.75i 1.5i 2.25i 3i 3.75i 4.5i
+.ta 0.7i +0.7i +0.7i +0.7i +0.7i +0.7i +0.7i
+.EX
+#include <u.h>
+#include <libc.h>
+#include <avl.h>
+.sp 0.3v
+typedef struct Avl Avl;
+struct Avl
+{
+ Avl *p; /* parent */
+ Avl *n[2]; /* children */
+ int bal; /* balance bits */
+};
+.sp 0.3v
+Avl *avlnext(Avlwalk *walk);
+Avl *avlprev(Avlwalk *walk);
+Avlwalk *avlwalk(Avltree *tree);
+void deleteavl(Avltree *tree, Avl *key, Avl **oldp);
+void endwalk(Avlwalk *walk);
+void insertavl(Avltree *tree, Avl *new, Avl **oldp);
+Avl *lookupavl(Avltree *tree, Avl *key);
+Avl *searchavl(Avltree *tree, Avl *key, int neighbor);
+Avltree *mkavltree(int(*cmp)(Avl*, Avl*));
+.EE
+.SH DESCRIPTION
+An AVL tree is a self-balancing binary search tree.
+These routines allow creation and maintenance of in-memory AVL trees.
+.PP
+An empty AVL tree is created by calling
+.I mkavltree
+with a comparison function as argument.
+This function should take two pointers to
+.B Avl
+objects and return -1, 0 or 1 as the first is
+respectively less than,
+equal to, or greater than,
+the second.
+.I Insertavl
+adds a
+.I new
+tree node into
+.IR tree .
+If
+.I oldp
+is non-nil upon return,
+it points to storage for an old node
+with the same key that may now be freed.
+.I Lookupavl
+returns the
+.I tree
+node that matches
+.I key
+by
+.IR tree 's
+comparison function,
+or
+.B nil
+if none.
+.PP
+.I Searchavl
+returns the
+.I tree
+node that matches
+.I key
+by
+.IR tree 's
+comparison function, if it exists.
+If it does not, and
+.I neighbor
+is positive, it returns the nearest node whose
+.I key
+is greater or
+.B nil
+if there is none and, if
+.I neighbor
+is negative, it returns the nearest node whose
+.I key
+is less or
+.B nil
+if there is none.
+It is an error to set
+.I neighbor
+to values other than \-1, 0, or +1.
+.PP
+.I Deleteavl
+removes the node matching
+.I key
+from
+.IR tree ;
+.I oldp
+is handled as per
+.IR insertavl .
+.PP
+.I Avlwalk
+returns a pointer to a newly-allocated
+.B Avlwalk
+object.
+.I Endwalk
+frees such an object.
+.I Avlnext
+and
+.I avlprev
+walk the tree associated with
+.IR walk ,
+returning the next
+(respectively, previous)
+tree node in the comparison order
+defined by the comparison function
+associated with the tree associated with
+.IR walk .
+.SH EXAMPLES
+Intended usage seems to be to make an anonymous
+.B Avl
+the first member of the application's tree-node structure,
+then pass these routines tree-node pointers instead of
+.BR Avl* s.
+.IP
+.EX
+typedef struct Node {
+ Avl;
+ uchar score[VtScoreSize];
+ int type;
+} Node;
+.sp 0.3v
+Avltree *tree;
+Avl *res;
+Node *np;
+\fI\&...\fP
+ res = lookupavl(tree, np);
+.EE
+.SH SOURCE
+.B /sys/src/libavl
+.SH SEE ALSO
+G. M. Adelson-Velsky,
+E. M. Landis,
+``An algorithm for the organization of information'',
+.IR "Soviet Mathematics" ,
+Vol. 3, pp. 1256—1263.
+.SH DIAGNOSTICS
+Functions returning pointers return
+.B nil
+on error.
diff --git a/sys/man/2/bin b/sys/man/2/bin
new file mode 100755
index 000000000..f711b21da
--- /dev/null
+++ b/sys/man/2/bin
@@ -0,0 +1,99 @@
+.TH BIN 2
+.SH NAME
+binalloc, bingrow, binfree \- grouped memory allocation
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bin.h>
+.PP
+.ta \w'\fLvoid* 'u
+.PP
+.B
+typedef struct Bin Bin;
+.PP
+.B
+void *binalloc(Bin **bp, ulong size, int clr);
+.PP
+.B
+void *bingrow(Bin **bp, void *op, ulong osize,
+.br
+.B
+ ulong size, int clr);
+.PP
+.B
+void binfree(Bin **bp);
+.SH DESCRIPTION
+These routines provide simple grouped memory allocation and deallocation.
+Items allocated with
+.I binalloc
+are added to the
+.I Bin
+pointed to by
+.IR bp .
+All items in a bin may be freed with one call to
+.IR binfree ;
+there is no way to free a single item.
+.PP
+.I Binalloc
+returns a pointer to a new block of at least
+.I size
+bytes.
+The block is suitably aligned for storage of any type of object.
+No two active pointers from
+.I binalloc
+will have the same value.
+The call
+.B binalloc(0)
+returns a valid pointer rather than null.
+If
+.I clr
+is non-zero, the allocated memory is set to 0;
+otherwise, the contents are undefined.
+.PP
+.I Bingrow
+is used to extend the size of a block of memory returned by
+.IR binalloc .
+.I Bp
+must point to the same bin group used to allocate the original block,
+and
+.I osize
+must be the last size used to allocate or grow the block.
+A pointer to a block of at least
+.I size
+bytes is returned, with the same contents in the first
+.I osize
+locations.
+If
+.I clr
+is non-zero, the remaining bytes are set to 0,
+and are undefined otherwise.
+If
+.I op
+is
+.BR nil ,
+it and
+.I osize
+are ignored, and the result is the same as calling
+.IR binalloc .
+.PP
+.I Binalloc
+and
+.I bingrow
+allocate large chunks of memory using
+.IR malloc (2)
+and return pieces of these chunks.
+The chunks are
+.IR free 'd
+upon a call to
+.IR binfree .
+.SH SOURCE
+.B /sys/src/libbin
+.SH SEE ALSO
+.IR malloc (2)
+.SH DIAGNOSTICS
+.I binalloc
+and
+.I bingrow
+return 0 if there is no available memory.
diff --git a/sys/man/2/bind b/sys/man/2/bind
new file mode 100755
index 000000000..98feb41f7
--- /dev/null
+++ b/sys/man/2/bind
@@ -0,0 +1,236 @@
+.TH BIND 2
+.SH NAME
+bind, mount, unmount \- change name space
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int bind(char *name, char *old, int flag)
+.PP
+.B
+int mount(int fd, int afd, char *old, int flag, char *aname)
+.PP
+.B
+int unmount(char *name, char *old)
+.SH DESCRIPTION
+.I Bind
+and
+.I mount
+modify the file name space of the current process and other
+processes in its name space group
+(see
+.IR fork (2)).
+For both calls,
+.I old
+is the name of an existing file or directory in the
+current name space where the modification is to be made.
+The name
+.I old
+is
+.I evaluated
+as described in
+.IR intro (2),
+except that no translation of the final path element is done.
+.PP
+For
+.IR bind ,
+.I name
+is the name of another (or possibly the same)
+existing file or directory in
+the current name space.
+After a successful
+.I bind
+call, the file name
+.I old
+is an alias for the object originally named by
+.IR name ;
+if the modification doesn't hide it,
+.I name
+will also still refer to its original file.
+The evaluation of
+.I new
+happens at the time of the
+.IR bind ,
+not when the binding is later used.
+.PP
+The
+.I fd
+argument to
+.I mount
+is a file descriptor of an open network connection
+or pipe to a file server, while
+.I afd
+is a authentication file descriptor as created by
+.IR fauth (2)
+and subsequently authenticated.
+If authentication is not required,
+.I afd
+should be -1.
+The
+.I old
+file must be a directory.
+After a successful
+.I mount
+the file tree
+.I served
+(see below) by
+.I fd
+will be visible with its root directory having name
+.IR old .
+.PP
+The
+.I flag
+controls details of the modification made to the name space.
+In the following,
+.I new
+refers to the file
+as defined by
+.I name
+or the root directory served by
+.IR fd .
+Either both
+.I old
+and new files must be directories,
+or both must not be directories.
+.I Flag
+can be one of:
+.TF MBEFORE
+.TP
+.B MREPL
+Replace the
+.I old
+file by the new one.
+Henceforth, an evaluation of
+.I old
+will be translated to the new file.
+If they are directories (for
+.IR mount ,
+this condition is true by definition),
+.I old
+becomes a
+.I "union directory"
+consisting of one directory (the new file).
+.TP
+.B MBEFORE
+Both the
+.I old
+and new files must be directories.
+Add the constituent files of the new directory
+to the union directory at
+.I old
+so its contents appear first in the union.
+After an
+.B MBEFORE
+.I bind
+or
+.IR mount ,
+the new directory will be searched first when evaluating file names
+in the union directory.
+.TP
+.B MAFTER
+Like
+.B MBEFORE
+but the new directory goes at the end of the union.
+.PD
+.PP
+The flags are defined in
+.BR <libc.h> .
+In addition, there is an
+.B MCREATE
+flag that can be OR'd with any of the above.
+When a
+.I create
+system call (see
+.IR open (2))
+attempts to create in a union directory, and the file does not exist,
+the elements of the union are searched in order until one is found
+with
+.B MCREATE
+set.
+The file is created in that directory; if that attempt fails,
+the
+.I create
+fails.
+.PP
+Finally, the
+.B MCACHE
+flag, valid for
+.I mount
+only, turns on caching for files made available by the mount.
+By default, file contents are always retrieved from the server.
+With caching enabled, the kernel may instead use a local cache to satisfy
+.IR read (5)
+requests for files accessible through this mount point.
+The currency of cached data for a file is verified at each
+.IR open (5)
+of the file from this client machine.
+.PP
+With
+.IR mount ,
+the file descriptor
+.I fd
+must be open for reading and writing
+and prepared to respond to 9P messages
+(see Section 5).
+After the
+.IR mount ,
+the file tree starting at
+.I old
+is served by a kernel
+.IR mnt (3)
+device.
+That device will turn operations in the tree into messages on
+.IR fd .
+.I Aname
+selects among different
+file trees on the server; the null string chooses the default tree.
+.PP
+The file descriptor
+.I fd
+is automatically closed by a successful
+.I mount
+call.
+.PP
+The effects of
+.I bind
+and
+.I mount
+can be undone by
+.IR unmount .
+If
+.I name
+is zero, everything bound to or mounted upon
+.I old
+is unbound or unmounted.
+If
+.I name
+is not zero, it is evaluated as described above for
+.IR bind ,
+and the effect of binding or mounting that particular result on
+.I old
+is undone.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR bind (1),
+.IR intro (2),
+.IR fcall (2),
+.IR auth (2)
+(particularly
+.BR amount ),
+.IR intro (5),
+.IR mnt (3),
+.IR srv (3)
+.SH DIAGNOSTICS
+The return value is a positive integer (a unique sequence number) for
+success, -1 for failure.
+These routines set
+.IR errstr .
+.SH BUGS
+.I Mount
+will not return until it has successfully attached
+to the file server, so the process doing a
+.I mount
+cannot be the one serving.
diff --git a/sys/man/2/bio b/sys/man/2/bio
new file mode 100755
index 000000000..4d8189ebf
--- /dev/null
+++ b/sys/man/2/bio
@@ -0,0 +1,361 @@
+.TH BIO 2
+.SH NAME
+Bopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetrune, Bgetd, Bungetc, Bungetrune, Bread, Bseek, Boffset, Bfildes, Blinelen, Bputc, Bputrune, Bprint, Bvprint, Bwrite, Bflush, Bterm, Bbuffered \- buffered input/output
+.SH SYNOPSIS
+.ta \w'Biobuf* 'u
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bio.h>
+.PP
+.B
+Biobuf* Bopen(char *file, int mode)
+.PP
+.B
+int Binit(Biobuf *bp, int fd, int mode)
+.PP
+.B
+int Binits(Biobufhdr *bp, int fd, int mode, uchar *buf, int size)
+.PP
+.B
+int Bterm(Biobufhdr *bp)
+.PP
+.B
+int Bprint(Biobufhdr *bp, char *format, ...)
+.PP
+.B
+int Bvprint(Biobufhdr *bp, char *format, va_list arglist);
+.PP
+.B
+void* Brdline(Biobufhdr *bp, int delim)
+.PP
+.B
+char* Brdstr(Biobufhdr *bp, int delim, int nulldelim)
+.PP
+.B
+int Blinelen(Biobufhdr *bp)
+.PP
+.B
+vlong Boffset(Biobufhdr *bp)
+.PP
+.B
+int Bfildes(Biobufhdr *bp)
+.PP
+.B
+int Bgetc(Biobufhdr *bp)
+.PP
+.B
+long Bgetrune(Biobufhdr *bp)
+.PP
+.B
+int Bgetd(Biobufhdr *bp, double *d)
+.PP
+.B
+int Bungetc(Biobufhdr *bp)
+.PP
+.B
+int Bungetrune(Biobufhdr *bp)
+.PP
+.B
+vlong Bseek(Biobufhdr *bp, vlong n, int type)
+.PP
+.B
+int Bputc(Biobufhdr *bp, int c)
+.PP
+.B
+int Bputrune(Biobufhdr *bp, long c)
+.PP
+.B
+long Bread(Biobufhdr *bp, void *addr, long nbytes)
+.PP
+.B
+long Bwrite(Biobufhdr *bp, void *addr, long nbytes)
+.PP
+.B
+int Bflush(Biobufhdr *bp)
+.PP
+.B
+int Bbuffered(Biobufhdr *bp)
+.PP
+.SH DESCRIPTION
+These routines implement fast buffered I/O.
+I/O on different file descriptors is independent.
+.PP
+.I Bopen
+opens
+.I file
+for mode
+.B OREAD
+or creates for mode
+.BR OWRITE .
+It calls
+.IR malloc (2)
+to allocate a buffer.
+.PP
+.I Binit
+initializes a standard size buffer, type
+.IR Biobuf ,
+with the open file descriptor passed in
+by the user.
+.I Binits
+initializes a non-standard size buffer, type
+.IR Biobufhdr ,
+with the open file descriptor,
+buffer area, and buffer size passed in
+by the user.
+.I Biobuf
+and
+.I Biobufhdr
+are related by the declaration:
+.IP
+.EX
+typedef struct Biobuf Biobuf;
+struct Biobuf
+{
+ Biobufhdr;
+ uchar b[Bungetsize+Bsize];
+};
+.EE
+.PP
+Arguments
+of types pointer to Biobuf and pointer to Biobufhdr
+can be used interchangeably in the following routines.
+.PP
+.IR Bopen ,
+.IR Binit ,
+or
+.I Binits
+should be called before any of the
+other routines on that buffer.
+.I Bfildes
+returns the integer file descriptor of the associated open file.
+.PP
+.I Bterm
+flushes the buffer for
+.IR bp
+and returns
+.IR Bflush 's
+return value.
+If the buffer was allocated by
+.IR Bopen ,
+the buffer is
+.I freed
+and the file is closed.
+.PP
+.I Brdline
+reads a string from the file associated with
+.I bp
+up to and including the first
+.I delim
+character.
+The delimiter character at the end of the line is
+not altered, thus the returned string probably won't be NUL-terminated.
+.I Brdline
+returns a pointer to the start of the line or
+.L 0
+on end-of-file or read error.
+.I Blinelen
+returns the length (including the delimiter)
+of the most recent string returned by
+.IR Brdline .
+.PP
+.I Brdstr
+returns a
+.IR malloc (2)-allocated
+buffer containing the next line of input delimited by
+.IR delim ,
+terminated by a NUL (0) byte.
+Unlike
+.IR Brdline ,
+which returns when its buffer is full even if no delimiter has been found,
+.I Brdstr
+will return an arbitrarily long line in a single call.
+If
+.I nulldelim
+is set, the terminal delimiter will be overwritten with a NUL.
+After a successful call to
+.IR Brdstr ,
+the return value of
+.I Blinelen
+will be the length of the returned buffer, excluding the NUL.
+.PP
+.I Bgetc
+returns the next character from
+.IR bp ,
+or a negative value
+at end of file.
+.I Bungetc
+may be called immediately after
+.I Bgetc
+to allow the same character to be reread.
+.PP
+.I Bgetrune
+calls
+.I Bgetc
+to read the bytes of the next
+.SM UTF
+sequence in the input stream and returns the value of the rune
+represented by the sequence.
+It returns a negative value
+at end of file.
+.I Bungetrune
+may be called immediately after
+.I Bgetrune
+to allow the same
+.SM UTF
+sequence to be reread as either bytes or a rune.
+.I Bungetc
+and
+.I Bungetrune
+may back up a maximum of five bytes.
+.PP
+.I Bgetd
+uses
+.I charstod
+(see
+.IR atof (2))
+and
+.I Bgetc
+to read the formatted
+floating-point number in the input stream,
+skipping initial blanks and tabs.
+The value is stored in
+.BR *d.
+.PP
+.I Bread
+reads
+.I nbytes
+of data from
+.I bp
+into memory starting at
+.IR addr .
+The number of bytes read is returned on success
+and a negative value is returned if a read error occurred.
+.PP
+.I Bseek
+applies
+.IR seek (2)
+to
+.IR bp .
+It returns the new file offset.
+.I Boffset
+returns the file offset of the next character to be processed.
+.PP
+.I Bputc
+outputs the low order 8 bits of
+.I c
+on
+.IR bp .
+If this causes a
+.IR write
+to occur and there is an error,
+a negative value is returned.
+Otherwise, a zero is returned.
+.PP
+.I Bputrune
+calls
+.I Bputc
+to output the low order
+16 bits of
+.I c
+as a rune
+in
+.SM UTF
+format
+on the output stream.
+.PP
+.I Bprint
+is a buffered interface to
+.IR print (2).
+If this causes a
+.IR write
+to occur and there is an error,
+a negative value
+.RB ( Beof )
+is returned.
+Otherwise,
+.I Bprint
+returns the number of bytes written.
+.I Bvprint
+does the same except it takes as argument a
+.B va_list
+parameter, so it can be called within a variadic function.
+.PP
+.I Bwrite
+outputs
+.I nbytes
+of data starting at
+.I addr
+to
+.IR bp .
+If this causes a
+.IR write
+to occur and there is an error,
+a negative value is returned.
+Otherwise, the number of bytes written is returned.
+.PP
+.I Bflush
+causes any buffered output associated with
+.I bp
+to be written.
+The return is as for
+.IR Bputc .
+.I Bflush
+is called on
+exit for every buffer still open
+for writing.
+.PP
+.I Bbuffered
+returns the number of bytes in the buffer.
+When reading, this is the number of bytes still available from the last
+read on the file; when writing, it is the number of bytes ready to be
+written.
+.SH SOURCE
+.B /sys/src/libbio
+.SH SEE ALSO
+.IR open (2),
+.IR print (2),
+.IR exits (2),
+.IR utf (6),
+.SH DIAGNOSTICS
+.I Bio
+routines that return integers yield
+.B Beof
+if
+.I bp
+is not the descriptor of an open file.
+.I Bopen
+returns zero if the file cannot be opened in the given mode.
+All routines set
+.I errstr
+on error.
+.SH BUGS
+.I Brdline
+returns an error on strings longer than the buffer associated
+with the file
+and also if the end-of-file is encountered
+before a delimiter.
+.I Blinelen
+will tell how many characters are available
+in these cases.
+In the case of a true end-of-file,
+.I Blinelen
+will return zero.
+At the cost of allocating a buffer,
+.I Brdstr
+sidesteps these issues.
+.PP
+Only the low byte of
+.IR Brdstr 's
+.I delim
+is examined, so
+.I delim
+cannot be an arbitrary rune.
+.PP
+The data returned by
+.I Brdline
+may be overwritten by calls to any other
+.I bio
+routine on the same
+.IR bp.
diff --git a/sys/man/2/blowfish b/sys/man/2/blowfish
new file mode 100755
index 000000000..578efc6fc
--- /dev/null
+++ b/sys/man/2/blowfish
@@ -0,0 +1,52 @@
+.TH BLOWFISH 2
+.SH NAME
+setupBFstate, bfCBCencrypt, bfCBCdecrypt, bfECBencrypt, bfECBdecrypt - blowfish encryption
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+void setupBFstate(BFstate *s, uchar key[], int keybytes,
+.B
+ uchar *ivec)
+.PP
+.B
+void bfCBCencrypt(uchar *data, int len, BFstate *s)
+.PP
+.B
+void bfCBCdecrypt(uchar *data, int len, BFstate *s)
+.PP
+.B
+void bfECBencrypt(uchar *data, int len, BFstate *s)
+.PP
+.B
+void bfECBdecrypt(uchar *data, int len, BFstate *s)
+.SH DESCRIPTION
+.PP
+Blowfish is Bruce Schneier's symmetric block cipher. It supports
+variable length keys from 32 to 448 bits and has a block size of 64
+bits. Both CBC and ECB modes are supported.
+.PP
+setupBFstate takes a BFstate structure, a key of at most 56 bytes, the
+length of the key in bytes, and an initialization vector of 8 bytes
+(set to all zeroes if argument is nil). The encryption and decryption
+functions take a BFstate structure, a data buffer, and a length, which
+must be a multiple of eight bytes as padding is currently unsupported.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR mp (2),
+.IR aes (2),
+.IR des (2),
+.IR dsa (2),
+.IR elgamal (2),
+.IR rc4 (2),
+.IR rsa (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2)
diff --git a/sys/man/2/brk b/sys/man/2/brk
new file mode 100755
index 000000000..f916a6877
--- /dev/null
+++ b/sys/man/2/brk
@@ -0,0 +1,62 @@
+.TH BRK 2
+.SH NAME
+brk, sbrk \- change memory allocation
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLvoid* 'u
+.B
+int brk(void *addr)
+.PP
+.B
+void* sbrk(ulong incr)
+.SH DESCRIPTION
+.I Brk
+sets the system's idea of the lowest bss location not used by the program
+(called the break)
+to
+.I addr
+rounded up to the next multiple of 8 bytes.
+Locations not less than
+.I addr
+and below the stack pointer
+may cause a memory violation if accessed.
+.PP
+In the alternate function
+.IR sbrk ,
+.I incr
+more bytes are added to the
+program's data space and a pointer to the
+start of the new area is returned.
+Rounding occurs as with
+.IR brk .
+.PP
+When a program begins execution via
+.I exec
+the break is set at the
+highest location defined by the program
+and data storage areas.
+Ordinarily, therefore, only programs with growing
+data areas need to use
+.IR brk .
+A call to
+.I sbrk
+with a zero argument returns the lowest address
+in the dynamic segment.
+.SH SOURCE
+.B /sys/src/libc/9sys/sbrk.c
+.SH SEE ALSO
+.IR intro (2),
+.IR malloc (2),
+.IR segattach (2),
+.IR segbrk (2)
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
+.PP
+The error return from
+.I sbrk
+is
+.BR (void*)-1 .
diff --git a/sys/man/2/cachechars b/sys/man/2/cachechars
new file mode 100755
index 000000000..3a0d2d2da
--- /dev/null
+++ b/sys/man/2/cachechars
@@ -0,0 +1,313 @@
+.TH CACHECHARS 2
+.SH NAME
+cachechars, agefont, loadchar, Subfont, Fontchar, Font \- font utilities
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <draw.h>
+.PP
+.ta \w'\fLCacheinfo 'u
+.PP
+.B
+int cachechars(Font *f, char **s, Rune **r, ushort *c, int max,
+.PP
+.B
+ int *widp, char **sfname)
+.PP
+.B
+int loadchar(Font *f, Rune r, Cacheinfo *c, int h,
+.PP
+.B
+ int noclr, char **sfname)
+.PP
+.B
+void agefont(Font *f)
+.SH DESCRIPTION
+A
+.I Font
+may contain too many characters to hold in memory
+simultaneously.
+The graphics library and draw device (see
+.IR draw (3))
+cooperate to solve this problem by maintaining a cache of recently used
+character images.
+The details of this cooperation need not be known by most programs:
+.I initdraw
+and its associated
+.I font
+variable,
+.IR openfont ,
+.IR stringwidth ,
+.IR string ,
+and
+.I freefont
+are sufficient for most purposes.
+The routines described below are used internally by the graphics library
+to maintain the font cache.
+.PP
+A
+.B Subfont
+is a set of images for a contiguous range of characters, stored as a single
+image
+with the characters
+placed side-by-side on a common baseline.
+It is described by the following data structures.
+.IP
+.EX
+.ta 6n +\w'Fontchar 'u +\w'bottom; 'u
+typedef
+struct Fontchar {
+ int x; /* left edge of bits */
+ uchar top; /* first non-zero scan-line */
+ uchar bottom; /* last non-zero scan-line */
+ char left; /* offset of baseline */
+ uchar width; /* width of baseline */
+} Fontchar;
+
+typedef
+struct Subfont {
+ char *name;
+ short n; /* number of chars in subfont */
+ uchar height; /* height of image */
+ char ascent; /* top of image to baseline */
+ Fontchar *info; /* n+1 Fontchars */
+ Image *bits; /* of font */
+} Subfont;
+.EE
+.PP
+The image fills the rectangle
+\fL(0, 0, \fIw\fP, height)\fR,
+where
+.I w
+is the sum of the horizontal extents (of non-zero pixels)
+for all characters.
+The pixels to be displayed for character
+.I c
+are in the rectangle
+\fL(\fIi\fP->x, \fIi\fP->top, (\fIi\fP+1)->x, \%\fIi\fP->bottom)\fR
+where
+.I i
+is
+.B
+&subfont->info[\fIc\fP]\fR.
+When a character is displayed at
+.B Point
+.B p
+in an image,
+the character rectangle is placed at
+.BI (p.x+ i ->left,
+.B p.y)
+and the next character of the string is displayed at
+.BI (p.x+ i ->width,
+.BR p.y) .
+The baseline of the characters is
+.L ascent
+rows down from the top of the subfont image.
+The
+.L info
+array has
+.B n+1
+elements, one each for characters 0 to
+.BR n-1
+plus an additional entry so the size of the last character
+can be calculated.
+Thus the width,
+.IR w ,
+of the
+.B Image
+associated with a
+.B Subfont
+.B s
+is
+.BR s->info[s->n].x .
+.PP
+A
+.B Font
+consists of an overall height and ascent
+and a collection of subfonts together with the ranges of runes (see
+.IR utf (6))
+they represent.
+Fonts are described by the following structures.
+.IP
+.EX
+.ta 6n +\w'Cacheinfo 'u +\w'height; 'u
+typedef
+struct Cachefont {
+ Rune min; /* value of 0th char in subfont */
+ Rune max; /* value+1 of last char in subfont */
+ int offset; /* posn in subfont of char at min */
+ char *name; /* stored in font */
+ char *subfontname; /* to access subfont */
+} Cachefont;
+
+typedef
+struct Cacheinfo {
+ ushort x; /* left edge of bits */
+ uchar width; /* width of baseline */
+ schar left; /* offset of baseline */
+ Rune value; /* of char at this slot in cache */
+ ushort age;
+} Cacheinfo;
+
+typedef
+struct Cachesubf {
+ ulong age; /* for replacement */
+ Cachefont *cf; /* font info that owns us */
+ Subfont *f; /* attached subfont */
+} Cachesubf;
+
+typedef
+struct Font {
+ char *name;
+ Display *display;
+ short height; /* max ht of image;interline space*/
+ short ascent; /* top of image to baseline */
+ short width; /* widest so far; used in caching */
+ short nsub; /* number of subfonts */
+ ulong age; /* increasing counter; for LRU */
+ int ncache; /* size of cache */
+ int nsubf; /* size of subfont list */
+ Cacheinfo *cache;
+ Cachesubf *subf;
+ Cachefont **sub; /* as read from file */
+ Image *cacheimage;
+} Font;
+.EE
+.PP
+The
+.LR height
+and
+.LR ascent
+fields of Font are described in
+.IR graphics (2).
+.L Sub
+contains
+.L nsub
+pointers to
+.BR Cachefonts .
+A
+.B Cachefont
+connects runes
+.L min
+through
+.LR max ,
+inclusive, to the subfont
+with file name
+.LR name ;
+it corresponds to a line of the file describing the font.
+.PP
+The characters
+are taken from the subfont starting at character number
+.L offset
+(usually zero) in the subfont, permitting selection of parts of subfonts.
+Thus
+the image for rune
+.I r
+is found in position
+.IB r -min+offset
+of the subfont.
+.PP
+For each font, the library, with support from the
+graphics server,
+maintains a cache of
+subfonts and a cache of recently used
+character images.
+The
+.B subf
+and
+.B cache
+fields are used by the library to maintain these caches.
+The
+.L width
+of a font is the maximum of the horizontal extents of the characters
+in the cache.
+.I String
+draws a string by loading the cache and emitting a sequence of
+cache indices to draw.
+.I Cachechars
+guarantees the images for the characters pointed to by
+.I *s
+or
+.I *r
+(one of these must be nil in each call)
+are in the cache of
+.IR f .
+It calls
+.I loadchar
+to put missing characters into the cache.
+.I Cachechars
+translates the character string into a set of cache indices
+which it loads into the array
+.IR c ,
+up to a maximum of
+.I n
+indices or the length of the string.
+.I Cachechars
+returns in
+.I c
+the number of cache indices emitted,
+updates
+.I *s
+to point to the next character to be processed, and sets
+.I *widp
+to the total width of the characters processed.
+.I Cachechars
+may return before the end of the string if it cannot
+proceed without destroying active data in the caches.
+If it needs to load a new subfont, it will fill
+.B *sfname
+with the name of the subfont it needs and return \-1.
+It can return zero if it is unable to make progress because
+it cannot resize the caches.
+.PP
+.I Loadchar
+loads a character image into the character cache.
+Then it tells the graphics server to copy the character
+into position
+.I h
+in the character cache.
+If the current font
+.L width
+is smaller than the horizontal extent of the character being loaded,
+.I loadfont
+clears the cache and resets it to
+accept characters with the bigger width, unless
+.I noclr
+is set, in which case it just returns \-1.
+If the character does not exist in the font at all,
+.I loadfont
+returns 0; if it is unable to load the character
+without destroying cached information, it returns \-1,
+updating
+.B *sfname
+as described above.
+It returns 1 to indicate success.
+.PP
+The
+.L age
+fields record when
+subfonts and characters have been used.
+The font
+.L age
+is increased every time the font is used
+.RI ( agefont
+does this).
+A character or subfont
+.L age
+is set to the font age at each use.
+Thus, characters or subfonts with small ages are the best candidates
+for replacement when the cache is full.
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR allocimage (2),
+.IR draw (2),
+.IR subfont (2),
+.IR image (6),
+.IR font (6)
+.SH DIAGNOSTICS
+All of the functions use the graphics error function (see
+.IR graphics (2)).
diff --git a/sys/man/2/chdir b/sys/man/2/chdir
new file mode 100755
index 000000000..24e1626b7
--- /dev/null
+++ b/sys/man/2/chdir
@@ -0,0 +1,32 @@
+.TH CHDIR 2
+.SH NAME
+chdir \- change working directory
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int chdir(char *dirname)
+.SH DESCRIPTION
+.I Chdir
+changes the working directory
+of the invoking process to
+.IR dirname .
+The working directory is the starting point for
+evaluating file names that do not begin with
+.L /
+or
+.LR # ,
+as explained in
+.IR intro (2).
+When Plan 9 boots, the initial process has
+.L /
+for its working directory.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/cleanname b/sys/man/2/cleanname
new file mode 100755
index 000000000..cd760e427
--- /dev/null
+++ b/sys/man/2/cleanname
@@ -0,0 +1,34 @@
+.TH CLEANNAME 2
+.SH NAME
+cleanname \- clean a path name
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.sp
+.B
+char* cleanname(char *filename)
+.SH DESCRIPTION
+.I Cleanname
+takes a
+.I filename
+and by lexical processing only returns the shortest string that names the same (possibly
+hypothetical) file.
+It eliminates multiple and trailing slashes, and it lexically interprets
+.B .
+and
+.B ..
+directory components in the name.
+The string is overwritten in place.
+.PP
+The shortest string
+.I cleanname
+can return is two bytes: the null-terminated string
+\f(CW"."\f1.
+Therefore
+.I filename
+must contain room for at least two bytes.
+.SH SOURCE
+.B /sys/src/libc/port/cleanname.c
+.SH SEE ALSO
+.IR cleanname (1)
diff --git a/sys/man/2/color b/sys/man/2/color
new file mode 100755
index 000000000..27569cb91
--- /dev/null
+++ b/sys/man/2/color
@@ -0,0 +1,56 @@
+.TH COLOR 2
+.SH NAME
+cmap2rgb, cmap2rgba, rgb2cmap \- colors and color maps
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <draw.h>
+.PP
+.B
+int rgb2cmap(int red, int green, int blue)
+.PP
+.B
+int cmap2rgb(int col)
+.PP
+.B
+int cmap2rgba(int col)
+.SH DESCRIPTION
+These routines convert between `true color' red/green/blue triples and the Plan 9 color map.
+See
+.IR color (6)
+for a description of RGBV, the standard color map.
+.PP
+.I Rgb2cmap
+takes a trio of color values, scaled from 0 (no intensity) to 255 (full intensity),
+and returns the index of the color in RGBV closest to that represented
+by those values.
+.PP
+.I Cmap2rgb
+decomposes the color of RGBV index
+.I col
+and returns a 24-bit integer with the low 8 bits representing the blue value,
+the next 8 representing green, and the next 8 representing red.
+.I Cmap2rgba
+decomposes the color of RGBV index
+.I col
+and returns a 32-bit integer with the low 8 bits representing an alpha value,
+defined to be 255,
+and the next 8 representing blue, then green, then red, as for
+.I cmap2rgba
+shifted up 8 bits.
+This 32-bit representation is the format used by
+.IR draw (2)
+and
+.IR memdraw (2)
+library routines that
+take colors as arguments.
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR allocimage (2),
+.IR draw (2),
+.IR image (6),
+.IR color (6)
diff --git a/sys/man/2/complete b/sys/man/2/complete
new file mode 100755
index 000000000..56e119b57
--- /dev/null
+++ b/sys/man/2/complete
@@ -0,0 +1,105 @@
+.TH COMPLETE 2
+.SH NAME
+complete \- file name completion
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <complete.h>
+.PP
+.ft L
+.nf
+.ta \w' 'u +\w' 'u +\w' 'u +\w' 'u +\w' 'u
+typedef struct Completion Completion;
+struct Completion{
+ uchar advance; /* whether forward progress has been made */
+ uchar complete; /* whether the completion now represents a file or directory */
+ char *string; /* the string to advance, suffixed " " or "/" for file or directory */
+ int nmatch; /* number of files that matched */
+ int nfile; /* number of files returned */
+ char **filename; /* their names */
+};
+
+.fi
+.PP
+.B
+.ta \w'\fLchar* 'u
+
+.PP
+.B
+Completion* complete(char *dir, char *s);
+.PP
+.B
+void freecompletion(Completion *c);
+.SH DESCRIPTION
+The
+.I complete
+function implements file name completion.
+Given a directory
+.I dir
+and a string
+.IR s ,
+it returns an analysis of the file names in that directory that begin with the string
+.IR s .
+The fields
+.B nmatch
+and
+.B nfile
+will be set to the number of files that match the prefix and
+.B filename
+will be filled in with their names.
+If the file named is a directory, a slash character will be appended to it.
+.PP
+If no files match the string,
+.B nmatch
+will be zero, but
+.I complete
+will return the full set of files in the directory, with
+.I nfile
+set to their number.
+.PP
+The flag
+.B advance
+reports whether the string
+.I s
+can be extended without changing the set of files that match. If true,
+.B string
+will be set to the extension; that is, the value of
+.B string
+may be appended to
+.I s
+by the caller to extend the embryonic file name unambiguously.
+.PP
+The flag
+.B complete
+reports whether the extended file name uniquely identifies a file.
+If true,
+.B string
+will be suffixed with a blank, or a slash and a blank,
+depending on whether the resulting file name identifies a plain file or a directory.
+.PP
+The
+.I freecompletion
+function frees a
+.B Completion
+structure and its contents.
+.PP
+In
+.IR rio (1)
+and
+.IR acme (1),
+file name completion is triggered by a control-F character or an Insert character.
+.SH SOURCE
+.B /sys/src/libcomplete
+.SH SEE ALSO
+.IR rio (1),
+.IR acme (1)
+.SH DIAGNOSTICS
+The
+.I complete
+function returns a null pointer and sets
+.I errstr
+if the directory is unreadable or there is some other error.
+.SH BUGS
+The behavior of file name completion should be controlled by the plumber.
diff --git a/sys/man/2/control b/sys/man/2/control
new file mode 100755
index 000000000..26de90f94
--- /dev/null
+++ b/sys/man/2/control
@@ -0,0 +1,1948 @@
+.TH CONTROL 2
+.SH NAME
+Control,
+Controlset,
+activate,
+closecontrol,
+closecontrolset,
+controlcalled,
+controlwire,
+createbox,
+createboxbox,
+createbutton,
+createcolumn,
+createentry,
+createkeyboard,
+createlabel,
+createmenu,
+createradiobutton,
+createrow,
+createscribble,
+createslider,
+createstack,
+createtab,
+createtext,
+createtextbutton,
+ctlerror,
+ctlmalloc,
+ctlrealloc,
+ctlstrdup,
+ctlprint,
+deactivate,
+freectlfont,
+freectlimage,
+initcontrols,
+namectlfont,
+namectlimage,
+newcontrolset,
+resizecontrolset
+\- interactive graphical controls
+.SH SYNOPSIS
+.EX
+.ta 4n +4n +4n +4n +4n +4n +4n
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <keyboard.h>
+#include <mouse.h>
+#include <control.h>
+.sp 0.3
+typedef struct Control Control;
+typedef struct Controlset Controlset;
+.sp 0.3
+struct Control
+{
+ char *name;
+ Rectangle rect; /* area on screen */
+ Rectangle size; /* min/max Dx, Dy (not a rect) */
+ Channel *event; /* chan(char*) to client */
+ Channel *data; /* chan(char*) to client */
+ \&...
+};
+.sp 0.3
+struct Controlset
+{
+ \&...
+ Channel *ctl;
+ Channel *data;
+ \&...
+ int clicktotype;
+ \&...
+};
+.sp 0.3
+void initcontrols(void)
+.sp 0.3
+Controlset* newcontrolset(Image *i, Channel *kc, Channel *mc, Channel *rc)
+.sp 0.3
+void closecontrolset(Controlset *cs)
+.sp 0.3
+int namectlfont(Font *font, char *name)
+.sp 0.3
+int freectlfont(char *name)
+.sp 0.3
+int namectlimage(Image *image, char *name)
+.sp 0.3
+int freectlimage(char *name)
+.sp 0.3
+Control* createbox(Controlset *cs, char *name)
+.sp 0.3
+Control* createboxbox(Controlset *cs, char *name)
+.sp 0.3
+Control* createbutton(Controlset *cs, char *name)
+.sp 0.3
+Control* createcolumn(Controlset*, char*)
+.sp 0.3
+Control* createentry(Controlset *cs, char *name)
+.sp 0.3
+Control* createkeyboard(Controlset *cs, char *name)
+.sp 0.3
+Control* createlabel(Controlset *cs, char *name)
+.sp 0.3
+Control* createmenu(Controlset *cs, char *name)
+.sp 0.3
+Control* createradiobutton(Controlset *cs, char *name)
+.sp 0.3
+Control* createrow(Controlset*, char*)
+.sp 0.3
+Control* createscribble(Controlset *cs, char *name)
+.sp 0.3
+Control* createslider(Controlset *cs, char *name)
+.sp 0.3
+Control* createstack(Controlset*, char*)
+.sp 0.3
+Control* createtab(Controlset*, char *)
+.sp 0.3
+Control* createtext(Controlset *cs, char *name)
+.sp 0.3
+Control* createtextbutton(Controlset *cs, char *name)
+.sp 0.3
+void closecontrol(Control *c)
+.sp 0.3
+int ctlprint(Control*, char*, ...);
+.sp 0.3
+void ctlerror(char *fmt, ...)
+.sp 0.3
+Control* controlcalled(char *name)
+.sp 0.3
+void controlwire(Control *c, char *cname, Channel *ch)
+.sp 0.3
+void activate(Control *c)
+.sp 0.3
+void deactivate(Control *c)
+.sp 0.3
+void resizecontrolset(Controlset *cs)
+.sp 0.3
+void* ctlmalloc(uint n)
+.sp 0.3
+void* ctlrealloc(void *p, uint n)
+.sp 0.3
+char* ctlstrdup(char *s)
+.sp 0.3
+int ctldeletequits;
+.EE
+.SH DESCRIPTION
+This library provides a set of interactive
+controls for graphical displays: buttons, sliders, text entry boxes, and so on.
+It also provides aggregator
+.BR Control s:
+boxes, columns, rows and stacks of
+.BR Control s.
+A stack is a collection of co-located
+.BR Control s,
+of which one is normally visible.
+A
+.B Controlset
+collects a group of
+.BR Control s
+that share mouse and keyboard. Each
+.B Controlset
+has a separate thread of control that processes keyboard and mouse events as
+well as commands to be passed on to the
+.BR Control s.
+Since each
+.B Controlset
+uses a thread, programs using the control library must
+be linked with the thread library,
+.IR thread (2).
+.PP
+.BR Control s
+are manipulated by reading and writing to the control channel,
+.BR ctl ,
+of their
+.BR Controlset .
+.BR Channel s
+are defined in
+.IR thread (2).
+Each
+.B Control
+has two output channels:
+.B Event
+delivers messages about actions within the control (such as a button press) and
+.B data
+delivers (if requested by an appropriate write to
+.BR ctl )
+control-specific data such as the contents of a field.
+.PP
+The library provides a simple mechanism for automatic layout:
+the minimum and maximum sizes of each simple control can be specified.
+.BR Boxbox ,
+.BR row ,
+.B column
+and
+.B stack
+.BR Control s
+then use these sizes to lay out their constituent
+.BR Control s
+when called upon
+to do so. See the description of these grouping
+.BR Control s
+for further details.
+.SS "Message format
+All messages are represented as
+.SM UTF\c
+-8
+text.
+Numbers are formatted in decimal, and strings are transmitted in the
+quoted form of
+.IR quote (2).
+.PP
+Messages sent to a
+.B Controlset
+are of the form,
+.IP
+.IR sender :
+.I destination
+.I verb
+.RI [ argument
+\&... ]
+.LP
+The sender (and the colon following it) may be ommitted.
+For example, the initial field of a text entry control called
+.I entry
+could be set by sending the message,
+.IP
+.B "entry value 'Hello, world!'
+.PP
+to its
+.BR Controlset 's
+.B ctl
+file.
+This message contains the verb
+.B value
+and the single argument
+.B "Hello, world!"
+.PP
+To make it easy to write messages, the function
+.IR chanprint
+(see
+.IR thread (2))
+can be used to print formatted text to a
+.BR Controlset 's
+channel.
+.PP
+The
+.B %q
+and
+.B %Q
+formats are convenient for properly quoting string arguments,
+as in
+.IP
+.EX
+chanprint(e->event, "value %q", "Don't touch!");
+.EE
+.PP
+It is wise to use
+.B %q
+always instead of
+.BR %s
+when sending messages, and avoid dealing with the quoting explicitly.
+In the other direction,
+.B tokenize
+(see
+.IR getfields (2))
+parses these messages and interprets the quotes correctly.
+.PP
+The destination of a message can be a named control, or a set of controls identified
+by name or type. The command
+.IP
+.B "'entry slider' show
+.PP
+(note the quotation) sends the `show' command to the entry named
+.I entry
+and all controls of type
+.IR slider .
+If there were a control whose name was
+.I slider
+that control would also be shown.
+.LP
+\f2
+Note that we are still experimenting with destination names.
+One proposal is that
+a destination of the form
+\fR"`name1 name2 ⋯ type1 type2 ⋯'\fP
+selects all controls of the named types in the control hierarchies (of columns, rows and
+stacks) whose names precede the types.
+.LP
+Messages sent by a control on its
+.B event
+channel are of the form
+.IP
+.IB sender :
+.IB event
+.PP
+The
+.I sender
+is the name of the control sending the message;
+the
+.I event
+describes the event. Its format can often be controlled by setting the
+.BR Control 's
+.IR "format string" .
+For example, when the user types a newline at a text entry
+.B Control
+named
+.BR entry,
+the control sends the message
+.IP
+.B entry:\ value\ 'Hello\ again!'
+on its
+.B event
+channel.
+.SS "Initialization and Control sets
+After
+.B initdraw
+(see
+.IR graphics (2))
+is called,
+the function
+.I initcontrols
+should be called to initialize the library.
+It calls
+.I quotefmtinstall
+to install the
+.B %q
+and
+.B %Q
+formats; see
+.IR quote (2).
+.PP
+Each control is represented by a
+.B Control
+data structure and is associated with a
+.B Controlset
+that groups a set of controls sharing mouse, keyboard, and display.
+Most applications will need only one
+.BR Controlset ;
+only those with multiple windows or unusual configurations will need
+more than one.
+The function
+.I newcontrolset
+creates a
+.BR Controlset .
+Its arguments are the image (usually a window)
+on which its controls will appear, typically the
+.B screen
+variable in the draw library, and three channels:
+.BR kc ,
+a channel of
+.B Runes
+from the keyboard;
+.BR mc ,
+a channel of
+.B Mouse
+structures from the mouse;
+and
+.BR rc ,
+a channel of
+.B int
+that indicates when the window has been resized.
+Any of the channels may be nil,
+in which case
+.I newcontrolset
+will call
+.B initkeyboard
+and/or
+.B initmouse
+(see
+.IR keyboard (2)
+and
+.IR mouse (2))
+to initialize the keyboard and mouse
+and connect them to the control set.
+The mouse and resize channels must both be nil or both be non-nil.
+.PP
+The function
+.I closecontrolset
+frees all the controls in the control set and tears down all the associated threads.
+It does not close the mouse and keyboard.
+.PP
+The public elements of a
+.B Controlset
+are the flag
+.BR clicktotype ,
+and the
+.I ctl
+and
+.I data
+channels.
+.PP
+.I Clicktotype
+is zero by default.
+If it is set to non-zero, the controls
+in the set will acquire `focus' by the click-to-type paradigm.
+Otherwise, focus is always given to the control under the mouse.
+.PP
+Commands for controls are sent through the
+.BR Controlset 's
+.I ctl
+channel.
+One special command is recognized by the
+.B Controlset
+itself: Sending
+the string
+.B sync
+to the
+.I ctl
+channel causes tha string to be echoed to the
+.BR Controlset 's
+.I data
+channel when all commands up to the
+.I sync
+command have been processed. The string is
+allocated and must be freed (see
+.IR malloc (2)).
+Synchronization is necessary between sending a command, for example, to resize
+all controls, and using their
+.I rect
+fields.
+.PP
+The function
+.I resizecontrolset
+must be provided by the user.
+When the associated window is resized, the library will call
+.I resizecontrolset
+with the affected
+.BR Controlset ;
+the function should reconnect to and redraw the window.
+.PP
+If all windows are organized in a hierachy of
+.IR boxboxes ,
+.IR columns ,
+.I rows
+and
+.IR stacks ,
+and minimum and maximum sizes have already been supplied, only
+the top control needs to be resized (see the
+.I rect
+command below).
+.SS "Fonts and images
+Fonts and images must be given names so they may be referenced
+in messages.
+The functions
+.I namectlfont
+and
+.I namectlimage
+associate a (unique) name with the specified font or image.
+The association is removed by
+.I freectlfont
+and
+.IR freectlimage .
+The font or image is not freed by these functions, however.
+.PP
+The function
+.I initcontrols
+establishes name bindings for all the colors mentioned in
+.BR <draw.h> ,
+such as
+.BR black ,
+.BR white ,
+.BR red ,
+.BR yellow ,
+etc., as well as masks
+.B transparent
+and
+.BR opaque .
+It also sets the name
+.B font
+to refer to the default
+.B font
+variable set up by
+.BR initdraw .
+.SS Creation
+Each type of control has an associated creation function:
+.IR createbutton ,
+.IR createentry ,
+etc.,
+whose arguments are the
+.B Controlset
+to attach it to and a globally unique name for it.
+A control may be destroyed by calling
+.IR closecontrol .
+.PP
+The function
+.I controlcalled
+returns a pointer to the
+.B Control
+with the given
+.IR name ,
+or nil if no such control exists.
+.SS Configuration
+After a control is created, it must be configured using the control-specific
+commands documented below.
+Commands are sent to the
+.B ctl
+channel of the
+.BR Controlset .
+Multiple commands may be sent in a single message; newline characters
+separate commands.
+For an example, see the implementation of
+.I resizecontrolset
+in the
+.B EXAMPLES
+section.
+Note that newline is a separator, not a terminator; the final command
+does not need a newline.
+.PP
+Messages sent to the
+.I ctl
+channel are delivered to all controls that match the
+.I destination
+field. This field is a set of names separated by spaces, tabs or newlines.
+A control matches the destination if its name or its type is among the set.
+.PP
+The recipient of a message ignores the initial
+.IB sender :
+field of the message, if present,
+making it possible to send messages generated on an
+.B event
+channel directly to another control's
+.B ctl
+channel.
+.SS Activation
+When they are created, controls are disabled: they do not respond to
+user input.
+Not all controls need to be responsive;
+for example, labels are static and a text display
+might show a log of messages but not be useful to edit.
+But buttons, entry boxes, and other text displays should be active.
+.PP
+To enable a control, call the
+.I activate
+function, which
+specifies that the
+.B Control
+.I c
+should respond to mouse and keyboard events;
+.I deactivate
+turns it off again.
+.PP
+Controls can be either
+.I revealed
+(default) or
+.IR hidden .
+When a control is hidden, it will not receive mouse or keyboard events
+and state changes or
+.I show
+commands will be ignored until the control is once again
+.IR revealed .
+Control hiding is particularly useful when different controls are overlayed,
+revealing only the `top' one.
+.PP
+The function
+.I controlwire
+permits rearrangement of the channels associated with a
+.BR Control .
+The channel
+.I cname
+(one of
+\f5"data"\fP
+or
+\f5"event"\fP)
+of
+.B Control
+.I c
+is reassigned to the channel
+.IR ch .
+There are several uses for this operation:
+one may reassign all the
+.B event
+channels to a single channel, in effect multiplexing all the events onto
+a single channel;
+or connect the
+.B event
+channel of a slider to the
+.B ctl
+channel for delivery to a text display (after setting the format for the slider's messages
+to name the destination control and the appropriate syntax for the rest of the command)
+to let the slider act as a scroll bar for the text without rerouting the messages explicitly.
+.SS Controls
+The following sections document the individual controls in alphabetical order.
+The layout of each section is a brief description of the control's behavior,
+followed by the messages it sends on
+.BR event ,
+followed by the messages it accepts via the
+.B ctl
+channel.
+The
+.B event
+messages are triggered
+.I only
+by mouse or keyboard action; messages to the
+.B ctl
+file do not cause events to be generated.
+.PP
+All controls accept the following messages:
+.TF \fLreveal
+.TP
+.BI rect " minx miny maxx maxy
+Set the bounding rectangle for the control on the display.
+The syntax generated by the
+.B %R
+print format of the draw library is also acceptable for the coordinates.
+.TP
+.BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
+Set the minimum and maximum size for automatic layout in
+.IR columns ,
+.I rows
+and
+.IR stacks .
+Without its four arguments, this command is ignored by primitive controls
+and used by grouping controls to calculate their minimum and maximum sizes
+by examining those of their constituent members.
+If all primitive controls have been assigned a size, a single size request addressed
+to the top of a layout hierarchy will assign sizes to all grouping
+.BR Control s.
+.TP
+.B hide
+Disable drawing of the control and ignore mouse and keyboard events
+until the control is once again revealed.
+Grouping
+.BR Control s
+(\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
+request down to their constituent
+.BR Control s.
+.TP
+.B reveal
+This is the opposite of
+.BR hide :
+the
+.B Control
+is displayed and mouse and keyboard operations resume.
+Grouping
+.BR Control s
+(\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
+request down to their constituent
+.BR Control s.
+The
+.B reveal
+command for
+.I stacks
+takes an optional argument naming the
+.B Control
+to be revealed; all
+other
+.BR Control s
+will be hidden.
+.TP
+.B show
+Display the
+.B Control
+on its screen if not hidden.
+Some actions will also cause the
+.BR Control s
+to show themselves automatically
+(but never when the
+.B control
+is hidden).
+Grouping
+.BR Control s
+(\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
+request down to their constituent
+.BR Control s.
+.PD
+.PP
+Many messages are common between multiple
+.BR Control s.
+Such messages are described in detail here to avoid repetition.
+In the individual descriptions, only the syntax is presented.
+.TF "\fLformat fmt"
+.TP
+.BI align " n
+Specify the alignment of (some part of) the
+.BR Control 's
+display within its rectangle.
+For textual
+.BR control s,
+the alignment specifies where the text should appear.
+For multiline text, the alignment refers to each line within its box,
+and only the
+horizontal part is honored.
+For other
+.BR Control s,
+the alignment affects the appearance of the display in
+a reasonable way.
+The valid alignments are words with obvious interpretations:
+.BR upperleft ,
+.BR uppercenter ,
+.BR upperright ,
+.BR centerleft ,
+.BR center ,
+.BR centerright ,
+.BR lowerleft,
+.BR lowercenter ,
+and
+.BR lowerright .
+.TP
+.BI border " n
+Inset the
+.B Control
+(or separate constituent
+.BR Control s
+in
+.IR boxbox ,
+.I column
+and
+.I row
+.BR Control s
+after the next
+.I rect
+command) within its rectangle by
+.I n
+pixels, default zero.
+.TP
+.BI bordercolor " name
+Paint the border of the control with the named color, default black.
+.TP
+.BI focus " n
+The
+.B Control
+now has (if
+.I n
+is non-zero) or does not have ( if
+.I n
+is zero) focus.
+Most
+.BR Control s
+ignore the message; there are plans to make them react.
+.TP
+.BI format " fmt
+Set the format of `value' messages sent on the
+.B event
+channel.
+By default, the format is
+.B \&"%q: value %q"
+for string-valued
+.BR Control s,
+.B \&"%q: value %d"
+for integer-valued
+.B Control s
+such as buttons,
+and
+.B \&"%q: value 0x%x"
+for the keyboard and scribble
+.BR Control s.
+The
+.B %q
+prints the name of the
+.BR Control ;
+the rest the value.
+Any supplied format string must be type-equivalent to the default for that
+.BR Control .
+.TP
+.BI image " name
+.TP
+.BI light " name
+.TP
+.BI mask " name
+Many controls set a background image or color for display.
+The
+.B image
+message sets the image.
+The
+.B mask
+and
+.B light
+images together specify how the
+.B Control
+shows it is enabled:
+the
+.B light
+is printed through the
+.B mask
+when the state is `on' or `pressed'.
+Otherwise, the image appears unmodified.
+The default image is white; mask opaque; light yellow.
+.TP
+.BI font " name
+.TP
+.BI textcolor " name
+These commands set the font and color for displaying text.
+The defaults are the default
+.B font
+set up by the draw library, and black.
+.TP
+.BI value " v
+Set the value of the
+.BR Control .
+Textual images accept an arbitrary string;
+others an integral value.
+.SS Box
+A box is a trivial control that does nothing more than pass keyboard, mouse,
+and focus messages back on its
+.B event
+channel.
+Keyboard characters are sent in the format
+.IP
+.EX
+boxname: key 0x\f2nn
+.EE
+.PP
+where
+.I nn
+is the hexadecimal value of the character.
+Mouse messages are sent in the format
+.IP
+.EX
+boxname: mouse [\f2x\fP \f2y\fP] \f2but\fP \f2msec\fP
+.EE
+.PP
+where
+.IR x ,
+.IR y ,
+.IR but ,
+and
+.I msec
+are the various fields of the
+.B Mouse
+structure.
+The focus message is just
+.IP
+.EX
+boxname: focus \f2n\f1
+.EE
+.PP
+where
+.I n
+is 0 if the box has lost focus, 1 if it has acquired it.
+.PP
+The box displays within its rectangle
+an image, under mask, with specified alignment.
+The control messages it accepts are:
+.TF "\fLalign a"
+.TP
+.BI align " a
+Controls the placement of the image in the rectangle (unimplemented).
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.BI show
+.TP
+.BI size " minΔx minΔy maxΔx maxΔy
+.PD
+.SS Boxbox
+A
+.B boxbox
+allows a set of controls (``boxes'')
+to be displayed in rows and columns within the
+rectangle of the
+.IR boxbox .
+The maximum of the minimum heights of the constituent controls determines the
+number of rows to be displayed. The number of columns is the minimum that
+allows all
+.BR Control s
+to be displayed. This aggregator works well for collections
+of buttons, labels, or textbuttons that all have a fixed height.
+.TF "\fLadd name ..."
+.TP
+.BI add " name ...
+adds the named control to the box of controls. The display order
+is determined by the order of adding. The first named control is top left,
+the second goes below it, etc.
+It is possible to add one control to multiple grouping controls but
+the layout of the result will be quite unpredictable.
+.TP
+.BI border " width
+.TP
+.BI bordercolor " color
+.TP
+.B hide
+This command is passed on to the member controls.
+.TP
+.BR image " color
+Background color displayed between member controls.
+.TP
+.B reveal
+This command is passed on to the member controls.
+.TP
+.BI separation " width
+Set the separation between member controls to
+.I n
+pixels.
+.TP
+.BI rect " minx miny maxx maxy
+The member controls are layed out within the given rectangle according to
+the minimum and maximum sizes given. If the rectangle is not large enough
+for the minimum a fatal error is currently generated.
+If the controls at their maximum size are not big enough to fit, they are top-left justified
+at their maximum size in the space given.
+Otherwise, controls will get their minimum size and be enlarged proportional
+to the extra size given by the maximum until they fit given rectangle.
+The members are separated by borders of the width established by
+.IR borderwidth .
+.TP
+.BI remove " name
+Remove the named
+control from the box.
+.TP
+.B show
+This command is passed on to the member controls.
+Show also (re)displays background and borders.
+.TP
+.BR size " \f2minΔx minΔy maxΔx maxΔy\fP
+.PD
+.SS Button
+A button is a simple control that toggles its state when mouse button 1 is pressed on its rectangle.
+Each state change triggers an event message:
+.IP
+.EX
+buttonname: value \f2n\fP
+.EE
+where
+.I n
+encodes the mouse buttons used to make the selection.
+.PP
+The button displays an image (which may of course be a simple color)
+and illuminates in the standard way when it is `on'.
+The control messages it accepts are:
+.TF "\fLborder b"
+.TP
+.BI align " a
+Controls the placement of the image in the rectangle (unimplemented).
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI format " fmt
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI light " name
+.TP
+.BI mask " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.B show
+.TP
+.BI size " minΔx minΔy maxΔx maxΔy
+.TP
+.BI value " n
+Set the button to `on' (if
+.I n
+is non-zero) or `off' (if
+.I n
+is zero).
+.PD
+.SS Column
+A column is a grouping control which lays out its members vertically,
+from top to bottom. Currently, columns ignore mouse and keyboard
+events, but there are plans to allow dragging the borders (when they
+have non-zero width) between constituent members.
+.TF "\fLadd name .."
+.TP
+.BI add " name ...
+adds the named control to the column of controls. The vertical order
+is determined by the order of adding. The first named control goes at
+the top. It is possible to add one control to multiple grouping controls but
+the layout of the result will be quite unpredictable.
+.TP
+.BI border " width
+Set the border between members to the width given.
+.TP
+.BI bordercolor " color
+.TP
+.B hide
+.TP
+.BR image " color
+Background color displayed between member controls.
+.TP
+.B reveal
+.TP
+.BI separation " width
+Set the separation between member controls to
+.I n
+pixels.
+.TP
+.B show
+These three commands are passed on to the member controls.
+Show also (re)displays the borders between members.
+.TP
+.BI rect " minx miny maxx maxy
+The member controls are layed out within the given rectangle according to
+the minimum and maximum sizes given. If the rectangle is not large enough
+for the minimum a fatal error is currently generated. However, see the example
+at the end of this man page.
+If the controls at their maximum size are not big enough to fit, they are centered
+at their maximum size in the space given.
+Otherwise, controls will get their minimum size and be enlarged proportional
+to the extra size given by the maximum until they fit given rectangle.
+The members are separated by borders of the width established by
+.IR borderwidth .
+.TP
+.BI remove " name
+Remove the named control from the column.
+.TP
+.BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
+Without arguments, this command computes the minimum and
+maximum size of a column by adding the minimum and maximum
+heights to set
+.I minΔy
+and
+.IR maxΔy ,
+and it finds the largest minimum and maximum widths to set
+.I minΔy
+and
+.IR maxΔy .
+When called with arguments, it simply sets the minimum and maximum
+sizes to those given.
+.PD
+.SS Entry
+The entry control manages a single line of editable text.
+When the user hits a carriage return anywhere
+in the text, the control generates the event message,
+.IP
+.EX
+entryname: value \f2s\fP
+.EE
+.PP
+with
+.I s
+the complete text of the entry box.
+.PP
+The cursor can be moved by clicking button 1; at the moment,
+there is no way to select characters, only a typing position.
+Some control characters have special actions:
+control-H (backspace) deletes the character before the cursor;
+control-U clears the line; and
+control-V pastes the snarf buffer at the typing position.
+Most important, carriage return sends the text to the event channel.
+.PP
+To enter passwords and other secret text without displaying the
+contents, set the font to one in which all characters are the same.
+The easiest way to do this is to make a font containing only one character,
+at position 0 (NUL), since that position is used to render all
+characters not otherwise defined in the font (see
+.IR draw (2)).
+The file
+.B /lib/font/bit/lucm/passwd.9.font
+defines such a font.
+.PP
+The control messages the entry control accepts are:
+.TF "\fLborder b"
+.TP
+.BI align " a
+Controls the placement of the text in the rectangle.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI data
+After receiving this message, the entry will send its value to its
+.B data
+channel as an unadorned, unquoted string.
+.TP
+.BI focus " n
+When it receives focus, the entry box displays a typing cursor.
+When it does not have focus, the cursor is not displayed.
+.TP
+.BI font " name
+.TP
+.BI format " fmt
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.B reveal
+.TP
+.B show
+.TP
+.BI size " minΔx minΔy maxΔx maxΔy
+.TP
+.BI textcolor " name
+.TP
+.BI value " s
+Set the string displayed in the entry box.
+.PD
+.SS Keyboard
+The keyboard control implements a simulated keyboard useful on palmtop devices.
+Keystrokes, generated by mouse button 1 on the simulated keys,
+are sent as event messages:
+.IP
+.EX
+keyboardname: value 0x\f2nn\f1
+.EE
+.PP
+where
+.I nn
+is the hexadecimal Unicode value of the character.
+Shift, control, and caps lock are handled by the keyboard control itself;
+shift and control affect only the next regular keystroke.
+The Alt key is unimplemented; it will become equivalent to the standard Plan 9
+key for synthesizing non-ASCII characters.
+.PP
+There are two special keys,
+.B Scrib
+and
+.BR Menu ,
+which return values
+.B 0x10000
+and
+.BR 0x10001 .
+.PP
+The image, mask, light rules are used to indicate that a key is pressed,
+but to aid clumsy fingers the keystroke is not generated until the key is released,
+so it is possible to slide the pointer to a different key to correct for bad aim.
+.PP
+The control messages the keyboard accepts are:
+.TF "\fLfont"
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI font " name1 name2
+Sets the font for the keys.
+If only one font is named, it is used for all keys.
+If two are named, the second is used for key caps with special names such
+as Shift and Enter.
+(Good choices on the Bitsy are
+.B /lib/font/bit/lucidasans/boldlatin1.6.font
+for the first and
+.B /lib/font/bit/lucidasans/unicode.6.font
+for the second argument.)
+If neither is specified, both will be set to the default global font.
+.TP
+.BI format " fmt
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI light " name
+.TP
+.BI mask " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.B show
+.TP
+.BI size " minx miny maxx maxy
+.PD
+.SS Label
+A label is like a textbutton
+.RI ( q.v. )
+that does not react, but whose value is the text it displays.
+The control messages it accepts are:
+.TF "\fLvalue s"
+.TP
+.BI align " a
+Controls the placement of the image in the rectangle.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI font " name
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.B show
+.TP
+.BI size " minx miny maxx maxy
+.TP
+.BI textcolor " name
+.TP
+.BI value " s
+The value is a string that can be modified only by sending this message to the
+.B ctl
+file.
+.PD
+.SS Menu
+A menu is a pop-up window containing a set of textual selections.
+When a selection is made, it removes itself from the screen and reports the selection
+by value:
+.IP
+.EX
+menuname: value \f2n\fP
+.EE
+.PP
+If no selection is made, no message is reported.
+Because it creates a window, programs using a menu must have their
+.B screen
+variable (see
+.IR graphics (2)
+and
+.IR window (2))
+set up to be refreshed properly.
+The easiest way to do this is to call
+.B getwindow
+with refresh argument
+.B Refbackup
+(see
+.IR graphics (2));
+most programs use
+.BR Refnone .
+.PP
+The control messages accepted by a menu are:
+.TF "\fLwindow n"
+.TP
+.BI add " text
+Add a line of
+.I text
+to the end of the menu.
+.TP
+.BI align " a
+Controls the left-right placement of the text in its rectangle.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI font " name
+.TP
+.BI format " fmt
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.BI size " minx miny maxx maxy
+Only the origin of the rectangle is significant; menus calculate the appropriate size.
+.TP
+.BI selectcolor " name
+Set the color in which to highlight selected lines; default yellow.
+.TP
+.BI selecttextcolor " name
+Set the color in which to draw the text in selected lines; default black.
+.TP
+.B show
+Display the menu. Not usually needed unless the menu is changed while visible; use
+.I window
+instead.
+.TP
+.B window
+.TP
+.BI window " n
+With no arguments, toggle the menu's visibility; otherwise make it visible (1) or invisible (0).
+When the selection is made, the menu will remove its window automatically.
+.PD
+.SS Radiobutton
+The radiobutton assembles a group of buttons or textbuttons into a
+single control with a numeric value.
+Its value is \-1 if none of the constituent buttons is pressed; otherwise
+it is the index, starting at zero, of the button that is pressed.
+Only one button may be pressed; the radiobutton manipulates its
+buttons to guarantee this.
+State changes trigger an event message:
+.IP
+.EX
+radiobuttonname: value \f2n\fP
+.EE
+.PP
+Buttons are added to the radio button using the
+.B add
+message; there is no way to remove them, although they may be turned off
+independently using
+.IR deactivate .
+The index reported in the value is defined by the order
+in which the buttons are added.
+The constituent buttons should be configured and layed out in the usual way;
+the rectangle of the radiobutton is used only to `catch' mouse events and
+should almost always correspond to the bounding box of the constituent
+buttons.
+In other words, the geometry is not maintained automatically.
+.PP
+The control messages the radiobutton accepts are:
+.TF "\fLadd name"
+.TP
+.BI add " name
+Add the control with the specified
+.I name
+to the radiobutton.
+.TP
+.BI focus " n
+.TP
+.BI format " fmt
+.TP
+.BI hide
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.BI size " minx miny maxx maxy
+.TP
+.B show
+.TP
+.BI value " n
+.PD
+.SS Row
+A row groups a number of member controls left to right in a rectangle.
+Rows behave exactly like columns with the roles of
+.I x
+and
+.I y
+interchanged.
+.PP
+The control messages it accepts are:
+.TF "\fLfont"
+.TP
+.BI add " name ...
+.TP
+.BI border " width
+.TP
+.BI bordercolor " color
+.TP
+.BI hide
+.TP
+.BR image " color
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI remove " name
+.TP
+.BI reveal
+.TP
+.BI separation " width
+.TP
+.BI show
+.TP
+.BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
+.PD
+.SS Scribble
+The scribble control provides a region in which strokes drawn with mouse button
+1 are interpreted as characters in the manner of
+.IR scribble (2).
+In most respects, including the format of its event messages, it is equivalent
+to a keyboard control.
+.PP
+The control messages it accepts are:
+.TF "\fLlinecolor \fIname\f(CW "
+.TP
+.BI align " a
+Controls the placement of the image in the rectangle (unimplemented).
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI font " name
+Used to display the indicia.
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI linecolor " name
+The color in which to draw the strokes; default black.
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.BI size " minx miny maxx maxy
+.TP
+.B show
+.PD
+.SS Stack
+A stack groups a number of member controls in the same shared rectangle.
+Only one of these controls will be visible (revealed), the others are hidden.
+.PP
+The control messages it accepts are:
+.TF "\fLreveal [\f2n\fP]"
+.TP
+.BI hide
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI remove " name
+.TP
+.BR reveal " [ \f2n\fP ]
+Without argument,
+.B reveal
+is the opposite of
+.BR hide :
+it makes its selected control visible after it was hidden.
+With an argument, it makes the
+.IR n 'th
+added control visible, hiding all others.
+.TP
+.BI show
+.TP
+.BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
+Without argument,
+.I size
+computes the maximum of the minimum and maximum sizes of
+its constituent controls. With arguments, it sets the size to the
+given values.
+.PD
+.SS Slider
+A slider controls an integer value by dragging the mouse with a button.
+Configured appropriately, it can serve as a scroll bar with the standard
+Plan 9 behavior.
+When the value changes, an event message is sent:
+.IP
+.EX
+slidername: value \f2n\f1
+.EE
+.PP
+The slider is a good candidate for connecting to another control
+by setting its format and rewiring its
+.B event
+channel to the other's
+.B ctl
+channel.
+.PP
+The geometry of the slider is defined by three numbers:
+.B max
+is a number representing the range of the slider;
+.B vis
+is a number representing how much of what is being controlled is visible;
+and
+.B value
+is a number representing the value of the slider within its range.
+For example, if the slider is managing a textual display of 1000 lines, with
+18 visible, and the first visible line (numbered starting form 0) is 304,
+.B max
+will be 1000,
+.B vis
+will be 18, and
+.B value
+will be 304.
+The
+.I indicator
+is the visual representation of the
+.I vis
+portion of the controlled object.
+.PP
+The control messages the slider accepts are:
+.TF "\fLabsolute n"
+.TP
+.BI absolute " n
+If
+.I n
+is zero,
+the slider behaves like a Plan 9 scroll bar:
+button 2 sets absolute position, button 1 decreases the value,
+and button 3 increases it.
+If
+.I n
+is non-zero, all buttons behave like button 2, setting the absolute value.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI clamp " end n
+The
+.I end
+is either the word
+.B high
+or
+.BR low ;
+.I n
+sets whether that end is clamped or not.
+If it is clamped, that end of the indicator is always at its supremum.
+A standard scroll bar has neither end clamped; a volume slider would
+have its low end clamped.
+If the low end is clamped, the value of the slider is represented by the
+high end of the indicator; otherwise it is represented by the low end.
+.TP
+.BI focus " n
+.TP
+.BI format " fmt
+.TP
+.BI hide
+.TP
+.BI image " name
+.TP
+.BI indicatorcolor " name
+Set the color in which to draw the indicator; default black.
+.TP
+.BI max " n
+Set the maximum value of the range covered by the slider.
+.TP
+.BI orient " dir
+The string
+.I dir
+begins either
+.B hor
+or
+.B ver
+to specify the orientation of the slider.
+The default is vertical.
+The value always increases to the right for horizontal sliders and
+downwards for vertical sliders.
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI reveal
+.TP
+.BI size " minx miny maxx maxy
+.TP
+.B show
+.TP
+.BI value " n
+.TP
+.BI vis " n
+Set the visible area shown by the indicator.
+.PD
+.SS Tab
+A tab control combines radiobottuns with a stack of windows giving the
+appearance of tabbed controls. Currently, the tabs are positioned at the
+top of the stack. The radiobutton consists of textbuttons, the stack
+can be composed of any type of control.
+.PP
+Control messages are
+.TF "\fLformat fmt"
+.TP
+.BI add " button control button control ...
+Adds a button to the radiobutton, and an associated control to the stack.
+Buttons and controls are numbered in the order of addition. There is
+no remove operation.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " color
+.TP
+.BI focus " n
+.TP
+.BI format " fmt
+When a format string is defined, the tab control reports which tab
+is selected using the format string (which must print a
+.B char*
+and an
+.BR int ).
+.TP
+.BI image " color
+Color between member controls.
+.TP
+.BI separation " n
+Spacing between buttons in the radiobutton and between the row of
+buttons and the stack below it.
+.TP
+.BI rect " n n n n
+.TP
+.B hide
+.TP
+.B reveal
+.TP
+.BI size " n n n n
+.TP
+.B show
+.TP
+.BI value " n
+Value must be an integer indicating which tab to bring to the top.
+.PD
+.SS Text
+A text control presents a set of lines of text.
+The text cannot be edited with the keyboard, but can be
+changed by control messages.
+(A more interactive text control will be created eventually.)
+The mouse can be used to select lines of text.
+The only event message reports a state change in the selection of a line:
+.IP
+.EX
+textname: select \f2n\f1 \f2s\f1
+.EE
+.PP
+states that line
+.I n
+has changed its selection state to
+.IR s ,
+either zero (unselected) or non-zero (selected).
+The non-zero value encodes the mouse buttons that were down
+when the selection occurred.
+.PP
+The control messages the text control accepts are:
+.TF "\fLselectmode \fIs\fP "
+.TP
+.BI accumulate " s
+.TP
+.BI accumulate " n s
+.TP
+.BI add " s
+.TP
+.BI add " n s
+With one argument, append the string
+.I s
+as a new last line of the control; if
+.I n
+is specified, add the line
+.I before
+the current line
+.IR n ,
+making the new line number
+.IR n.
+The lines are zero indexed and
+.I n
+can be no greater than the current number of lines.
+.I Add
+refreshes the display, but
+.I accumulate
+does not, to avoid n-squared behavior when assembling a piece of text.
+.TP
+.BI align " a
+Controls the placement of each line of text left-to-right in its rectangle.
+Vertically, lines are tightly packed with separation set by the font's interline
+spacing.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI clear
+Delete all text.
+.TP
+.BI delete " n
+Delete line
+.IR n .
+.TP
+.BI focus " n
+.TP
+.BI font " name
+.TP
+.BI image " name
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.BI replace " n s
+Replace line
+.I n
+by the string
+.IR s .
+.TP
+.BI reveal
+.TP
+.BI scroll " n
+If
+.I n
+is non-zero, the text will automatically scroll so the last line is always visible
+when new text is added.
+.TP
+.BI select " n m
+Set the selection state of line
+.I n
+to
+.IR m .
+.TP
+.BI selectcolor " name
+Set the color in which to highlight selected lines; default yellow.
+.TP
+.BI selectmode " s
+The string
+.I s
+is either
+.B single
+or
+.BR multi .
+If
+.BR single ,
+the default,
+only one line may be selected at a time; when a line is selected,
+other lines are unselected.
+If
+.BR multi ,
+the selection state of individual lines can be toggled independently.
+.TP
+.BI size " minx miny maxx maxy
+.TP
+.B show
+.TP
+.BI textcolor " name
+.TP
+.BI topline " n
+Scroll the text so the top visible line is number
+.IR n .
+.TP
+.BI value " s
+Delete all the text in the control and then add the single line
+.IR s .
+.PD
+.SS Textbutton
+A textbutton is a textual variant of a plain button.
+Each state change triggers an event message:
+.IP
+.EX
+textbuttonname: value \f2n\fP
+.EE
+.LP
+where
+.I n
+encodes the mouse buttons used to make the selection.
+.PP
+Like a regular button, the value of a textbutton is an integer; the
+.I text
+is the string that appears in the button.
+It uses the image, light, mask method of indicating its state;
+moreover, the color of the text can be set to change when the button is pressed.
+The control messages it accepts are:
+.TF "\fLalign a"
+.TP
+.BI align " a
+Controls the placement of the text in the rectangle.
+.TP
+.BI border " b
+.TP
+.BI bordercolor " name
+.TP
+.BI focus " n
+.TP
+.BI font " name
+.TP
+.BI format " fmt
+.TP
+.B hide
+.TP
+.BI image " name
+.TP
+.BI light " name
+.TP
+.BI mask " name
+.TP
+.BI pressedtextcolor " name
+Set the color in which to display text when the textbutton is pressed.
+.TP
+.BI rect " minx miny maxx maxy
+.TP
+.B reveal
+.TP
+.BI size " minx miny maxx maxy
+.TP
+.B show
+.TP
+.BI text " s
+Set the text displayed in the button.
+.TP
+.BI textcolor " name
+.TP
+.BI value " n
+Set the button to `on' (if
+.I n
+is non-zero) or `off' (if
+.I n
+is zero).
+.SS "Helper functions
+The function
+.I ctlerror
+is called when the library encounters an error.
+It prints the formatted message and exits the program.
+.PP
+The functions
+.IR ctlmalloc ,
+.IR ctlrealloc ,
+.IR ctlstrdup ,
+and
+.I ctlrunestrdup
+are packagings of the corresponding C library functions.
+They call
+.I ctlerror
+if they fail to allocate memory, and
+.I ctlmalloc
+zeros the memory it returns.
+.PP
+Finally, for debugging, if the global variable
+.I ctldeletequits
+is set to a non-zero value, typing a
+.SM DEL
+will cause the program to call
+.IP
+.EX
+ctlerror("delete");
+.EE
+.SS Caveat
+This library is very new and is still missing a number of important features.
+The details are all subject to change.
+Another level of library that handles geometry and has sensible default
+appearances for the controls would be useful.
+.PP
+One unusual design goal of this library was to make the controls themselves
+easy to implement.
+The reader is encouraged
+to create new controls by adapting the source to existing ones.
+.SH EXAMPLES
+This example creates two entry boxes,
+.BR top
+and
+.BR bot ,
+and copies the contents of one to the other whenever a newline is typed.
+.PP
+.EX
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <control.h>
+.sp 0.4v
+Controlset *cs;
+.sp 0.4v
+int ctldeletequits = 1;
+.sp 0.4v
+void
+resizecontrolset(Controlset*)
+{
+ int i;
+ Rectangle r, r1, r2;
+.sp 0.4v
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("resize failed: %r");
+ r = insetrect(screen->r, 10);
+ r1 = r;
+ r2 = r;
+ r1.max.y = r1.min.y+1+font->height+1;
+ r2.min.y = r1.max.y+10;
+ r2.max.y = r2.min.y+1+font->height+1;
+ chanprint(cs->ctl, "top rect %R\entop show", r1);
+ chanprint(cs->ctl, "bot rect %R\enbot show", r2);
+}
+.sp 0.4v
+void
+threadmain(int argc, char *argv[])
+{
+ char *s, *args[3];
+ Channel *c;
+ Control *top, *bot;
+ int n;
+.sp 0.4v
+ initdraw(0, 0, "example");
+ initcontrols();
+ cs = newcontrolset(screen, nil, nil, nil);
+ cs->clicktotype = 1;
+.sp 0.4v
+ top = createentry(cs, "top");
+ chanprint(cs->ctl, "top image paleyellow");
+ chanprint(cs->ctl, "top border 1");
+ bot = createentry(cs, "bot");
+ chanprint(cs->ctl, "bot image paleyellow");
+ chanprint(cs->ctl, "bot border 1");
+.sp 0.4v
+ c = chancreate(sizeof(char*), 0);
+ controlwire(top, "event", c);
+ controlwire(bot, "event", c);
+.sp 0.4v
+ activate(top);
+ activate(bot);
+ resizecontrolset(cs);
+.sp 0.4v
+ for(;;){
+ s = recvp(c);
+ n = tokenize(s, args, nelem(args));
+ if(n==3 && strcmp(args[1], "value")==0){
+ if(strcmp(args[0], "top:") == 0)
+ chanprint(cs->ctl, "bot value %q", args[2]);
+ else
+ chanprint(cs->ctl, "top value %q", args[2]);
+ }
+ }
+ threadexitsall(nil);
+}
+.EE
+.PP
+A richer variant couples a text entry box to a slider.
+Since the value of a slider is its numerical setting, as a decimal number,
+all that needs changing is the setup of
+.BR bot :
+.PP
+.EX
+ bot = createslider(cs, "bot");
+ chanprint(cs->ctl, "bot border 1");
+ chanprint(cs->ctl, "bot image paleyellow");
+ chanprint(cs->ctl, "bot indicatorcolor red");
+ chanprint(cs->ctl, "bot max 100");
+ chanprint(cs->ctl, "bot clamp low 1");
+ chanprint(cs->ctl, "bot orient horizontal");
+.EE
+.PP
+The rest is the same.
+Of course, the value of the entry box is only meaningful to the slider
+if it is also a decimal number.
+.PP
+Finally, we can avoid processing events altogether by cross-coupling
+the controls. Replace the rest of
+.B threadmain
+with this:
+.PP
+.EX
+ chanprint(cs->ctl, "bot format %q", "%q: top value %q");
+ chanprint(cs->ctl, "top format %q", "%q: bot value %q");
+.sp 0.4v
+ controlwire(top, "event", cs->ctl);
+ controlwire(bot, "event", cs->ctl);
+.sp 0.4v
+ activate(top);
+ activate(bot);
+ resizecontrolset(cs);
+.sp 0.4v
+ for(;;)
+ yield();
+ threadexitsall(nil);
+.EE
+.SH SOURCE
+.B /sys/src/libcontrol
+.SH SEE ALSO
+.IR draw (2),
+.IR frame (2),
+.IR graphics (2),
+.IR quote (2),
+.IR thread (2)
+.SH BUGS
+The library is strict about matters of formatting, argument count in messages,
+etc., and calls
+.I ctlerror
+in situations where it may be fine to ignore the error and continue.
diff --git a/sys/man/2/cputime b/sys/man/2/cputime
new file mode 100755
index 000000000..8b122bb72
--- /dev/null
+++ b/sys/man/2/cputime
@@ -0,0 +1,60 @@
+.TH CPUTIME 2
+.SH NAME
+cputime, times, cycles \- cpu time in this process and children
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLdouble 'u
+.B
+int times(long t[4])
+.PP
+.B
+double cputime(void)
+.PP
+.B
+void cycles(vlong *cyclep)
+.SH DESCRIPTION
+If
+.I t
+is non-null,
+.I times
+fills it in
+with the number of milliseconds spent in user code, system calls,
+child processes in user code, and child processes in system calls.
+.I Cputime
+returns the sum of those same times, converted to seconds.
+.I Times
+returns the elapsed real time, in milliseconds, that the process has been running.
+.PP
+These functions read
+.BR /dev/cputime ,
+opening that file when they are first called.
+.PP
+.I Cycles
+reads the processor's timestamp counter of cycles since reset,
+if any, and stores it via
+.IR cyclep .
+Currently supported architectures are
+.BR 386 ,
+.BR amd64 ,
+and
+.BR power ;
+on all others,
+.I cycles
+will store zero.
+.SH SOURCE
+.B /sys/src/libc/9sys
+.br
+.B /sys/src/libc/*/cycles.[cs]
+.SH SEE ALSO
+.IR exec (2),
+.IR cons (3)
+.SH BUGS
+Only
+.B 386
+processors starting with the Pentium have timestamp counters;
+calling
+.I cycles
+on earlier processors may execute an illegal instruction.
diff --git a/sys/man/2/ctime b/sys/man/2/ctime
new file mode 100755
index 000000000..a4e074343
--- /dev/null
+++ b/sys/man/2/ctime
@@ -0,0 +1,129 @@
+.TH CTIME 2
+.SH NAME
+ctime, localtime, gmtime, asctime, tm2sec, timezone \- convert date and time
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLchar* 'u
+.B
+char* ctime(long clock)
+.PP
+.B
+Tm* localtime(long clock)
+.PP
+.B
+Tm* gmtime(long clock)
+.PP
+.B
+char* asctime(Tm *tm)
+.PP
+.B
+long tm2sec(Tm *tm)
+.PP
+.B
+/env/timezone
+.SH DESCRIPTION
+.I Ctime
+converts a time
+.I clock
+such as returned by
+.IR time (2)
+into
+.SM ASCII
+(sic)
+and returns a pointer to a
+30-byte string
+in the following form.
+All the fields have constant width.
+.PP
+.B
+ Wed Aug 5 01:07:47 EST 1973\en\e0
+.PP
+.I Localtime
+and
+.I gmtime
+return pointers to structures containing
+the broken-down time.
+.I Localtime
+corrects for the time zone and possible daylight savings time;
+.I gmtime
+converts directly to GMT.
+.I Asctime
+converts a broken-down time to
+.SM ASCII
+and returns a pointer
+to a 30-byte string.
+.IP
+.EX
+.ta 6n +\w'char 'u +\w'zone[4]; 'u
+typedef
+struct {
+ int sec; /* seconds (range 0..59) */
+ int min; /* minutes (0..59) */
+ int hour; /* hours (0..23) */
+ int mday; /* day of the month (1..31) */
+ int mon; /* month of the year (0..11) */
+ int year; /* year A.D. \- 1900 */
+ int wday; /* day of week (0..6, Sunday = 0) */
+ int yday; /* day of year (0..365) */
+ char zone[4]; /* time zone name */
+ int tzoff; /* time zone delta from GMT */
+} Tm;
+.EE
+.PP
+.I Tm2sec
+converts a broken-down time to
+seconds since the start of the epoch.
+It ignores
+.BR wday ,
+and assumes the local time zone
+if
+.B zone
+is not
+.BR GMT .
+.PP
+When local time is first requested,
+the program consults the
+.B timezone
+environment variable to determine the time zone and
+converts accordingly.
+(This variable is set at system boot time by
+.IR init (8).)
+The
+.B timezone
+variable contains
+the normal time zone name and its difference from GMT
+in seconds followed by an alternate (daylight) time zone name and
+its difference followed by a newline.
+The remainder is a list of pairs of times
+(seconds past the start of 1970, in the first time zone)
+when the alternate time zone applies.
+For example:
+.IP
+.EX
+EST -18000 EDT -14400
+ 9943200 25664400 41392800 57718800 ...
+.EE
+.PP
+Greenwich Mean Time is represented by
+.IP
+.EX
+GMT 0
+.EE
+.SH SOURCE
+.B /sys/src/libc/9sys
+.SH "SEE ALSO"
+.IR date (1),
+.IR time (2),
+.IR init (8)
+.SH BUGS
+The return values point to static data
+whose content is overwritten by each call.
+.br
+Daylight Savings Time is ``normal'' in the Southern hemisphere.
+.br
+These routines are not equipped to handle non-\c
+.SM ASCII
+text, and are provincial anyway.
diff --git a/sys/man/2/ctype b/sys/man/2/ctype
new file mode 100755
index 000000000..5a8bc864d
--- /dev/null
+++ b/sys/man/2/ctype
@@ -0,0 +1,160 @@
+.TH CTYPE 2
+.SH NAME
+isalpha, isupper, islower, isdigit, isxdigit, isalnum, isspace, ispunct, isprint, isgraph, iscntrl, isascii, toascii, _toupper, _tolower, toupper, tolower \- ASCII character classification
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <ctype.h>
+.PP
+.if t .2C
+.B isalpha(c)
+.PP
+.B isupper(c)
+.PP
+.B islower(c)
+.PP
+.B isdigit(c)
+.PP
+.B isxdigit(c)
+.PP
+.B isalnum(c)
+.PP
+.B isspace(c)
+.PP
+.B ispunct(c)
+.PP
+.B isprint(c)
+.PP
+.B isgraph(c)
+.PP
+.B iscntrl(c)
+.PP
+.B isascii(c)
+.PP
+.B _toupper(c)
+.PP
+.B _tolower(c)
+.PP
+.B toupper(c)
+.PP
+.B tolower(c)
+.PP
+.B toascii(c)
+.if t .1C
+.SH DESCRIPTION
+These macros classify
+.SM ASCII\c
+-coded integer values
+by table lookup.
+Each is a predicate returning nonzero for true,
+zero for false.
+.I Isascii
+is defined on all integer values; the rest
+are defined only where
+.I isascii
+is true and on the single non-\c
+.SM ASCII
+value
+.BR EOF ;
+see
+.IR fopen (2).
+.TP "\w'isalnum 'u"
+.I isalpha
+.I c
+is a letter, a\-z or A\-Z
+.TP
+.I isupper
+.I c
+is an upper case letter, A\-Z
+.TP
+.I islower
+.I c
+is a lower case letter, a\-z
+.TP
+.I isdigit
+.I c
+is a digit, 0\-9
+.TP
+.I isxdigit
+.I c
+is a hexadecimal digit, 0\-9 or a\-f or A\-F
+.TP
+.I isalnum
+.I c
+is an alphanumeric character, a\-z or A\-Z or 0\-9
+.TP
+.I isspace
+.I c
+is a space, horizontal tab, newline, vertical tab, formfeed, or carriage return
+(0x20, 0x9, 0xA, 0xB, 0xC, 0xD)
+.TP
+.I ispunct
+.I c
+is a punctuation character
+(one of
+.L
+!"#$%&'()*+,-./:;<=>?@[\e]^_`{|}~\fR)
+.TP
+.I isprint
+.I c
+is a printing character, 0x20 (space)
+through 0x7E (tilde)
+.TP
+.I isgraph
+.I c
+is a visible printing character, 0x21 (exclamation) through 0x7E
+(tilde)
+.TP
+.I iscntrl
+.I c
+is a delete character, 0x7F,
+or ordinary control character, 0x0 through 0x1F
+.TP
+.I isascii
+.I c
+is an
+.SM ASCII
+character, 0x0 through 0x7F
+.PP
+.I Toascii
+is not a classification macro;
+it converts its argument to
+.SM ASCII
+range by
+.IR and ing
+with 0x7F.
+.PP
+If
+.I c
+is an upper case letter,
+.I tolower
+returns the lower case version of the character;
+otherwise it returns the original character.
+.I Toupper
+is similar, returning the upper case version of a character
+or the original character.
+.I Tolower
+and
+.I toupper
+are functions;
+.I _tolower
+and
+.I _toupper
+are corresponding macros which should only be used when it
+is known that the argument is upper case or lower case, respectively.
+.SH SOURCE
+.TF /sys/src/libc/port/ctype.c
+.TP
+.B /sys/include/ctype.h
+for the macros.
+.TP
+.B /sys/src/libc/port/ctype.c
+for the tables.
+.SH "SEE ALSO
+.IR isalpharune (2)
+.SH BUGS
+These macros are
+.SM ASCII\c
+-centric.
diff --git a/sys/man/2/debugger b/sys/man/2/debugger
new file mode 100755
index 000000000..5a2ec634f
--- /dev/null
+++ b/sys/man/2/debugger
@@ -0,0 +1,386 @@
+.TH DEBUGGER 2
+.SH NAME
+cisctrace, risctrace, ciscframe, riscframe, localaddr, symoff,
+fpformat, beieee80ftos, beieeesftos, beieeedftos, leieee80ftos,
+leieeesftos, leieeedftos, ieeesftos, ieeedftos \- machine-independent debugger functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bio.h>
+.br
+.B #include <mach.h>
+.PP
+.ta \w'\fLmachines 'u
+.nf
+.B
+int cisctrace(Map *map, ulong pc, ulong sp, ulong link,
+.B
+ Tracer trace)
+.PP
+.nf
+.B
+int risctrace(Map *map, ulong pc, ulong sp, ulong link,
+.B
+ Tracer trace)
+.PP
+.nf
+.B
+ulong ciscframe(Map *map, ulong addr, ulong pc, ulong sp,
+.B
+ ulong link)
+.PP
+.nf
+.B
+ulong riscframe(Map *map, ulong addr, ulong pc, ulong sp,
+.B
+ ulong link)
+.PP
+.nf
+.B
+int localaddr(Map *map, char *fn, char *var, long *ret,
+.B
+ Rgetter rget)
+.PP
+.B
+int symoff(char *buf, int n, long addr, int type)
+.PP
+.B
+int fpformat(Map *map, Reglist *rp, char *buf, int n, int code)
+.PP
+.B
+int beieee80ftos(char *buf, int n, void *fp)
+.PP
+.B
+int beieeesftos(char *buf, int n, void *fp)
+.PP
+.B
+int beieeedftos(char *buf, int n, void *fp)
+.PP
+.B
+int leieee80ftos(char *buf, int n, void *fp)
+.PP
+.B
+int leieeesftos(char *buf, int n, void *fp)
+.PP
+.B
+int leieeedftos(char *buf, int n, void *fp)
+.PP
+.B
+int ieeesftos(char *buf, int n, ulong f)
+.PP
+.B
+int ieeedftos(char *buf, int n, ulong high, ulong low)
+.PP
+.B
+extern Machdata *machdata;
+.SH DESCRIPTION
+These functions provide machine-independent implementations
+of common debugger functions.
+Many of the functions assume that global variables
+.I mach
+and
+.I machdata
+point to the
+.I Mach
+and
+.I Machdata
+data structures describing the target architecture.
+The former contains machine parameters and a description of
+the register set; it is usually
+set by invoking
+.I crackhdr
+(see
+.IR mach (2))
+to interpret the header of an executable.
+The
+.I Machdata
+structure
+is primarily a jump table specifying
+functions appropriate for processing an
+executable image for a given architecture.
+Each application is responsible for setting
+.I machdata
+to the address of the
+.I Machdata
+structure for the target architecture.
+Many of the functions described here are not
+called directly; instead, they are invoked
+indirectly through the
+.I Machdata
+jump table.
+.PP
+These functions must retrieve data and register contents
+from an executing image. The
+.I Map
+(see
+.IR mach (2))
+data structure
+supports the consistent retrieval of data, but
+no uniform access mechanism exists for registers.
+The application passes the address of a register
+retrieval function as an argument to those functions
+requiring register values.
+This function, called an
+.IR Rgetter ,
+is of the form
+.PP
+.RS
+.B "ulong rget(Map *map, char *name);
+.RE
+.PP
+It returns the contents of a register when given
+the address of a
+.I Map
+associated with an executing image and the name of the register.
+.PP
+.I Cisctrace
+and
+.I risctrace
+unwind the stack for up to 40 levels or until the frame for
+.I main
+is found. They return the
+count of the number of levels unwound. These functions
+process stacks conforming to the generic compiler model for
+.SM RISC
+and
+.SM CISC
+architectures, respectively.
+.I Map
+is the address of a
+.I Map
+data structure associated with the image
+of an executing process.
+.IR Sp ,
+.I pc
+and
+.I link
+are starting values for the stack pointer, program counter, and
+link register from which the unwinding is to take place. Normally, they are
+the current contents of the appropriate
+registers but they can be any values defining a legitimate
+process context, for example, an alternate stack in a
+multi-threaded process.
+.I Trace
+is the address of an application-supplied function to be called
+on each iteration as the frame unwinds. The prototype of this
+function is:
+.PP
+.RS
+.B "void tracer(Map *map, ulong pc, ulong fp, Symbol *s);
+.RE
+.PP
+where
+.I Map
+is the
+.I Map
+pointer passed to
+.I cisctrace
+or
+.I risctrace
+and
+.I pc
+and
+.I fp
+are the program counter and frame pointer.
+.I S
+is the address of a
+.I Symbol
+structure, as defined in
+.IR symbol (2),
+containing the symbol table information for the
+function owning the frame (i.e., the function that
+caused the frame to be instantiated).
+.PP
+.I Ciscframe
+and
+.I riscframe
+calculate the frame pointer associated with
+a function. They are suitable for
+programs conforming to the
+.SM CISC
+and
+.SM RISC
+stack models.
+.I Map
+is the address of a
+.I Map
+associated with the memory image of an executing
+process.
+.I Addr
+is the entry point of the desired function.
+.IR Pc ,
+.I sp
+and
+.I link
+are the program counter, stack pointer and link register of
+an execution context. As with the stack trace
+functions, these can be the current values of the
+registers or any legitimate execution context.
+The value of the frame pointer is returned. A return
+value of zero indicates an error.
+.PP
+.I Localaddr
+fills the location
+pointed to by
+.I ret
+with the address of a local variable.
+.I Map
+is the address of a
+.I Map
+associated with an executing memory image.
+.I Fn
+and
+.I var
+are pointers to the names of the function and variable of interest.
+.I Rget
+is the address of a register retrieval function.
+If both
+.I fn
+and
+.I var
+are non-zero, the frame for function
+.I fn
+is calculated and the address of the automatic or
+argument named
+.I var
+in that frame is returned.
+If
+.I var
+is zero, the address of the
+frame for function
+.I fn
+is returned.
+In all cases, the frame for the function named
+.I fn
+must be instantiated somewhere on the current stack.
+If there are multiple frames for the function (that is, if
+it is recursive), the most recent frame is used.
+The search starts from the context defined by the
+current value of the program counter and stack pointer.
+If a valid address is found,
+.I localaddr
+returns 1. A negative return indicates an error in
+resolving the address.
+.PP
+.I Symoff
+converts a virtual address to a symbolic reference. The
+string containing that reference is of
+the form `name+offset', where `name' is the name of the
+nearest symbol with an address less than
+or equal to the target address and `offset' is the hexadecimal offset
+beyond that symbol. If `offset' is zero, only the name of
+the symbol is printed. If no symbol is found within 4,096
+bytes of the address, the address is formatted as a hexadecimal
+address.
+.I Buf
+is the address of a buffer of
+.I n
+characters to receive the formatted string.
+.I Addr
+is the address to be converted.
+.I Type
+is the type code of the search space:
+.BR CTEXT ,
+.BR CDATA ,
+or
+.BR CANY .
+.I Symoff
+returns the length of the formatted string contained in
+.IR buf .
+.PP
+.I Fpformat
+converts the contents of a floating point register to a
+string.
+.I Map
+is the address of a
+.I Map
+associated with an executing process.
+.I Rp
+is the address of a
+.I Reglist
+data structure describing the desired register.
+.I Buf
+is the address of a buffer of
+.I n
+characters to hold the resulting string.
+.I Code
+must be either
+.B F
+or
+.BR f,
+selecting double
+or single precision, respectively. If
+.I code
+is
+.BR F ,
+the contents of the specified register and
+the following register
+are interpreted as a double precision floating point
+number; this
+is only meaningful for architectures that implement
+double precision floats by combining adjacent
+single precision registers.
+For
+.I code
+.BR f ,
+the specified register is formatted
+as a single precision float.
+.I Fpformat
+returns 1 if the number is successfully converted or \-1
+in the case of an error.
+.PP
+.IR Beieee80ftos ,
+.I beieeesftos
+and
+.I beieeedftos
+convert big-endian 80-bit extended, 32-bit single precision,
+and 64-bit double precision floating point values to
+a string.
+.IR Leieee80ftos ,
+.IR leieeesftos ,
+and
+.I leieeedftos
+are the little-endian counterparts.
+.I Buf
+is the address of a buffer of
+.I n
+characters to receive the formatted string.
+.I Fp
+is the address of the floating point value to be
+converted. These functions return the length of
+the resulting string.
+.PP
+.I Ieeesftos
+converts the 32-bit single precision floating point value
+.IR f ,
+to a string in
+.IR buf ,
+a buffer of
+.I n
+bytes. It returns the length of the resulting string.
+.PP
+.I Ieeedftos
+converts a 64-bit double precision floating point value
+to a character string.
+.I Buf
+is the address of a buffer of
+.I n
+characters to hold the resulting string.
+.I High
+and
+.I low
+contain the most and least significant 32 bits of
+the floating point value, respectively.
+.I Ieeedftos
+returns the number of characters in the resulting string.
+.SH SOURCE
+.B /sys/src/libmach
+.SH "SEE ALSO"
+.IR mach (2),
+.IR symbol (2),
+.IR errstr (2)
+.SH DIAGNOSTICS
+Set
+.IR errstr .
diff --git a/sys/man/2/des b/sys/man/2/des
new file mode 100755
index 000000000..be25d399b
--- /dev/null
+++ b/sys/man/2/des
@@ -0,0 +1,149 @@
+.TH DES 2
+.SH NAME
+setupDESstate, des_key_setup, block_cipher, desCBCencrypt, desCBCdecrypt, desECBencrypt, desECBdecrypt, des3CBCencrypt, des3CBCdecrypt, des3ECBencrypt, des3ECBdecrypt, key_setup, des56to64, des64to56, setupDES3state, triple_block_cipher - single and triple digital encryption standard
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+void des_key_setup(uchar key[8], ulong schedule[32])
+.PP
+.B
+void block_cipher(ulong *schedule, uchar *data, int decrypting)
+.PP
+.B
+void setupDESstate(DESstate *s, uchar key[8], uchar *ivec)
+.PP
+.B
+void desCBCencrypt(uchar *p, int len, DESstate *s)
+.PP
+.B
+void desCBCdecrypt(uchar *p, int len, DESstate *s)
+.PP
+.B
+void desECBencrypt(uchar *p, int len, DESstate *s)
+.PP
+.B
+void desECBdecrypt(uchar *p, int len, DESstate *s)
+.PP
+.in +0.5i
+.ti -0.5i
+.B
+void triple_block_cipher(ulong expanded_key[3][32], uchar text[8], int ende)
+.PP
+.B
+void setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec)
+.PP
+.B
+void des3CBCencrypt(uchar *p, int len, DES3state *s)
+.PP
+.B
+void des3CBCdecrypt(uchar *p, int len, DES3state *s)
+.PP
+.B
+void des3ECBencrypt(uchar *p, int len, DES3state *s)
+.PP
+.B
+void des3ECBdecrypt(uchar *p, int len, DES3state *s)
+.PP
+.B
+void key_setup(uchar[7], ulong[32])
+.PP
+.B
+void des56to64(uchar *k56, uchar *k64)
+.PP
+.B
+void des64to56(uchar *k64, uchar *k56)
+.SH DESCRIPTION
+The Digital Encryption Standard (DES)
+is a shared-key or symmetric encryption algorithm using either
+a 56-bit key for single DES or three 56-bit keys for triple DES.
+The keys are encoded into 64 bits where every eight bit
+is parity.
+.PP
+The basic DES function,
+.IR block_cipher ,
+works on a block of 8 bytes, converting them in place.
+It takes a key schedule, a pointer to the block, and
+a flag indicating encrypting (0) or decrypting (1).
+The key schedule is created from the key using
+.IR des_key_setup .
+.PP
+Since it is a bit awkward,
+.I block_cipher
+is rarely called directly. Instead, one normally uses
+routines that encrypt larger buffers of data and
+which may chain the encryption state from one buffer
+to the next.
+These routines keep track of the state of the
+encryption using a
+.B DESstate
+structure that contains the key schedule and any chained
+state.
+.I SetupDESstate
+sets up the
+.B DESstate
+structure using the key and an 8-byte initialization vector.
+.PP
+Electronic code book, using
+.I desECBencrypt
+and
+.IR desECBdecrypt ,
+is the less secure mode. The encryption of each 8 bytes
+does not depend on the encryption of any other.
+Hence the encryption is a substitution
+cipher using 64 bit characters.
+.PP
+Cipher block chaining mode, using
+.I desCBCencrypt
+and
+.IR desCBCdecrypt ,
+is more secure. Every block encrypted depends on the initialization
+vector and all blocks encrypted before it.
+.PP
+For both CBC and ECB modes, a stream of data can be encrypted as
+multiple buffers. However, all buffers except the last must
+be a multiple of 8 bytes to ensure successful decryption of
+the stream.
+.PP
+There are equivalent triple-DES (DES3-EDE) functions for each of the
+DES functions.
+.PP
+In the past, Plan 9 used a 56-bit or 7-byte
+format for DES keys. To be compatible with the rest
+of the world, we've abandoned this format.
+There are two functions,
+.I des56to64
+and
+.IR des64to56 ,
+to convert back and forth between the two formats.
+Also a key schedule can be set up from the 7-byte format using
+.IR key_setup .
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR mp (2),
+.IR aes (2),
+.IR blowfish (2),
+.IR dsa (2),
+.IR elgamal (2),
+.IR rc4 (2),
+.IR rsa (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2)
+.br
+.IR "Breaking DES" ,
+Electronic Frontier Foundation,
+O'Reilly, 1998
+.SH BUGS
+Single DES can be realistically broken by brute-force;
+its 56-bit key is just too short.
+It should not be used in new code, which should probably use
+.IR aes (2)
+instead, or at least triple DES.
diff --git a/sys/man/2/dial b/sys/man/2/dial
new file mode 100755
index 000000000..0d76065f8
--- /dev/null
+++ b/sys/man/2/dial
@@ -0,0 +1,333 @@
+.TH DIAL 2
+.SH NAME
+dial, hangup, announce, listen, accept, reject, netmkaddr, setnetmtpt, getnetconninfo, freenetconninfo \- make and break network connections
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int dial(char *addr, char *local, char *dir, int *cfdp)
+.PP
+.B
+int hangup(int ctl)
+.PP
+.B
+int announce(char *addr, char *dir)
+.PP
+.B
+int listen(char *dir, char *newdir)
+.PP
+.B
+int accept(int ctl, char *dir)
+.PP
+.B
+int reject(int ctl, char *dir, char *cause)
+.PP
+.B
+char* netmkaddr(char *addr, char *defnet, char *defservice)
+.PP
+.B
+void setnetmtpt(char *to, int tolen, char *from)
+.PP
+.B
+NetConnInfo* getnetconninfo(char *conndir, int fd)
+.PP
+.B
+void freenetconninfo(NetConnInfo*)
+.SH DESCRIPTION
+For these routines,
+.I addr
+is a network address of the form
+.IB network ! netaddr ! service\f1,
+.IB network ! netaddr\f1,
+or simply
+.IR netaddr .
+.I Network
+is any directory listed in
+.B /net
+or the special token,
+.BR net .
+.B Net
+is a free variable that stands for any network in common
+between the source and the host
+.IR netaddr .
+.I Netaddr
+can be a host name, a domain name, a network address,
+or a meta-name of the form
+.BI $ attribute\f1,
+which
+is replaced by
+.I value
+from the value-attribute pair
+.IB attribute = value
+most closely associated with the source host in the
+network data base (see
+.IR ndb (6)).
+.PP
+If a connection attempt is successful and
+.I dir
+is non-zero,
+the path name of a
+.I line directory
+that has files for accessing the connection
+is copied into
+.IR dir .
+The path name is guaranteed to be less than 40
+bytes long.
+One line directory exists for each possible connection.
+The
+.B data
+file in the line directory should be used to communicate with the destination.
+The
+.B ctl
+file in the line directory can be used to send commands to the line.
+See
+.IR ip (3)
+for messages that can be written to the
+.B ctl
+file.
+The last close of the
+.B data
+or
+.B ctl
+file will close the connection.
+.PP
+.I Dial
+makes a call to destination
+.I addr
+on a multiplexed network.
+If the network in
+.I addr
+is
+.BR net ,
+.I dial
+will try in parallel all addresses on
+networks in common between source and destination
+until a call succeeds.
+It returns a file descriptor open for reading and writing the
+.B data
+file in the line directory.
+The
+.B addr
+file in the line directory contains the address called.
+If the network allows the local address to be set,
+as is the case with UDP and TCP port numbers, and
+.IR local
+is non-zero, the local address will be set to
+.IR local .
+If
+.I cfdp
+is non-zero,
+.BI * cfdp
+is set to a file descriptor open for reading and
+writing the control file.
+.PP
+.I Hangup
+is a means of forcing a connection to hang up without
+closing the
+.B ctl
+and
+.B data
+files.
+.P
+.I Announce
+and
+.I listen
+are the complements of
+.IR dial .
+.I Announce
+establishes a network
+name to which calls can be made.
+Like
+.IR dial ,
+.I announce
+returns an open
+.B ctl
+file.
+The
+.I netaddr
+used in announce may be a local address or an asterisk,
+to indicate all local addresses, e.g.
+.BR tcp!*!echo .
+The
+.I listen
+routine takes as its first argument the
+.I dir
+of a previous
+.IR announce .
+When a call is received,
+.I listen
+returns an open
+.B ctl
+file for the line the call was received on.
+It sets
+.I newdir
+to the path name of the new line directory.
+.I Accept
+accepts a call received by
+.IR listen ,
+while
+.I reject
+refuses the call because of
+.IR cause .
+.I Accept
+returns a file descriptor for the data file opened
+.BR ORDWR .
+.PP
+.I Netmkaddr
+makes an address suitable for dialing or announcing.
+It takes an address along with a default network and service to use
+if they are not specified in the address.
+It returns a pointer to static data holding the actual address to use.
+.PP
+.I Getnetconninfo
+returns a structure containing information about a
+network connection. The structure is:
+.EX
+ typedef struct NetConnInfo NetConnInfo;
+ struct NetConnInfo
+ {
+ char *dir; /* connection directory */
+ char *root; /* network root */
+ char *spec; /* binding spec */
+ char *lsys; /* local system */
+ char *lserv; /* local service */
+ char *rsys; /* remote system */
+ char *rserv; /* remote service */
+ char *laddr; /* local address */
+ char *raddr; /* remote address */
+ };
+.EE
+.PP
+The information is obtained from the connection directory,
+.IR conndir .
+If
+.I conndir
+is nil, the directory is obtained by performing
+.IR fd2path (2)
+on
+.IR fd .
+.I Getnetconninfo
+returns either a completely specified structure, or
+nil if either the structure can't be allocated or the
+network directory can't be determined.
+The structure
+is freed using
+.IR freenetconninfo .
+.PP
+.I Setnetmtpt
+copies the name of the network mount point into
+the buffer
+.IR to ,
+whose length is
+.IR tolen .
+It exists to merge two pre-existing conventions for specifying
+the mount point.
+Commands that take a network mount point as a parameter
+(such as
+.BR dns ,
+.BR cs
+(see
+.IR ndb (8)),
+and
+.IR ipconfig (8))
+should now call
+.IR setnetmtpt .
+If
+.I from
+is
+.BR nil ,
+the mount point is set to the default,
+.BR /net .
+If
+.I from
+points to a string starting with a slash,
+the mount point is that path.
+Otherwise, the mount point is the string pointed to by
+.I from
+appended to the string
+.BR /net .
+The last form is obsolete and is should be avoided.
+It exists only to aid in conversion.
+.SH EXAMPLES
+Make a call and return an open file descriptor to
+use for communications:
+.IP
+.EX
+int callkremvax(void)
+{
+ return dial("kremvax", 0, 0, 0);
+}
+.EE
+.PP
+Call the local authentication server:
+.IP
+.EX
+int dialauth(char *service)
+{
+ return dial(netmkaddr("$auth", 0, service), 0, 0, 0);
+}
+.EE
+.PP
+Announce as
+.B kremvax
+on TCP/IP and
+loop forever receiving calls and echoing back
+to the caller anything sent:
+.IP
+.EX
+int
+bekremvax(void)
+{
+ int dfd, acfd, lcfd;
+ char adir[40], ldir[40];
+ int n;
+ char buf[256];
+
+ acfd = announce("tcp!*!7", adir);
+ if(acfd < 0)
+ return -1;
+ for(;;){
+ /* listen for a call */
+ lcfd = listen(adir, ldir);
+ if(lcfd < 0)
+ return -1;
+ /* fork a process to echo */
+ switch(fork()){
+ case -1:
+ perror("forking");
+ close(lcfd);
+ break;
+ case 0:
+ /* accept the call and open the data file */
+ dfd = accept(lcfd, ldir);
+ if(dfd < 0)
+ return -1;
+
+ /* echo until EOF */
+ while((n = read(dfd, buf, sizeof(buf))) > 0)
+ write(dfd, buf, n);
+ exits(0);
+ default:
+ close(lcfd);
+ break;
+ }
+ }
+}
+.EE
+.SH SOURCE
+.BR /sys/src/libc/9sys ,
+.B /sys/src/libc/port
+.SH "SEE ALSO"
+.IR auth (2),
+.IR ip (3),
+.IR ndb (8)
+.SH DIAGNOSTICS
+.IR Dial ,
+.IR announce ,
+and
+.I listen
+return \-1 if they fail.
+.I Hangup
+returns nonzero if it fails.
diff --git a/sys/man/2/dirread b/sys/man/2/dirread
new file mode 100755
index 000000000..6a3ad34c5
--- /dev/null
+++ b/sys/man/2/dirread
@@ -0,0 +1,103 @@
+.TH DIRREAD 2
+.SH NAME
+dirread, dirreadall \- read directory
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+long dirread(int fd, Dir **buf)
+.PP
+.B
+long dirreadall(int fd, Dir **buf)
+.PP
+.B
+#define STATMAX 65535U
+.PP
+.B
+#define DIRMAX (sizeof(Dir)+STATMAX)
+.SH DESCRIPTION
+The data returned by a
+.IR read (2)
+on a directory is a set of complete directory entries
+in a machine-independent format, exactly equivalent to
+the result of a
+.IR stat (2)
+on each file or subdirectory in the directory.
+.I Dirread
+decodes the directory entries into a machine-dependent form.
+It reads from
+.IR fd
+and unpacks the data into an array of
+.B Dir
+structures
+whose address is returned in
+.B *buf
+(see
+.IR stat (2)
+for the layout of a
+.BR Dir ).
+The array is allocated with
+.IR malloc (2)
+each time
+.I dirread
+is called.
+.PP
+.I Dirreadall
+is like
+.IR dirread ,
+but reads in the entire directory; by contrast,
+.I dirread
+steps through a directory one
+.IR read (2)
+at a time.
+.PP
+Directory entries have variable length.
+A successful
+.I read
+of a directory always returns an integral number of complete directory entries;
+.I dirread
+always returns complete
+.B Dir
+structures.
+See
+.IR read (5)
+for more information.
+.PP
+The constant
+.B STATMAX
+is the maximum size that a directory entry can occupy.
+The constant
+.B DIRMAX
+is an upper limit on the size necessary to hold a
+.B Dir
+structure and all the associated data.
+.PP
+.I Dirread
+and
+.I dirreadall
+return the number of
+.B Dir
+structures filled in
+.BR buf .
+The file offset is advanced by the number of bytes actually read.
+.SH SOURCE
+.B /sys/src/libc/9sys/dirread.c
+.SH SEE ALSO
+.IR intro (2),
+.IR open (2),
+.IR read (2)
+.SH DIAGNOSTICS
+.I Dirread
+and
+.I Dirreadall
+return zero for end of file and a negative value for error.
+In either case,
+.B *buf
+is set to
+.B nil
+so the pointer can always be freed with impunity.
+.PP
+These functions set
+.IR errstr .
diff --git a/sys/man/2/disk b/sys/man/2/disk
new file mode 100755
index 000000000..726131391
--- /dev/null
+++ b/sys/man/2/disk
@@ -0,0 +1,172 @@
+.TH DISK 2
+.SH NAME
+opendisk, Disk \- generic disk device interface
+.SH SYNOPSIS
+.nf
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <disk.h>
+.ft
+.PP
+.ft L
+typedef struct Disk {
+ char *prefix;
+ char part[NAMELEN];
+ int fd, wfd, ctlfd, rdonly;
+ int type;
+ vlong secs, secsize, size, offset;
+ int c, h, s;
+} Disk;
+.ft
+.PP
+.B
+Disk* opendisk(char *file, int rdonly, int noctl)
+.SH DESCRIPTION
+These routines provide a simple way to gather
+and use information about
+.IR floppy (3)
+and
+.IR sd (3)
+disks and disk partitions,
+as well as plain files.
+.PP
+.I Opendisk
+opens
+.I file
+for reading and stores the file descriptor in
+the
+.B fd
+field of the
+.B Disk
+structure.
+If
+.I rdonly
+is not set,
+.I opendisk
+also opens
+.I file
+for writing and stores that file descriptor in
+.BR wfd .
+The two file descriptors are kept separate to
+help prevent accidents.
+.PP
+If
+.I noctl
+is not set,
+.I opendisk
+looks for a
+.B ctl
+file in the same directory as the
+disk file;
+if it finds one, it declares
+the disk to be
+an
+.I sd
+device,
+setting the
+.B type
+field in the
+.B Disk
+structure
+to
+.BR Tsd .
+If the passed
+.I file
+is named
+.BI fd n disk \fR,
+it looks for a file
+.BI fd n ctl \fR,
+and if it finds that,
+declares the disk to be
+a floppy disk, of type
+.BR Tfloppy .
+If either
+control
+file is found, it is opened for reading
+and writing, and the resulting file descriptor
+is saved as
+.BR ctlfd .
+Otherwise the returned disk
+has type
+.BR Tfile .
+.PP
+.I Opendisk
+then stats the file and stores its length in
+.BR size .
+If the disk is an
+.I sd
+partition,
+.I opendisk
+reads the sector size from the
+control
+file and stores it in
+.BR secsize ;
+otherwise the sector size is assumed to be 512,
+as is the case for floppy disks.
+.I Opendisk
+then stores the disk size measured in sectors in
+.BR secs .
+.PP
+If the disk is an
+.I sd
+partition,
+.I opendisk
+parses the
+control
+file to find the partition's offset
+within its disk;
+otherwise it sets
+.B offset
+to zero.
+If the disk is an ATA disk,
+.I opendisk
+reads
+the disk geometry (number of cylinders, heads, and sectors)
+from the
+.B geometry
+line in the
+.I sd
+control file;
+otherwise it sets these to zero as well.
+.B Name
+is initialized with the base name of
+the disk partition, and is useful for forming messages to the
+.I sd
+control file.
+.B Prefix
+is set to the passed filename without
+the
+.B name
+suffix.
+.PP
+The IBM PC BIOS interface allocates
+10 bits for the number of cylinders, 8 for
+the number of heads, and 6 for the number of sectors per track.
+Disk geometries are not quite so simple
+anymore, but to keep the interface useful,
+modern disks and BIOSes present geometries
+that still fit within these constraints.
+These numbers are still used when partitioning
+and formatting disks.
+.I Opendisk
+employs a number of heuristics to discover this
+supposed geometry and store it in the
+.BR c ,
+.BR h ,
+and
+.B s
+fields.
+Disk offsets in partition tables and
+in FAT descriptors are stored in a form
+dependent upon these numbers, so
+.I opendisk
+works hard to report numbers that
+agree with those used by other operating
+systems; the numbers bear little or no resemblance
+to reality.
+.SH SOURCE
+.B /sys/src/libdisk/disk.c
+.SH SEE ALSO
+.IR floppy (3),
+.IR sd (3)
diff --git a/sys/man/2/draw b/sys/man/2/draw
new file mode 100755
index 000000000..2cda38ec4
--- /dev/null
+++ b/sys/man/2/draw
@@ -0,0 +1,821 @@
+.TH DRAW 2
+.SH NAME
+Image, draw, gendraw, drawreplxy, drawrepl,
+replclipr, line, poly, fillpoly, bezier, bezspline, fillbezier, fillbezspline, ellipse,
+fillellipse, arc, fillarc, icossin, icossin2, border, string, stringn,
+runestring, runestringn, stringbg, stringnbg, runestringbg,
+runestringnbg, _string, ARROW, drawsetdebug \- graphics functions
+.de PB
+.PP
+.ft L
+.nf
+..
+.SH SYNOPSIS
+.de PB
+.PP
+.ft L
+.nf
+..
+.PB
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+.PB
+typedef
+struct Image
+{
+ Display *display; /* display holding data */
+ int id; /* id of system-held Image */
+ Rectangle r; /* rectangle in data area, local coords */
+ Rectangle clipr; /* clipping region */
+ ulong chan; /* pixel channel format descriptor */
+ int depth; /* number of bits per pixel */
+ int repl; /* flag: data replicates to tile clipr */
+ Screen *screen; /* 0 if not a window */
+ Image *next; /* next in list of windows */
+} Image;
+.PB
+typedef enum
+{
+ /* Porter-Duff compositing operators */
+ Clear = 0,
+.sp 0.1
+ SinD = 8,
+ DinS = 4,
+ SoutD = 2,
+ DoutS = 1,
+.sp 0.1
+ S = SinD|SoutD,
+ SoverD = SinD|SoutD|DoutS,
+ SatopD = SinD|DoutS,
+ SxorD = SoutD|DoutS,
+.sp 0.1
+ D = DinS|DoutS,
+ DoverS = DinS|DoutS|SoutD,
+ DatopS = DinS|SoutD,
+ DxorS = DoutS|SoutD, /* == SxorD */
+.sp 0.1
+ Ncomp = 12,
+} Drawop;
+.PB
+.PD 0
+.ta +\w'\fL 'u +\w'\fL 'u +6n +4n
+void draw(Image *dst, Rectangle r, Image *src,
+ Image *mask, Point p)
+.PB
+void drawop(Image *dst, Rectangle r, Image *src,
+ Image *mask, Point p, Drawop op)
+.PB
+void gendraw(Image *dst, Rectangle r, Image *src, Point sp,
+ Image *mask, Point mp)
+.PB
+void gendrawop(Image *dst, Rectangle r, Image *src, Point sp,
+ Image *mask, Point mp, Drawop op)
+.PB
+int drawreplxy(int min, int max, int x)
+.PB
+Point drawrepl(Rectangle r, Point p)
+.PB
+void replclipr(Image *i, int repl, Rectangle clipr)
+.PB
+void line(Image *dst, Point p0, Point p1, int end0, int end1,
+ int radius, Image *src, Point sp)
+.PB
+void lineop(Image *dst, Point p0, Point p1, int end0, int end1,
+ int radius, Image *src, Point sp, Drawop op)
+.PB
+void poly(Image *dst, Point *p, int np, int end0, int end1,
+ int radius, Image *src, Point sp)
+.PB
+void polyop(Image *dst, Point *p, int np, int end0, int end1,
+ int radius, Image *src, Point sp, Drawop op)
+.PB
+void fillpoly(Image *dst, Point *p, int np, int wind,
+ Image *src, Point sp)
+.PB
+void fillpolyop(Image *dst, Point *p, int np, int wind,
+ Image *src, Point sp, Drawop op)
+.PB
+int bezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
+ int end0, int end1, int radius, Image *src, Point sp)
+.PB
+int bezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
+ int end0, int end1, int radius, Image *src, Point sp,
+ Drawop op)
+.PB
+int bezspline(Image *dst, Point *pt, int npt, int end0, int end1,
+ int radius, Image *src, Point sp)
+.PB
+int bezsplineop(Image *dst, Point *pt, int npt, int end0, int end1,
+ int radius, Image *src, Point sp, Drawop op)
+.PB
+int bezsplinepts(Point *pt, int npt, Point **pp)
+.PB
+int fillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
+ int w, Image *src, Point sp)
+.PB
+int fillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
+ int w, Image *src, Point sp, Drawop op)
+.PB
+int fillbezspline(Image *dst, Point *pt, int npt, int w,
+ Image *src, Point sp)
+.PB
+int fillbezsplineop(Image *dst, Point *pt, int npt, int w,
+ Image *src, Point sp, Drawop op)
+.PB
+void ellipse(Image *dst, Point c, int a, int b, int thick,
+ Image *src, Point sp)
+.PB
+void ellipseop(Image *dst, Point c, int a, int b, int thick,
+ Image *src, Point sp, Drawop op)
+.PB
+void fillellipse(Image *dst, Point c, int a, int b,
+ Image *src, Point sp)
+.PB
+void fillellipseop(Image *dst, Point c, int a, int b,
+ Image *src, Point sp, Drawop op)
+.PB
+void arc(Image *dst, Point c, int a, int b, int thick,
+ Image *src, Point sp, int alpha, int phi)
+.PB
+void arcop(Image *dst, Point c, int a, int b, int thick,
+ Image *src, Point sp, int alpha, int phi, Drawop op)
+.PB
+void fillarc(Image *dst, Point c, int a, int b, Image *src,
+ Point sp, int alpha, int phi)
+.PB
+void fillarcop(Image *dst, Point c, int a, int b, Image *src,
+ Point sp, int alpha, int phi, Drawop op)
+.PB
+int icossin(int deg, int *cosp, int *sinp)
+.PB
+int icossin2(int x, int y, int *cosp, int *sinp)
+.PB
+void border(Image *dst, Rectangle r, int i, Image *color, Point sp)
+.br
+.PB
+Point string(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s)
+.PB
+Point stringop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, Drawop op)
+.PB
+Point stringn(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, int len)
+.PB
+Point stringnop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, int len, Drawop op)
+.PB
+Point runestring(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r)
+.PB
+Point runestringop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, Drawop op)
+.PB
+Point runestringn(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, int len)
+.PB
+Point runestringnop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, int len, Drawop op)
+.PB
+Point stringbg(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, Image *bg, Point bgp)
+.PB
+Point stringbgop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, Image *bg, Point bgp, Drawop op)
+.PB
+Point stringnbg(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, int len, Image *bg, Point bgp)
+.PB
+Point stringnbgop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, char *s, int len, Image *bg, Point bgp, Drawop op)
+.PB
+Point runestringbg(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, Image *bg, Point bgp)
+.PB
+Point runestringbgop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, Image *bg, Point bgp, Drawop op)
+.PB
+Point runestringnbg(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, int len, Image *bg, Point bgp)
+.PB
+Point runestringnbgop(Image *dst, Point p, Image *src, Point sp,
+ Font *f, Rune *r, int len, Image *bg, Point bgp, Drawop op)
+.PB
+Point _string(Image *dst, Point p, Image *src,
+ Point sp, Font *f, char *s, Rune *r, int len,
+ Rectangle clipr, Image *bg, Point bgp, Drawop op)
+.PB
+void drawsetdebug(int on)
+.PD
+.PB
+enum
+{
+ /* line ends */
+ Endsquare = 0,
+ Enddisc = 1,
+ Endarrow = 2,
+ Endmask = 0x1F
+};
+.PB
+#define ARROW(a, b, c) (Endarrow|((a)<<5)|((b)<<14)|((c)<<23))
+.SH DESCRIPTION
+The
+.B Image
+type defines rectangular pictures and the methods to draw upon them;
+it is also the building block for higher level objects such as
+windows and fonts.
+In particular, a window is represented as an
+.BR Image ;
+no special operators are needed to draw on a window.
+.PP
+.TP 10
+.B r
+The coordinates of the rectangle in the plane for which the
+.B Image
+has defined pixel values.
+It should not be modified after the image is created.
+.TP
+.B clipr
+The clipping rectangle: operations that read or write
+the image will not access pixels outside
+.BR clipr .
+Frequently,
+.B clipr
+is the same as
+.BR r ,
+but it may differ; see in particular the discussion of
+.BR repl .
+The clipping region may be modified dynamically using
+.I replclipr
+.RI ( q.v. ).
+.TP
+.B chan
+The pixel channel format descriptor, as described in
+.IR image (6).
+The value should not be modified after the image is created.
+.TP
+.B depth
+The
+number of bits per pixel in the picture;
+it is identically
+.B chantodepth(chan)
+(see
+.IR graphics (2))
+and is provided as a convenience.
+The value should not be modified after the image is created.
+.TP
+.B repl
+A boolean value specifying whether the image is tiled to cover
+the plane when used as a source for a drawing operation.
+If
+.B repl
+is zero, operations are restricted to the intersection of
+.B r
+and
+.BR clipr .
+If
+.B repl
+is set,
+.B r
+defines the tile to be replicated and
+.B clipr
+defines the portion of the plane covered by the tiling, in other words,
+.B r
+is replicated to cover
+.BR clipr ;
+in such cases
+.B r
+and
+.B clipr
+are independent.
+.IP
+For example, a replicated image with
+.B r
+set to ((0,\ 0),\ (1,\ 1)) and
+.B clipr
+set to ((0,\ 0),\ (100,\ 100)),
+with the single pixel of
+.B r
+set to blue,
+behaves identically to an image with
+.B r
+and
+.B clipr
+both set to ((0,\ 0),\ (100,\ 100)) and all pixels set to blue.
+However,
+the first image requires far less memory.
+The replication flag may be modified dynamically using
+.I replclipr
+.RI ( q.v. ).
+.PP
+Most of the drawing functions come in two forms:
+a basic form, and an extended form that takes an extra
+.B Drawop
+to specify a Porter-Duff compositing operator to use.
+The basic forms assume the operator is
+.BR SoverD ,
+which suffices for the vast majority of applications.
+The extended forms are named by adding an
+.RB - op
+suffix to the basic form.
+Only the basic forms are listed below.
+.TP
+.BI draw( dst\fP,\fP\ r\fP,\fP\ src\fP,\fP\ mask\fP,\fP\ p )
+.I Draw
+is the standard drawing function.
+Only those pixels within the intersection of
+.IB dst ->r
+and
+.IB dst ->clipr
+will be affected;
+.I draw
+ignores
+.IB dst ->repl\fR.
+The operation proceeds as follows
+(this is a description of the behavior, not the implementation):
+.RS
+.IP 1.
+If
+.B repl
+is set in
+.I src
+or
+.IR mask ,
+replicate their contents to fill
+their clip rectangles.
+.IP 2.
+Translate
+.I src
+and
+.I mask
+so
+.I p
+is aligned with
+.IB r .min\fR.
+.IP 3.
+Set
+.I r
+to the intersection of
+.I r
+and
+.IB dst ->r\fR.
+.IP 4.
+Intersect
+.I r
+with
+.IB src ->clipr\fR.
+If
+.IB src ->repl
+is false, also intersect
+.I r
+with
+.IB src ->r\fR.
+.IP 5.
+Intersect
+.I r
+with
+.IB mask ->clipr\fR.
+If
+.IB mask ->repl
+is false, also intersect
+.I r
+with
+.IB mask ->r\fR.
+.IP 6.
+For each location in
+.IR r ,
+combine the
+.I dst
+pixel with the
+.I src
+pixel using the alpha value
+corresponding to the
+.I mask
+pixel.
+If the
+.I mask
+has an explicit alpha channel, the alpha value
+corresponding to the
+.I mask
+pixel is simply that pixel's alpha channel.
+Otherwise, the alpha value is the NTSC greyscale equivalent
+of the color value, with white meaning opaque and black transparent.
+In terms of the Porter-Duff compositing algebra,
+.I draw
+replaces the
+.I dst
+pixels with
+.RI ( src
+in
+.IR mask )
+over
+.IR dst .
+(In the extended form,
+``over'' is replaced by
+.IR op ).
+.RE
+.IP
+The various
+pixel channel formats
+involved need not be identical.
+If the channels involved are smaller than 8-bits, they will
+be promoted before the calculation by replicating the extant bits;
+after the calculation, they will be truncated to their proper sizes.
+.TP
+\f5gendraw(\f2dst\fP, \f2r\fP, \f2src\fP, \f2p0\fP, \f2mask\fP, \f2p1\f5)\fP
+Similar to
+.I draw
+except that
+.I gendraw
+aligns the source and mask differently:
+.I src
+is aligned so
+.I p0
+corresponds to
+.IB r .min
+and
+.I mask
+is aligned so
+.I p1
+corresponds to
+.IB r .min .
+For most purposes with simple masks and source images,
+.B draw
+is sufficient, but
+.B gendraw
+is the general operator and the one all other drawing primitives are built upon.
+.TP
+.BI drawreplxy( min , max , x\f5)
+Clips
+.I x
+to be in the half-open interval [\fImin\fP, \fImax\fP) by adding
+or subtracting a multiple of \fImax-min\fP.
+.TP
+.BI drawrepl( r , p )
+Clips the point \fIp\fP to be within the rectangle \fIr\fP
+by translating the point horizontally by an integer multiple of rectangle width
+and vertically by the height.
+.TP
+.BI replclipr( i , repl , clipr\f5)
+Because the image data is stored on the server, local modifications to the
+.B Image
+data structure itself will have no effect.
+.I Repclipr
+modifies the local
+.B Image
+data structure's
+.B repl
+and
+.B clipr
+fields, and notifies the server of their modification.
+.TP
+\f5line(\f2dst\fP, \f2p0\fP, \f2p1\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
+Line
+draws in
+.I dst
+a line of width
+.RI 1+2* thick
+pixels joining points
+.I p0
+and
+.IR p1 .
+The line is drawn using pixels from the
+.I src
+image aligned so
+.I sp
+in the source corresponds to
+.I p0
+in the destination.
+The line touches both
+.I p0
+and
+.IR p1 ,
+and
+.I end0
+and
+.I end1
+specify how the ends of the line are drawn.
+.B Endsquare
+terminates the line perpendicularly to the direction of the line; a thick line with
+.B Endsquare
+on both ends will be a rectangle.
+.B Enddisc
+terminates the line by drawing a disc of diameter
+.RI 1+2* thick
+centered on the end point.
+.B Endarrow
+terminates the line with an arrowhead whose tip touches the endpoint.
+.IP
+The macro
+.B ARROW
+permits explicit control of the shape of the arrow.
+If all three parameters are zero, it produces the default arrowhead,
+otherwise,
+.I a
+sets the distance along line from end of the regular line to tip,
+.I b
+sets the distance along line from the barb to the tip,
+and
+.I c
+sets the distance perpendicular to the line from edge of line to the tip of the barb,
+all in pixels.
+.IP
+.I Line
+and the other geometrical operators are equivalent to calls to
+.I gendraw
+using a mask produced by the geometric procedure.
+.TP
+\f5poly(\f2dst\fP, \f2p\fP, \f2np\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
+.I Poly
+draws a general polygon; it
+is conceptually equivalent to a series of calls to
+.I line
+joining adjacent points in the
+array of
+.B Points
+.IR p ,
+which has
+.I np
+elements.
+The ends of the polygon are specified as in
+.IR line ;
+interior lines are terminated with
+.B Enddisc
+to make smooth joins.
+The source is aligned so
+.I sp
+corresponds to
+.IB p [0]\f1.
+.TP
+\f5fillpoly(\f2dst\fP, \f2p\fP, \f2np\fP, \f2wind\fP, \f2src\fP, \f2sp\fP)
+.I Fillpoly
+is like
+.I poly
+but fills in the resulting polygon rather than outlining it.
+The source is aligned so
+.I sp
+corresponds to
+.IB p [0]\f1.
+The winding rule parameter
+.I wind
+resolves ambiguities about what to fill if the polygon is self-intersecting.
+If
+.I wind
+is
+.BR ~0 ,
+a pixel is inside the polygon if the polygon's winding number about the point
+is non-zero.
+If
+.I wind
+is
+.BR 1 ,
+a pixel is inside if the winding number is odd.
+Complementary values (0 or ~1) cause outside pixels to be filled.
+The meaning of other values is undefined.
+The polygon is closed with a line if necessary.
+.TP
+\f5bezier(\f2dst\fP, \f2a\fP, \f2b\fP, \f2c\fP, \f2d\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
+.I Bezier
+draws the
+cubic Bezier curve defined by
+.B Points
+.IR a ,
+.IR b ,
+.IR c ,
+and
+.IR d .
+The end styles are determined by
+.I end0
+and
+.IR end1 ;
+the thickness of the curve is
+.RI 1+2* thick .
+The source is aligned so
+.I sp
+in
+.I src
+corresponds to
+.I a
+in
+.IR dst .
+.TP
+\f5bezspline(\f2dst\fP, \f2p\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
+.I Bezspline
+takes the same arguments as
+.I poly
+but draws a quadratic B-spline (despite its name) rather than a polygon.
+If the first and last points in
+.I p
+are equal, the spline has periodic end conditions.
+.TP
+\f5bezsplinepts(\f2pt\fP, \f2npt\fP, \f2pp\fP)
+.I Bezsplinepts
+returns in
+.I pp
+a list of points making up the open polygon that
+.I bezspline
+would draw.
+The caller is responsible for freeing
+.IR *pp .
+.TP
+\f5fillbezier(\f2dst\fP, \f2a\fP, \f2b\fP, \f2c\fP, \f2d\fP, \f2wind\fP, \f2src\fP, \f2sp\fP)
+.I Fillbezier
+is to
+.I bezier
+as
+.I fillpoly
+is to
+.IR poly .
+.TP
+\f5fillbezspline(\f2dst\fP, \f2p\fP, \f2wind\fP, \f2src\fP, \f2sp\fP)
+.I Fillbezspline
+is like
+.I fillpoly
+but fills the quadratic B-spline rather than the polygon outlined by
+.IR p .
+The spline is closed with a line if necessary.
+.TP
+\f5ellipse(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
+.I Ellipse
+draws in
+.I dst
+an ellipse centered on
+.I c
+with horizontal and vertical semiaxes
+.I a
+and
+.IR b .
+The source is aligned so
+.I sp
+in
+.I src
+corresponds to
+.I c
+in
+.IR dst .
+The ellipse is drawn with thickness
+.RI 1+2* thick .
+.TP
+\f5fillellipse(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2src\fP, \f2sp\fP)
+.I Fillellipse
+is like
+.I ellipse
+but fills the ellipse rather than outlining it.
+.TP
+\f5arc(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2thick\fP, \f2src\fP, \f2sp\fP, \f2alpha\fP, \f2phi\fP)
+.I Arc
+is like
+.IR ellipse ,
+but draws only that portion of the ellipse starting at angle
+.I alpha
+and extending through an angle of
+.IR phi .
+The angles are measured in degrees counterclockwise from the positive
+.I x
+axis.
+.TP
+\f5fillarc(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2src\fP, \f2sp\fP, \f2alpha\fP, \f2phi\fP)
+.I Fillarc
+is like
+.IR arc ,
+but fills the sector with the source color.
+.TP
+\f5icossin(\f2deg\fP, \f2cosp\fP, \f2sinp\fP)
+.I Icossin
+stores in
+.BI * cosp
+and
+.BI * sinp
+scaled integers representing the cosine and sine of the angle
+.IR deg ,
+measured in integer degrees.
+The values are scaled so cos(0) is 1024.
+.TP
+\f5icossin2(\f2x\fP, \f2y\fP, \f2cosp\fP, \f2sinp\fP)
+.I Icossin2
+is analogous to
+.IR icossin,
+with the angle represented not in degrees but implicitly by the point
+.RI ( x , y ).
+It is to
+.I icossin
+what
+.B atan2
+is to
+.B atan
+(see
+.IR sin (2)).
+.TP
+.BI border( dst\fP,\fP\ r\fP,\fP\ i\fP,\fP\ color\fP,\fP\ sp\fP)
+.I Border
+draws an outline of rectangle
+.I r
+in the specified
+.IR color .
+The outline has width
+.IR i ;
+if positive, the border goes inside the rectangle; negative, outside.
+The source is aligned so
+.I sp
+corresponds to
+.IB r .min .
+.TP
+.BI string( dst\fP,\fP\ p\fP,\fP\ src\fP,\fP\ sp\fP,\fP\ font\fP,\fP\ s )
+.I String
+draws in
+.I dst
+characters specified by the string
+.I s
+and
+.IR font ;
+it is equivalent to a series of calls to
+.I gendraw
+using source
+.I src
+and masks determined by the character shapes.
+The text is positioned with the left of the first character at
+.IB p .x
+and the top of the line of text at
+.IB p .y\f1.
+The source is positioned so
+.I sp
+in
+.I src
+corresponds to
+.I p
+in
+.IR dst .
+.I String
+returns a
+.B Point
+that is the position of the next character that would be drawn if the string were longer.
+.IP
+For characters with undefined
+or zero-width images in the font, the character at font position 0 (NUL) is drawn.
+.IP
+The other string routines are variants of this basic form, and
+have names that encode their variant behavior.
+Routines whose names contain
+.B rune
+accept a string of Runes rather than
+.SM UTF\c
+-encoded bytes.
+Routines ending in
+.B n
+accept an argument,
+.IR n ,
+that defines the number of characters to draw rather than accepting a NUL-terminated
+string.
+Routines containing
+.B bg
+draw the background behind the characters in the specified color
+.RI ( bg )
+and
+alignment
+.RI ( bgp );
+normally the text is drawn leaving the background intact.
+.IP
+The routine
+.I _string
+captures all this behavior into a single operator. Whether it draws a
+.SM UTF
+string
+or Rune string depends on whether
+.I s
+or
+.I r
+is null (the string length is always determined by
+.IR len ).
+If
+.I bg
+is non-null, it is used as a background color.
+The
+.I clipr
+argument allows further management of clipping when drawing the string;
+it is intersected with the usual clipping rectangles to further limit the extent of the text.
+.TP
+.BI drawsetdebug( on )
+Turns on or off debugging output (usually
+to a serial line) according to whether
+.I on
+is non-zero.
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR stringsize (2),
+.IR color (6),
+.IR utf (6),
+.IR addpt (2)
+.PP
+T. Porter, T. Duff.
+``Compositing Digital Images'',
+.I "Computer Graphics
+(Proc. SIGGRAPH), 18:3, pp. 253-259, 1984.
+.SH DIAGNOSTICS
+These routines call the graphics error function on fatal errors.
+.SH BUGS
+Anti-aliased characters can be drawn by defining a font
+with multiple bits per pixel, but there are
+no anti-aliasing geometric primitives.
diff --git a/sys/man/2/dsa b/sys/man/2/dsa
new file mode 100755
index 000000000..31c31f038
--- /dev/null
+++ b/sys/man/2/dsa
@@ -0,0 +1,139 @@
+.TH DSA 2
+.SH NAME
+dsagen, dsasign, dsaverify, dsapuballoc, dsapubfree, dsaprivalloc, dsaprivfree, dsasigalloc, dsasigfree, dsaprivtopub - digital signature algorithm
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+DSApriv* dsagen(DSApub *opub)
+.PP
+.B
+DSAsig* dsasign(DSApriv *k, mpint *m)
+.PP
+.B
+int dsaverify(DSApub *k, DSAsig *sig, mpint *m)
+.PP
+.B
+DSApub* dsapuballoc(void)
+.PP
+.B
+void dsapubfree(DSApub*)
+.PP
+.B
+DSApriv* dsaprivalloc(void)
+.PP
+.B
+void dsaprivfree(DSApriv*)
+.PP
+.B
+DSAsig* dsasigalloc(void)
+.PP
+.B
+void dsasigfree(DSAsig*)
+.PP
+.B
+DSApub* dsaprivtopub(DSApriv*)
+.SH DESCRIPTION
+.PP
+DSA is the NIST approved digital signature algorithm. The owner of a key publishes
+the public part of the key:
+.IP
+.EX
+struct DSApub
+{
+ mpint *p; // modulus
+ mpint *q; // group order, q divides p-1
+ mpint *alpha; // group generator
+ mpint *key; // alpha**secret mod p
+};
+.EE
+.LP
+This part can be used for verifying signatures (with
+.IR dsaverify )
+created by the owner.
+The owner signs (with
+.IR dsasign )
+using his private key:
+.IP
+.EX
+struct DSApriv
+{
+ DSApub pub;
+ mpint *secret; // (decryption key)
+};
+.EE
+.PP
+Keys are generated using
+.IR dsagen .
+If
+.IR dsagen 's
+argument
+.I opub
+is
+.BR nil ,
+a key is created using a new
+.B p
+and
+.B q
+generated by
+.I DSAprimes
+(see
+.IR prime (2)).
+Otherwise,
+.B p
+and
+.B q
+are copied from the old key.
+.PP
+.I Dsaprivtopub
+returns a newly allocated copy of the public key
+corresponding to the private key.
+.PP
+The routines
+.IR dsapuballoc ,
+.IR dsapubfree ,
+.IR dsaprivalloc ,
+and
+.I dsaprivfree
+are provided to manage key storage.
+.PP
+.I Dsasign
+signs message
+.I m
+using a private key
+.I k
+yielding a
+.IP
+.EX
+struct DSAsig
+{
+ mpint *r, *s;
+};
+.EE
+.LP
+.I Dsaverify
+returns 0 if the signature is valid and \-1 if not.
+.PP
+The routines
+.I dsasigalloc
+and
+.I dsasigfree
+are provided to manage signature storage.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR mp (2),
+.IR aes (2),
+.IR blowfish (2),
+.IR des (2),
+.IR rc4 (2),
+.IR rsa (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2)
diff --git a/sys/man/2/dup b/sys/man/2/dup
new file mode 100755
index 000000000..cd3414106
--- /dev/null
+++ b/sys/man/2/dup
@@ -0,0 +1,42 @@
+.TH DUP 2
+.SH NAME
+dup \- duplicate an open file descriptor
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int dup(int oldfd, int newfd)
+.SH DESCRIPTION
+Given a file descriptor,
+.IR oldfd ,
+referring to an open file,
+.I dup
+returns a new file descriptor referring to the same file.
+.PP
+If
+.I newfd
+is \-1 the system chooses the lowest available file descriptor.
+Otherwise,
+.I dup
+will use
+.I newfd
+for the new file descriptor
+(closing any old file associated with
+.IR newfd ).
+File descriptors are allocated dynamically,
+so to prevent unwarranted growth of the file descriptor table,
+.I dup
+requires that
+.I newfd
+be no greater than 20 more than the highest file descriptor ever used by
+the program.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2),
+.IR dup (3)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/elgamal b/sys/man/2/elgamal
new file mode 100755
index 000000000..a3d999191
--- /dev/null
+++ b/sys/man/2/elgamal
@@ -0,0 +1,125 @@
+.TH ELGAMAL 2
+.SH NAME
+eggen, egencrypt, egdecrypt, egsign, egverify, egpuballoc, egpubfree, egprivalloc, egprivfree, egsigalloc, egsigfree, egprivtopub - elgamal encryption
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+EGpriv* eggen(int nlen, int nrep)
+.PP
+.B
+mpint* egencrypt(EGpub *k, mpint *in, mpint *out)
+.PP
+.B
+mpint* egdecrypt(EGpriv *k, mpint *in, mpint *out)
+.PP
+.B
+EGsig* egsign(EGpriv *k, mpint *m)
+.PP
+.B
+int egverify(EGpub *k, EGsig *sig, mpint *m)
+.PP
+.B
+EGpub* egpuballoc(void)
+.PP
+.B
+void egpubfree(EGpub*)
+.PP
+.B
+EGpriv* egprivalloc(void)
+.PP
+.B
+void egprivfree(EGpriv*)
+.PP
+.B
+EGsig* egsigalloc(void)
+.PP
+.B
+void egsigfree(EGsig*)
+.PP
+.B
+EGpub* egprivtopub(EGpriv*)
+.SH DESCRIPTION
+.PP
+Elgamal is a public key encryption and signature algorithm. The owner of a key publishes
+the public part of the key:
+.EX
+ struct EGpub
+ {
+ mpint *p; // modulus
+ mpint *alpha; // generator
+ mpint *key; // (encryption key) alpha**secret mod p
+ };
+.EE
+This part can be used for encrypting data (with
+.IR egencrypt )
+to be sent to the owner.
+The owner decrypts (with
+.IR egdecrypt )
+using his private key:
+.EX
+ struct EGpriv
+ {
+ EGpub pub;
+ mpint *secret; // (decryption key)
+ };
+.EE
+.PP
+Keys are generated using
+.IR eggen .
+.I Eggen
+takes both bit length of the modulus
+and the number of repetitions of the Miller-Rabin
+primality test to run. If the latter is 0, it does the default number
+of rounds.
+.I Egprivtopub
+returns a newly allocated copy of the public key
+corresponding to the private key.
+.PP
+The routines
+.IR egpuballoc ,
+.IR egpubfree ,
+.IR egprivalloc ,
+and
+.I egprivfree
+are provided to manage key storage.
+.PP
+.I Egsign
+signs message
+.I m
+using a private key
+.I k
+yielding a
+.EX
+ struct EGsig
+ {
+ mpint *r, *s;
+ };
+.EE
+.I Egverify
+returns 0 if the signature is valid and \-1 if not.
+.PP
+The routines
+.I egsigalloc
+and
+.I egsigfree
+are provided to manage signature storage.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR mp (2),
+.IR aes (2),
+.IR blowfish (2),
+.IR des (2),
+.IR dsa (2),
+.IR rc4 (2),
+.IR rsa (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2)
diff --git a/sys/man/2/encode b/sys/man/2/encode
new file mode 100755
index 000000000..9436d94de
--- /dev/null
+++ b/sys/man/2/encode
@@ -0,0 +1,85 @@
+.TH ENCODE 2
+.SH NAME
+dec64, enc64, dec32, enc32, dec16, enc16, encodefmt \- encoding byte arrays as strings
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int dec64(uchar *out, int lim, char *in, int n)
+.PP
+.B
+int enc64(char *out, int lim, uchar *in, int n)
+.PP
+.B
+int dec32(uchar *out, int lim, char *in, int n)
+.PP
+.B
+int enc32(char *out, int lim, uchar *in, int n)
+.PP
+.B
+int dec16(uchar *out, int lim, char *in, int n)
+.PP
+.B
+int enc16(char *out, int lim, uchar *in, int n)
+.PP
+.B
+int encodefmt(Fmt*)
+.SH DESCRIPTION
+.PP
+.IR Enc16 ,
+.I enc32
+and
+.I enc64
+create null terminated strings. They return the size of the
+encoded string (without the null) or -1 if the encoding fails.
+The encoding fails if
+.IR lim ,
+the length of the output buffer, is too small.
+.PP
+.IR Dec16 ,
+.I dec32
+and
+.I dec64
+return the number of bytes decoded or -1 if the decoding fails.
+The decoding fails if the output buffer is not large enough or,
+for base 32, if the input buffer length is not a multiple
+of 8.
+.PP
+.I Encodefmt
+can be used with
+.IR fmtinstall (2)
+and
+.IR print (2)
+to print encoded representations of byte arrays.
+The verbs are
+.TP
+.B H
+base 16 (i.e. hexadecimal). The default encoding is
+in upper case. The
+.B l
+flag forces lower case.
+.TP
+.B <
+base 32
+.TP
+.B [
+base 64 (same as MIME)
+.PD
+.PP
+The length of the array is specified as
+.IR f2 .
+For example, to display a 15 byte array as hex:
+.EX
+
+ char x[15];
+
+ fmtinstall('H', encodefmt);
+ print("%.*H\\n", sizeof x, x);
+
+.EE
+.SH SOURCE
+.B /sys/src/libc/port/u32.c
+.br
+.B /sys/src/libc/port/u64.c
diff --git a/sys/man/2/encrypt b/sys/man/2/encrypt
new file mode 100755
index 000000000..3f7b41da9
--- /dev/null
+++ b/sys/man/2/encrypt
@@ -0,0 +1,76 @@
+.TH ENCRYPT 2
+.SH NAME
+encrypt, decrypt, netcrypt \- DES encryption
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int encrypt(void *key, void *data, int len)
+.PP
+.B
+int decrypt(void *key, void *data, int len)
+.PP
+.B
+int netcrypt(void *key, void *data)
+.SH DESCRIPTION
+.I Encrypt
+and
+.I decrypt
+perform DES encryption and decryption.
+.I Key
+is an array of
+.B DESKEYLEN
+(defined as 7 in
+.BR <auth.h> )
+bytes containing the encryption key.
+.I Data
+is an array of
+.I len
+bytes;
+it must be at least 8 bytes long.
+The bytes are encrypted or decrypted in place.
+.PP
+The DES algorithm encrypts an individual 8-byte block of data.
+.I Encrypt
+uses the following method to encrypt data longer than 8 bytes.
+The first 8 bytes are encrypted as usual.
+The last byte of the encrypted result
+is prefixed to the next 7 unencrypted bytes to make the next 8
+bytes to encrypt.
+This is repeated until fewer than 7 bytes remain unencrypted.
+Any remaining unencrypted bytes are encrypted with enough of the preceding
+encrypted bytes to make a full 8-byte block.
+.I Decrypt
+uses the inverse algorithm.
+.PP
+.I Netcrypt
+performs the same encryption as a SecureNet Key.
+.I Data
+points to an
+.SM ASCII
+string of decimal digits with numeric value between 0 and 10000.
+These digits are copied into an 8-byte buffer with trailing binary zero fill
+and encrypted as one DES block.
+The first four bytes are each formatted as two digit
+.SM ASCII
+hexadecimal numbers,
+and the string is copied into
+.IR data .
+.SH SOURCE
+.B /sys/src/libc/port
+.SH DIAGNOSTICS
+These routines return 1 if the data was encrypted,
+and 0 if the encryption fails.
+.I Encrypt
+and
+.I decrypt
+fail if the data passed is less than 8 bytes long.
+.I Netcrypt
+can fail if it is passed invalid data.
+.SH SEE ALSO
+.IR securenet (8)
+.SH BUGS
+The implementation is broken in a way that makes
+it unsuitable for anything but authentication.
diff --git a/sys/man/2/errstr b/sys/man/2/errstr
new file mode 100755
index 000000000..4e801c395
--- /dev/null
+++ b/sys/man/2/errstr
@@ -0,0 +1,85 @@
+.TH ERRSTR 2
+.SH NAME
+errstr, rerrstr, werrstr \- description of last system call error
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int errstr(char *err, uint nerr)
+.PP
+.B
+void rerrstr(char *err, uint nerr)
+.PP
+.B
+void werrstr(char *fmt, ...)
+.SH DESCRIPTION
+When a system call fails it returns \-1 and
+records a null terminated string describing the error in a per-process buffer.
+.I Errstr
+swaps the contents of that buffer with the contents of the array
+.IR err .
+.I Errstr
+will write at most
+.I nerr
+bytes into
+.IR err ;
+if the per-process error string does not fit,
+it is silently truncated at a UTF character boundary.
+The returned string is NUL-terminated.
+Usually
+.I errstr
+will be called with an empty string,
+but the exchange property provides a mechanism for
+libraries to set the return value for the next call to
+.IR errstr .
+.PP
+The per-process buffer is
+.B ERRMAX
+bytes long. Any error string provided by the user will
+be truncated at
+.B ERRMAX-1
+bytes.
+.B ERRMAX
+is defined in
+.BR <libc.h> .
+.PP
+If no system call has generated an error since the last call to
+.I errstr
+with an empty string,
+the result is an empty string.
+.PP
+The verb
+.B r
+in
+.IR print (2)
+calls
+.I errstr
+and outputs the error string.
+.PP
+.I Rerrstr
+reads the error string but does not modify the per-process buffer, so
+a subsequent
+.I errstr
+will recover the same string.
+.PP
+.I Werrstr
+takes a
+.I print
+style format as its argument and uses it to format
+a string to pass to
+.IR errstr .
+The string returned from
+.I errstr
+is discarded.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.br
+.B /sys/src/libc/9sys/werrstr.c
+.SH DIAGNOSTICS
+.I Errstr
+always returns 0.
+.SH SEE ALSO
+.IR intro (2),
+.IR perror (2)
diff --git a/sys/man/2/event b/sys/man/2/event
new file mode 100755
index 000000000..11324a9af
--- /dev/null
+++ b/sys/man/2/event
@@ -0,0 +1,384 @@
+.TH EVENT 2
+.SH NAME
+event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, ereadmouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, emoveto, esetcursor, Event, Mouse, Menu \- graphics events
+.SH SYNOPSIS
+.nf
+.PP
+.B
+#include <u.h>
+.B
+#include <libc.h>
+.B
+#include <draw.h>
+.B
+#include <event.h>
+.B
+#include <cursor.h>
+.ta \w'\fLRectangle 'u
+.PP
+.B
+void einit(ulong keys)
+.PP
+.B
+ulong event(Event *e)
+.PP
+.B
+Mouse emouse(void)
+.PP
+.B
+int ekbd(void)
+.PP
+.B
+int ecanmouse(void)
+.PP
+.B
+int ecankbd(void)
+.PP
+.B
+int ereadmouse(Mouse *m)
+.PP
+.B
+int eatomouse(Mouse *m, char *buf, int n)
+.PP
+.B
+ulong estart(ulong key, int fd, int n)
+.PP
+.B
+ulong estartfn(int id, ulong key, int fd, int n,
+.B
+ int (*fn)(Event*, uchar*, int))
+.PP
+.B
+ulong etimer(ulong key, int n)
+.PP
+.B
+ulong eread(ulong keys, Event *e)
+.PP
+.B
+int ecanread(ulong keys)
+.PP
+.B
+void eresized(int new)
+.PP
+.B
+Rectangle egetrect(int but, Mouse *m)
+.PP
+.B
+void edrawgetrect(Rectangle r, int up)
+.PP
+.B
+int emenuhit(int but, Mouse *m, Menu *menu)
+.PP
+.PP
+.B
+int emoveto(Point p)
+.PP
+.PP
+.B
+int esetcursor(Cursor *c)
+.PP
+.B
+extern Mouse *mouse
+.PP
+.B
+enum{
+.B
+ Emouse = 1,
+.B
+ Ekeyboard = 2,
+.B
+};
+.PP
+.SH DESCRIPTION
+These routines provide an interface to multiple sources of input for unthreaded
+programs.
+Threaded programs (see
+.IR thread (2))
+should instead use the threaded mouse and keyboard interface described
+in
+.IR mouse (2)
+and
+.IR keyboard (2).
+.PP
+.I Einit
+must be called first.
+If the argument to
+.I einit
+has the
+.B Emouse
+and
+.B Ekeyboard
+bits set,
+the mouse and keyboard events will be enabled;
+in this case,
+.IR initdraw
+(see
+.IR graphics (2))
+must have already been called.
+The user must provide a function called
+.IR eresized
+to be called whenever the window in which the process
+is running has been resized; the argument
+.I new
+is a flag specifying whether the program must call
+.I getwindow
+(see
+.IR graphics (2))
+to re-establish a connection to its window.
+After resizing (and perhaps calling
+.IR getwindow ),
+the global variable
+.B screen
+will be updated to point to the new window's
+.B Image
+structure.
+.PP
+As characters are typed on the keyboard, they are read by the
+event mechanism and put in a queue.
+.I Ekbd
+returns the next rune from the queue, blocking until the
+queue is non-empty.
+The characters are read in raw mode
+(see
+.IR cons (3)),
+so they are available as soon as a complete rune is typed.
+.PP
+When the mouse moves or a mouse button is pressed or released,
+a new mouse event is queued by the event mechanism.
+.I Emouse
+returns the next mouse event from the queue, blocking until the
+queue is non-empty.
+.I Emouse
+returns a
+.B Mouse
+structure:
+.IP
+.EX
+.ta 6n +\w'Point 'u
+struct Mouse
+{
+ int buttons;
+ Point xy;
+ ulong msec;
+};
+.EE
+.PP
+.B Buttons&1
+is set when the left mouse button is pressed,
+.B buttons&2
+when the middle button is pressed,
+and
+.B buttons&4
+when the right button is pressed.
+The current mouse position is always returned in
+.BR xy .
+.B Msec
+is a time stamp in units of milliseconds.
+.PP
+.I Ecankbd
+and
+.I ecanmouse
+return non-zero when there are keyboard or mouse events available
+to be read.
+.PP
+.I Ereadmouse
+reads the next mouse event from the file descriptor connected to the mouse,
+converts the textual data into a
+.B Mouse
+structure by calling
+.I eatomouse
+with the buffer and count from the read call,
+and returns the number of bytes read, or \-1 for an error.
+.PP
+.I Estart
+can be used to register additional file descriptors to scan for input.
+It takes as arguments the file descriptor to register,
+the maximum length of an event message on that descriptor,
+and a key to be used in accessing the event.
+The key must be a power of 2 and must not conflict with any previous keys.
+If a zero key is given, a key will be allocated and returned.
+.I Estartfn
+is similar to
+.IR estart ,
+but processes the data received by calling
+.I fn
+before returning the event to the user.
+The function
+.I fn
+is called with the
+.B id
+of the event; it should return
+.B id
+if the event is to be passed to the user,
+.B 0
+if it is to be ignored.
+The variable
+.B Event.v
+can be used by
+.I fn
+to attach an arbitrary data item to the returned
+.B Event
+structure.
+.B
+Ekeyboard
+and
+.B Emouse
+are the keyboard and mouse event keys.
+.PP
+.I Etimer
+starts a repeating timer with a period of
+.I n
+milliseconds; it returns the timer event key, or zero if it fails.
+Only one timer can be started.
+Extra timer events are not queued and the timer channel has no associated data.
+.PP
+.I Eread
+waits for the next event specified by the mask
+.I keys
+of event keys submitted to
+.IR estart .
+It fills in the appropriate field of the argument
+.B Event
+structure, which looks like:
+.IP
+.EX
+struct Event
+{
+ int kbdc;
+ Mouse mouse;
+ int n;
+ void *v;
+ uchar data[EMAXMSG];
+};
+.EE
+.PP
+.B Data
+is an array which is large enough to hold a 9P message.
+.I Eread
+returns the key for the event which was chosen.
+For example, if a mouse event was read,
+.B Emouse
+will be returned.
+.PP
+.I Event
+waits for the next event of any kind.
+The return is the same as for
+.IR eread .
+.PP
+As described in
+.IR graphics (2),
+the graphics functions are buffered.
+.IR Event ,
+.IR eread ,
+.IR emouse ,
+and
+.I ekbd
+all cause a buffer flush unless there is an event of the
+appropriate type already queued.
+.PP
+.I Ecanread
+checks whether a call to
+.B eread(keys)
+would block, returning 0 if it would, 1 if it would not.
+.PP
+.I Getrect
+prompts the user to sweep a rectangle.
+It should be called with
+.I m
+holding the mouse event that triggered the
+.I egetrect
+(or, if none, a
+.B Mouse
+with
+.B buttons
+set to 7).
+It changes to the sweep cursor,
+waits for the buttons all to be released,
+and then waits for button number
+.I but
+to be pressed, marking the initial corner.
+If another button is pressed instead,
+.I egetrect
+returns a rectangle
+with zero for both corners, after
+waiting for all the buttons to be released.
+Otherwise,
+.I egetrect
+continually draws the swept rectangle
+until the button is released again, and returns the swept rectangle.
+The mouse structure pointed to by
+.I m
+will contain the final mouse event.
+.PP
+.I Egetrect
+uses successive calls to
+.I edrawgetrect
+to maintain the red rectangle showing the sweep-in-progress.
+The rectangle to be drawn is specified by
+.I rc
+and the
+.I up
+parameter says whether to draw (1) or erase (0) the rectangle.
+.PP
+.I Emenuhit
+displays a menu and returns a selected menu item number.
+It should be called with
+.I m
+holding the mouse event that triggered the
+.IR emenuhit ;
+it will call
+.I emouse
+to update it.
+A
+.B Menu
+is a structure:
+.IP
+.EX
+struct Menu
+{
+ char **item;
+ char *(*gen)(int);
+ int lasthit;
+};
+.EE
+.PP
+If
+.B item
+is nonzero, it should be a null-terminated array of the character strings
+to be displayed as menu items.
+Otherwise,
+.B gen
+should be a function that, given an item number, returns the character
+string for that item, or zero if the number is past the end of the list.
+Items are numbered starting at zero.
+.I Menuhit
+waits until
+.I but
+is released, and then returns the number of the selection,
+or \-1 for no selection.
+The
+.I m
+argument is filled in with the final mouse event.
+.PP
+.I Emoveto
+moves the mouse cursor to the position
+.B p
+on the screen.
+.PP
+.I Esetcursor
+changes the cursor image to that described by the
+.B Cursor
+.I c
+(see
+.IR mouse (2)).
+If
+.B c
+is nil, it restores the image to the default arrow.
+.SH SOURCE
+.B /sys/src/libdraw
+.SH "SEE ALSO"
+.IR rio (1),
+.IR graphics (2),
+.IR plumb (2),
+.IR cons (3),
+.IR draw (3)
diff --git a/sys/man/2/exec b/sys/man/2/exec
new file mode 100755
index 000000000..5c5e79669
--- /dev/null
+++ b/sys/man/2/exec
@@ -0,0 +1,200 @@
+.TH EXEC 2
+.SH NAME
+exec, execl, _privates, _nprivates, _tos \- execute a file
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+void* exec(char *name, char* argv[])
+.PP
+.B
+void* execl(char *name, ...)
+.PP
+.B
+void **_privates;
+.PP
+.B
+int _nprivates;
+.PP
+.B
+#include <tos.h>
+.PP
+.ft L
+typedef struct Tos Tos;
+struct Tos {
+ struct { ... } prof; /* profiling data */
+ uvlong cyclefreq; /* cycle clock frequency */
+ vlong kcycles; /* kernel cycles */
+ vlong pcycles; /* process cycles (kernel + user) */
+ ulong pid; /* process id */
+ ulong clock; /* profiling clock */
+ /* top of stack is here */
+};
+.PP
+.B
+extern Tos *_tos;
+.fi
+.SH DESCRIPTION
+.I Exec
+and
+.I execl
+overlay the calling process with the named file, then
+transfer to the entry point of the image of the file.
+.PP
+.I Name
+points to the name of the file
+to be executed; it must not be a directory, and the permissions
+must allow the current user to execute it
+(see
+.IR stat (2)).
+It should also be a valid binary image, as defined in the
+.IR a.out (6)
+for the current machine architecture,
+or a shell script
+(see
+.IR rc (1)).
+The first line of a
+shell script must begin with
+.L #!
+followed by the name of the program to interpret the file
+and any initial arguments to that program, for example
+.IP
+.EX
+#!/bin/rc
+ls | mc
+.EE
+.PP
+When a C program is executed,
+it is called as follows:
+.IP
+.EX
+void main(int argc, char *argv[])
+.EE
+.PP
+.I Argv
+is a copy of the array of argument pointers passed to
+.IR exec ;
+that array must end in a null pointer, and
+.I argc
+is the number of elements before the null pointer.
+By convention, the first argument should be the name of
+the program to be executed.
+.I Execl
+is like
+.I exec
+except that
+.I argv
+will be an array of the parameters that follow
+.I name
+in the call. The last argument to
+.I execl
+must be a null pointer.
+.PP
+For a file beginning
+.BR #! ,
+the arguments passed to the program
+.RB ( /bin/rc
+in the example above) will be the name of the file being
+executed, any arguments on the
+.B #!
+line, the name of the file again,
+and finally the second and subsequent arguments given to the original
+.I exec
+call.
+The result honors the two conventions of a program accepting as argument
+a file to be interpreted and
+.B argv[0]
+naming the file being
+executed.
+.PP
+Most attributes of the calling process are carried
+into the result; in particular,
+files remain open across
+.I exec
+(except those opened with
+.B OCEXEC
+OR'd
+into the open mode; see
+.IR open (2));
+and the working directory and environment
+(see
+.IR env (3))
+remain the same.
+However, a newly
+.I exec'ed
+process has no notification handler
+(see
+.IR notify (2)).
+.PP
+The global cell
+.B _privates
+points to an array of
+.B _nprivates
+elements of per-process private data.
+This storage is private for each process, even if the processes share data segments.
+.PP
+When the new program begins, the global pointer
+.B _tos
+is set to the address of a structure
+that holds information
+allowing accurate time keeping and clock reading in user space.
+These data are updated by the kernel during of the life of the process,
+including across
+.IR rfork s
+and
+.IR exec s.
+If there is a user-space accessible fast clock (a processor
+cycle counter),
+.B cyclefreq
+will be set to its frequency in Hz.
+.B Kcycles
+.RB ( pcycles )
+counts the number of cycles
+this process has spent in kernel mode
+(kernel and user mode).
+.B Pid
+is the current process's id.
+.B Clock
+is the user-profiling clock (see
+.IR prof (1)).
+Its time is measured in milliseconds but is updated at
+a system-dependent lower rate.
+This clock is typically used by the profiler but is available
+to all programs.
+.PP
+The above conventions apply to C programs; the raw system
+interface to the new image is as follows:
+the word pointed to by the stack pointer is
+.BR argc ;
+the words beyond that are the zeroth and subsequent elements
+of
+.BR argv ,
+followed by a terminating null pointer; and
+the return register (e.g.
+.B R0
+on the 68020) contains the address of the clock information.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.br
+.B /sys/src/libc/port/execl.c
+.SH SEE ALSO
+.IR prof (1),
+.IR intro (2),
+.IR stat (2)
+.SH DIAGNOSTICS
+If these functions fail, they return and set
+.IR errstr .
+There can be no return to the calling process from a successful
+.I exec
+or
+.IR execl ;
+the calling image is lost.
+.SH BUGS
+There is a large but finite limit on the size of an argment list,
+typically around 409,600 bytes.
+The kernel constant
+.B TSTKSIZ
+controls this.
diff --git a/sys/man/2/exits b/sys/man/2/exits
new file mode 100755
index 000000000..78e3f6d29
--- /dev/null
+++ b/sys/man/2/exits
@@ -0,0 +1,81 @@
+.TH EXITS 2
+.SH NAME
+exits, _exits, atexit, atexitdont, terminate \- terminate process, process cleanup
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+void _exits(char *msg)
+.B
+void exits(char *msg)
+.PP
+.B
+int atexit(void(*)(void))
+.PP
+.B
+void atexitdont(void(*)(void))
+.fi
+.SH DESCRIPTION
+.I Exits
+is the conventional way to terminate a process.
+.I _Exits
+is the underlying system call.
+They
+can never return.
+.PP
+.I Msg
+conventionally includes a brief (maximum length
+.BR ERRLEN )
+explanation of the reason for
+exiting, or a null pointer or empty string to indicate normal termination.
+The string is passed to the parent process, prefixed by the name and process
+id of the exiting process, when the parent does a
+.IR wait (2).
+.PP
+Before calling
+.I _exits
+with
+.I msg
+as an argument,
+.I exits
+calls in reverse order all the functions
+recorded by
+.IR atexit .
+.PP
+.I Atexit
+records
+.I fn
+as a function to be called by
+.IR exits .
+It returns zero if it failed,
+nonzero otherwise.
+A typical use is to register a cleanup routine for an I/O package.
+To simplify programs that fork or share memory,
+.I exits
+only calls those
+.IR atexit -registered
+functions that were registered by the same
+process as that calling
+.IR exits .
+.PP
+Calling
+.I atexit
+twice (or more) with the same function argument causes
+.I exits
+to invoke the function twice (or more).
+.PP
+There is a limit to the number of exit functions
+that will be recorded;
+.I atexit
+returns 0 if that limit has been reached.
+.PP
+.I Atexitdont
+cancels a previous registration of an exit function.
+.SH SOURCE
+.B /sys/src/libc/port/atexit.c
+.SH "SEE ALSO"
+.IR fork (2),
+.IR wait (2)
diff --git a/sys/man/2/exp b/sys/man/2/exp
new file mode 100755
index 000000000..55147ed9f
--- /dev/null
+++ b/sys/man/2/exp
@@ -0,0 +1,62 @@
+.TH EXP 2
+.SH NAME
+exp, log, log10, pow, pow10, sqrt \- exponential, logarithm, power, square root
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+double exp(double x)
+.PP
+.B
+double log(double x)
+.PP
+.B
+double log10(double x)
+.PP
+.B
+double pow(double x, double y)
+.PP
+.B
+double pow10(int n)
+.PP
+.B
+double sqrt(double x)
+.fi
+.SH DESCRIPTION
+.I Exp
+returns the exponential function of
+.IR x .
+.PP
+.I Log
+returns the natural logarithm of
+.IR x ;
+.I log10
+returns the base 10 logarithm.
+.PP
+.I Pow
+returns
+.if t .I x\u\s8y\s10\d
+.if n x^y,
+and
+.I pow10
+returns
+.if t .I 10\u\s8n\s10\d
+.if n 10^n
+as a double.
+.PP
+.I Sqrt
+returns the square root of
+.IR x .
+.SH SOURCE
+All these routines have portable C implementations in
+.BR /sys/src/libc/port .
+Most also have machine-dependent implementations, written either in assembler
+or C, in
+.BR /sys/src/libc/$objtype .
+.SH SEE ALSO
+.IR hypot (2),
+.IR sinh (2),
+.IR intro (2)
diff --git a/sys/man/2/fauth b/sys/man/2/fauth
new file mode 100755
index 000000000..4b666ee83
--- /dev/null
+++ b/sys/man/2/fauth
@@ -0,0 +1,66 @@
+.TH FAUTH 2
+.SH NAME
+fauth \- set up authentication on a file descriptor to a file server
+.SH SYNOPSIS
+.nf
+.PP
+.ft L
+#include <u.h>
+#include <libc.h>
+.PP
+.ft P
+.B
+int fauth(int fd, char *aname)
+.SH DESCRIPTION
+.PP
+.I Fauth
+is used to establish authentication for the current user to access
+the resources available through the 9P connection represented by
+.IR fd .
+The return value is a file descriptor, conventionally called
+.BR afd ,
+that is subsequently used to negotiate the authentication protocol
+for the server, typically using
+.IR auth_proxy
+or
+.IR fauth_proxy
+(see
+.IR auth (2)).
+After successful authentication,
+.B afd
+may be passed as the second argument to a subsequent
+.B mount
+call (see
+.IR bind (2)),
+with the same
+.IR aname,
+as a ticket-of-entry for the user.
+.PP
+If
+.I fauth
+returns -1, the error case, that means the file server does not require
+authentication for the connection, and
+.B afd
+should be set to -1
+in the call to
+.BR mount.
+.PP
+It is rare to use
+.IR fauth
+directly; more commonly
+.I amount
+(see
+.IR auth (2))
+is used.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR attach (5),
+.IR auth (2)
+(particularly
+.BR amount ),
+.IR authsrv (6),
+.IR auth (8)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/fcall b/sys/man/2/fcall
new file mode 100755
index 000000000..1ca3edb77
--- /dev/null
+++ b/sys/man/2/fcall
@@ -0,0 +1,357 @@
+.TH FCALL 2
+.SH NAME
+Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt, dirmodefmt, read9pmsg, statcheck, sizeS2M, sizeD2M \- interface to Plan 9 File protocol
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.br
+.B #include <fcall.h>
+.PP
+.B
+uint convS2M(Fcall *f, uchar *ap, uint nap)
+.PP
+.B
+uint convD2M(Dir *d, uchar *ap, uint nap)
+.PP
+.B
+uint convM2S(uchar *ap, uint nap, Fcall *f)
+.PP
+.B
+uint convM2D(uchar *ap, uint nap, Dir *d, char *strs)
+.PP
+.B
+int dirfmt(Fmt*)
+.PP
+.B
+int fcallfmt(Fmt*)
+.PP
+.B
+int dirmodefmt(Fmt*)
+.PP
+.B
+int read9pmsg(int fd, uchar *buf, uint nbuf)
+.PP
+.B
+int statcheck(uchar *buf, uint nbuf)
+.PP
+.B
+uint sizeS2M(Fcall *f)
+.PP
+.B
+uint sizeD2M(Dir *d)
+.SH DESCRIPTION
+These
+routines convert messages in the machine-independent format of
+the Plan 9 file protocol,
+9P, to and from a more convenient form,
+an
+.B Fcall
+structure:
+.PP
+.EX
+.if n .ta 4n +6n +5n +6n +18n +4n
+.if t .ta \w'xxxx'u +\w'short 'u +\w'xxxx'u +\w'ushort 'u +\w'ticket[TICKETLEN]; 'u +\w'/* 'u
+#define MAXWELEM 16
+
+typedef
+struct Fcall
+{
+ uchar type;
+ u32int fid;
+ ushort tag;
+ union {
+ struct {
+ u32int msize; /* Tversion, Rversion */
+ char *version; /* Tversion, Rversion */
+ };
+ struct {
+ ushort oldtag; /* Tflush */
+ };
+ struct {
+ char *ename; /* Rerror */
+ };
+ struct {
+ Qid qid; /* Rattach, Ropen, Rcreate */
+ u32int iounit; /* Ropen, Rcreate */
+ };
+ struct {
+ Qid aqid; /* Rauth */
+ };
+ struct {
+ u32int afid; /* Tauth, Tattach */
+ char *uname; /* Tauth, Tattach */
+ char *aname; /* Tauth, Tattach */
+ };
+ struct {
+ u32int perm; /* Tcreate */
+ char *name; /* Tcreate */
+ uchar mode; /* Tcreate, Topen */
+ };
+ struct {
+ u32int newfid; /* Twalk */
+ ushort nwname; /* Twalk */
+ char *wname[MAXWELEM]; /* Twalk */
+ };
+ struct {
+ ushort nwqid; /* Rwalk */
+ Qid wqid[MAXWELEM]; /* Rwalk */
+ };
+ struct {
+ vlong offset; /* Tread, Twrite */
+ u32int count; /* Tread, Twrite, Rread */
+ char *data; /* Twrite, Rread */
+ };
+ struct {
+ ushort nstat; /* Twstat, Rstat */
+ uchar *stat; /* Twstat, Rstat */
+ };
+ };
+} Fcall;
+.EE
+.EX
+
+/* these are implemented as macros */
+
+uchar GBIT8(uchar*)
+ushort GBIT16(uchar*)
+ulong GBIT32(uchar*)
+vlong GBIT64(uchar*)
+
+void PBIT8(uchar*, uchar)
+void PBIT16(uchar*, ushort)
+void PBIT32(uchar*, ulong)
+void PBIT64(uchar*, vlong)
+
+#define BIT8SZ 1
+#define BIT16SZ 2
+#define BIT32SZ 4
+#define BIT64SZ 8
+.EE
+.PP
+This structure is defined in
+.BR <fcall.h> .
+See section 5
+for a full description of 9P messages and their encoding.
+For all message types, the
+.B type
+field of an
+.B Fcall
+holds one of
+.BR Tversion ,
+.BR Rversion ,
+.BR Tattach ,
+.BR Rattach ,
+etc. (defined in an enumerated type in
+.BR <fcall.h> ).
+.B Fid
+is used by most messages, and
+.B tag
+is used by all messages.
+The other fields are used selectively by the message types
+given in comments.
+.PP
+.I ConvM2S
+takes a 9P message at
+.I ap
+of length
+.IR nap ,
+and uses it to fill in
+.B Fcall
+structure
+.IR f .
+If the passed message
+including any data for
+.B Twrite
+and
+.B Rread
+messages
+is formatted properly,
+the return value is the number of bytes the message occupied in the buffer
+.IR ap ,
+which will always be less than or equal to
+.IR nap ;
+otherwise it is 0.
+For
+.B Twrite
+and
+.B Tread
+messages,
+.B data
+is set to a pointer into the argument message,
+not a copy.
+.PP
+.I ConvS2M
+does the reverse conversion, turning
+.I f
+into a message starting at
+.IR ap .
+The length of the resulting message is returned.
+For
+.B Twrite
+and
+.B Rread
+messages,
+.B count
+bytes starting at
+.B data
+are copied into the message.
+.PP
+The constant
+.B IOHDRSZ
+is a suitable amount of buffer to reserve for storing
+the 9P header;
+the data portion of a
+.B Twrite
+or
+.B Rread
+will be no more than the buffer size negotiated in the
+.BR Tversion/Rversion
+exchange, minus
+.BR IOHDRSZ .
+.PP
+The routine
+.I sizeS2M
+returns the number of bytes required to store the machine-independent representation of the
+.B Fcall
+structure
+.IR f ,
+including its initial 32-bit size field.
+In other words, it reports the number of bytes produced
+by a successful call to
+.IR convS2M .
+.PP
+Another structure is
+.BR Dir ,
+used by the routines described in
+.IR stat (2).
+.I ConvM2D
+converts the machine-independent form starting at
+.I ap
+into
+.IR d
+and returns the length of the machine-independent encoding.
+The strings in the returned
+.B Dir
+structure are stored at successive locations starting at
+.BR strs .
+Usually
+.B strs
+will point to storage immediately after the
+.B Dir
+itself.
+It can also be a
+.B nil
+pointer, in which case the string pointers in the returned
+.B Dir
+are all
+.BR nil ;
+however, the return value still includes their length.
+.PP
+.I ConvD2M
+does the reverse translation,
+also returning the length of the encoding.
+If the buffer is too short, the return value will be
+.B BIT16SZ
+and the correct size will be returned in the first
+.B BIT16SZ
+bytes.
+(If the buffer is less that
+.BR BIT16SZ ,
+the return value is zero; therefore a correct test for
+complete packing of the message is that the return value is
+greater than
+.BR BIT16SZ ).
+The macro
+.B GBIT16
+can be used to extract the correct value.
+The related macros with different sizes retrieve the corresponding-sized quantities.
+.B PBIT16
+and its brethren place values in messages.
+With the exception of handling short buffers in
+.IR convD2M ,
+these macros are not usually needed except by internal routines.
+.PP
+Analogous to
+.IR sizeS2M ,
+.I sizeD2M
+returns the number of bytes required to store the machine-independent representation of the
+.B Dir
+structure
+.IR d ,
+including its initial 16-bit size field.
+.PP
+The routine
+.B statcheck
+checks whether the
+.I nbuf
+bytes of
+.I buf
+contain a validly formatted machine-independent
+.B Dir
+entry suitable as an argument, for example, for the
+.B wstat
+(see
+.IR stat (2))
+system call.
+It checks that the sizes of all the elements of the the entry sum to exactly
+.IR nbuf ,
+which is a simple but effective test of validity.
+.I Nbuf
+and
+.I buf
+should include the second two-byte (16-bit) length field that precedes the entry when
+formatted in a 9P message (see
+.IR stat (5));
+in other words,
+.I nbuf
+is 2 plus the sum of the sizes of the entry itself.
+.I Statcheck
+also verifies that the length field has the correct value (that is,
+.IB nbuf -2\f1).
+It returns
+.B 0
+for a valid entry and
+.B -1
+for an incorrectly formatted entry.
+.PP
+.IR Dirfmt ,
+.IR fcallfmt ,
+and
+.I dirmodefmt
+are formatting routines, suitable for
+.IR fmtinstall (2).
+They convert
+.BR Dir* ,
+.BR Fcall* ,
+and
+.BR long
+values into string representations of the directory buffer,
+.B Fcall
+buffer,
+or file mode value.
+.I Fcallfmt
+assumes that
+.I dirfmt
+has been installed with format letter
+.L D
+and
+.I dirmodefmt
+with format letter
+.LR M .
+.PP
+.I Read9pmsg
+calls
+.IR read (2)
+multiple times, if necessary, to read an entire 9P message into
+.BR buf .
+The return value is 0 for end of file, or -1 for error; it does not return
+partial messages.
+.SH SOURCE
+.B /sys/src/libc/9sys
+.SH SEE ALSO
+.IR intro (2),
+.IR 9p (2),
+.IR stat (2),
+.IR intro (5)
diff --git a/sys/man/2/fd2path b/sys/man/2/fd2path
new file mode 100755
index 000000000..9876c132a
--- /dev/null
+++ b/sys/man/2/fd2path
@@ -0,0 +1,57 @@
+.TH FD2PATH 2
+.SH NAME
+fd2path \- return file name associated with file descriptor
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int fd2path(int fd, char *buf, int nbuf)
+.SH DESCRIPTION
+As described in
+.IR intro (2),
+the kernel stores a rooted path name with every open file or directory;
+typically, it is the name used in the original access of the file.
+.I Fd2path
+returns the path name associated with open file descriptor
+.IR fd .
+Up to
+.I nbuf
+bytes of the name are stored in
+.IR buf ;
+if the name is too long, it will be silently truncated at a UTF-8
+character boundary.
+The name is always null-terminated.
+The return value of
+.I fd2path
+will be zero unless an error occurs.
+.PP
+Changes to the underlying name space do not update the path name
+stored with the file descriptor.
+Therefore,
+the path returned by
+.I fd2path
+may no longer refer to the same file (or indeed any file)
+after some component directory or file in the path has been removed, renamed
+or rebound.
+.PP
+As an example,
+.IR getwd (2)
+is implemented by opening
+.B .
+and executing
+.I fd2path
+on the resulting file descriptor.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR bind (1),
+.IR ns (1),
+.IR bind (2),
+.IR intro (2),
+.IR getwd (2),
+.IR proc (3)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/fgetc b/sys/man/2/fgetc
new file mode 100755
index 000000000..87bc98e9c
--- /dev/null
+++ b/sys/man/2/fgetc
@@ -0,0 +1,213 @@
+.TH FGETC 2
+.SH NAME
+fgetc, getc, getchar, fputc, putc, putchar, ungetc, fgets, gets, fputs, puts, fread, fwrite \- Stdio input and output
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <stdio.h>
+.ta \w'\fLlong 'u
+.PP
+.B
+int fgetc(FILE *f)
+.PP
+.B
+int getc(FILE *f)
+.PP
+.B
+int getchar(void)
+.PP
+.B
+int fputc(int c, FILE *f)
+.PP
+.B
+int putc(int c, FILE *f)
+.PP
+.B
+int putchar(int c)
+.PP
+.B
+int ungetc(int c, FILE *f)
+.PP
+.B
+char *fgets(char *s, int n, FILE *f)
+.PP
+.B
+char *gets(char *s)
+.PP
+.B
+int fputs(char *s, FILE *f)
+.PP
+.B
+int puts(char *s)
+.PP
+.B
+long fread(void *ptr, long itemsize, long nitems, FILE *stream)
+.PP
+.B
+long fwrite(void *ptr, long itemsize, long nitems, FILE *stream)
+.SH DESCRIPTION
+The functions described here work on open Stdio streams (see
+.IR fopen ).
+.PP
+.I Fgetc
+returns as an
+.B int
+the next
+.B unsigned
+.B char
+from input stream
+.IR f .
+If the stream is at end-of-file, the end-of-file indicator for the
+stream is set and
+.I fgetc
+returns
+.BR EOF .
+If a read error occurs, the error indicator for the stream is set and
+.I fgetc
+returns
+.BR EOF .
+.I Getc
+is like
+.I fgetc
+except that it is implemented as a macro.
+.I Getchar
+is like
+.I getc
+except that it always reads from
+.BR stdin .
+.PP
+.I Ungetc
+pushes character
+.I c
+back onto the input stream
+.BR f .
+The pushed-back character will be returned by subsequent reads in
+the reverse order of their pushing.
+A successful intervening
+.IR fseek ,
+.IR fsetpos ,
+or
+.I rewind
+on
+.I f
+discards any pushed-back characters for
+.IR f .
+One character of push-back is guaranteed.
+.I Ungetc
+returns the character pushed back (converted to
+.B unsigned
+.BR char ),
+or
+.B EOF
+if the operation fails.
+A successful call to
+.I ungetc
+clears the end-of-file indicator for the stream.
+The file position indicator for the stream after reading or discarding
+all pushed-back characters is the same as it was before the
+characters were pushed back.
+.PP
+.I Fputc
+writes character
+.I c
+(converted to
+.B unsigned
+.BR char )
+to output stream
+.IR f
+at the position indicated by the position indicator for the stream
+and advances the indicator appropriately.
+If the file cannot support positioning requests, or if the stream was
+opened with append mode, the character is appended to the output stream.
+.I Fputc
+returns the character written or
+.B EOF
+if there was a write error.
+.I Putc
+is like
+.IR fputc
+but is implemented as a macro.
+.I Putchar
+is like
+.I putc
+except that it always writes to
+.BR stdout .
+.PP
+All other input takes place as if characters were read by successive
+calls to
+.I fgetc
+and all other output takes place as if characters were written by
+successive calls to
+.IR fputc .
+.PP
+.I Fgets
+reads up to and including the next newline, but not past end-of-file
+or more than
+.IR n -1
+characters, from stream
+.I f
+into array
+.IR s .
+A null character is written immediately after the last character read
+into the array (if any characters are read at all).
+.I Fgets
+returns
+.I s
+if successful, otherwise a null pointer.
+.I Gets
+is similar to
+.IR fgets
+except that it always reads from
+.B stdin
+and it discards the terminating newline, if any.
+.I Gets
+does not check for overflow of the receiving array, so its use is deprecated.
+.PP
+.I Fputs
+writes the string
+.I s
+to stream
+.IR f ,
+returning
+.B EOF
+if a write error occurred, otherwise a nonnegative value.
+The terminating null character is not written.
+.I Puts
+is the same, writing to
+.BR stdout .
+.PP
+.I Fread
+reads from the named input
+.IR stream
+at most
+.I nitems
+of data of size
+.I itemsize
+and the type of
+.I *ptr
+into a block beginning at
+.IR ptr .
+It returns the number of items actually read.
+.PP
+.I Fwrite
+appends to the named output
+.I stream
+at most
+.I nitems
+of data of size
+.I itemsize
+and the type of
+.I *ptr
+from a block beginning at
+.IR ptr .
+It returns the number of items actually written.
+.SH SOURCE
+.B /sys/src/libstdio
+.SH "SEE ALSO"
+.IR read (2),
+.IR fopen (2),
+.IR bio (2)
+.SH BUGS
+Stdio does not handle
+.SM UTF
+or runes; use Bio instead.
diff --git a/sys/man/2/flate b/sys/man/2/flate
new file mode 100755
index 000000000..39f4c108d
--- /dev/null
+++ b/sys/man/2/flate
@@ -0,0 +1,207 @@
+.TH FLATE 2
+.SH NAME
+deflateinit, deflate, deflatezlib, deflateblock, deflatezlibblock, inflateinit, inflate, inflatezlib, inflateblock, inflatezlibblock, flateerr, mkcrctab, blockcrc, adler32 \- deflate compression
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <flate.h>
+.PP
+.ta \w'ulongmm'u
+.PP
+.B
+int deflateinit(void)
+.PP
+.B
+int deflate(void *wr, int (*w)(void*,void*,int),
+.br
+.B
+ void *rr, int (*r)(void*,void*,int),
+.br
+.B
+ int level, int debug)
+.PP
+.B
+int deflatezlib(void *wr, int (*w)(void*,void*,int),
+.br
+.B
+ void *rr, int (*r)(void*,void*,int),
+.br
+.B
+ int level, int debug)
+.PP
+.B
+int deflateblock(uchar *dst, int dsize,
+.br
+.B
+ uchar *src, int ssize,
+.br
+.B
+ int level, int debug)
+.PP
+.B
+int deflatezlibblock(uchar *dst, int dsize,
+.br
+.B
+ uchar *src, int ssize,
+.br
+.B
+ int level, int debug)
+.PP
+.B
+int inflateinit(void)
+.PP
+.B
+int inflate(void *wr, int (*w)(void*, void*, int),
+.br
+.B
+ void *getr, int (*get)(void*))
+.PP
+.B
+int inflatezlib(void *wr, int (*w)(void*, void*, int),
+.br
+.B
+ void *getr, int (*get)(void*))
+.PP
+.B
+int inflateblock(uchar *dst, int dsize,
+.br
+.B
+ uchar *src, int ssize)
+.PP
+.B
+int inflatezlibblock(uchar *dst, int dsize,
+.br
+.B
+ uchar *src, int ssize)
+.PP
+.B
+char *flateerr(int error)
+.PP
+.B
+ulong *mkcrctab(ulong poly)
+.PP
+.B
+ulong blockcrc(ulong *tab, ulong crc, void *buf, int n)
+.PP
+.B
+ulong adler32(ulong adler, void *buf, int n)
+.SH DESCRIPTION
+These routines compress and decompress data using the deflate compression algorithm,
+which is used for most gzip, zip, and zlib files.
+.PP
+.I Deflate
+compresses input data retrieved by calls to
+.I r
+with arguments
+.IR rr ,
+an input buffer, and a count of bytes to read.
+.I R
+should return the number of bytes read;
+end of input is signaled by returning zero, an input error by
+returning a negative number.
+The compressed output is written to
+.I w
+with arguments
+.IR wr ,
+the output data, and the number of bytes to write.
+.I W
+should return the number of bytes written;
+writing fewer than the requested number of bytes is an error.
+.I Level
+indicates the amount of computation deflate should do while compressing the data.
+Higher
+.I levels
+usually take more time and produce smaller outputs.
+Valid values are 1 to 9, inclusive; 6 is a good compromise.
+If
+.I debug
+is non-zero, cryptic debugging information is produced on standard error.
+.PP
+.I Inflate
+reverses the process, converting compressed data into uncompressed output.
+Input is retrieved one byte at a time by calling
+.I get
+with the argument
+.IR getr .
+End of input of signaled by returning a negative value.
+The uncompressed output is written to
+.IR w ,
+which has the same interface as for
+.IR deflate .
+.PP
+.I
+Deflateblock
+and
+.I inflateblock
+operate on blocks of memory but are otherwise similar to
+.I deflate
+and
+.IR inflate .
+.PP
+The zlib functions are similar, but operate on files with a zlib header and trailer.
+.PP
+.I Deflateinit
+or
+.I inflateinit
+must be called once before any call to the corresponding routines.
+.PP
+If the above routines fail,
+they return a negative number indicating the problem.
+The possible values are
+.IR FlateNoMem ,
+.IR FlateInputFail ,
+.IR FlateOutputFail ,
+.IR FlateCorrupted ,
+and
+.IR FlateInternal .
+.I Flateerr
+converts the number into a printable message.
+.I FlateOk
+is defined to be zero,
+the successful return value for
+.IR deflateinit ,
+.IR deflate ,
+.IR deflatezlib ,
+.IR inflateinit ,
+.IR inflate ,
+and
+.IR inflatezlib .
+The block functions return the number of bytes produced when they succeed.
+.PP
+.I Mkcrctab
+allocates
+(using
+.IR malloc (2)),
+initializes, and returns a table for rapid computation of 32 bit CRC values using the polynomial
+.IR poly .
+.I Blockcrc
+uses
+.IR tab ,
+a table returned by
+.IR mkcrctab ,
+to update
+.I crc
+for the
+.I n
+bytes of data in
+.IR buf ,
+and returns the new value.
+.I Crc
+should initially be zero.
+.I Blockcrc
+pre-conditions and post-conditions
+.I crc
+by ones complementation.
+.PP
+.I Adler32
+updates the Adler 32-bit checksum of the
+.I n
+butes of data in
+.IR buf.
+The initial value of
+.I adler
+(that is, its value after seeing zero bytes) should be 1.
+.SH SOURCE
+.B /sys/src/libflate
diff --git a/sys/man/2/floor b/sys/man/2/floor
new file mode 100755
index 000000000..9205c011d
--- /dev/null
+++ b/sys/man/2/floor
@@ -0,0 +1,58 @@
+.TH FLOOR 2
+.SH NAME
+fabs, fmod, floor, ceil \- absolute value, remainder, floor, ceiling functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+double floor(double x)
+.PP
+.B
+double ceil(double x)
+.PP
+.B
+double fabs(double x)
+.PP
+.B
+double fmod(double x, double y)
+.SH DESCRIPTION
+.I Fabs
+returns the absolute value
+.RI | \|x\| |.
+.PP
+.I Floor
+returns the
+largest integer
+not greater than
+.IR x .
+.PP
+.I Ceil
+returns the
+smallest integer
+not less than
+.IR x .
+.PP
+.I Fmod
+returns
+.I x
+if
+.I y
+is zero, otherwise the number
+.I f
+with the same sign as
+.IR x ,
+such that
+.I "x = iy + f\|"
+for some integer
+.IR i ,
+and
+.RI | \|f\| |
+<
+.RI | \|y\| |.
+.SH SOURCE
+.B /sys/src/libc/port
+.SH SEE ALSO
+.IR abs (2),
+.IR frexp (2)
diff --git a/sys/man/2/fmtinstall b/sys/man/2/fmtinstall
new file mode 100755
index 000000000..6d10f0eb1
--- /dev/null
+++ b/sys/man/2/fmtinstall
@@ -0,0 +1,372 @@
+.TH FMTINSTALL 2
+.SH NAME
+fmtinstall, dofmt, dorfmt, fmtprint, fmtvprint, fmtrune, fmtstrcpy, fmtrunestrcpy, fmtfdinit, fmtfdflush, fmtstrinit, fmtstrflush, runefmtstrinit, runefmtstrflush, errfmt \- support for user-defined print formats and output routines
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ft L
+.nf
+.ta \w' 'u +\w' 'u +\w' 'u +\w' 'u +\w' 'u
+typedef struct Fmt Fmt;
+struct Fmt{
+ uchar runes; /* output buffer is runes or chars? */
+ void *start; /* of buffer */
+ void *to; /* current place in the buffer */
+ void *stop; /* end of the buffer; overwritten if flush fails */
+ int (*flush)(Fmt*); /* called when to == stop */
+ void *farg; /* to make flush a closure */
+ int nfmt; /* num chars formatted so far */
+ va_list args; /* args passed to dofmt */
+ int r; /* % format Rune */
+ int width;
+ int prec;
+ ulong flags;
+};
+.sp 0.3v
+enum{
+ FmtWidth = 1,
+ FmtLeft = FmtWidth << 1,
+ FmtPrec = FmtLeft << 1,
+ FmtSharp = FmtPrec << 1,
+ FmtSpace = FmtSharp << 1,
+ FmtSign = FmtSpace << 1,
+ FmtZero = FmtSign << 1,
+ FmtUnsigned = FmtZero << 1,
+ FmtShort = FmtUnsigned << 1,
+ FmtLong = FmtShort << 1,
+ FmtVLong = FmtLong << 1,
+ FmtComma = FmtVLong << 1,
+.sp 0.3v
+ FmtFlag = FmtComma << 1
+};
+.fi
+.PP
+.B
+.ta \w'\fLchar* 'u
+.sp 0.3v
+.PP
+.B
+int fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);
+.PP
+.B
+int fmtfdflush(Fmt *f);
+.PP
+.B
+int fmtstrinit(Fmt *f);
+.PP
+.B
+char* fmtstrflush(Fmt *f);
+.PP
+.B
+int runefmtstrinit(Fmt *f);
+.PP
+.B
+Rune* runefmtstrflush(Fmt *f);
+.sp 0.3v
+.PP
+.B
+int fmtinstall(int c, int (*fn)(Fmt*));
+.PP
+.B
+int dofmt(Fmt *f, char *fmt);
+.PP
+.B
+int dorfmt(Fmt*, Rune *fmt);
+.PP
+.B
+int fmtprint(Fmt *f, char *fmt, ...);
+.PP
+.B
+int fmtvprint(Fmt *f, char *fmt, va_list v);
+.PP
+.B
+int fmtrune(Fmt *f, int r);
+.PP
+.B
+int fmtstrcpy(Fmt *f, char *s);
+.PP
+.B
+int fmtrunestrcpy(Fmt *f, Rune *s);
+.PP
+.B
+int errfmt(Fmt *f);
+.SH DESCRIPTION
+The interface described here allows the construction of custom
+.IR print (2)
+verbs and output routines.
+In essence, they provide access to the workings of the formatted print code.
+.PP
+The
+.IR print (2)
+suite maintains its state with a data structure called
+.BR Fmt .
+A typical call to
+.IR print (2)
+or its relatives initializes a
+.B Fmt
+structure, passes it to subsidiary routines to process the output,
+and finishes by emitting any saved state recorded in the
+.BR Fmt .
+The details of the
+.B Fmt
+are unimportant to outside users, except insofar as the general
+design influences the interface.
+The
+.B Fmt
+records whether the output is in runes or bytes,
+the verb being processed, its precision and width,
+and buffering parameters.
+Most important, it also records a
+.I flush
+routine that the library will call if a buffer overflows.
+When printing to a file descriptor, the flush routine will
+emit saved characters and reset the buffer; when printing
+to an allocated string, it will resize the string to receive more output.
+The flush routine is nil when printing to fixed-size buffers.
+User code need never provide a flush routine; this is done internally
+by the library.
+.SS Custom output routines
+To write a custom output routine, such as an error handler that
+formats and prints custom error messages, the output sequence can be run
+from outside the library using the routines described here.
+There are two main cases: output to an open file descriptor
+and output to a string.
+.PP
+To write to a file descriptor, call
+.I fmtfdinit
+to initialize the local
+.B Fmt
+structure
+.IR f ,
+giving the file descriptor
+.IR fd ,
+the buffer
+.IR buf ,
+and its size
+.IR nbuf .
+Then call
+.IR fmtprint
+or
+.IR fmtvprint
+to generate the output.
+These behave like
+.B fprint
+(see
+.IR print (2))
+or
+.B vfprint
+except that the characters are buffered until
+.I fmtfdflush
+is called and the return value is either 0 or \-1.
+A typical example of this sequence appears in the Examples section.
+.PP
+The same basic sequence applies when outputting to an allocated string:
+call
+.I fmtstrinit
+to initialize the
+.BR Fmt ,
+then call
+.I fmtprint
+and
+.I fmtvprint
+to generate the output.
+Finally,
+.I fmtstrflush
+will return the allocated string, which should be freed after use.
+To output to a rune string, use
+.I runefmtstrinit
+and
+.IR runefmtstrflush .
+Regardless of the output style or type,
+.I fmtprint
+or
+.I fmtvprint
+generates the characters.
+.SS Custom format verbs
+.I Fmtinstall
+is used to install custom verbs and flags labeled by character
+.IR c ,
+which may be any non-zero Unicode character.
+.I Fn
+should be declared as
+.IP
+.EX
+int fn(Fmt*)
+.EE
+.PP
+.IB Fp ->r
+is the flag or verb character to cause
+.I fn
+to be called.
+In
+.IR fn ,
+.IB fp ->width ,
+.IB fp ->prec
+are the width and precision, and
+.IB fp ->flags
+the decoded flags for the verb (see
+.IR print (2)
+for a description of these items).
+The standard flag values are:
+.B FmtSign
+.RB ( + ),
+.B FmtLeft
+.RB ( - ),
+.B FmtSpace
+.RB ( '\ ' ),
+.B FmtSharp
+.RB ( # ),
+.B FmtComma
+.RB ( , ),
+.B FmtLong
+.RB ( l ),
+.B FmtShort
+.RB ( h ),
+.B FmtUnsigned
+.RB ( u ),
+and
+.B FmtVLong
+.RB ( ll ).
+The flag bits
+.B FmtWidth
+and
+.B FmtPrec
+identify whether a width and precision were specified.
+.PP
+.I Fn
+is passed a pointer to the
+.B Fmt
+structure recording the state of the output.
+If
+.IB fp ->r
+is a verb (rather than a flag),
+.I fn
+should use
+.B Fmt->args
+to fetch its argument from the list,
+then format it, and return zero.
+If
+.IB fp ->r
+is a flag,
+.I fn
+should return one.
+All interpretation of
+.IB fp ->width\f1,
+.IB fp ->prec\f1,
+and
+.IB fp-> flags
+is left up to the conversion routine.
+.I Fmtinstall
+returns 0 if the installation succeeds, \-1 if it fails.
+.PP
+.IR Fmtprint
+and
+.IR fmtvprint
+may be called to
+help prepare output in custom conversion routines.
+However, these functions clear the width, precision, and flags.
+Both functions return 0 for success and \-1 for failure.
+.PP
+The functions
+.I dofmt
+and
+.I dorfmt
+are the underlying formatters; they
+use the existing contents of
+.B Fmt
+and should be called only by sophisticated conversion routines.
+These routines return the number of characters (bytes of UTF or runes)
+produced.
+.PP
+Some internal functions may be useful to format primitive types.
+They honor the width, precision and flags as described in
+.IR print (2).
+.I Fmtrune
+formats a single character
+.BR r .
+.I Fmtstrcpy
+formats a string
+.BR s ;
+.I fmtrunestrcpy
+formats a rune string
+.BR s .
+.I Errfmt
+formats the system error string.
+All these routines return zero for successful execution.
+Conversion routines that call these functions will work properly
+regardless of whether the output is bytes or runes.
+.PP
+.IR 2c (1)
+describes the C directive
+.B #pragma
+.B varargck
+that can be used to provide type-checking for custom print verbs and output routines.
+.SH EXAMPLES
+This function prints an error message with a variable
+number of arguments and then quits.
+Compared to the corresponding example in
+.IR print (2),
+this version uses a smaller buffer, will never truncate
+the output message, but might generate multiple
+.B write
+system calls to produce its output.
+.IP
+.EX
+.ta 6n +6n +6n +6n +6n +6n +6n +6n +6n
+#pragma varargck argpos fatal 1
+.sp 0.3v
+void
+fatal(char *fmt, ...)
+{
+ Fmt f;
+ char buf[64];
+ va_list arg;
+.sp 0.3v
+ fmtfdinit(&f, 1, buf, sizeof buf);
+ fmtprint(&f, "fatal: ");
+ va_start(arg, fmt);
+ fmtvprint(&f, fmt, arg);
+ va_end(arg);
+ fmtprint(&f, "\en");
+ fmtfdflush(&f);
+ exits("fatal error");
+}
+.EE
+.PP
+This example adds a verb to print complex numbers.
+.IP
+.EX
+typedef struct {
+ double r, i;
+} Complex;
+.sp 0.3v
+#pragma varargck type "X" Complex
+.sp 0.3v
+int
+Xfmt(Fmt *f)
+{
+ Complex c;
+.sp 0.3v
+ c = va_arg(f->args, Complex);
+ return fmtprint(f, "(%g,%g)", c.r, c.i);
+}
+.sp 0.3v
+main(...)
+{
+ Complex x = (Complex){ 1.5, -2.3 };
+.sp 0.3v
+ fmtinstall('X', Xfmt);
+ print("x = %X\en", x);
+}
+.EE
+.SH SOURCE
+.B /sys/src/libc/fmt
+.SH SEE ALSO
+.IR print (2),
+.IR utf (6),
+.IR errstr (2)
+.SH DIAGNOSTICS
+These routines return negative numbers or nil for errors and set
+.IR errstr .
diff --git a/sys/man/2/fopen b/sys/man/2/fopen
new file mode 100755
index 000000000..c91a8bdf9
--- /dev/null
+++ b/sys/man/2/fopen
@@ -0,0 +1,354 @@
+.TH FOPEN 2
+.SH NAME
+fopen, freopen, fdopen, fileno, fclose, sopenr, sopenw, sclose, fflush, setvbuf, setbuf, fgetpos, ftell, fsetpos, fseek, rewind, feof, ferror, clearerr \- standard buffered input/output package
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <stdio.h>
+.PP
+.ta \w'\fLFILE 'u
+.B
+FILE *fopen(char *filename, char *mode)
+.PP
+.B
+FILE *freopen(char *filename, char *mode, FILE *f)
+.PP
+.B
+FILE *fdopen(int fd, char *mode)
+.PP
+.B
+int fileno(FILE *f)
+.PP
+.B
+FILE *sopenr(char *s)
+.PP
+.B
+FILE *sopenw(void)
+.PP
+.B
+char *sclose(FILE *f)
+.PP
+.B
+int fclose(FILE *f)
+.PP
+.B
+int fflush(FILE *f)
+.PP
+.B
+int setvbuf(FILE *f, char *buf, int type, long size)
+.PP
+.B
+void setbuf(FILE *f, char *buf)
+.PP
+.B
+int fgetpos(FILE *f, long *pos)
+.PP
+.B
+long ftell(FILE *f)
+.PP
+.B
+int fsetpos(FILE *f, long *pos)
+.PP
+.B
+int fseek(FILE *f, long offset, int whence)
+.PP
+.B
+void rewind(FILE *f)
+.PP
+.B
+int feof(FILE *f)
+.PP
+.B
+int ferror(FILE *f)
+.PP
+.B
+void clearerr(FILE *f)
+.SH DESCRIPTION
+The functions described in this and related pages
+.RI ( fgetc (2),
+.IR fprintf (2),
+.IR fscanf (2),
+and
+.IR tmpfile (2))
+implement the
+ANSI C buffered I/O package with extensions.
+.PP
+A file with associated buffering is called a
+.I stream
+and is declared to be a pointer to a defined type
+.BR FILE .
+.IR Fopen (2)
+creates certain descriptive data for a stream
+and returns a pointer to designate the stream in all
+further transactions.
+There are three normally open streams with constant
+pointers declared in
+the include file and associated with the standard open files:
+.TP 10n
+.BR stdin
+standard input file
+.br
+.ns
+.TP
+.B stdout
+standard output file
+.br
+.ns
+.TP
+.B stderr
+standard error file
+.PP
+A constant pointer
+.B NULL
+designates no stream at all.
+.PP
+.I Fopen
+opens the file named by
+.I filename
+and associates a stream with it.
+.I Fopen
+returns a pointer to be used to identify
+the stream in subsequent operations, or
+.B NULL
+if the open fails.
+.I Mode
+is a character string having one of the following values:
+.nf
+.ta 8n
+\fL"r"\fP open for reading
+\fL"w"\fP truncate to zero length or create for writing
+\fL"a"\fP append; open or create for writing at end of file
+\fL"r+"\fP open for update (reading and writing)
+\fL"w+"\fP truncate to zero length or create for update
+\fL"a+"\fP append; open or create for update at end of file
+.fi
+.PP
+In addition, each of the above strings can have a
+.L b
+somewhere after the first character,
+meaning `binary file', but this implementation makes no distinction
+between binary and text files.
+.PP
+.I Fclose
+causes the stream pointed to by
+.I f
+to be flushed (see below) and does a
+.I close
+(see
+.IR open (2))
+on the associated file.
+It frees any automatically allocated buffer.
+.I Fclose
+is called automatically on
+.IR exits (2)
+for all open streams.
+.PP
+.I Freopen
+is like open except that it reuses stream pointer
+.IR f .
+.I Freopen
+first attempts to close any file associated with
+.IR f ;
+it ignores any errors in that close.
+.PP
+.I Fdopen
+associates a stream with an open Plan 9 file descriptor.
+.PP
+.I Fileno
+returns the number of the Plan 9 file descriptor associated with the stream.
+.PP
+.I Sopenr
+associates a read-only stream with a null-terminated string.
+.PP
+.I Sopenw
+opens a stream for writing.
+No file descriptor is associated with the stream;
+instead, all output is written to the stream buffer.
+.PP
+.I Sclose
+closes a stream opened with
+.I sopenr
+or
+.IR sopenw .
+It returns a pointer to the 0 terminated buffer associated with the stream.
+.PP
+By default, output to a stream is fully buffered: it is accumulated in
+a buffer until the buffer is full, and then
+.I write
+(see
+.IR read (2))
+is used to write the buffer.
+An exception is standard error, which is line buffered:
+output is accumulated in a buffer until
+a newline is written.
+Input is also fully buffered by default; this means that
+.IR read (2)
+is used to fill a buffer as much as it can, and then characters
+are taken from that buffer until it empties.
+.I Setvbuf
+changes the buffering method for file
+.I f
+according to
+.IR type:
+either
+.B _IOFBF
+for fully buffered,
+.B _IOLBF
+for line buffered,
+or
+.B _IONBF
+for unbuffered (each character causes a
+.I read
+or
+.IR write).
+If
+.I buf
+is supplied, it is used as the buffer and
+.I size
+should be its size;
+If
+.I buf
+is zero, a buffer of the given size is allocated (except for the unbuffered case) using
+.IR malloc (2).
+.PP
+.I Setbuf
+is an older method for changing buffering. If
+.I buf
+is supplied, it changes to fully buffered with the given buffer, which should
+be of size
+.B BUFSIZ
+(defined in
+.BR stdio.h ).
+If
+.I buf
+is zero, the buffering method changes to unbuffered.
+.PP
+.I Fflush
+flushes the buffer of output stream
+.IR f ,
+delivering any unwritten buffered data to the host file.
+.PP
+There is a
+.I file position indicator
+associated with each stream.
+It starts out pointing at the first character (unless the file is opened
+with append mode, in which case the indicator is always ignored).
+The file position indicator is maintained by the reading and writing
+functions described in
+.IR fgetc (2).
+.PP
+.I Fgetpos
+stores the current value of the file position indicator for stream
+.I f
+in the object pointed to by
+.IR pos .
+It returns zero on success, nonzero otherwise.
+.I Ftell
+returns the current value of the file position indicator.
+The file position indicator is to
+be used only as an argument to
+.IR fseek.
+.PP
+.I Fsetpos
+sets the file position indicator for stream
+.I f
+to the value of the object pointed to by
+.IR pos ,
+which shall be a value returned by an earlier call to
+.I fgetpos
+on the same stream.
+It returns zero on success, nonzero otherwise.
+.I Fseek
+obtains a new position, measured in characters from the beginning
+of the file, by adding
+.I offset
+to the position specified by
+.IR whence :
+the beginning of the file if
+.I whence
+is
+.BR SEEK_SET ;
+the current value of the file position indicator for
+.BR SEEK_CUR ;
+and the end-of-file for
+.BR SEEK_END .
+.I Rewind
+sets the file position indicator to the beginning of the file.
+.PP
+An integer constant
+.B EOF
+is returned
+upon end of file or error by integer-valued functions that
+deal with streams.
+.I Feof
+returns non-zero if and only if
+.I f
+is at its end of file.
+.PP
+.I Ferror
+returns non-zero if and only if
+.I f
+is in the error state. It can get into the error state
+if a system call failed on the associated file
+or a memory allocation failed.
+.I Clearerr
+takes a stream out of the error state.
+.SH SOURCE
+.B /sys/src/libstdio
+.SH "SEE ALSO"
+.IR fprintf (2),
+.IR fscanf (2),
+.IR fgetc (2)
+.br
+.IR open (2),
+.IR read (2)
+.SH DIAGNOSTICS
+The value
+.B EOF
+is returned uniformly to indicate that a
+.B FILE
+pointer has not been initialized with
+.IR fopen ,
+input (output) has been attempted on an output (input) stream,
+or a
+.B FILE
+pointer designates corrupt or otherwise unintelligible
+.B FILE
+data.
+.br
+Some of these functions set
+.IR errstr .
+.SH BUGS
+Buffering of output can prevent output data
+from being seen until long after it is computed \- perhaps
+never, as when an abort occurs between buffer filling and flushing.
+.br
+Buffering of input can cause a process to consume
+more input than it actually uses.
+This can cause trouble across
+.IR exec (2).
+.br
+Buffering may delay the receipt of a write error until a subsequent
+.I stdio
+writing, seeking, or file-closing call.
+.br
+ANSI says that a file can be fully buffered only if
+the file is not attached to an interactive device.
+In Plan 9 all are fully buffered except standard error.
+.PP
+.IR Fdopen ,
+.IR fileno ,
+.IR sopenr ,
+.IR sopenw ,
+and
+.I sclose
+are not ANSI Stdio functions.
+.PP
+Stdio offers no support for runes or
+.SM UTF
+characters.
+Unless external compatibility is necessary, use
+.IR bio (2),
+which supports
+.SM UTF
+and is smaller, faster, and simpler than Stdio.
diff --git a/sys/man/2/fork b/sys/man/2/fork
new file mode 100755
index 000000000..6f80e68de
--- /dev/null
+++ b/sys/man/2/fork
@@ -0,0 +1,166 @@
+.TH FORK 2
+.SH NAME
+fork, rfork \- manipulate process resources
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+int fork(void)
+.PP
+.B
+int rfork(int flags)
+.fi
+.SH DESCRIPTION
+Forking is the only way new processes are created.
+The
+.I flags
+argument to
+.I rfork
+selects which resources of the
+invoking process (parent) are shared
+by the new process (child) or initialized to
+their default values.
+The resources include
+the file name space,
+the open file descriptor table (which, when shared, permits processes
+to open and close files for other processes),
+the set of environment variables
+(see
+.IR env (3)),
+the note group
+(the set of processes that receive notes written to a member's
+.B notepg
+file;
+see
+.IR proc (3)),
+the set of rendezvous tags
+(see
+.IR rendezvous (2));
+and open files.
+.I Flags
+is the logical OR of some subset of
+.TF RFCNAMEG
+.TP
+.B RFPROC
+If set a new process is created; otherwise changes affect the
+current process.
+.TP
+.B RFNOWAIT
+If set, the child process will be dissociated from the parent. Upon
+exit the child will leave no
+.B Waitmsg
+(see
+.IR wait (2))
+for the parent to collect.
+.TP
+.B RFNAMEG
+If set, the new process inherits a copy of the parent's name space;
+otherwise the new process shares the parent's name space.
+Is mutually exclusive with
+.BR RFCNAMEG .
+.TP
+.B RFCNAMEG
+If set, the new process starts with a clean name space. A new
+name space must be built from a mount of an open file descriptor.
+Is mutually exclusive with
+.BR RFNAMEG .
+.TP
+.B RFNOMNT
+If set, subsequent mounts into the new name space and dereferencing
+of pathnames starting with
+.B #
+are disallowed.
+.TP
+.B RFENVG
+If set, the environment variables are copied;
+otherwise the two processes share environment variables.
+Is mutually exclusive with
+.BR RFCENVG .
+.TP
+.B RFCENVG
+If set, the new process starts with an empty environment.
+Is mutually exclusive with
+.BR RFENVG .
+.TP
+.B RFNOTEG
+Each process is a member of a group of processes that all
+receive notes when a note is written to any of their
+.B notepg
+files (see
+.IR proc (3)).
+The group of a new process is by default the same as its parent, but if
+.B RFNOTEG
+is set (regardless of
+.BR RFPROC ),
+the process becomes the first in a new group, isolated from
+previous processes.
+.TP
+.B RFFDG
+If set, the invoker's file descriptor table (see
+.IR intro (2))
+is copied; otherwise the two processes share a
+single table.
+.TP
+.B RFCFDG
+If set, the new process starts with a clean file descriptor table.
+Is mutually exclusive with
+.BR RFFDG .
+.TP
+.B RFREND
+If set, the process will be unable to
+.IR rendezvous (2)
+with any of its ancestors; its children will, however, be able to
+.B rendezvous
+with it. In effect,
+.B RFREND
+makes the process the first in a group of processes that share a space for
+.B rendezvous
+tags.
+.TP
+.B RFMEM
+If set, the child and the parent will share
+.B data
+and
+.B bss
+segments.
+Otherwise, the child inherits a copy of those segments.
+Other segment types, in particular stack segments, will be unaffected.
+May be set only with
+.BR RFPROC .
+.PD
+.PP
+File descriptors in a shared file descriptor table are kept
+open until either they are explicitly closed
+or all processes sharing the table exit.
+.PP
+If
+.B RFPROC
+is set, the
+value returned in the parent process
+is the process id
+of the child process; the value returned in the child is zero.
+Without
+.BR RFPROC ,
+the return value is zero.
+Process ids range from 1 to the maximum integer
+.RB ( int )
+value.
+.I Rfork
+will sleep, if necessary, until required process resources are available.
+.PP
+.I Fork
+is just a call of
+.BR rfork(RFFDG|RFREND|RFPROC) .
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.br
+.B /sys/src/libc/9sys/fork.c
+.SH SEE ALSO
+.IR intro (2),
+.IR proc (3),
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
diff --git a/sys/man/2/fprintf b/sys/man/2/fprintf
new file mode 100755
index 000000000..b7f616c33
--- /dev/null
+++ b/sys/man/2/fprintf
@@ -0,0 +1,506 @@
+.TH FPRINTF 2
+.SH NAME
+fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf, vsnprintf \- print formatted output
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <stdio.h>
+.PP
+.B
+int fprintf(FILE *f, char *format, ...)
+.PP
+.B
+int printf(char *format, ...)
+.PP
+.B
+int sprintf(char *s, char *format, ...)
+.PP
+.B
+int snprintf(char *s, int n, char *format, ...)
+.PP
+.B
+int vfprintf(FILE *f, char *format, va_list args)
+.PP
+.B
+int vprintf(char *format, va_list args)
+.PP
+.B
+int vsprintf(char *s, char *format, va_list args)
+.PP
+.B
+int vsnprintf(char *s, int n, char *format, va_list args)
+.SH DESCRIPTION
+.I Fprintf
+places output on the named output stream
+.I f
+(see
+.IR fopen (2)).
+.I Printf
+places output on the standard output stream
+.IR stdout .
+.I Sprintf
+places output
+followed by the null character
+.RB ( \e0 )
+in consecutive bytes starting at
+.IR s ;
+it is the user's responsibility to ensure that
+enough storage is available.
+.I Snprintf
+is like
+.I sprintf
+but writes at most
+.I n
+bytes (including the null character)
+into
+.IR s .
+.IR Vfprintf ,
+.IR vprintf ,
+.IR vsnprintf ,
+and
+.I vsprintf
+are the same, except the
+.I args
+argument is the argument list of the
+calling function, and the effect is as if the calling function's
+argument list from that point on is passed to the
+.I printf
+routines.
+.PP
+Each function returns the number of characters
+transmitted (not including the
+.B \e0
+in the case of
+.IR sprintf
+and friends),
+or
+a negative value if an output error was encountered.
+.PP
+These functions
+convert, format, and print their
+trailing arguments
+under control of a
+.IR format
+string.
+The
+.I format
+contains two types of objects:
+plain characters, which are simply copied to the
+output stream,
+and conversion specifications,
+each of which results in fetching of
+zero or more
+arguments.
+The results are undefined if there are arguments of the
+wrong type or too few
+arguments for the format.
+If the format is exhausted while
+arguments remain, the excess
+are ignored.
+.PP
+Each conversion specification is introduced by
+the character
+.BR % .
+After the
+.BR % ,
+the following
+appear in sequence:
+.PP
+.RS
+Zero or more
+.IR flags ,
+which modify the meaning of
+the conversion specification.
+.PP
+An optional decimal digit string specifying a minimum
+.IR "field width" .
+If the converted value has fewer characters
+than the field width, it will be padded with spaces on the
+left (or right, if the left adjustment, described later, has been given)
+to the field width.
+.PP
+An optional
+.I precision\^
+that gives
+the minimum number of digits to appear for the
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x ,
+and
+.B X
+conversions,
+the number of digits to appear after the
+decimal point for the
+.BR e ,
+.BR E ,
+and
+.B f
+conversions,
+the maximum number of significant digits
+for the
+.B g
+and
+.B G
+conversions,
+or the maximum number of characters
+to be written from a string in
+.B s
+conversion.
+The precision takes the form of a period
+.RB ( \&. )
+followed by an optional decimal integer;
+if the integer is omitted, it is treated as zero.
+.PP
+An optional
+.B h
+specifying that a following
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x
+or
+.BR X
+conversion specifier applies to a
+.B short
+.B int
+or
+.B unsigned
+.B short
+argument (the argument will have been promoted according to the integral
+promotions, and its value shall be converted to
+.B short
+or
+.B unsigned
+.B short
+before printing);
+an optional
+.B h
+specifying that a following
+.B n
+conversion specifier applies to a pointer to a
+.B short
+argument;
+an optional
+.B l
+(ell) specifying that a following
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x ,
+or
+.B X
+conversion character applies to a
+.B long
+or
+.B unsigned
+.B long
+argument;
+an optional
+.B l
+specifying that a following
+.B n
+conversion specifier applies to a pointer to a
+.B long
+.B int
+argument;
+or an optional
+.B L
+specifying that a following
+.BR e ,
+.BR E ,
+.BR f ,
+.BR g ,
+or
+.B G
+conversion specifier applies to a
+.B long double
+argument.
+If an
+.BR h ,
+.BR l ,
+or
+.B L
+appears with any other conversion specifier, the behavior is undefined.
+.PP
+A character that indicates the type of
+conversion to be applied.
+.RE
+.PP
+A field width or precision, or both, may be
+indicated by an asterisk
+.RB ( * )
+instead of a digit string.
+In this case, an
+.B int
+.I arg\^
+supplies
+the field width or precision.
+The arguments specifying field width or precision, or both,
+shall appear (in that order) before the argument (if any) to be converted.
+A negative field width argument is taken as a
+.B -
+flag followed by a positive field width.
+A negative precision is taken as if it were missing.
+.PP
+The flag characters and their meanings are:
+.PD 0
+.TP 10
+.B -
+The result of the conversion is left-justified within the field.
+.TP
+.B +
+The result of a signed
+conversion always begins with a sign
+.RB ( +
+or
+.BR - ).
+.TP
+blank
+If the first character of a signed conversion is not a sign,
+or a signed conversion results in no characters,
+a blank
+is prefixed to the result.
+This implies that if the blank and
+.B +
+flags both appear, the blank flag is ignored.
+.TP
+.B #
+The result is to be converted
+to an ``alternate form.''
+For
+.B o
+conversion, it increases the precision to force
+the first digit of the result to be a zero.
+For
+.B x
+or
+.B X
+conversion, a non-zero result has
+.B 0x
+or
+.B 0X
+prefixed to it.
+For
+.BR e ,
+.BR E ,
+.BR f ,
+.BR g ,
+and
+.B G
+conversions, the result always contains a decimal point,
+even if no digits follow the point (normally, a decimal point
+appears in the result of these conversions only if a digit
+follows it).
+For
+.B g
+and
+.B G
+conversions, trailing zeros are
+.I not\^
+be removed from the result
+as they normally are.
+For other conversions, the behavior is undefined.
+.TP
+.B 0
+For
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x ,
+.BR X ,
+.BR e ,
+.BR E ,
+.BR f ,
+.BR g ,
+and
+.B G
+conversions, leading zeros (following any indication of sign or base)
+are used to pad the field width; no space padding is performed.
+If the
+.B 0
+and
+.B -
+flags both appear, the
+.B 0
+flag will be ignored.
+For
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x ,
+and
+.B X
+conversions, if a precision is specified, the
+.B 0
+flag will be ignored.
+For other conversions, the behavior is undefined.
+.PD
+.PP
+The conversion characters
+and their meanings are:
+.PP
+.PD 0
+.TP 10
+\fLd\fP,\fLo\fP,\fLu\fP,\fLx\fP,\fLX\fP
+The integer
+.I arg\^
+is converted to signed decimal
+.RB ( d
+or
+.BR i ),
+unsigned octal
+.RB ( o ),
+unsigned decimal
+.RB ( u ),
+or unsigned hexadecimal notation
+.RB ( x
+or
+.BR X );
+the letters
+.B abcdef
+are used for
+.B x
+conversion and the letters
+.B ABCDEF
+for
+.B X
+conversion.
+The precision specifies the minimum number of digits
+to appear; if the value being converted can be represented
+in fewer digits, it is expanded with leading zeros.
+The default precision is 1.
+The result of converting a zero value with a precision
+of zero is no characters.
+.TP
+.BR f
+The
+.B double
+argument is converted to decimal notation
+in the style
+[\-]\fIddd\fL.\fIddd\fR,
+where the number of digits after the decimal point
+is equal to the precision specification.
+If the precision
+is missing,
+it is taken as 6;
+if the precision is explicitly
+.LR 0 ,
+no decimal point appears.
+.TP
+.BR e , E
+The
+.B double
+argument is converted in the style
+[\-]\fId\fL.\fIddd\fLe\fR±\fIdd\fR,
+where there is one digit before the decimal point and
+the number of digits after it is equal to the
+precision;
+when the precision is missing, it is taken as 6;
+if the precision is zero, no decimal point appears.
+The
+.B E
+format code produces a number with
+.B E
+instead of
+.B e
+introducing the exponent.
+The exponent always contains at least two digits.
+.TP
+.BR g , G
+The
+.B double
+argument is printed in style
+.BR f
+or
+.BR e
+(or in style
+.B E
+in the case of a
+.B G
+conversion specifier),
+with the precision specifying the number of significant digits.
+If an explicit precision is zero, it is taken as 1.
+The style used depends on the value converted:
+style
+.B e
+is used only if the exponent resulting from
+the conversion is less than \-4
+or greater than or equal to the precision.
+Trailing zeros are removed from the fractional portion of the result;
+a decimal point appears only if it is followed by a digit.
+.TP
+.B c
+The
+.B int
+argument is converted to an
+.B unsigned
+.BR char ,
+and the resulting character is written.
+.TP
+.B s
+The
+argument is taken to be a string (character pointer)
+and characters from the string are printed until
+a null character
+.RB ( \e0 )
+is encountered or
+the number of characters indicated by the precision
+specification is reached.
+If the precision is missing, it is taken to be infinite, so
+all characters up to the first null character are printed.
+A
+zero
+value for
+the argument yields undefined results.
+.TP
+.B P
+The
+.B void*
+argument is printed in an implementation-defined way (for Plan 9:
+the address as hexadecimal number).
+.TP
+.B n
+The argument shall be a pointer to an integer into which is
+.I written
+the number of characters written to the output stream so far by
+this call to
+.IR fprintf .
+No argument is converted.
+.TP
+.B %
+Print a
+.BR % ;
+no argument is converted.
+.PD
+.PP
+If a conversion specification is invalid, the behavior is undefined.
+.PP
+If any argument is, or points to, a union or an aggregate
+(except for an array of character type using
+.B %s
+conversion, or a pointer cast to be a pointer to
+.B void
+using
+.B %P
+conversion), the behavior is undefined.
+.PP
+In no case does a nonexistent or small field width cause truncation
+of a field; if the result of a conversion is wider than the field width,
+the field is expanded to contain the conversion result.
+.SH SOURCE
+.B /sys/src/libstdio
+.SH SEE ALSO
+.IR fopen (2),
+.IR fscanf (2),
+.IR print (2)
+.SH BUGS
+There is no way to print a wide character (rune); use
+.IR print (2)
+or
+.IR bio (2).
diff --git a/sys/man/2/frame b/sys/man/2/frame
new file mode 100755
index 000000000..1ef43dbfe
--- /dev/null
+++ b/sys/man/2/frame
@@ -0,0 +1,362 @@
+.TH FRAME 2
+.SH NAME
+frinit, frsetrects, frinittick, frclear, frcharofpt, frptofchar, frinsert, frdelete, frselect, frtick, frselectpaint, frdrawsel, frdrawsel0, frgetmouse \- frames of text
+.SH SYNOPSIS
+.nf
+.B
+#include <u.h>
+.B
+#include <libc.h>
+.B
+#include <draw.h>
+.B
+#include <thread.h>
+.B
+#include <mouse.h>
+.B
+#include <frame.h>
+.PP
+.B
+void frinit(Frame *f, Rectangle r, Font *ft, Image *b, Image **cols)
+.PP
+.B
+void frsetrects(Frame *f, Rectangle r, Image *b)
+.PP
+.B
+void frinittick(Frame *f)
+.PP
+.B
+void frclear(Frame *f, int resize)
+.PP
+.B
+ulong frcharofpt(Frame *f, Point pt)
+.PP
+.B
+Point frptofchar(Frame *f, ulong p)
+.PP
+.B
+void frinsert(Frame *f, Rune *r0, Rune *r1, ulong p)
+.PP
+.B
+int frdelete(Frame *f, ulong p0, ulong p1)
+.PP
+.B
+void frselect(Frame *f, Mousectl *m)
+.PP
+.B
+void frtick(Frame *f, Point pt, int up)
+.PP
+.B
+void frselectpaint(Frame *f, Point p0, Point p1, Image *col)
+.PP
+.B
+void frdrawsel(Frame *f, Point pt0, ulong p0, ulong p1,
+.B
+ int highlighted)
+.PP
+.B
+void frdrawsel0(Frame *f, Point pt0, ulong p0, ulong p1,
+.B
+ Image *back, Image *text)
+.PP
+.ft L
+enum{
+ BACK,
+ HIGH,
+ BORD,
+ TEXT,
+ HTEXT,
+ NCOL
+};
+.fi
+.SH DESCRIPTION
+This library supports
+.I frames
+of editable text in a single font on raster displays, such as in
+.IR sam (1)
+and
+.IR rio (1).
+Frames may hold any character except NUL (0).
+Long lines are folded and tabs are at fixed intervals.
+.PP
+The user-visible data structure, a
+.BR Frame ,
+is defined in
+.BR <frame.h> :
+.IP
+.EX
+.ta 6n +\w'Rectangle 'u +\w'lastlinefull; 'u
+typedef struct Frame Frame;
+struct Frame
+{
+ Font *font; /* of chars in the frame */
+ Display *display; /* on which frame appears */
+ Image *b; /* on which frame appears */
+ Image *cols[NCOL]; /* text and background colors */
+ Rectangle r; /* in which text appears */
+ Rectangle entire; /* of full frame */
+ Frbox *box;
+ ulong p0, p1; /* selection */
+ ushort nbox, nalloc;
+ ushort maxtab; /* max size of tab, in pixels */
+ ushort nchars; /* # runes in frame */
+ ushort nlines; /* # lines with text */
+ ushort maxlines; /* total # lines in frame */
+ ushort lastlinefull; /* last line fills frame */
+ ushort modified; /* changed since frselect() */
+ Image *tick; /* typing tick */
+ Image *tickback; /* saved image under tick */
+ int ticked; /* flag: is tick onscreen? */
+};
+.EE
+.PP
+.B Frbox
+is an internal type and is not used by the interface.
+.B P0
+and
+.B p1
+may be changed by the application provided the selection routines are called
+afterwards to maintain a consistent display.
+.I Maxtab
+determines the size of tab stops.
+.I Frinit
+sets it to 8 times the width of a
+.B 0
+(zero)
+character in the font;
+it may be changed before any text is added to the frame.
+The other elements of the structure are maintained by the library and
+should not be modified directly.
+.PP
+The text within frames
+is not directly addressable;
+instead frames are designed to work alongside
+another structure that holds the text.
+The typical application is to display a section of a longer document such
+as a text file or terminal session.
+Usually the program will keep its own copy of the
+text in the window (probably as
+an array of
+.BR Runes )
+and pass components of this text to the frame routines to
+display the visible portion.
+Only the text that is visible is held by the
+.BR Frame ;
+the application must check
+.BR maxlines ,
+.BR nlines ,
+and
+.B lastlinefull
+to determine, for example, whether new text needs to be appended
+at the end of the
+.B Frame
+after calling
+.I frdelete
+(q.v.).
+.PP
+There are no routines in the library to allocate
+.BR Frames ;
+instead the interface assumes that
+.B Frames
+will be components of larger structures.
+.I Frinit
+prepares the
+.B Frame
+.I f
+so characters drawn in it will appear
+in the single
+.B Font
+.IR ft .
+It then calls
+.I frsetrects
+and
+.I frinittick
+to initialize the geometry for the
+.BR Frame .
+The
+.B Image
+.I b
+is where the
+.B Frame
+is to be drawn;
+.B Rectangle
+.I r
+defines the limit of the portion of the
+.B Image
+the text will occupy.
+The
+.B Image
+pointer
+may be null, allowing the other routines to be called to maintain the
+associated data structure in, for example, an obscured window.
+.PP
+The array of
+.B Images
+cols sets the colors in which text and borders will be drawn. The background of the frame will be drawn in
+.BR cols[BACK] ;
+the background of highlighted text in
+.BR cols[HIGH] ;
+borders and scroll bar in
+.BR cols[BORD] ;
+regular text in
+.BR cols[TEXT] ;
+and highlighted text in
+.BR cols[HTEXT] .
+.PP
+.I Frclear
+frees the internal structures associated with
+.IR f ,
+permitting another
+.I frinit
+or
+.I frsetrects
+on the
+.BR Frame .
+It does not clear the associated display.
+If
+.I f
+is to be deallocated, the associated
+.B Font
+and
+.B Image
+must be freed separately.
+The
+.B resize
+argument should be non-zero if the frame is to be redrawn with
+a different font; otherwise the frame will maintain some
+data structures associated with the font.
+.PP
+To resize a
+.BR Frame ,
+use
+.I frclear
+and
+.I frinit
+and then
+.I frinsert
+(q.v.) to recreate the display.
+If a
+.B Frame
+is being moved but not resized, that is, if the shape of its containing
+rectangle is unchanged, it is sufficient to use
+.IR draw (2)
+to copy the containing rectangle from the old to the new location and then call
+.I frsetrects
+to establish the new geometry.
+(It is unnecessary to call
+.I frinittick
+unless the font size has changed.)
+No redrawing is necessary.
+.PP
+.B Frames
+hold text as runes,
+not as bytes.
+.I Frptofchar
+returns the location of the upper left corner of the
+.I p'th
+rune, starting from 0, in the
+.B Frame
+.IR f .
+If
+.I f
+holds fewer than
+.I p
+runes,
+.I frptofchar
+returns the location of the upper right corner of the last character in
+.IR f .
+.I Frcharofpt
+is the inverse: it
+returns the index of the closest rune whose image's upper left corner
+is up and to the left of
+.IR pt .
+.PP
+.I Frinsert
+inserts into
+.B Frame
+.I f
+starting at rune index
+.I p
+the runes between
+.I r0
+and
+.IR r1 .
+If a NUL (0) character
+is inserted, chaos will ensue.
+Tabs and newlines
+are handled by the library, but all other characters,
+including control characters, are just displayed.
+For example, backspaces are printed; to erase
+a character, use
+.IR frdelete .
+.PP
+.I Frdelete
+deletes from the
+.B Frame
+the text between
+.I p0
+and
+.IR p1 ;
+.I p1
+points at the first rune beyond the deletion.
+.PP
+.I Frselect
+tracks the mouse to select a contiguous string of text in the
+.BR Frame .
+When called, a mouse button is typically down.
+.I Frselect
+will return when the button state has changed (some buttons may
+still be down) and will set
+.IB f ->p0
+and
+.IB f ->p1
+to the selected range of text.
+.PP
+Programs that wish to manage the selection themselves have several routines to help.
+They involve the maintenance of the `tick', the vertical line indicating a null selection
+between characters, and the colored region representing a non-null selection.
+.I Frtick
+draws (if
+.I up
+is non-zero) or removes (if
+.I up
+is zero) the tick at the screen position indicated by
+.IR pt .
+.I Frdrawsel
+repaints a section of the frame, delimited by character positions
+.I p0
+and
+.IR p1 ,
+either with plain background or
+entirely highlighted, according to the flag
+.IR highlighted ,
+managing the tick appropriately.
+The point
+.I pt0
+is the geometrical location of
+.I p0
+on the screen; like all of the selection-helper routines'
+.B Point
+arguments, it must be a value generated by
+.IR frptofchar .
+.I Frdrawsel0
+is a lower-level routine, taking as arguments a background color,
+.IR back ,
+and text color,
+.IR text .
+It assumes that the tick is being handled (removed beforehand, replaced afterwards, as required)
+by its caller.
+.I Frselectpaint
+uses a solid color,
+.IR col ,
+to paint a region of the frame defined by the
+.B Points
+.I p0
+and
+.IR p1 .
+.SH SOURCE
+.B /sys/src/libframe
+.SH SEE ALSO
+.IR graphics (2),
+.IR draw (2),
+.IR cachechars (2).
diff --git a/sys/man/2/frexp b/sys/man/2/frexp
new file mode 100755
index 000000000..59b4eabcc
--- /dev/null
+++ b/sys/man/2/frexp
@@ -0,0 +1,47 @@
+.TH FREXP 2
+.SH NAME
+frexp, ldexp, modf \- split into mantissa and exponent
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+double frexp(double value, int *eptr)
+.PP
+.B
+double ldexp(double value, int exp)
+.PP
+.B
+double modf(double value, double *iptr)
+.SH DESCRIPTION
+.I Frexp
+returns the mantissa of
+.I value
+and stores the exponent indirectly through
+.IR eptr ,
+so that
+.I value
+=
+.if t .IR frexp ( value )×2\u\s-2 (*eptr) \s0\d
+.if n .IR frexp ( value )*2** (*eptr).
+.PP
+.I Ldexp
+returns the quantity
+.if t .IR value ×2\u\s-2 exp \s0\d.
+.if n .IR value *2** exp.
+.PP
+.I Modf
+returns the signed fractional part of
+.I value
+and stores the integer part indirectly
+through
+.IR iptr .
+.SH SOURCE
+.B /sys/src/libc/port/frexp.c
+.SH SEE ALSO
+.IR intro (2)
+.SH DIAGNOSTICS
+.I Ldexp
+returns 0 for underflow and the appropriately signed infinity
+for overflow.
diff --git a/sys/man/2/fscanf b/sys/man/2/fscanf
new file mode 100755
index 000000000..d57c06b0f
--- /dev/null
+++ b/sys/man/2/fscanf
@@ -0,0 +1,404 @@
+.TH FSCANF 2
+.SH NAME
+fscanf, scanf, sscanf, vfscanf \- scan formatted input
+.SH SYNOPSIS
+.B "#include <u.h>
+.br
+.B "#include <stdio.h>"
+.PP
+.B
+int fscanf(FILE *f, char *format, ...)
+.PP
+.B
+int scanf(char *format, ... )
+.PP
+.B
+int sscanf(char *s, char *format, ...)
+.PP
+.B
+int vfscanf(FILE *stream, char *format, char *args)
+.SH DESCRIPTION
+.I Fscanf
+reads from the named input stream
+.I f
+(see
+.IR fopen (2))
+under control of the string pointed to by
+.I format
+that specifies the admissible input sequences and how they are to be converted
+for assignment, using subsequent arguments as pointers to the objects
+to receive the converted input.
+If there are insufficient arguments for the format, the behavior is undefined.
+If the format is exhausted while arguments remain, the excess arguments
+are evaluated (as always) but are otherwise ignored.
+.PP
+.I Scanf
+and
+.I sscanf
+are the same, but they read from
+.I stdin
+and the character string
+.IR s ,
+respectively.
+.I Vfscanf
+is like
+.IR scanf ,
+except the
+.I args
+argument is a pointer to an argument in an argument list of the
+calling function and the effect is as if the calling function's
+argument list from that point on is passed to the scanf routines.
+.PP
+The format is composed of zero or more directives:
+one or more white-space characters; an ordinary character (not
+.BR % );
+or a conversion specification.
+Each conversion specification is introduced by the character
+.BR %.
+After the
+.BR % ,
+the following appear in sequence:
+.PP
+.RS
+An optional assignment-suppressing character
+.BR * .
+.PP
+An optional decimal integer that specifies the maximum field width.
+.PP
+An optional
+.BR h ,
+.B l
+(ell) or
+.B L
+indicating the size of the receiving object.
+The conversion specifiers
+.BR d ,
+.BR i ,
+and
+.B n
+shall be preceded by
+.B h
+if the corresponding argument is a pointer to
+.B short
+rather than a pointer to
+.BR int ,
+or by
+.B l
+if it is a pointer to
+.BR long .
+Similarly, the conversion specifiers
+.BR o ,
+.BR u ,
+and
+.B x
+shall be preceded by
+.B h
+if the corresponding argument is a pointer to
+.B unsigned
+.B short
+rather than a pointer to
+.BR unsigned ,
+or by
+.B l
+if it is a pointer to
+.B unsigned
+.BR long .
+Finally, the conversion specifiers
+.BR e ,
+.BR f ,
+and
+.B g
+shall be preceded by
+.B l
+if the corresponding argument is a pointer to
+.B double
+rather than a pointer to
+.BR float ,
+or by
+.B L
+if it is a pointer to
+.B long
+.BR double .
+If an
+.BR h ,
+.BR l ,
+or
+.B L
+appears with any other conversion specifier, the behavior is undefined.
+.PP
+A character that specifies the type of conversion to be applied.
+The valid conversion specifiers are described below.
+.RE
+.PP
+.I Fscanf
+executes each directive of the format in turn.
+If a directive fails, as detailed below,
+.I fscanf
+returns.
+Failures are described as input failures (due to the unavailability
+of input),
+or matching failures (due to inappropriate input).
+.PP
+A directive composed of white space is executed by reading input up
+to the first non-white-space character (which remains unread),
+or until no more characters can be read.
+.PP
+A directive that is an ordinary character is executed by reading
+the next character from the stream.
+If if differs from the one comprising the directive,
+the directive fails, and the differing and subsequent characters
+remain unread.
+.PP
+A directive that is a conversion specification defines a set of
+matching input sequences, as described below for each specifier.
+A conversion specification is executed in the following steps:
+.PP
+Input white-space characters (as specified by
+.IR isspace ,
+see
+.IR ctype (2))
+are skipped, unless the specification includes a
+.BR [ ,
+.BR c ,
+or
+.B n
+specifier.
+.PP
+An input item is read from the stream,
+unless the specification includes an
+.B n
+specifier.
+An input item is defined as the longest sequence of input characters
+(up to any specified maximum field width) which is an initial
+subsequence of a matching sequence.
+The first character, if any, after the input item remains unread.
+If the length of the input item is zero, the execution of
+the directive fails: this condition is a matching failure,
+unless an error prevented input from the stream,
+in which case it is an input failure.
+.PP
+Except in the case of a
+.B %
+specifier, the input item (or, in the case of a
+.B %n
+directive, the count of input characters)
+is converted to a type appropriate to the conversion specifier.
+If the input item is not a matching sequence, the execution of
+the directive fails: this condition is a matching failure.
+Unless assignment suppression was indicated by a
+.BR * ,
+the result of the conversion is placed in the object pointed to by the
+first argument following the
+.I format
+argument that has not already received a conversion result.
+If this object does not have an appropriate type,
+or if the result of the conversion cannot be represented
+in the space provided, the behavior is undefined.
+.PP
+The following conversion specifiers are valid:
+.TP 6
+.B d
+Matches an optionally signed decimal integer,
+whose format is the same as expected for the subject sequence
+of the
+.I strtol
+(see
+.IR atof (2))
+function with 10 for the
+.B base
+argument.
+The corresponding argument shall be a pointer to
+.BR int .
+.TP
+.B i
+Matches an optionally signed decimal integer,
+whose format is the same as expected for the subject sequence
+of the
+.I strtol
+function with 0 for the
+.B base
+argument.
+The corresponding argument shall be a pointer to
+.BR int .
+.TP
+.B o
+Matches an optionally signed octal integer,
+whose format is the same as expected for the subject sequence
+of the
+.I strtoul
+(see
+.IR atof (2))
+function with 8 for the
+.B base
+argument.
+The corresponding argument shall be a pointer to
+.B unsigned
+.BR int .
+.TP
+.B u
+Matches an optionally signed decimal integer,
+whose format is the same as expected for the subject sequence
+of the
+.I strtoul
+function with 10 for the
+.B base
+argument.
+The corresponding argument shall be a pointer to
+.B unsigned
+.BR int .
+.TP
+.B x
+Matches an optionally signed hexadecimal integer,
+whose format is the same as expected for the subject sequence
+of the
+.I strtoul
+function with 16 for the
+.B base
+argument.
+The corresponding argument shall be a pointer to
+.B unsigned
+.BR int .
+.TP
+.BR e , f , g
+Matches an optionally signed floating-point number, whose format is
+the same as expected for the subject string of the
+.I strtod
+(see
+.IR atof (2))
+function.
+The corresponding argument shall be a pointer to
+.BR float .
+.TP
+.B s
+Matches a sequence of non-white-space characters.
+The corresponding argument shall be a pointer to the initial
+character of an array large enough to accept the sequence
+and a terminating NUL (0) character, which will be added automatically.
+.TP
+.B [
+Matches a nonempty sequence of characters from a set of expected
+characters (the
+.IR scanset ).
+The corresponding argument shall be a pointer to the initial
+character of an array large enough to accept the sequence and a terminating
+NUL character, which will be added automatically.
+The conversion specifier includes all subsequent characters in the
+.I format
+string, up to and including the matching right brace
+.RB ( ] ).
+The characters between the brackets (the
+.IR scanlist )
+comprise the scanset, unless the character after the left bracket
+is a circumflex
+.RB ( ^ ),
+in which case the scanset contains all characters that do not appear
+in the scanlist between the circumflex and the right bracket.
+As a special case, if the conversion specifier begins with
+.B []
+or
+.BR [^] ,
+the right bracket character is in the scanlist and the next
+right bracket character is the matching right bracket
+that ends the specification.
+If a
+.B -
+character is in the scanlist and is not the first, nor the second
+where the first character is a
+.BR ^ ,
+nor the last character, the behavior is implementation-defined
+(in Plan 9: the scanlist includes all characters in the
+.SM ASCII
+(sic)
+range between the two characters on either side of the
+.BR - ).
+.TP
+.B c
+Matches a sequence of characters of the number specified by the field width
+(1 if no field width is present in the directive).
+The corresponding argument shall be a pointer to the initial character
+of an array large enough to accept the sequence.
+No NUL character is added.
+.TP
+.B P
+Matches an implementation-defined set of sequences,
+which should be the same as the set of sequences that may be
+produced by the
+.B %P
+conversion of the
+.IR fprintf (2)
+function
+(in Plan 9, a hexadecimal number).
+The corresponding argument shall be a pointer to a pointer to
+.BR void .
+The interpretation of the input item is implementation defined;
+however, for any input item other than a value converted earlier
+during the same program execution, the behavior of the
+.B %P
+conversion is undefined.
+.TP
+.B n
+No input is consumed.
+The corresponding argument shall be a pointer to integer into which
+is written the number of characters read from the input stream so far
+by this call to
+.IR fscanf .
+Execution of a
+.B %n
+directive does not increment the assignment count returned at the
+completion of
+.IR fscanf .
+.TP
+.B %
+Matches a single
+.BR % ;
+no conversion or assignment occurs.
+The complete conversion specification shall be
+.BR %% .
+.PD
+.PP
+If a conversion specification is invalid, the behavior is undefined.
+.PP
+The conversion specifiers
+.BR E ,
+.BR G ,
+and
+.B X
+are also valid and behave the same as, respectively,
+.BR e ,
+.BR g ,
+and
+.BR x .
+.PP
+If end-of-file is encountered during input, conversion is terminated.
+If end-of-file occurs before any characters matching the current
+directive have been read (other than leading white space,
+where permitted), execution of the current directive terminates with
+an input failure;
+otherwise, unless execution of the current directive is terminated
+with a matching failure, execution of the following directive
+(if any) is terminated with an input failure.
+.PP
+If conversion terminates on a conflicting input character,
+the offending input character is left unread in the input stream.
+Trailing white space (including newline characters) is left unread
+unless matched by a directive.
+The success of literal matches and suppressed assignments is not
+directly determinable other than via the
+.B %n
+directive.
+.PP
+The return value from
+.I fscanf
+is the number of input items assigned, which can be fewer than
+provided for, or even zero, in the event of an early matching failure.
+However, if an input failure occurs before any conversion,
+.B EOF
+is returned.
+.SH SOURCE
+.B /sys/src/libstdio
+.SH "SEE ALSO"
+.IR fopen (2),
+.IR fgetc (2)
+.SH BUGS
+Does not know about
+.SM UTF.
diff --git a/sys/man/2/fversion b/sys/man/2/fversion
new file mode 100755
index 000000000..711cca7ba
--- /dev/null
+++ b/sys/man/2/fversion
@@ -0,0 +1,72 @@
+.TH FVERSION 2
+.SH NAME
+fversion \- initialize 9P connection and negotiate version
+.SH SYNOPSIS
+.nf
+.PP
+.ft L
+#include <u.h>
+#include <libc.h>
+.PP
+.ft P
+.B
+int fversion(int fd, int bufsize, char *version, int nversion)
+.SH DESCRIPTION
+.PP
+.I Fversion
+is used to initialize the 9P connection represented by
+.I fd
+and to negotiate the version of the protocol to be used.
+.PP
+The
+.I bufsize
+determines the size of the I/O buffer used to stage 9P requests to the server,
+subject to the constraints of the server itself.
+The
+.I version
+is a text string that represents the highest version level the protocol will support.
+The
+.I version
+will be overwritten with the negotiated, possibly lower, version of the protocol.
+The return value of
+.I fversion
+is the length of the returned version string; the value of
+.I nversion
+is therefore not the length of the version string presented to the system call,
+but the total length of the buffer to accept the final result, in the manner of a read system call.
+.PP
+Default values of zero for
+.I bufsize
+and the empty string for
+.I version
+will negotiate sensible defaults for the connection.
+If
+.I version
+is the empty string,
+.I nversion
+must still be large enough to receive the returned version string.
+.PP
+The interpretation of the version strings is defined in
+.IR version (5).
+.PP
+It is rare to use
+.IR fversion
+directly; usually the default negotiation performed
+by the kernel during
+.B mount
+(see
+.IR bind (2))
+or even more commonly
+.B amount
+(see
+.IR auth (2))
+is sufficient.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (5),
+.IR version (5),
+.IR fauth (2).
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/getcallerpc b/sys/man/2/getcallerpc
new file mode 100755
index 000000000..b5e6a7775
--- /dev/null
+++ b/sys/man/2/getcallerpc
@@ -0,0 +1,38 @@
+.TH GETCALLERPC 2
+.SH NAME
+getcallerpc \- fetch return PC of current function
+.SH SYNOPSIS
+.br
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B uintptr getcallerpc(void *firstarg)
+.SH DESCRIPTION
+.I Getcallerpc
+is a portable way to discover the PC to which the current function will return.
+.I Firstarg
+should be a pointer to the first argument to the function in question.
+.SH EXAMPLE
+.IP
+.EX
+void
+printpc(int arg)
+{
+ print("Called from %p\en", getcallerpc(&arg));
+}
+
+void
+main(int argc, char *argv[])
+{
+ printpc(0);
+ printpc(0);
+ printpc(0);
+}
+.EE
+.SH SOURCE
+.B /sys/src/libc/$objtype/getcallerpc.[cs]
+.SH BUGS
+The
+.I firstarg
+parameter should not be necessary.
diff --git a/sys/man/2/getenv b/sys/man/2/getenv
new file mode 100755
index 000000000..339acb823
--- /dev/null
+++ b/sys/man/2/getenv
@@ -0,0 +1,44 @@
+.TH GETENV 2
+.SH NAME
+getenv, putenv \- access environment variables
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+char* getenv(char *name)
+.br
+.B
+int putenv(char *name, char *val)
+.fi
+.SH DESCRIPTION
+.I Getenv
+reads the contents of
+.BI /env/ name
+(see
+.IR env (3))
+into memory allocated with
+.IR malloc (2),
+0-terminates it,
+and returns a pointer to that area.
+If no file exists, 0
+is returned.
+.PP
+.I Putenv
+creates the file
+.BI /env/ name
+and writes the string
+.I val
+to it. The terminating
+.B 0
+is not written.
+If the file value cannot be written, \-1 is returned.
+.SH SOURCE
+.B /sys/src/libc/9sys
+.SH SEE ALSO
+.IR env (3)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/getfcr b/sys/man/2/getfcr
new file mode 100755
index 000000000..87e93d5a2
--- /dev/null
+++ b/sys/man/2/getfcr
@@ -0,0 +1,119 @@
+.TH GETFCR 2
+.SH NAME
+getfcr, setfcr, getfsr, setfsr \- control floating point
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+ulong getfcr(void)
+.PP
+.B
+void setfcr(ulong fcr)
+.PP
+.B
+ulong getfsr(void)
+.PP
+.B
+void setfsr(ulong fsr)
+.SH DESCRIPTION
+These routines provide a fairly portable interface to control the
+rounding and exception characteristics of IEEE 754 floating point units.
+In effect, they define a pair of pseudo-registers, the floating
+point control register,
+.BR fcr ,
+which affects rounding, precision, and exceptions, and the
+floating point status register,
+.BR fsr ,
+which holds the accrued exception bits.
+Each register has a
+.I get
+routine to retrieve its value, a
+.I set
+routine to modify it,
+and macros that identify its contents.
+.PP
+The
+.B fcr
+contains bits that, when set, halt execution upon exceptions:
+.B FPINEX
+(enable inexact exceptions),
+.B FPOVFL
+(enable overflow exceptions),
+.B FPUNFL
+(enable underflow exceptions),
+.B FPZDIV
+(enable zero divide exceptions), and
+.B FPINVAL
+(enable invalid operation exceptions).
+Rounding is controlled by installing in
+.BR fcr ,
+under mask
+.BR FPRMASK ,
+one of the values
+.B FPRNR
+(round to nearest),
+.B FPRZ
+(round towards zero),
+.B FPRPINF
+(round towards positive infinity), and
+.B FPRNINF
+(round towards negative infinity).
+Precision is controlled by installing in
+.BR fcr ,
+under mask
+.BR FPPMASK ,
+one of the values
+.B FPPEXT
+(extended precision),
+.B FPPSGL
+(single precision), and
+.B FPPDBL
+(double precision).
+.PP
+The
+.B fsr
+holds the accrued exception bits
+.BR FPAINEX ,
+.BR FPAOVFL ,
+.BR FPAUNFL ,
+.BR FPAZDIV ,
+and
+.BR FPAINVAL ,
+corresponding to the
+.B fsr
+bits without the
+.B A
+in the name.
+.PP
+Not all machines support all modes. If the corresponding mask
+is zero, the machine does not support the rounding or precision modes.
+On some machines it is not possible to clear selective accrued
+exception bits; a
+.I setfsr
+clears them all.
+The exception bits defined here work on all architectures.
+Where possible, the initial state is equivalent to
+.IP
+.EX
+setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL);
+.EE
+.PP
+However, this may vary between architectures:
+the default is to provide what the hardware does most efficiently.
+Use these routines
+if you need guaranteed behavior.
+Also, gradual underflow is not available on some machines.
+.SH EXAMPLE
+To enable overflow traps and make sure registers are rounded
+to double precision (for example on the MC68020, where the
+internal registers are 80 bits long):
+.EX
+.IP
+.ft L
+setfcr((getfcr() & ~FPPMASK) | FPPDBL | FPOVFL);
+.ft
+.EE
+.SH SOURCE
+.B /sys/src/libc/$objtype/getfcr.s
diff --git a/sys/man/2/getfields b/sys/man/2/getfields
new file mode 100755
index 000000000..9a5281fda
--- /dev/null
+++ b/sys/man/2/getfields
@@ -0,0 +1,99 @@
+.TH GETFIELDS 2
+.SH NAME
+getfields, gettokens, tokenize \- break a string into fields
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLchar* \fP'u
+.B
+int getfields(char *str, char **args, int maxargs, int multiflag,
+.br
+.B
+ char *delims)
+.PP
+.B
+int gettokens(char *str, char **args, int maxargs, char *delims)
+.PP
+.B
+int tokenize(char *str, char **args, int maxargs)
+.SH DESCRIPTION
+.I Getfields
+places into the array
+.I args
+pointers to the first
+.I maxargs
+fields of the null terminated
+.SM UTF
+string
+.IR str .
+Delimiters between these fields are set to null.
+.PP
+Fields are substrings of
+.I str
+whose definition depends on the value of
+.IR multiflag.
+If
+.I multiflag
+is zero,
+adjacent fields are separated by exactly one delimiter.
+For example
+.EX
+
+ getfields("#alice#bob##charles###", arg, 3, 0, "#");
+
+.EE
+yields three substrings:
+null-string ,
+.BR "alice" ,
+and
+.BR "bob##charles###" .
+If the
+.I multiflag
+argument is not zero,
+a field is a non-empty string of non-delimiters.
+For example
+.EX
+
+ getfields("#alice#bob##charles###", arg, 3, 1, "#");
+
+.EE
+yields the three substrings:
+.BR "alice" ,
+.BR "bob" ,
+and
+.BR "charles###" .
+.PP
+Getfields returns the number of fields pointed to.
+.PP
+.I Gettokens
+is the same as
+.I getfields
+with
+.I multiflag
+non-zero,
+except that fields may be quoted using single quotes, in the manner
+of
+.IR rc (1).
+Any such quotes remain in the resulting
+.IR args .
+See
+.IR quote (2)
+for related quote-handling software.
+.PP
+.I Tokenize
+is similar to
+.I gettokens
+with
+.I delims
+set to \f5"\et\er\en\ "\fP,
+except that quotes are interpreted but do not appear in the resulting
+.IR args .
+.SH SOURCE
+.B /sys/src/libc/port/tokenize.c
+.SH SEE ALSO
+.I strtok
+in
+.IR strcat (2),
+.IR quote (2).
diff --git a/sys/man/2/getpid b/sys/man/2/getpid
new file mode 100755
index 000000000..6d795746d
--- /dev/null
+++ b/sys/man/2/getpid
@@ -0,0 +1,42 @@
+.TH GETPID 2
+.SH NAME
+getpid, getppid \- get process ids
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int getpid(void)
+.PP
+.B
+int getppid(void)
+.SH DESCRIPTION
+.I Getpid
+reads
+.B /dev/pid
+(see
+.IR cons (3))
+and converts it to get the process id of the current process,
+a number guaranteed to be unique among all running processes on the machine
+executing
+.IR getpid .
+.PP
+.I Getppid
+reads
+.B /dev/ppid
+(see
+.IR cons (3))
+and converts it to get the id of the parent of the current process.
+.SH SOURCE
+.B /sys/src/libc/9sys
+.SH SEE ALSO
+.IR intro (2),
+.IR exec (2),
+.IR cons (3),
+.IR proc (3)
+.SH DIAGNOSTICS
+Returns 0 and
+sets
+.I errstr
+if unsuccessful.
diff --git a/sys/man/2/getuser b/sys/man/2/getuser
new file mode 100755
index 000000000..7303fe24a
--- /dev/null
+++ b/sys/man/2/getuser
@@ -0,0 +1,37 @@
+.TH GETUSER 2
+.SH NAME
+getuser, sysname \- get user or system name
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+char* getuser(void)
+.PP
+.B
+char* sysname(void)
+.SH DESCRIPTION
+.I Getuser
+returns a pointer to static data which contains the
+null-terminated
+name of the user who
+owns the current process.
+.I Getuser
+reads
+.B /dev/user
+to find the name.
+.PP
+.I Sysname
+provides the same service for the file
+.BR #c/sysname ,
+which contains the name of the machine.
+Unlike
+.IR getuser ,
+.I sysname
+caches the string, reading the file only once.
+.SH SOURCE
+.B /sys/src/libc/port/getuser.c
+.SH SEE ALSO
+.IR intro (2),
+.IR cons (3)
diff --git a/sys/man/2/getwd b/sys/man/2/getwd
new file mode 100755
index 000000000..ac99719e0
--- /dev/null
+++ b/sys/man/2/getwd
@@ -0,0 +1,37 @@
+.TH GETWD 2
+.SH NAME
+getwd \- get current directory
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+char* getwd(char *buf, int size)
+.SH DESCRIPTION
+.I Getwd
+fills
+.I buf
+with a null-terminated string representing the current directory
+and returns
+.IR buf .
+.PP
+.I Getwd
+places no more than
+.I size
+bytes in the buffer provided.
+.SH SOURCE
+.B /sys/src/libc/9sys/getwd.c
+.SH "SEE ALSO"
+.IR pwd (1),
+.IR fd2path (2)
+.SH DIAGNOSTICS
+On error, zero is returned.
+.IR Errstr (2)
+may be consulted for more information.
+.SH BUGS
+Although the name returned by
+.I getwd
+is guaranteed to be the path used to reach the directory,
+if the name space has changed underfoot, the name may be
+incorrect.
diff --git a/sys/man/2/graphics b/sys/man/2/graphics
new file mode 100755
index 000000000..315e59aad
--- /dev/null
+++ b/sys/man/2/graphics
@@ -0,0 +1,642 @@
+.TH GRAPHICS 2
+.SH NAME
+Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getdefont, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, openfont, buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth \- interactive graphics
+.SH SYNOPSIS
+.nf
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <cursor.h>
+.ft P
+.PP
+.ta \w'\fLFont* 'u
+.B
+int initdraw(void (*errfun)(Display*, char*), char *font,
+.B
+ char *label)
+.PP
+.B
+int geninitdraw(char *devdir, void(*errfun)(Display*, char*),
+.PP
+.B
+ char *font, char *label, char *mousedir, char *windir,
+.B
+ int ref)
+.PP
+.B
+int newwindow(char *str)
+.PP
+.B
+void drawerror(Display *d, char *msg)
+.PP
+.B
+Display* initdisplay(char *devdir, char *win, void(*errfun)(Display*, char*))
+.PP
+.B
+void closedisplay(Display *d)
+.PP
+.B
+Subfont* getdefont(Display *d)
+.PP
+.B
+int flushimage(Display *d, int vis)
+.PP
+.B
+uchar* bufimage(Display *d, int n)
+.PP
+.B
+void lockdisplay(Display *d)
+.PP
+.B
+void unlockdisplay(Display *d)
+.PP
+.B
+int getwindow(Display *d, int ref)
+.PP
+.B
+int gengetwindow(Display *d, char *winname,
+.br
+.B
+ Image **ip, Screen **sp, int ref)
+.PP
+.B
+Font* openfont(Display *d, char *name)
+.PP
+.B
+Font* buildfont(Display *d, char *desc, char *name)
+.PP
+.B
+void freefont(Font *f)
+.PP
+.B
+int Pfmt(Fmt*)
+.PP
+.B
+int Rfmt(Fmt*)
+.PP
+.B
+ulong strtochan(char *s)
+.PP
+.B
+char* chantostr(char *s, ulong chan)
+.PP
+.B
+int chantodepth(ulong chan)
+.PP
+.B
+extern Display *display
+.PP
+.B
+extern Image *screen
+.PP
+.B
+extern Screen *_screen
+.PP
+.B
+extern Font *font
+.fi
+.SH DESCRIPTION
+A
+.B Display
+structure represents a connection to the graphics device,
+.IR draw (3),
+holding all graphics resources associated with the connection,
+including in particular raster image data in use by the client program.
+The structure is defined (in part) as:
+.IP
+.EX
+.ta 6n +10n
+typedef
+struct Display
+{
+ ...
+ void (*error)(Display*, char*);
+ ...
+ Image *black;
+ Image *white;
+ Image *opaque;
+ Image *transparent;
+ Image *image;
+ Font *defaultfont;
+ Subfont *defaultsubfont;
+ ...
+};
+.EE
+.PP
+A
+.B Point
+is a location in an Image
+(see below and
+.IR draw (2)),
+such as the display, and is defined as:
+.IP
+.EX
+.ta 6n
+typedef
+struct Point {
+ int x;
+ int y;
+} Point;
+.EE
+.PP
+The coordinate system has
+.I x
+increasing to the right and
+.I y
+increasing down.
+.PP
+A
+.B Rectangle
+is a rectangular area in an image.
+.IP
+.EX
+.ta 6n
+typedef
+struct Rectangle {
+ Point min; /* upper left */
+ Point max; /* lower right */
+} Rectangle;
+.EE
+.PP
+By definition,
+.BR min.x ≤ max.x
+and
+.BR min.y ≤ max.y .
+By convention, the right (maximum
+.IR x )
+and bottom (maximum
+.IR y )
+edges are
+excluded from the represented rectangle, so abutting rectangles have no
+points in common.
+Thus,
+.B max
+contains the coordinates of the first point beyond the rectangle.
+.PP
+The
+.B Image
+data structure is defined in
+.IR draw (2).
+.PP
+A
+.B Font
+is a set of character images, indexed by runes (see
+.IR utf (6)).
+The images are organized into
+.BR Subfonts ,
+each containing the images for a small, contiguous set of runes.
+The detailed format of these data structures,
+which are described in detail in
+.IR cachechars (2),
+is immaterial for most applications.
+.B Font
+and
+.B Subfont
+structures contain two interrelated fields:
+.LR ascent ,
+the distance from the top of the highest character
+(actually the top of the image holding all the characters)
+to the baseline,
+and
+.LR height ,
+the distance from the top of the highest character to the bottom of
+the lowest character (and hence, the interline spacing).
+See
+.IR cachechars (2)
+for more details.
+.PP
+.I Buildfont
+parses the font description in the buffer
+.BR desc ,
+returning a
+.B Font*
+pointer that can be used by
+.B string
+(see
+.IR draw (2))
+to draw characters from the font.
+.I Openfont
+does the same, but reads the description
+from the named file.
+.I Freefont
+frees a font.
+The convention for naming font files is:
+.IP
+.B /lib/font/bit/\fIname\fP/\fIrange\fP.\fIsize\fP.font
+.PD
+.PP
+where
+.I size
+is approximately the height in pixels of the lower case letters
+(without ascenders or descenders).
+.I Range
+gives some indication of which characters will be available: for example
+.BR ascii ,
+.BR latin1 ,
+.BR euro ,
+or
+.BR unicode .
+.B Euro
+includes most European languages, punctuation marks, the International Phonetic
+Alphabet, etc., but no Oriental languages.
+.B Unicode
+includes every character for which appropriate-sized images exist on the system.
+.PP
+A
+.I Cursor
+is defined:
+.IP
+.EX
+.ta 6n +\w'Point 'u
+typedef struct
+Cursor {
+ Point offset;
+ uchar clr[2*16];
+ uchar set[2*16];
+} Cursor;
+.EE
+.PP
+The arrays are arranged in rows, two bytes per row, left to
+right in big-endian order to give 16 rows
+of 16 bits each.
+A cursor is displayed on the screen by adding
+.B offset
+to the current mouse position, using
+.B clr
+as a mask to draw white at the pixels where
+.B clr
+is one, and then drawing black at the pixels where
+.B set
+is one.
+.I Setcursor
+and
+.I moveto
+(see
+.IR mouse (2))
+and
+.I esetcursor
+and
+.I emoveto
+(see
+.IR event (2))
+change the cursor image and its location on the screen.
+.PP
+The routine
+.I initdraw
+connects to the display; it returns \-1 if it fails and sets the error string.
+.I Initdraw
+sets up the global variables
+.B display
+(the
+.B Display
+structure representing the connection),
+.B screen
+(an
+.B Image
+representing the display memory itself or, if
+.IR rio (1)
+is running, the client's window),
+and
+.B font
+(the default font for text).
+The arguments to
+.I initdraw
+include a
+.IR label ,
+which is written to
+.B /dev/label
+if non-nil
+so that it can be used to identify the window when hidden (see
+.IR rio (1)).
+The font is created by reading the named
+.I font
+file. If
+.B font
+is null,
+.I initdraw
+reads the file named in the environment variable
+.BR $font ;
+if
+.B $font
+is not set, it imports the default (usually minimal)
+font from the operating system.
+The global
+.I font
+will be set to point to the resulting
+.B Font
+structure.
+The
+.I errfun
+argument is a
+.I graphics error function
+to call in the event of a fatal error in the library; it must never return.
+Its arguments are the
+display pointer and an error string.
+If
+.I errfun
+is nil, the library provides a default, called
+.IR drawerror .
+Another effect of
+.I initdraw
+is that it installs
+.IR print (2)
+formats
+.I Pfmt
+and
+.I Rfmt
+as
+.L %P
+and
+.L %R
+for printing
+.B Points
+and
+.BR Rectangles .
+.PP
+The
+.I geninitdraw
+function provides a less automated way to establish a connection, for programs
+that wish to connect to multiple displays.
+.I Devdir
+is the name of the directory containing the device files for the display
+(if nil, default
+.BR /dev );
+.IR errfun ,
+.IR font ,
+and
+.I label
+are as in
+.IR initdraw ;
+.I mousedir
+and
+.I windir
+are the directories holding the
+.B mouse
+and
+.B winname
+files; and
+.I ref
+specifies the refresh function to be used to create the window, if running under
+.IR rio (1)
+(see
+.IR window (2)).
+.PP
+The function
+.I newwindow
+may be called before
+.I initdraw
+or
+.IR geninitdraw
+to cause the program to occupy a newly created window rather than take over the one in
+which it is running when it starts.
+The
+.I str
+argument, if non-null, is concatenated to the string \f5\&"new\ "\fP
+that is used to create the window (see
+.IR rio (4)).
+For example,
+.B newwindow("-hide -dy 100")
+will cause the program to run in a newly created, hidden window
+100 pixels high.
+.PP
+.I Initdisplay
+is part of
+.IR geninitdraw ;
+it sets up the display structures but does not allocate any fonts or call
+.IR getwindow .
+The arguments are similar to those of
+.IR initdraw ;
+.I win
+names the directory, default
+.BR /dev ,
+in which the files associated with the window reside.
+.I Closedisplay
+disconnects the display and frees the associated data structures.
+.I Getdefont
+builds a
+.B Subfont
+structure from in-core data describing a default subfont.
+None of these routines is needed by most programs, since
+.I initdraw
+calls them as needed.
+.PP
+The data structures associated with the display must be protected in a multi-process program,
+because they assume only one process will be using them at a time.
+Multi-process programs should set
+.B display->locking
+to
+.BR 1 ,
+to notify the library to use a locking protocol for its own accesses,
+and call
+.I lockdisplay
+and
+.I unlockdisplay
+around any calls to the graphics library that will cause messages to be sent to the display device.
+.I Initdraw
+and
+.I geninitdraw
+initialize the display to the locked state.
+.PP
+.I Getwindow
+returns a pointer to the window associated with the application; it is called
+automatically by
+.I initdraw
+to establish the
+.B screen
+pointer but must be called after each resizing of the window to restore
+the library's connection to the window.
+If
+.B rio
+is not running, it returns
+.BR display->image ;
+otherwise it negotiates with
+.B rio
+by looking in
+.B /dev/winname
+to find the name of the window and opening it using
+.B namedimage
+(see
+.IR allocimage (2)).
+The resulting window will be created using the refresh method
+.I ref
+(see
+.IR window (2));
+this should almost always be
+.B Refnone
+because
+.B rio
+provides backing store for the window.
+.PP
+.I Getwindow
+overwrites the global variables
+.BR screen ,
+a pointer to the
+.B Image
+defining the window (or the overall display, if no window system is running); and
+.BR _screen ,
+a pointer to the
+.B Screen
+representing the root of the window's hierarchy. (See
+.IR window (2).
+The overloading of the
+.B screen
+word is an unfortunate historical accident.)
+.I Getwindow
+arranges that
+.B screen
+point to the portion of the window inside the border;
+sophisticated clients may use
+.B _screen
+to make further subwindows.
+Programs desiring multiple independent windows
+may use the mechanisms of
+.IR rio (4)
+to create more windows (usually by a fresh mount of the window sytem
+in a directory other than
+.BR /dev ),
+then use
+.I gengetwindow
+to connect to them.
+.IR Gengetwindow 's
+extra arguments are the full path of the window's
+.B winname
+file and pointers to be overwritten with the values of the `global'
+.B Image
+and
+.B Screen
+variables for the new window.
+.PP
+The graphics functions described in
+.IR draw (2),
+.IR allocimage (2),
+.IR cachechars (2),
+and
+.IR subfont (2)
+are implemented by writing commands to files under
+.B /dev/draw
+(see
+.IR draw (3));
+the writes are buffered, so the functions may not take effect immediately.
+.I Flushimage
+flushes the buffer, doing all pending graphics operations.
+If
+.I vis
+is non-zero, any changes are also copied from the `soft screen' (if any) in the
+driver to the visible frame buffer.
+The various allocation routines in the library flush automatically, as does the event
+package (see
+.IR event (2));
+most programs do not need to call
+.IR flushimage .
+It returns \-1 on error.
+.PP
+.I Bufimage
+is used to allocate space for
+.I n
+bytes in the display buffer.
+It is used by all the graphics routines to send messages to the display.
+.PP
+The functions
+.I strtochan
+and
+.I chantostr
+convert between the channel descriptor strings
+used by
+.IR image (6)
+and the internal
+.B ulong
+representation
+used by the graphics protocol
+(see
+.IR draw (3)'s
+.B b
+message).
+.B Chantostr
+writes at most nine bytes into the buffer pointed at by
+.I s
+and returns
+.I s
+on success,
+0
+on failure.
+.B Chantodepth
+returns the number of bits per pixel used by the
+format specified by
+.IR chan .
+Both
+.B chantodepth
+and
+.B strtochan
+return 0 when presented
+with bad input.
+.SH EXAMPLES
+To reconnect to the window after a resize event,
+.IP
+.EX
+if(getwindow(display, Refnone) < 0)
+ sysfatal("resize failed: %r");
+.EE
+.PP
+To create and set up a new
+.IR rio (1)
+window,
+.IP
+.EX
+Image *screen2;
+Screen *_screen2;
+
+srvwsys = getenv("wsys");
+if(srvwsys == nil)
+ sysfatal("can't find $wsys: %r");
+rfork(RFNAMEG); /* keep mount of rio private */
+
+fd = open(srvwsys, ORDWR);
+if(fd < 0)
+ sysfatal("can't open $wsys: %r");
+
+/* mount creates window; see \f2rio\fP(4) */
+if(mount(fd, -1, "/tmp", MREPL, "new -dx 300-dy 200") < 0)
+ sysfatal("can't mount new window: %r");
+if(gengetwindow(display, "/tmp/winname",
+ &screen2, &_screen2, Refnone) < 0)
+ sysfatal("resize failed: %r");
+
+/* now open /tmp/cons, /tmp/mouse */
+\&...
+.EE
+.SH FILES
+.BR /lib/font/bit " directory of fonts
+.SH SOURCE
+.B /sys/src/libdraw
+.SH "SEE ALSO"
+.IR rio (1),
+.IR addpt (2),
+.IR allocimage (2),
+.IR cachechars (2),
+.IR subfont (2),
+.IR draw (2),
+.IR event (2),
+.IR frame (2),
+.IR print (2),
+.IR window (2),
+.IR draw (3),
+.IR rio (4),
+.IR image (6),
+.IR font (6)
+.SH DIAGNOSTICS
+An error function may call
+.IR errstr (2)
+for further diagnostics.
+.SH BUGS
+The names
+.B clr
+and
+.B set
+in the
+.B Cursor
+structure are reminders of an archaic color map
+and might be more appropriately called
+.B white
+and
+.BR black .
diff --git a/sys/man/2/html b/sys/man/2/html
new file mode 100755
index 000000000..ef641e41d
--- /dev/null
+++ b/sys/man/2/html
@@ -0,0 +1,1420 @@
+.TH HTML 2
+.SH NAME
+parsehtml,
+printitems,
+validitems,
+freeitems,
+freedocinfo,
+dimenkind,
+dimenspec,
+targetid,
+targetname,
+fromStr,
+toStr
+\- HTML parser
+.SH SYNOPSIS
+.nf
+.PP
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <html.h>
+.ft P
+.PP
+.ta \w'\fLToken* 'u
+.B
+Item* parsehtml(uchar* data, int datalen, Rune* src, int mtype,
+.B
+ int chset, Docinfo** pdi)
+.PP
+.B
+void printitems(Item* items, char* msg)
+.PP
+.B
+int validitems(Item* items)
+.PP
+.B
+void freeitems(Item* items)
+.PP
+.B
+void freedocinfo(Docinfo* d)
+.PP
+.B
+int dimenkind(Dimen d)
+.PP
+.B
+int dimenspec(Dimen d)
+.PP
+.B
+int targetid(Rune* s)
+.PP
+.B
+Rune* targetname(int targid)
+.PP
+.B
+uchar* fromStr(Rune* buf, int n, int chset)
+.PP
+.B
+Rune* toStr(uchar* buf, int n, int chset)
+.SH DESCRIPTION
+.PP
+This library implements a parser for HTML 4.0 documents.
+The parsed HTML is converted into an intermediate representation that
+describes how the formatted HTML should be laid out.
+.PP
+.I Parsehtml
+parses an entire HTML document contained in the buffer
+.I data
+and having length
+.IR datalen .
+The URL of the document should be passed in as
+.IR src .
+.I Mtype
+is the media type of the document, which should be either
+.B TextHtml
+or
+.BR TextPlain .
+The character set of the document is described in
+.IR chset ,
+which can be one of
+.BR US_Ascii ,
+.BR ISO_8859_1 ,
+.B UTF_8
+or
+.BR Unicode .
+The return value is a linked list of
+.B Item
+structures, described in detail below.
+As a side effect,
+.BI * pdi
+is set to point to a newly created
+.B Docinfo
+structure, containing information pertaining to the entire document.
+.PP
+The library expects two allocation routines to be provided by the
+caller,
+.B emalloc
+and
+.BR erealloc .
+These routines are analogous to the standard malloc and realloc routines,
+except that they should not return if the memory allocation fails.
+In addition,
+.B emalloc
+is required to zero the memory.
+.PP
+For debugging purposes,
+.I printitems
+may be called to display the contents of an item list; individual items may
+be printed using the
+.B %I
+print verb, installed on the first call to
+.IR parsehtml .
+.I validitems
+traverses the item list, checking that all of the pointers are valid.
+It returns
+.B 1
+is everything is ok, and
+.B 0
+if an error was found.
+Normally, one would not call these routines directly.
+Instead, one sets the global variable
+.I dbgbuild
+and the library calls them automatically.
+One can also set
+.IR warn ,
+to cause the library to print a warning whenever it finds a problem with the
+input document, and
+.IR dbglex ,
+to print debugging information in the lexer.
+.PP
+When an item list is finished with, it should be freed with
+.IR freeitems .
+Then,
+.I freedocinfo
+should be called on the pointer returned in
+.BI * pdi\f1.
+.PP
+.I Dimenkind
+and
+.I dimenspec
+are provided to interpret the
+.B Dimen
+type, as described in the section
+.IR "Dimension Specifications" .
+.PP
+Frame target names are mapped to integer ids via a global, permanent mapping.
+To find the value for a given name, call
+.IR targetid ,
+which allocates a new id if the name hasn't been seen before.
+The name of a given, known id may be retrieved using
+.IR targetname .
+The library predefines
+.BR FTtop ,
+.BR FTself ,
+.B FTparent
+and
+.BR FTblank .
+.PP
+The library handles all text as Unicode strings (type
+.BR Rune* ).
+Character set conversion is provided by
+.I fromStr
+and
+.IR toStr .
+.I FromStr
+takes
+.I n
+Unicode characters from
+.I buf
+and converts them to the character set described by
+.IR chset .
+.I ToStr
+takes
+.I n
+bytes from
+.IR buf ,
+interpretted as belonging to character set
+.IR chset ,
+and converts them to a Unicode string.
+Both routines null-terminate the result, and use
+.B emalloc
+to allocate space for it.
+.SS Items
+The return value of
+.I parsehtml
+is a linked list of variant structures,
+with the generic portion described by the following definition:
+.PP
+.EX
+.ta 6n +\w'Genattr* 'u
+typedef struct Item Item;
+struct Item
+{
+ Item* next;
+ int width;
+ int height;
+ int ascent;
+ int anchorid;
+ int state;
+ Genattr* genattr;
+ int tag;
+};
+.EE
+.PP
+The field
+.B next
+points to the successor in the linked list of items, while
+.BR width ,
+.BR height ,
+and
+.B ascent
+are intended for use by the caller as part of the layout process.
+.BR Anchorid ,
+if non-zero, gives the integer id assigned by the parser to the anchor that
+this item is in (see section
+.IR Anchors ).
+.B State
+is a collection of flags and values described as follows:
+.PP
+.EX
+.ta 6n +\w'IFindentshift = 'u
+enum
+{
+ IFbrk = 0x80000000,
+ IFbrksp = 0x40000000,
+ IFnobrk = 0x20000000,
+ IFcleft = 0x10000000,
+ IFcright = 0x08000000,
+ IFwrap = 0x04000000,
+ IFhang = 0x02000000,
+ IFrjust = 0x01000000,
+ IFcjust = 0x00800000,
+ IFsmap = 0x00400000,
+ IFindentshift = 8,
+ IFindentmask = (255<<IFindentshift),
+ IFhangmask = 255
+};
+.EE
+.PP
+.B IFbrk
+is set if a break is to be forced before placing this item.
+.B IFbrksp
+is set if a 1 line space should be added to the break (in which case
+.B IFbrk
+is also set).
+.B IFnobrk
+is set if a break is not permitted before the item.
+.B IFcleft
+is set if left floats should be cleared (that is, if the list of pending left floats should be placed)
+before this item is placed, and
+.B IFcright
+is set for right floats.
+In both cases, IFbrk is also set.
+.B IFwrap
+is set if the line containing this item is allowed to wrap.
+.B IFhang
+is set if this item hangs into the left indent.
+.B IFrjust
+is set if the line containing this item should be right justified,
+and
+.B IFcjust
+is set for center justified lines.
+.B IFsmap
+is used to indicate that an image is a server-side map.
+The low 8 bits, represented by
+.BR IFhangmask ,
+indicate the current hang into left indent, in tenths of a tabstop.
+The next 8 bits, represented by
+.B IFindentmask
+and
+.BR IFindentshift ,
+indicate the current indent in tab stops.
+.PP
+The field
+.B genattr
+is an optional pointer to an auxiliary structure, described in the section
+.IR "Generic Attributes" .
+.PP
+Finally,
+.B tag
+describes which variant type this item has.
+It can have one of the values
+.BR Itexttag ,
+.BR Iruletag ,
+.BR Iimagetag ,
+.BR Iformfieldtag ,
+.BR Itabletag ,
+.B Ifloattag
+or
+.BR Ispacertag .
+For each of these values, there is an additional structure defined, which
+includes Item as an unnamed initial substructure, and then defines additional
+fields.
+.PP
+Items of type
+.B Itexttag
+represent a piece of text, using the following structure:
+.PP
+.EX
+.ta 6n +\w'Rune* 'u
+struct Itext
+{
+ Item;
+ Rune* s;
+ int fnt;
+ int fg;
+ uchar voff;
+ uchar ul;
+};
+.EE
+.PP
+Here
+.B s
+is a null-terminated Unicode string of the actual characters making up this text item,
+.B fnt
+is the font number (described in the section
+.IR "Font Numbers" ),
+and
+.B fg
+is the RGB encoded color for the text.
+.B Voff
+measures the vertical offset from the baseline; subtract
+.B Voffbias
+to get the actual value (negative values represent a displacement down the page).
+The field
+.B ul
+is the underline style:
+.B ULnone
+if no underline,
+.B ULunder
+for conventional underline, and
+.B ULmid
+for strike-through.
+.PP
+Items of type
+.B Iruletag
+represent a horizontal rule, as follows:
+.PP
+.EX
+.ta 6n +\w'Dimen 'u
+struct Irule
+{
+ Item;
+ uchar align;
+ uchar noshade;
+ int size;
+ Dimen wspec;
+};
+.EE
+.PP
+Here
+.B align
+is the alignment specification (described in the corresponding section),
+.B noshade
+is set if the rule should not be shaded,
+.B size
+is the height of the rule (as set by the size attribute),
+and
+.B wspec
+is the desired width (see section
+.IR "Dimension Specifications" ).
+.PP
+Items of type
+.B Iimagetag
+describe embedded images, for which the following structure is defined:
+.PP
+.EX
+.ta 6n +\w'Iimage* 'u
+struct Iimage
+{
+ Item;
+ Rune* imsrc;
+ int imwidth;
+ int imheight;
+ Rune* altrep;
+ Map* map;
+ int ctlid;
+ uchar align;
+ uchar hspace;
+ uchar vspace;
+ uchar border;
+ Iimage* nextimage;
+};
+.EE
+.PP
+Here
+.B imsrc
+is the URL of the image source,
+.B imwidth
+and
+.BR imheight ,
+if non-zero, contain the specified width and height for the image,
+and
+.B altrep
+is the text to use as an alternative to the image, if the image is not displayed.
+.BR Map ,
+if set, points to a structure describing an associated client-side image map.
+.B Ctlid
+is reserved for use by the application, for handling animated images.
+.B Align
+encodes the alignment specification of the image.
+.B Hspace
+contains the number of pixels to pad the image with on either side, and
+.B Vspace
+the padding above and below.
+.B Border
+is the width of the border to draw around the image.
+.B Nextimage
+points to the next image in the document (the head of this list is
+.BR Docinfo.images ).
+.PP
+For items of type
+.BR Iformfieldtag ,
+the following structure is defined:
+.PP
+.EX
+.ta 6n +\w'Formfield* 'u
+struct Iformfield
+{
+ Item;
+ Formfield* formfield;
+};
+.EE
+.PP
+This adds a single field,
+.BR formfield ,
+which points to a structure describing a field in a form, described in section
+.IR Forms .
+.PP
+For items of type
+.BR Itabletag ,
+the following structure is defined:
+.PP
+.EX
+.ta 6n +\w'Table* 'u
+struct Itable
+{
+ Item;
+ Table* table;
+};
+.EE
+.PP
+.B Table
+points to a structure describing the table, described in the section
+.IR Tables .
+.PP
+For items of type
+.BR Ifloattag ,
+the following structure is defined:
+.PP
+.EX
+.ta 6n +\w'Ifloat* 'u
+struct Ifloat
+{
+ Item;
+ Item* item;
+ int x;
+ int y;
+ uchar side;
+ uchar infloats;
+ Ifloat* nextfloat;
+};
+.EE
+.PP
+The
+.B item
+points to a single item (either a table or an image) that floats (the text of the
+document flows around it), and
+.B side
+indicates the margin that this float sticks to; it is either
+.B ALleft
+or
+.BR ALright .
+.B X
+and
+.B y
+are reserved for use by the caller; these are typically used for the coordinates
+of the top of the float.
+.B Infloats
+is used by the caller to keep track of whether it has placed the float.
+.B Nextfloat
+is used by the caller to link together all of the floats that it has placed.
+.PP
+For items of type
+.BR Ispacertag ,
+the following structure is defined:
+.PP
+.EX
+.ta 6n +\w'Item; 'u
+struct Ispacer
+{
+ Item;
+ int spkind;
+};
+.EE
+.PP
+.B Spkind
+encodes the kind of spacer, and may be one of
+.B ISPnull
+(zero height and width),
+.B ISPvline
+(takes on height and ascent of the current font),
+.B ISPhspace
+(has the width of a space in the current font) and
+.B ISPgeneral
+(for all other purposes, such as between markers and lists).
+.SS Generic Attributes
+.PP
+The genattr field of an item, if non-nil, points to a structure that holds
+the values of attributes not specific to any particular
+item type, as they occur on a wide variety of underlying HTML tags.
+The structure is as follows:
+.PP
+.EX
+.ta 6n +\w'SEvent* 'u
+typedef struct Genattr Genattr;
+struct Genattr
+{
+ Rune* id;
+ Rune* class;
+ Rune* style;
+ Rune* title;
+ SEvent* events;
+};
+.EE
+.PP
+Fields
+.BR id ,
+.BR class ,
+.B style
+and
+.BR title ,
+when non-nil, contain values of correspondingly named attributes of the HTML tag
+associated with this item.
+.B Events
+is a linked list of events (with corresponding scripted actions) associated with the item:
+.PP
+.EX
+.ta 6n +\w'SEvent* 'u
+typedef struct SEvent SEvent;
+struct SEvent
+{
+ SEvent* next;
+ int type;
+ Rune* script;
+};
+.EE
+.PP
+Here,
+.B next
+points to the next event in the list,
+.B type
+is one of
+.BR SEonblur ,
+.BR SEonchange ,
+.BR SEonclick ,
+.BR SEondblclick ,
+.BR SEonfocus ,
+.BR SEonkeypress ,
+.BR SEonkeyup ,
+.BR SEonload ,
+.BR SEonmousedown ,
+.BR SEonmousemove ,
+.BR SEonmouseout ,
+.BR SEonmouseover ,
+.BR SEonmouseup ,
+.BR SEonreset ,
+.BR SEonselect ,
+.B SEonsubmit
+or
+.BR SEonunload ,
+and
+.B script
+is the text of the associated script.
+.SS Dimension Specifications
+.PP
+Some structures include a dimension specification, used where
+a number can be followed by a
+.B %
+or a
+.B *
+to indicate
+percentage of total or relative weight.
+This is encoded using the following structure:
+.PP
+.EX
+.ta 6n +\w'int 'u
+typedef struct Dimen Dimen;
+struct Dimen
+{
+ int kindspec;
+};
+.EE
+.PP
+Separate kind and spec values are extracted using
+.I dimenkind
+and
+.IR dimenspec .
+.I Dimenkind
+returns one of
+.BR Dnone ,
+.BR Dpixels ,
+.B Dpercent
+or
+.BR Drelative .
+.B Dnone
+means that no dimension was specified.
+In all other cases,
+.I dimenspec
+should be called to find the absolute number of pixels, the percentage of total,
+or the relative weight.
+.SS Background Specifications
+.PP
+It is possible to set the background of the entire document, and also
+for some parts of the document (such as tables).
+This is encoded as follows:
+.PP
+.EX
+.ta 6n +\w'Rune* 'u
+typedef struct Background Background;
+struct Background
+{
+ Rune* image;
+ int color;
+};
+.EE
+.PP
+.BR Image ,
+if non-nil, is the URL of an image to use as the background.
+If this is nil,
+.B color
+is used instead, as the RGB value for a solid fill color.
+.SS Alignment Specifications
+.PP
+Certain items have alignment specifiers taken from the following
+enumerated type:
+.PP
+.EX
+.ta 6n
+enum
+{
+ ALnone = 0, ALleft, ALcenter, ALright, ALjustify,
+ ALchar, ALtop, ALmiddle, ALbottom, ALbaseline
+};
+.EE
+.PP
+These values correspond to the various alignment types named in the HTML 4.0
+standard.
+If an item has an alignment of
+.B ALleft
+or
+.BR ALright ,
+the library automatically encapsulates it inside a float item.
+.PP
+Tables, and the various rows, columns and cells within them, have a more
+complex alignment specification, composed of separate vertical and
+horizontal alignments:
+.PP
+.EX
+.ta 6n +\w'uchar 'u
+typedef struct Align Align;
+struct Align
+{
+ uchar halign;
+ uchar valign;
+};
+.EE
+.PP
+.B Halign
+can be one of
+.BR ALnone ,
+.BR ALleft ,
+.BR ALcenter ,
+.BR ALright ,
+.B ALjustify
+or
+.BR ALchar .
+.B Valign
+can be one of
+.BR ALnone ,
+.BR ALmiddle ,
+.BR ALbottom ,
+.BR ALtop
+or
+.BR ALbaseline .
+.SS Font Numbers
+.PP
+Text items have an associated font number (the
+.B fnt
+field), which is encoded as
+.BR style*NumSize+size .
+Here,
+.B style
+is one of
+.BR FntR ,
+.BR FntI ,
+.B FntB
+or
+.BR FntT ,
+for roman, italic, bold and typewriter font styles, respectively, and size is
+.BR Tiny ,
+.BR Small ,
+.BR Normal ,
+.B Large
+or
+.BR Verylarge .
+The total number of possible font numbers is
+.BR NumFnt ,
+and the default font number is
+.B DefFnt
+(which is roman style, normal size).
+.SS Document Info
+.PP
+Global information about an HTML page is stored in the following structure:
+.PP
+.EX
+.ta 6n +\w'DestAnchor* 'u
+typedef struct Docinfo Docinfo;
+struct Docinfo
+{
+ // stuff from HTTP headers, doc head, and body tag
+ Rune* src;
+ Rune* base;
+ Rune* doctitle;
+ Background background;
+ Iimage* backgrounditem;
+ int text;
+ int link;
+ int vlink;
+ int alink;
+ int target;
+ int chset;
+ int mediatype;
+ int scripttype;
+ int hasscripts;
+ Rune* refresh;
+ Kidinfo* kidinfo;
+ int frameid;
+
+ // info needed to respond to user actions
+ Anchor* anchors;
+ DestAnchor* dests;
+ Form* forms;
+ Table* tables;
+ Map* maps;
+ Iimage* images;
+};
+.EE
+.PP
+.B Src
+gives the URL of the original source of the document,
+and
+.B base
+is the base URL.
+.B Doctitle
+is the document's title, as set by a
+.B <title>
+element.
+.B Background
+is as described in the section
+.IR "Background Specifications" ,
+and
+.B backgrounditem
+is set to be an image item for the document's background image (if given as a URL),
+or else nil.
+.B Text
+gives the default foregound text color of the document,
+.B link
+the unvisited hyperlink color,
+.B vlink
+the visited hyperlink color, and
+.B alink
+the color for highlighting hyperlinks (all in 24-bit RGB format).
+.B Target
+is the default target frame id.
+.B Chset
+and
+.B mediatype
+are as for the
+.I chset
+and
+.I mtype
+parameters to
+.IR parsehtml .
+.B Scripttype
+is the type of any scripts contained in the document, and is always
+.BR TextJavascript .
+.B Hasscripts
+is set if the document contains any scripts.
+Scripting is currently unsupported.
+.B Refresh
+is the contents of a
+.B "<meta http-equiv=Refresh ...>"
+tag, if any.
+.B Kidinfo
+is set if this document is a frameset (see section
+.IR Frames ).
+.B Frameid
+is this document's frame id.
+.PP
+.B Anchors
+is a list of hyperlinks contained in the document,
+and
+.B dests
+is a list of hyperlink destinations within the page (see the following section for details).
+.BR Forms ,
+.B tables
+and
+.B maps
+are lists of the various forms, tables and client-side maps contained
+in the document, as described in subsequent sections.
+.B Images
+is a list of all the image items in the document.
+.SS Anchors
+.PP
+The library builds two lists for all of the
+.B <a>
+elements (anchors) in a document.
+Each anchor is assigned a unique anchor id within the document.
+For anchors which are hyperlinks (the
+.B href
+attribute was supplied), the following structure is defined:
+.PP
+.EX
+.ta 6n +\w'Anchor* 'u
+typedef struct Anchor Anchor;
+struct Anchor
+{
+ Anchor* next;
+ int index;
+ Rune* name;
+ Rune* href;
+ int target;
+};
+.EE
+.PP
+.B Next
+points to the next anchor in the list (the head of this list is
+.BR Docinfo.anchors ).
+.B Index
+is the anchor id; each item within this hyperlink is tagged with this value
+in its
+.B anchorid
+field.
+.B Name
+and
+.B href
+are the values of the correspondingly named attributes of the anchor
+(in particular, href is the URL to go to).
+.B Target
+is the value of the target attribute (if provided) converted to a frame id.
+.PP
+Destinations within the document (anchors with the name attribute set)
+are held in the
+.B Docinfo.dests
+list, using the following structure:
+.PP
+.EX
+.ta 6n +\w'DestAnchor* 'u
+typedef struct DestAnchor DestAnchor;
+struct DestAnchor
+{
+ DestAnchor* next;
+ int index;
+ Rune* name;
+ Item* item;
+};
+.EE
+.PP
+.B Next
+is the next element of the list,
+.B index
+is the anchor id,
+.B name
+is the value of the name attribute, and
+.B item
+is points to the item within the parsed document that should be considered
+to be the destination.
+.SS Forms
+.PP
+Any forms within a document are kept in a list, headed by
+.BR Docinfo.forms .
+The elements of this list are as follows:
+.PP
+.EX
+.ta 6n +\w'Formfield* 'u
+typedef struct Form Form;
+struct Form
+{
+ Form* next;
+ int formid;
+ Rune* name;
+ Rune* action;
+ int target;
+ int method;
+ int nfields;
+ Formfield* fields;
+};
+.EE
+.PP
+.B Next
+points to the next form in the list.
+.B Formid
+is a serial number for the form within the document.
+.B Name
+is the value of the form's name or id attribute.
+.B Action
+is the value of any action attribute.
+.B Target
+is the value of the target attribute (if any) converted to a frame target id.
+.B Method
+is one of
+.B HGet
+or
+.BR HPost .
+.B Nfields
+is the number of fields in the form, and
+.B fields
+is a linked list of the actual fields.
+.PP
+The individual fields in a form are described by the following structure:
+.PP
+.EX
+.ta 6n +\w'Formfield* 'u
+typedef struct Formfield Formfield;
+struct Formfield
+{
+ Formfield* next;
+ int ftype;
+ int fieldid;
+ Form* form;
+ Rune* name;
+ Rune* value;
+ int size;
+ int maxlength;
+ int rows;
+ int cols;
+ uchar flags;
+ Option* options;
+ Item* image;
+ int ctlid;
+ SEvent* events;
+};
+.EE
+.PP
+Here,
+.B next
+points to the next field in the list.
+.B Ftype
+is the type of the field, which can be one of
+.BR Ftext ,
+.BR Fpassword ,
+.BR Fcheckbox ,
+.BR Fradio ,
+.BR Fsubmit ,
+.BR Fhidden ,
+.BR Fimage ,
+.BR Freset ,
+.BR Ffile ,
+.BR Fbutton ,
+.B Fselect
+or
+.BR Ftextarea .
+.B Fieldid
+is a serial number for the field within the form.
+.B Form
+points back to the form containing this field.
+.BR Name ,
+.BR value ,
+.BR size ,
+.BR maxlength ,
+.B rows
+and
+.B cols
+each contain the values of corresponding attributes of the field, if present.
+.B Flags
+contains per-field flags, of which
+.B FFchecked
+and
+.B FFmultiple
+are defined.
+.B Image
+is only used for fields of type
+.BR Fimage ;
+it points to an image item containing the image to be displayed.
+.B Ctlid
+is reserved for use by the caller, typically to store a unique id
+of an associated control used to implement the field.
+.B Events
+is the same as the corresponding field of the generic attributes
+associated with the item containing this field.
+.B Options
+is only used by fields of type
+.BR Fselect ;
+it consists of a list of possible options that may be selected for that
+field, using the following structure:
+.PP
+.EX
+.ta 6n +\w'Option* 'u
+typedef struct Option Option;
+struct Option
+{
+ Option* next;
+ int selected;
+ Rune* value;
+ Rune* display;
+};
+.EE
+.PP
+.B Next
+points to the next element of the list.
+.B Selected
+is set if this option is to be displayed initially.
+.B Value
+is the value to send when the form is submitted if this option is selected.
+.B Display
+is the string to display on the screen for this option.
+.SS Tables
+.PP
+The library builds a list of all the tables in the document,
+headed by
+.BR Docinfo.tables .
+Each element of this list has the following format:
+.PP
+.EX
+.ta 6n +\w'Tablecell*** 'u
+typedef struct Table Table;
+struct Table
+{
+ Table* next;
+ int tableid;
+ Tablerow* rows;
+ int nrow;
+ Tablecol* cols;
+ int ncol;
+ Tablecell* cells;
+ int ncell;
+ Tablecell*** grid;
+ Align align;
+ Dimen width;
+ int border;
+ int cellspacing;
+ int cellpadding;
+ Background background;
+ Item* caption;
+ uchar caption_place;
+ Lay* caption_lay;
+ int totw;
+ int toth;
+ int caph;
+ int availw;
+ Token* tabletok;
+ uchar flags;
+};
+.EE
+.PP
+.B Next
+points to the next element in the list of tables.
+.B Tableid
+is a serial number for the table within the document.
+.B Rows
+is an array of row specifications (described below) and
+.B nrow
+is the number of elements in this array.
+Similarly,
+.B cols
+is an array of column specifications, and
+.B ncol
+the size of this array.
+.B Cells
+is a list of all cells within the table (structure described below)
+and
+.B ncell
+is the number of elements in this list.
+Note that a cell may span multiple rows and/or columns, thus
+.B ncell
+may be smaller than
+.BR nrow*ncol .
+.B Grid
+is a two-dimensional array of cells within the table; the cell
+at row
+.B i
+and column
+.B j
+is
+.BR Table.grid[i][j] .
+A cell that spans multiple rows and/or columns will
+be referenced by
+.B grid
+multiple times, however it will only occur once in
+.BR cells .
+.B Align
+gives the alignment specification for the entire table,
+and
+.B width
+gives the requested width as a dimension specification.
+.BR Border ,
+.B cellspacing
+and
+.B cellpadding
+give the values of the corresponding attributes for the table,
+and
+.B background
+gives the requested background for the table.
+.B Caption
+is a linked list of items to be displayed as the caption of the
+table, either above or below depending on whether
+.B caption_place
+is
+.B ALtop
+or
+.BR ALbottom .
+Most of the remaining fields are reserved for use by the caller,
+except
+.BR tabletok ,
+which is reserved for internal use.
+The type
+.B Lay
+is not defined by the library; the caller can provide its
+own definition.
+.PP
+The
+.B Tablecol
+structure is defined for use by the caller.
+The library ensures that the correct number of these
+is allocated, but leaves them blank.
+The fields are as follows:
+.PP
+.EX
+.ta 6n +\w'Point 'u
+typedef struct Tablecol Tablecol;
+struct Tablecol
+{
+ int width;
+ Align align;
+ Point pos;
+};
+.EE
+.PP
+The rows in the table are specified as follows:
+.PP
+.EX
+.ta 6n +\w'Background 'u
+typedef struct Tablerow Tablerow;
+struct Tablerow
+{
+ Tablerow* next;
+ Tablecell* cells;
+ int height;
+ int ascent;
+ Align align;
+ Background background;
+ Point pos;
+ uchar flags;
+};
+.EE
+.PP
+.B Next
+is only used during parsing; it should be ignored by the caller.
+.B Cells
+provides a list of all the cells in a row, linked through their
+.B nextinrow
+fields (see below).
+.BR Height ,
+.B ascent
+and
+.B pos
+are reserved for use by the caller.
+.B Align
+is the alignment specification for the row, and
+.B background
+is the background to use, if specified.
+.B Flags
+is used by the parser; ignore this field.
+.PP
+The individual cells of the table are described as follows:
+.PP
+.EX
+.ta 6n +\w'Background 'u
+typedef struct Tablecell Tablecell;
+struct Tablecell
+{
+ Tablecell* next;
+ Tablecell* nextinrow;
+ int cellid;
+ Item* content;
+ Lay* lay;
+ int rowspan;
+ int colspan;
+ Align align;
+ uchar flags;
+ Dimen wspec;
+ int hspec;
+ Background background;
+ int minw;
+ int maxw;
+ int ascent;
+ int row;
+ int col;
+ Point pos;
+};
+.EE
+.PP
+.B Next
+is used to link together the list of all cells within a table
+.RB ( Table.cells ),
+whereas
+.B nextinrow
+is used to link together all the cells within a single row
+.RB ( Tablerow.cells ).
+.B Cellid
+provides a serial number for the cell within the table.
+.B Content
+is a linked list of the items to be laid out within the cell.
+.B Lay
+is reserved for the user to describe how these items have
+been laid out.
+.B Rowspan
+and
+.B colspan
+are the number of rows and columns spanned by this cell,
+respectively.
+.B Align
+is the alignment specification for the cell.
+.B Flags
+is some combination of
+.BR TFparsing ,
+.B TFnowrap
+and
+.B TFisth
+or'd together.
+Here
+.B TFparsing
+is used internally by the parser, and should be ignored.
+.B TFnowrap
+means that the contents of the cell should not be
+wrapped if they don't fit the available width,
+rather, the table should be expanded if need be
+(this is set when the nowrap attribute is supplied).
+.B TFisth
+means that the cell was created by the
+.B <th>
+element (rather than the
+.B <td>
+element),
+indicating that it is a header cell rather than a data cell.
+.B Wspec
+provides a suggested width as a dimension specification,
+and
+.B hspec
+provides a suggested height in pixels.
+.B Background
+gives a background specification for the individual cell.
+.BR Minw ,
+.BR maxw ,
+.B ascent
+and
+.B pos
+are reserved for use by the caller during layout.
+.B Row
+and
+.B col
+give the indices of the row and column of the top left-hand
+corner of the cell within the table grid.
+.SS Client-side Maps
+.PP
+The library builds a list of client-side maps, headed by
+.BR Docinfo.maps ,
+and having the following structure:
+.PP
+.EX
+.ta 6n +\w'Rune* 'u
+typedef struct Map Map;
+struct Map
+{
+ Map* next;
+ Rune* name;
+ Area* areas;
+};
+.EE
+.PP
+.B Next
+points to the next element in the list,
+.B name
+is the name of the map (use to bind it to an image), and
+.B areas
+is a list of the areas within the image that comprise the map,
+using the following structure:
+.PP
+.EX
+.ta 6n +\w'Dimen* 'u
+typedef struct Area Area;
+struct Area
+{
+ Area* next;
+ int shape;
+ Rune* href;
+ int target;
+ Dimen* coords;
+ int ncoords;
+};
+.EE
+.PP
+.B Next
+points to the next element in the map's list of areas.
+.B Shape
+describes the shape of the area, and is one of
+.BR SHrect ,
+.B SHcircle
+or
+.BR SHpoly .
+.B Href
+is the URL associated with this area in its role as
+a hypertext link, and
+.B target
+is the target frame it should be loaded in.
+.B Coords
+is an array of coordinates for the shape, and
+.B ncoords
+is the size of this array (number of elements).
+.SS Frames
+.PP
+If the
+.B Docinfo.kidinfo
+field is set, the document is a frameset.
+In this case, it is typical for
+.I parsehtml
+to return nil, as a document which is a frameset should have no actual
+items that need to be laid out (such will appear only in subsidiary documents).
+It is possible that items will be returned by a malformed document; the caller
+should check for this and free any such items.
+.PP
+The
+.B Kidinfo
+structure itself reflects the fact that framesets can be nested within a document.
+If is defined as follows:
+.PP
+.EX
+.ta 6n +\w'Kidinfo* 'u
+typedef struct Kidinfo Kidinfo;
+struct Kidinfo
+{
+ Kidinfo* next;
+ int isframeset;
+
+ // fields for "frame"
+ Rune* src;
+ Rune* name;
+ int marginw;
+ int marginh;
+ int framebd;
+ int flags;
+
+ // fields for "frameset"
+ Dimen* rows;
+ int nrows;
+ Dimen* cols;
+ int ncols;
+ Kidinfo* kidinfos;
+ Kidinfo* nextframeset;
+};
+.EE
+.PP
+.B Next
+is only used if this structure is part of a containing frameset; it points to the next
+element in the list of children of that frameset.
+.B Isframeset
+is set when this structure represents a frameset; if clear, it is an individual frame.
+.PP
+Some fields are used only for framesets.
+.B Rows
+is an array of dimension specifications for rows in the frameset, and
+.B nrows
+is the length of this array.
+.B Cols
+is the corresponding array for columns, of length
+.BR ncols .
+.B Kidinfos
+points to a list of components contained within this frameset, each
+of which may be a frameset or a frame.
+.B Nextframeset
+is only used during parsing, and should be ignored.
+.PP
+The remaining fields are used if the structure describes a frame, not a frameset.
+.B Src
+provides the URL for the document that should be initially loaded into this frame.
+Note that this may be a relative URL, in which case it should be interpretted
+using the containing document's URL as the base.
+.B Name
+gives the name of the frame, typically supplied via a name attribute in the HTML.
+If no name was given, the library allocates one.
+.BR Marginw ,
+.B marginh
+and
+.B framebd
+are the values of the marginwidth, marginheight and frameborder attributes, respectively.
+.B Flags
+can contain some combination of the following:
+.B FRnoresize
+(the frame had the noresize attribute set, and the user should not be allowed to resize it),
+.B FRnoscroll
+(the frame should not have any scroll bars),
+.B FRhscroll
+(the frame should have a horizontal scroll bar),
+.B FRvscroll
+(the frame should have a vertical scroll bar),
+.B FRhscrollauto
+(the frame should be automatically given a horizontal scroll bar if its contents
+would not otherwise fit), and
+.B FRvscrollauto
+(the frame gets a vertical scrollbar only if required).
+.SH SOURCE
+.B /sys/src/libhtml
+.SH SEE ALSO
+.IR fmt (1)
+.PP
+W3C World Wide Web Consortium,
+``HTML 4.01 Specification''.
+.SH BUGS
+The entire HTML document must be loaded into memory before
+any of it can be parsed.
diff --git a/sys/man/2/httpd b/sys/man/2/httpd
new file mode 100755
index 000000000..3318f550f
--- /dev/null
+++ b/sys/man/2/httpd
@@ -0,0 +1,307 @@
+.TH HTTPD 2
+.SH NAME
+HConnect,
+HContent,
+HContents,
+HETag,
+HFields,
+Hio,
+Htmlesc,
+HttpHead,
+HttpReq,
+HRange,
+HSPairs,
+hmydomain,
+hversion,
+htmlesc,
+halloc,
+hbodypush,
+hbuflen,
+hcheckcontent,
+hclose,
+hdate2sec,
+hdatefmt,
+hfail,
+hflush,
+hgetc,
+hgethead,
+hinit,
+hiserror,
+hload,
+hlower,
+hmkcontent,
+hmkhfields,
+hmkmimeboundary,
+hmkspairs,
+hmoved,
+hokheaders,
+hparseheaders,
+hparsequery,
+hparsereq,
+hprint,
+hputc,
+hreadbuf,
+hredirected,
+hreqcleanup,
+hrevhfields,
+hrevspairs,
+hstrdup,
+http11,
+httpfmt,
+httpunesc,
+hunallowed,
+hungetc,
+hunload,
+hurlfmt,
+hurlunesc,
+hvprint,
+hwrite,
+hxferenc,
+ \- routines for creating an http server
+.SH SYNOPSIS
+.nf
+.B #include <u.h>
+.B #include <libc.h>
+.B #include <httpd.h>
+.PP
+.ft L
+typedef struct HConnect HConnect;
+typedef struct HContent HContent;
+typedef struct HContents HContents;
+typedef struct HETag HETag;
+typedef struct HFields HFields;
+typedef struct Hio Hio;
+typedef struct Htmlesc Htmlesc;
+typedef struct HttpHead HttpHead;
+typedef struct HttpReq HttpReq;
+typedef struct HRange HRange;
+typedef struct HSPairs HSPairs;
+
+typedef struct Bin Bin;
+.ta \w'\fLHContents 'u +\w'\fLHContentsxx 'u +\w'\fLheader[HBufSize + 2]; 'u
+
+struct Htmlesc
+{
+ char *name;
+ Rune value;
+};
+
+struct HContent
+{
+ HContent *next;
+ char *generic;
+ char *specific;
+ float q; /* desirability of this kind of file */
+ int mxb; /* max uchars until worthless */
+};
+
+struct HContents
+{
+ HContent *type;
+ HContent *encoding;
+};
+
+/*
+ * generic http header with a list of tokens,
+ * each with an optional list of parameters
+ */
+struct HFields
+{
+ char *s;
+ HSPairs *params;
+ HFields *next;
+};
+
+/*
+ * list of pairs a strings
+ * used for tag=val pairs for a search or form submission,
+ * and attribute=value pairs in headers.
+ */
+struct HSPairs
+{
+ char *s;
+ char *t;
+ HSPairs *next;
+};
+
+/*
+ * byte ranges within a file
+ */
+struct HRange
+{
+ int suffix; /* is this a suffix request? */
+ ulong start;
+ ulong stop; /* ~0UL -> not given */
+ HRange *next;
+};
+
+/*
+ * list of http/1.1 entity tags
+ */
+struct HETag
+{
+ char *etag;
+ int weak;
+ HETag *next;
+};
+
+/*
+ * HTTP custom IO
+ * supports chunked transfer encoding
+ * and initialization of the input buffer from a string.
+ */
+enum
+{
+ Hnone,
+ Hread,
+ Hend,
+ Hwrite,
+ Herr,
+
+ Hsize = HBufSize
+};
+
+struct Hio {
+ Hio *hh; /* next lower layer Hio, or nil if reads from fd */
+ int fd; /* associated file descriptor */
+ ulong seek; /* of start */
+ uchar state; /* state of the file */
+ uchar xferenc; /* chunked transfer encoding state */
+ uchar *pos; /* current position in the buffer */
+ uchar *stop; /* last character active in the buffer */
+ uchar *start; /* start of data buffer */
+ ulong bodylen; /* remaining length of message body */
+ uchar buf[Hsize+32];
+};
+
+/*
+ * request line
+ */
+struct HttpReq
+{
+ char *meth;
+ char *uri;
+ char *urihost;
+ char *search;
+ int vermaj;
+ int vermin;
+};
+
+/*
+ * header lines
+ */
+struct HttpHead
+{
+ int closeit; /* http1.1 close connection after this request? */
+ uchar persist; /* http/1.1 requests a persistent connection */
+
+ uchar expectcont; /* expect a 100-continue */
+ uchar expectother; /* expect anything else; should reject with ExpectFail */
+ ulong contlen; /* if != ~0UL, length of included message body */
+ HFields *transenc; /* if present, encoding of included message body */
+ char *client;
+ char *host;
+ HContent *okencode;
+ HContent *oklang;
+ HContent *oktype;
+ HContent *okchar;
+ ulong ifmodsince;
+ ulong ifunmodsince;
+ ulong ifrangedate;
+ HETag *ifmatch;
+ HETag *ifnomatch;
+ HETag *ifrangeetag;
+ HRange *range;
+ char *authuser; /* authorization info */
+ char *authpass;
+
+ /*
+ * experimental headers
+ */
+ int fresh_thresh;
+ int fresh_have;
+};
+
+/*
+ * all of the state for a particular connection
+ */
+struct HConnect
+{
+ void *private; /* for the library clients */
+ void (*replog)(HConnect*, char*, ...); /* called when reply sent */
+
+ HttpReq req;
+ HttpHead head;
+
+ Bin *bin;
+
+ ulong reqtime; /* time at start of request */
+ char xferbuf[HBufSize]; /* buffer for making up or transferring data */
+ uchar header[HBufSize + 2]; /* room for \\n\\0 */
+ uchar *hpos;
+ uchar *hstop;
+ Hio hin;
+ Hio hout;
+};
+
+/*
+ * configuration for all connections within the server
+ */
+extern char *hmydomain;
+extern char *hversion;
+extern Htmlesc htmlesc[];
+
+void *halloc(HConnect *c, ulong size);
+Hio *hbodypush(Hio *hh, ulong len, HFields *te);
+int hbuflen(Hio *h, void *p);
+int hcheckcontent(HContent*, HContent*, char*, int);
+void hclose(Hio*);
+ulong hdate2sec(char*);
+int hdatefmt(Fmt*);
+int hfail(HConnect*, int, ...);
+int hflush(Hio*);
+int hgetc(Hio*);
+int hgethead(HConnect *c, int many);
+int hinit(Hio*, int, int);
+int hiserror(Hio *h);
+int hload(Hio*, char*);
+char *hlower(char*);
+HContent *hmkcontent(HConnect *c, char *generic, char *specific, HContent *next);
+HFields *hmkhfields(HConnect *c, char *s, HSPairs *p, HFields *next);
+char *hmkmimeboundary(HConnect *c);
+HSPairs *hmkspairs(HConnect *c, char *s, char *t, HSPairs *next);
+int hmoved(HConnect *c, char *uri);
+void hokheaders(HConnect *c);
+int hparseheaders(HConnect*, int timeout);
+HSPairs *hparsequery(HConnect *c, char *search);
+int hparsereq(HConnect *c, int timeout);
+int hprint(Hio*, char*, ...);
+int hputc(Hio*, int);
+void *hreadbuf(Hio *h, void *vsave);
+int hredirected(HConnect *c, char *how, char *uri);
+void hreqcleanup(HConnect *c);
+HFields *hrevhfields(HFields *hf);
+HSPairs *hrevspairs(HSPairs *sp);
+char *hstrdup(HConnect *c, char *s);
+int http11(HConnect*);
+int httpfmt(Fmt*);
+char *httpunesc(HConnect *c, char *s);
+int hunallowed(HConnect *, char *allowed);
+int hungetc(Hio *h);
+char *hunload(Hio*);
+int hurlfmt(Fmt*);
+char *hurlunesc(HConnect *c, char *s);
+int hvprint(Hio*, char*, va_list);
+int hwrite(Hio*, void*, int);
+int hxferenc(Hio*, int);
+.ft R
+.SH DESCRIPTION
+For now, look at the source, or
+.IR httpd (8).
+.SH SOURCE
+.B /sys/src/libhttpd
+.SH SEE ALSO
+.IR bin (2)
+.SH BUGS
+This is a rough implementation and many details are going to change.
+
diff --git a/sys/man/2/hypot b/sys/man/2/hypot
new file mode 100755
index 000000000..dc25ed2d6
--- /dev/null
+++ b/sys/man/2/hypot
@@ -0,0 +1,21 @@
+.TH HYPOT 2
+.SH NAME
+hypot \- Euclidean distance
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+double hypot(double x, double y)
+.fi
+.SH DESCRIPTION
+.I Hypot
+returns
+.EX
+ sqrt(x*x + y*y)
+.EE
+taking precautions against unwarranted overflows.
+.SH SOURCE
+.B /sys/src/libc/port/hypot.c
diff --git a/sys/man/2/intmap b/sys/man/2/intmap
new file mode 100755
index 000000000..22dec998a
--- /dev/null
+++ b/sys/man/2/intmap
@@ -0,0 +1,126 @@
+.TH INTMAP 2
+.SH NAME
+Intmap, allocmap, freemap, insertkey, caninsertkey, lookupkey,
+deletekey \- integer to data structure maps
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fLIntmap* 'u
+Intmap* allocmap(void (*inc)(void*))
+void freemap(Intmap *map, void (*dec)(void*))
+void* lookupkey(Intmap *map, ulong key)
+void* insertkey(Intmap *map, ulong key, void *val)
+int caninsertkey(Intmap *map, ulong key, void *val)
+void* lookupkey(Intmap *map, ulong key)
+void* deletekey(Intmap *map, ulong key)
+.fi
+.SH DESCRIPTION
+An
+.B Intmap
+is an arbitrary mapping from integers to pointers.
+.I Allocmap
+creates a new map, and
+.I freemap
+destroys it.
+The
+.I inc
+function is called each time a new pointer is added
+to the map; similarly,
+.I dec
+is called on each pointer left in the map
+when it is being freed.
+Typically these functions maintain reference counts.
+New entries are added to the map by calling
+.IR insertkey ,
+which will return the previous value
+associated with the given
+.IR key ,
+or zero if there was no previous value.
+.I Caninsertkey
+is like
+.I insertkey
+but only inserts
+.I val
+if there is no current mapping.
+It returns 1 if
+.I val
+was inserted, 0 otherwise.
+.I Lookupkey
+returns the pointer associated with
+.IR key ,
+or zero if there is no such pointer.
+.I Deletekey
+removes the entry for
+.I id
+from the map, returning the
+associated pointer, if any.
+.PP
+Concurrent access to
+.BR Intmap s
+is safe,
+moderated via a
+.B QLock
+stored in the
+.B Intmap
+structure.
+.PP
+In anticipation of the storage of reference-counted
+structures, an increment function
+.I inc
+may be specified
+at map creation time.
+.I Lookupkey
+calls
+.I inc
+(if non-zero)
+on pointers before returning them.
+If the reference count adjustments were
+left to the caller (and thus not protected by the lock),
+it would be possible to accidentally reclaim a structure
+if, for example, it was deleted from the map and its
+reference count decremented between the return
+of
+.I insertkey
+and the external increment.
+.IR Insertkey
+and
+.IR caninsertkey
+do
+.I not
+call
+.I inc
+when inserting
+.I val
+into the map, nor do
+.I insertkey
+or
+.I deletekey
+call
+.I inc
+when returning old map entries.
+The rationale is that calling
+an insertion function transfers responsibility for the reference
+to the map, and responsibility is given back via the return value of
+.I deletekey
+or the next
+.IR insertkey .
+.PP
+.BR Intmap s
+are used by the 9P library to implement
+.BR Fidpool s
+and
+.BR Reqpool s.
+.SH SOURCE
+.B /sys/src/lib9p/intmap.c
+.SH SEE ALSO
+.IR 9p (2),
+.IR 9pfid (2).
diff --git a/sys/man/2/ioproc b/sys/man/2/ioproc
new file mode 100755
index 000000000..b20ba034b
--- /dev/null
+++ b/sys/man/2/ioproc
@@ -0,0 +1,178 @@
+.TH IOPROC 2
+.SH NAME
+closeioproc,
+iocall,
+ioclose,
+iointerrupt,
+iodial,
+ioopen,
+ioproc,
+ioread,
+ioreadn,
+iowrite \- slave I/O processes for threaded programs
+.SH SYNOPSIS
+.PP
+.de XX
+.ift .sp 0.5
+.ifn .sp
+..
+.EX
+.ta \w'Ioproc* 'u
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+.sp
+typedef struct Ioproc Ioproc;
+.sp
+Ioproc* ioproc(void);
+.XX
+int ioopen(Ioproc *io, char *file, int omode);
+int ioclose(Ioproc *io, int fd);
+long ioread(Ioproc *io, int fd, void *a, long n);
+long ioreadn(Ioproc *io, int fd, void *a, long n);
+long iowrite(Ioproc *io, int fd, void *a, long n);
+int iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp);
+.XX
+void iointerrupt(Ioproc *io);
+void closeioproc(Ioproc *io);
+.XX
+long iocall(Ioproc *io, long (*op)(va_list *arg), ...);
+.EE
+.SH DESCRIPTION
+.PP
+These routines provide access to I/O in slave procs.
+Since the I/O itself is done in a slave proc, other threads
+in the calling proc can run while the calling thread
+waits for the I/O to complete.
+.PP
+.I Ioproc
+forks a new slave proc and returns a pointer to the
+.B Ioproc
+associated with it.
+.I Ioproc
+uses
+.I mallocz
+and
+.IR proccreate ;
+if either fails, it calls
+.I sysfatal
+rather than return an error.
+.PP
+.IR Ioopen ,
+.IR ioclose ,
+.IR ioread ,
+.IR ioreadn ,
+.IR iowrite ,
+and
+.IR iodial
+execute the
+similarly named library or system calls
+(see
+.IR open (2),
+.IR read (2),
+and
+.IR dial (2))
+in the slave process associated with
+.IR io .
+It is an error to execute more than one call
+at a time in an I/O proc.
+.PP
+.I Iointerrupt
+interrupts the call currently executing in the I/O proc.
+If no call is executing,
+.IR iointerrupt
+is a no-op.
+.PP
+.I Closeioproc
+terminates the I/O proc and frees the associated
+.B Ioproc .
+.PP
+.I Iocall
+is a primitive that may be used to implement
+more slave I/O routines.
+.I Iocall
+arranges for
+.I op
+to be called in
+.IR io 's
+proc, with
+.I arg
+set to the variable parameter list,
+returning the value that
+.I op
+returns.
+.SH EXAMPLE
+Relay messages between two file descriptors,
+counting the total number of bytes seen:
+.IP
+.EX
+.ta +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
+int tot;
+
+void
+relaythread(void *v)
+{
+ int *fd, n;
+ char buf[1024];
+ Ioproc *io;
+
+ fd = v;
+ io = ioproc();
+ while((n = ioread(io, fd[0], buf, sizeof buf)) > 0){
+ if(iowrite(io, fd[1], buf, n) != n)
+ sysfatal("iowrite: %r");
+ tot += n;
+ }
+ closeioproc(io);
+}
+
+void
+relay(int fd0, int fd1)
+{
+ int fd[4];
+
+ fd[0] = fd[3] = fd0;
+ fd[1] = fd[2] = fd1;
+ threadcreate(relaythread, fd, 8192);
+ threadcreate(relaythread, fd+2, 8192);
+}
+.EE
+.LP
+If the two
+.I relaythread
+instances were running in different procs, the
+common access to
+.I tot
+would be unsafe.
+.PP
+Implement
+.IR ioread :
+.IP
+.EX
+static long
+_ioread(va_list *arg)
+{
+ int fd;
+ void *a;
+ long n;
+
+ fd = va_arg(*arg, int);
+ a = va_arg(*arg, void*);
+ n = va_arg(*arg, long);
+ return read(fd, a, n);
+}
+
+long
+ioread(Ioproc *io, int fd, void *a, long n)
+{
+ return iocall(io, _ioread, fd, a, n);
+}
+.EE
+.SH SOURCE
+.B /sys/src/libthread/io*.c
+.SH SEE ALSO
+.IR dial (2),
+.IR open (2),
+.IR read (2),
+.IR thread (2)
+
diff --git a/sys/man/2/iounit b/sys/man/2/iounit
new file mode 100755
index 000000000..a31d70792
--- /dev/null
+++ b/sys/man/2/iounit
@@ -0,0 +1,37 @@
+.TH IOUNIT 2
+.SH NAME
+iounit \- return size of atomic I/O unit for file descriptor
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int iounit(int fd)
+.SH DESCRIPTION
+Reads and writes of files are transmitted using the 9P protocol (see
+.IR intro (5))
+and in general, operations involving large amounts of data must be
+broken into smaller pieces by the operating system.
+The `I/O unit' associated with each file descriptor records the maximum
+size, in bytes, that may be read or written without breaking up the transfer.
+.PP
+The
+.I iounit
+routine uses the
+.IR dup (3)
+interface to discover the I/O unit size for the file descriptor
+.I fd
+and returns its value.
+Certain file descriptors, particularly those associated with devices, may
+have no specific I/O unit, in which case
+.I iounit
+will return
+.BR 0 .
+.SH SOURCE
+.B /sys/src/libc/9sys
+.SH SEE ALSO
+.IR dup (3),
+.IR read (5)
+.SH DIAGNOSTICS
+Returns zero if any error occurs or if the I/O unit size of the fd is unspecified or unknown.
diff --git a/sys/man/2/ip b/sys/man/2/ip
new file mode 100755
index 000000000..e84b14c08
--- /dev/null
+++ b/sys/man/2/ip
@@ -0,0 +1,364 @@
+.TH IP 2
+.SH NAME
+eipfmt, parseip, parseipmask, v4parseip, v4parsecidr, parseether, myipaddr, myetheraddr, maskip, equivip4, equivip6, defmask, isv4, v4tov6, v6tov4, nhgetv, nhgetl, nhgets, hnputv, hnputl, hnputs, ptclbsum, readipifc \- Internet Protocol addressing
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <ip.h>
+.PP
+.B
+int eipfmt(Fmt*)
+.PP
+.B
+vlong parseip(uchar *ipaddr, char *str)
+.PP
+.B
+vlong parseipmask(uchar *ipaddr, char *str)
+.PP
+.B
+char* v4parseip(uchar *ipaddr, char *str)
+.PP
+.B
+ulong v4parsecidr(uchar *addr, uchar *mask, char *str)
+.PP
+.B
+int parseether(uchar *eaddr, char *str)
+.PP
+.B
+int myetheraddr(uchar *eaddr, char *dev)
+.PP
+.B
+int myipaddr(uchar *ipaddr, char *net)
+.PP
+.B
+void maskip(uchar *from, uchar *mask, uchar *to)
+.PP
+.B
+int equivip4(uchar *ipaddr1, uchar *ipaddr2)
+.PP
+.B
+int equivip6(uchar *ipaddr1, uchar *ipaddr2)
+.PP
+.B
+uchar* defmask(uchar *ipaddr)
+.PP
+.B
+int isv4(uchar *ipaddr)
+.PP
+.B
+void v4tov6(uchar *ipv6, uchar *ipv4)
+.PP
+.B
+void v6tov4(uchar *ipv4, uchar *ipv6)
+.PP
+.B
+ushort nhgets(void *p)
+.PP
+.B
+uint nhgetl(void *p)
+.PP
+.B
+uvlong nhgetv(void *p)
+.PP
+.B
+void hnputs(void *p, ushort v)
+.PP
+.B
+void hnputl(void *p, uint v)
+.PP
+.B
+void hnputv(void *p, uvlong v)
+.PP
+.B
+ushort ptclbsum(uchar *a, int n)
+.PP
+.B
+Ipifc* readipifc(char *net, Ipifc *ifc, int index)
+.PP
+.B
+uchar IPv4bcast[IPaddrlen];
+.PP
+.B
+uchar IPv4allsys[IPaddrlen];
+.PP
+.B
+uchar IPv4allrouter[IPaddrlen];
+.PP
+.B
+uchar IPallbits[IPaddrlen];
+.PP
+.B
+uchar IPnoaddr[IPaddrlen];
+.PP
+.B
+uchar v4prefix[IPaddrlen];
+.SH DESCRIPTION
+These routines are used by Internet Protocol (IP) programs to
+manipulate IP and Ethernet addresses.
+Plan 9, by default, uses V6 format IP addresses. Since V4
+addresses fit into the V6 space, all IP addresses can be represented.
+IP addresses are stored as a string of 16
+.B unsigned
+.BR chars ,
+Ethernet
+addresses as 6
+.B unsigned
+.BR chars .
+Either V4 or V6 string representation can be used for IP addresses.
+For V4 addresses, the representation can be (up to) 4 decimal
+integers from 0 to 255 separated by periods.
+For V6 addresses, the representation is (up to) 8 hex integers
+from 0x0 to 0xFFFF separated by colons.
+Strings of 0 integers can be elided using two colons.
+For example,
+.B FFFF::1111
+is equivalent to
+.BR FFFF:0:0:0:0:0:0:1111 .
+The string representation for IP masks is a superset of the
+address representation. It includes slash notation that indicates
+the number of leading 1 bits in the mask. Thus, a
+V4 class C mask can be represented as
+.BR FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00 ,
+.BR 255.255.255.0 ,
+or
+.BR /120.
+The string representation of Ethernet addresses is exactly
+12 hexadecimal digits.
+.PP
+.I Eipfmt
+is a
+.IR print (2)
+formatter for Ethernet (verb
+.BR E )
+addresses,
+IP V6 (verb
+.BR I )
+addresses,
+IP V4 (verb
+.BR V )
+addresses,
+and IP V6 (verb
+.BR M )
+masks.
+.PP
+.I Parseip
+converts a string pointed to by
+.I str
+to a 16-byte IP address starting at
+.IR ipaddr .
+As a concession to backwards compatibility,
+if the string is a V4 address, the return value
+is an unsigned long integer containing the big-endian V4 address.
+If not, the return value is 6.
+.I Parseipmask
+converts a string pointed to by
+.I str
+to a 6-byte IP mask starting at
+.IR ipaddr .
+It too returns an unsigned long big-endian V4 address or 6.
+Both routines return -1 on errors.
+.PP
+.I V4parseip
+converts a string pointed to by
+.I str
+to a 4-byte V4 IP address starting at
+.IR ipaddr .
+.PP
+.I V4parsecidr
+converts a string of the form
+addr/mask, pointed to by
+.IR str ,
+to a 4-byte V4 IP address starting at
+.I ipaddr
+and a 4-byte V4 IP mask starting at
+.IR mask .
+.PP
+.I Myipaddr
+returns the first valid IP address in
+the IP stack rooted at
+.IR net .
+.PP
+.I Parseether
+converts a string pointed to by
+.I str
+to a 6-byte Ethernet address starting at
+.IR eaddr .
+.I Myetheraddr
+reads the Ethernet address string from file
+.IB dev /addr
+and parses it into
+.IR eaddr .
+Both routines return a negative number on errors.
+.PP
+.I Maskip
+places the bit-wise AND of the IP addresses pointed
+to by its first two arguments into the buffer pointed
+to by the third.
+.PP
+.I Equivip
+returns non-zero if the IP addresses pointed to by its two
+arguments are equal.
+.I Equivip4
+operates on v4 addresses,
+.I equivip6
+operates on v6 addresses.
+.PP
+.I Defmask
+returns the standard class A, B, or C mask for
+.IR ipaddr .
+.PP
+.I Isv4
+returns non-zero if the V6 address is in the V4 space, that is,
+if it starts with
+.BR 0:0:0:0:0:0:FFFF .
+.I V4tov6
+converts the 4-byte V4 address,
+.IR v4ip ,
+to a V6 address and puts the result in
+.IR v6ip .
+.I V6tov4
+converts the V6 address,
+.IR v6ip ,
+to a 4-byte V4 address and puts the result in
+.IR v4ip .
+.PP
+.IR Hnputs ,
+.I hnputl
+and
+.I hnputv
+are used to store 16-bit, 32-bit, and 64-bit integers, respectively, into IP big-endian form.
+.IR Nhgets ,
+.I nhgetl
+and
+.I nhgetv
+convert big-endian 2, 4 and 8 byte quantities into integers (or
+.IR uvlong s).
+.PP
+.I Pctlbsum
+returns the one's complement checksum used in IP protocols, typically invoked as
+.IP
+.EX
+hnputs(hdr->cksum, ~ptclbsum(data, len) & 0xffff);
+.EE
+.PP
+A number of standard IP addresses in V6 format are also defined. They are:
+.TF IPv4allrouter
+.TP
+.B IPv4bcast
+the V4 broadcast address
+.TP
+.B IPv4allsys
+the V4 all systems multicast address
+.TP
+.B IPv4allrouter
+the V4 all routers multicast address
+.TP
+.B IPallbits
+the V6 all bits on address
+.TP
+.B IPnoaddr
+the V6 null address, all zeros
+.TP
+.B v4prefix
+the IP V6 prefix to all embedded V4 addresses
+.PD
+.PP
+.I Readipifc
+returns information about
+a particular interface
+.RI ( index
+>= 0)
+or all IP interfaces
+.RI ( index
+< 0)
+configured under a mount point
+.IR net ,
+default
+.BR /net .
+Each interface is described by one
+.I Ipifc
+structure which in turn points to a linked list of
+.IR Iplifc
+structures describing the addresses assigned
+to this interface.
+If the list
+.IR ifc
+is supplied,
+that list is freed.
+Thus, subsequent calls can be used
+to free the list returned by the previous call.
+.I Ipifc
+is:
+.PP
+.EX
+typedef struct Ipifc
+{
+ Ipifc *next;
+ Iplifc *lifc; /* local addressses */
+
+ /* per ip interface */
+ int index; /* number of interface in ipifc dir */
+ char dev[64]; /* associated physical device */
+ int mtu; /* max transfer unit */
+
+ uchar sendra6; /* on == send router adv */
+ uchar recvra6; /* on == rcv router adv */
+
+ ulong pktin; /* packets read */
+ ulong pktout; /* packets written */
+ ulong errin; /* read errors */
+ ulong errout; /* write errors */
+ Ipv6rp rp; /* route advertisement params */
+} Ipifc;
+.EE
+.PP
+.I Iplifc
+is:
+.PP
+.EX
+struct Iplifc
+{
+ Iplifc *next;
+
+ uchar ip[IPaddrlen];
+ uchar mask[IPaddrlen];
+ uchar net[IPaddrlen]; /* ip & mask */
+ ulong preflt; /* preferred lifetime */
+ ulong validlt; /* valid lifetime */
+};
+.EE
+.PP
+.I Ipv6rp
+is:
+.PP
+.EX
+struct Ipv6rp
+{
+ int mflag;
+ int oflag;
+ int maxraint; /* max route adv interval */
+ int minraint; /* min route adv interval */
+ int linkmtu;
+ int reachtime;
+ int rxmitra;
+ int ttl;
+ int routerlt;
+};
+.EE
+.PP
+.I Dev
+contains the first 64 bytes of the device configured with this
+interface.
+.I Net
+is
+.IB ip & mask
+if the network is multipoint or
+the remote address if the network is
+point to point.
+.SH SOURCE
+.B /sys/src/libip
+.SH SEE ALSO
+.IR print (2),
+.IR ip (3)
diff --git a/sys/man/2/isalpharune b/sys/man/2/isalpharune
new file mode 100755
index 000000000..1c28369a2
--- /dev/null
+++ b/sys/man/2/isalpharune
@@ -0,0 +1,54 @@
+.TH ISALPHARUNE 2
+.SH NAME
+isalpharune, islowerrune, isspacerune, istitlerune, isupperrune, isdigitrune, tolowerrune, totitlerune, toupperrune \- Unicode character classes and cases
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int isalpharune(Rune c)
+.PP
+.B
+int islowerrune(Rune c)
+.PP
+.B
+int isspacerune(Rune c)
+.PP
+.B
+int istitlerune(Rune c)
+.PP
+.B
+int isupperrune(Rune c)
+.PP
+.B
+int isdigitrune(Rune c)
+.PP
+.B
+Rune tolowerrune(Rune c)
+.PP
+.B
+Rune totitlerune(Rune c)
+.PP
+.B
+Rune toupperrune(Rune c)
+.SH DESCRIPTION
+These routines examine and operate on Unicode characters,
+in particular a subset of their properties as defined in the Unicode standard.
+Unicode defines some characters as alphabetic and specifies three cases:
+upper, lower, and title.
+Analogously to
+.IR ctype (2)
+for
+.SM ASCII\c
+,
+these routines
+test types and modify cases for Unicode characters.
+The names are self-explanatory.
+.PP
+The case-conversion routines return the character unchanged if it has no case.
+.SH SOURCE
+.B /sys/src/libc/port/runetype.c
+.SH "SEE ALSO
+.IR ctype (2) ,
+.IR "The Unicode Standard" .
diff --git a/sys/man/2/keyboard b/sys/man/2/keyboard
new file mode 100755
index 000000000..d0463f789
--- /dev/null
+++ b/sys/man/2/keyboard
@@ -0,0 +1,104 @@
+.TH KEYBOARD 2
+.SH NAME
+initkeyboard, ctlkeyboard, closekeyboard \- keyboard control
+.SH SYNOPSIS
+.nf
+.B
+#include <u.h>
+.B
+#include <libc.h>
+.B
+#include <thread.h>
+.B
+#include <keyboard.h>
+.PP
+.B
+Keyboardctl *initkeyboard(char *file)
+.PP
+.B
+int ctlkeyboard(Keyboardctl *kc, char *msg)
+.PP
+.B
+void closekeyboard(Keyboard *kc)
+.SH DESCRIPTION
+These functions access and control a keyboard interface
+for character-at-a-time I/O in a multi-threaded environment, usually in combination with
+.IR mouse (2).
+They use the message-passing
+.B Channel
+interface in the threads library
+(see
+.IR thread (2));
+programs that wish a more event-driven, single-threaded approach should use
+.IR event (2).
+.PP
+.I Initkeyboard
+opens a connection to the keyboard and returns a
+.B Keyboardctl
+structure:
+.IP
+.EX
+.ta 6n +\w'Channel 'u +\w'consfd; 'u
+typedef struct Keyboardct Keyboardctl;
+struct Keyboardctl
+{
+ Channel *c; /* chan(Rune[20]) */
+
+ char *file;
+ int consfd; /* to cons file */
+ int ctlfd; /* to ctl file */
+ int pid; /* of slave proc */
+};
+.EE
+.PP
+The argument to
+.I initkeyboard
+is a
+.I file
+naming the device file from which characters may be read,
+typically
+.BR /dev/cons .
+If
+.I file
+is nil,
+.B /dev/cons
+is assumed.
+.PP
+Once the
+.B Keyboardctl
+is set up a
+message containing a
+.BR Rune
+will be sent on the
+.B Channel
+.B Keyboardctl.c
+to report each character read from the device.
+.PP
+.I Ctlkeyboard
+is used to set the state of the interface, typically to turn raw mode on and off
+(see
+.IR cons (3)).
+It writes the string
+.I msg
+to the control file associated with the device, which is assumed to be the regular device file name
+with the string
+.B ctl
+appended.
+.PP
+.I Closekeyboard
+closes the file descriptors associated with the keyboard, kills the slave processes,
+and frees the
+.B Keyboardctl
+structure.
+.PP
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR draw (2),
+.IR event (2),
+.IR thread (2).
+.SH BUGS
+Because the interface delivers complete runes,
+there is no way to report lesser actions such as
+shift keys or even individual bytes.
diff --git a/sys/man/2/lock b/sys/man/2/lock
new file mode 100755
index 000000000..76d15b1fe
--- /dev/null
+++ b/sys/man/2/lock
@@ -0,0 +1,313 @@
+.TH LOCK 2
+.SH NAME
+lock, canlock, unlock,
+qlock, canqlock, qunlock,
+rlock, canrlock, runlock,
+wlock, canwlock, wunlock,
+rsleep, rwakeup, rwakeupall,
+incref, decref
+\- spin locks, queueing rendezvous locks, reader-writer locks, rendezvous points, and reference counts
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+.PP
+.ft L
+.nf
+void lock(Lock *l)
+int canlock(Lock *l)
+void unlock(Lock *l)
+.PP
+.ft L
+.nf
+void qlock(QLock *l)
+int canqlock(QLock *l)
+void qunlock(QLock *l)
+.PP
+.ft L
+.nf
+void rlock(RWLock *l)
+int canrlock(RWLock *l)
+void runlock(RWLock *l)
+.PP
+.ft L
+.nf
+void wlock(RWLock *l)
+int canwlock(RWLock *l)
+void wunlock(RWLock *l)
+.PP
+.ft L
+.nf
+typedef struct Rendez {
+ QLock *l;
+ \fI...\fP
+} Rendez;
+.PP
+.ft L
+.nf
+void rsleep(Rendez *r)
+int rwakeup(Rendez *r)
+int rwakeupall(Rendez *r)
+.PP
+.ft L
+#include <thread.h>
+.PP
+.ft L
+.nf
+typedef struct Ref {
+ long ref;
+} Ref;
+.PP
+.ft L
+.nf
+void incref(Ref*)
+long decref(Ref*)
+.fi
+.SH DESCRIPTION
+These routines are used to synchronize processes sharing memory.
+.PP
+.B Locks
+are spin locks,
+.B QLocks
+and
+.B RWLocks
+are different types of queueing rendezvous locks,
+and
+.B Rendezes
+are rendezvous points.
+.PP
+Locks and rendezvous points work in regular programs as
+well as programs that use the thread library
+(see
+.IR thread (2)).
+The thread library replaces the
+.IR rendezvous (2)
+system call
+with its own implementation,
+.IR threadrendezvous ,
+so that threads as well as processes may be synchronized by locking calls
+in threaded programs.
+.PP
+Used carelessly, spin locks can be expensive and can easily generate deadlocks.
+Their use is discouraged, especially in programs that use the
+thread library because they prevent context switches between threads.
+.PP
+.I Lock
+blocks until the lock has been obtained.
+.I Canlock
+is non-blocking.
+It tries to obtain a lock and returns a non-zero value if it
+was successful, 0 otherwise.
+.I Unlock
+releases a lock.
+.PP
+.B QLocks
+have the same interface but are not spin locks; instead if the lock is taken
+.I qlock
+will suspend execution of the calling task until it is released.
+.PP
+Although
+.B Locks
+are the more primitive lock, they have limitations; for example,
+they cannot synchronize between tasks in the same
+.IR proc .
+Use
+.B QLocks
+instead.
+.PP
+.B RWLocks
+manage access to a data structure that has distinct readers and writers.
+.I Rlock
+grants read access;
+.I runlock
+releases it.
+.I Wlock
+grants write access;
+.I wunlock
+releases it.
+.I Canrlock
+and
+.I canwlock
+are the non-blocking versions.
+There may be any number of simultaneous readers,
+but only one writer.
+Moreover,
+if write access is granted no one may have
+read access until write access is released.
+.PP
+All types of lock should be initialized to all zeros before use; this
+puts them in the unlocked state.
+.PP
+.B Rendezes
+are rendezvous points. Each
+.B Rendez
+.I r
+is protected by a
+.B QLock
+.IB r -> l \fR,
+which must be held by the callers of
+.IR rsleep ,
+.IR rwakeup ,
+and
+.IR rwakeupall .
+.I Rsleep
+atomically releases
+.IB r -> l
+and suspends execution of the calling task.
+After resuming execution,
+.I rsleep
+will reacquire
+.IB r -> l
+before returning.
+If any processes are sleeping on
+.IR r ,
+.I rwakeup
+wakes one of them.
+it returns 1 if a process was awakened, 0 if not.
+.I Rwakeupall
+wakes all processes sleeping on
+.IR r ,
+returning the number of processes awakened.
+.I Rwakeup
+and
+.I rwakeupall
+do not release
+.IB r -> l
+and do not suspend execution of the current task.
+.PP
+Before use,
+.B Rendezes
+should be initialized to all zeros except for
+.IB r -> l
+pointer, which should point at the
+.B QLock
+that will guard
+.IR r .
+It is important that this
+.B QLock
+is the same one that protects the rendezvous condition; see the example.
+.PP
+A
+.B Ref
+contains a
+.B long
+that can be incremented and decremented atomically:
+.I Incref
+increments the
+.I Ref
+in one atomic operation.
+.I Decref
+atomically decrements the
+.B Ref
+and returns zero if the resulting value is zero, non-zero otherwise.
+.SH EXAMPLE
+Implement a buffered single-element channel using
+.I rsleep
+and
+.IR rwakeup :
+.IP
+.EX
+.ta +4n +4n +4n
+typedef struct Chan
+{
+ QLock l;
+ Rendez full, empty;
+ int val, haveval;
+} Chan;
+.EE
+.IP
+.EX
+.ta +4n +4n +4n
+Chan*
+mkchan(void)
+{
+ Chan *c;
+
+ c = mallocz(sizeof *c, 1);
+ c->full.l = &c->l;
+ c->empty.l = &c->l;
+ return c;
+}
+.EE
+.IP
+.EX
+.ta +4n +4n +4n
+void
+send(Chan *c, int val)
+{
+ qlock(&c->l);
+ while(c->haveval)
+ rsleep(&c->full);
+ c->haveval = 1;
+ c->val = val;
+ rwakeup(&c->empty); /* no longer empty */
+ qunlock(&c->l);
+}
+.EE
+.IP
+.EX
+.ta +4n +4n +4n
+int
+recv(Chan *c)
+{
+ int v;
+
+ qlock(&c->l);
+ while(!c->haveval)
+ rsleep(&c->empty);
+ c->haveval = 0;
+ v = c->val;
+ rwakeup(&c->full); /* no longer full */
+ qunlock(&c->l);
+ return v;
+}
+.EE
+.LP
+Note that the
+.B QLock
+protecting the
+.B Chan
+is the same
+.B QLock
+used for the
+.BR Rendez ;
+this ensures that wakeups are not missed.
+.SH SOURCE
+.B /sys/src/libc/port/lock.c
+.br
+.B /sys/src/libc/9sys/qlock.c
+.br
+.B /sys/src/libthread/ref.c
+.SH SEE ALSO
+.I rfork
+in
+.IR fork (2)
+.SH BUGS
+.B Locks
+are not strictly spin locks.
+After each unsuccessful attempt,
+.I lock
+calls
+.B sleep(0)
+to yield the CPU; this handles the common case
+where some other process holds the lock.
+After a thousand unsuccessful attempts,
+.I lock
+sleeps for 100ms between attempts.
+After another thousand unsuccessful attempts,
+.I lock
+sleeps for a full second between attempts.
+.B Locks
+are not intended to be held for long periods of time.
+The 100ms and full second sleeps are only heuristics to
+avoid tying up the CPU when a process deadlocks.
+As discussed above,
+if a lock is to be held for much more than a few instructions,
+the queueing lock types should be almost always be used.
+.PP
+It is an error for a program to
+.I fork
+when it holds a lock in shared memory, since this will result
+in two processes holding the same lock at the same time,
+which should not happen.
diff --git a/sys/man/2/mach b/sys/man/2/mach
new file mode 100755
index 000000000..a41170dad
--- /dev/null
+++ b/sys/man/2/mach
@@ -0,0 +1,393 @@
+.TH MACH 2
+.SH NAME
+crackhdr, machbytype, machbyname, newmap, setmap, findseg, unusemap,
+loadmap, attachproc, get1, get2, get4, get8, put1, put2, put4, put8,
+beswab, beswal, beswav, leswab, leswal, leswav \- machine-independent access to executable files
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bio.h>
+.br
+.B #include <mach.h>
+.PP
+.ta \w'\fLmachines 'u
+.B
+int crackhdr(int fd, Fhdr *fp)
+.PP
+.B
+void machbytype(int type)
+.PP
+.B
+int machbyname(char *name)
+.PP
+.B
+Map *newmap(Map *map, int n)
+.PP
+.B
+int setmap(Map *map, int fd, ulong base, ulong end,
+.PP
+.B
+ ulong foffset, char *name)
+.PP
+.B
+int findseg(Map *map, char *name)
+.PP
+.B
+void unusemap(Map *map, int seg)
+.PP
+.B
+Map *loadmap(Map *map, int fd, Fhdr *fp)
+.PP
+.B
+Map *attachproc(int pid, int kflag, int corefd, Fhdr *fp)
+.PP
+.B
+int get1(Map *map, ulong addr, uchar *buf, int n)
+.PP
+.B
+int get2(Map *map, ulong addr, ushort *val)
+.PP
+.B
+int get4(Map *map, ulong addr, long *val)
+.PP
+.B
+int get8(Map *map, ulong addr, vlong *val)
+.PP
+.B
+int put1(Map *map, ulong addr, uchar *buf, int n)
+.PP
+.B
+int put2(Map *map, ulong addr, ushort val)
+.PP
+.B
+int put4(Map *map, ulong addr, long val)
+.PP
+.B
+int put8(Map *map, ulong addr, vlong val)
+.PP
+.B
+ushort beswab(ushort val)
+.PP
+.B
+long beswal(long val)
+.PP
+.B
+long beswav(vlong val)
+.PP
+.B
+ushort leswab(ushort val)
+.PP
+.B
+long leswal(long val)
+.PP
+.B
+long leswav(vlong val)
+.PP
+.B
+extern Mach mach;
+.PP
+.B
+extern Machdata machdata;
+.SH DESCRIPTION
+These functions provide
+a processor-independent interface for accessing
+the executable files or executing images of all
+architectures.
+Related library functions described in
+.IR symbol (2)
+and
+.IR object (2)
+provide similar access to symbol tables and object files.
+.PP
+An
+.I executable
+is a file containing an executable program or the
+.B text
+file of the
+.B /proc
+file system associated with an executing process as
+described in
+.IR proc (3).
+After opening an executable, an application
+invokes a library function which parses the
+file header,
+determines the target architecture and
+initializes data structures with parameters
+and pointers to functions appropriate for
+that architecture. Next, the application
+invokes functions to construct one or more
+.IR maps ,
+data structures that translate references
+in the address space of the executable
+to offsets in the file. Each
+.I map
+comprises one or more
+.BR segments ,
+each associating a non-overlapping range of
+memory addresses with a logical section of
+the executable.
+Other library functions then use a map
+and the architecture-specific data structures
+to provide a generic interface to the
+processor-dependent data.
+.PP
+.I Crackhdr
+interprets the header of the executable
+associated with
+the open file descriptor
+.IR fd .
+It loads the data structure
+.I fp
+with a machine-independent description
+of the header information and
+points global variable
+.I mach
+to the
+.B Mach
+data structure containing processor-dependent parameters
+of the target architecture.
+.PP
+.I Machbytype
+selects architecture-specific data structures and parameter
+values based on
+the code stored in the
+field named
+.I type
+in the
+.B Fhdr
+data structure.
+.I Machbyname
+performs the same selection based
+on the name of a processor class; see
+.IR 2c (1)
+for a list of valid names.
+Both functions point global variables
+.I mach
+and
+.I machdata
+to the
+.I Mach
+and
+.I Machdata
+data structures appropriate for the
+target architecture and load global variable
+.I asstype
+with the proper disassembler type code.
+.PP
+.I Newmap
+creates an empty map with
+.I n
+segments.
+If
+.I map
+is zero, the new map is dynamically
+allocated, otherwise it is assumed to
+point to an existing dynamically allocated map whose
+size is adjusted, as necessary.
+A zero return value indicates an allocation error.
+.PP
+.I Setmap
+loads the first unused segment in
+.I map
+with the
+segment mapping parameters.
+.I Fd
+is an open file descriptor associated with
+an executable.
+.I Base
+and
+.I end
+contain the lowest and highest virtual addresses
+mapped by the segment.
+.I Foffset
+is the offset to the start of the segment in the file.
+.I Name
+is a name to be attached to the segment.
+.PP
+.I Findseg
+returns the index of the the
+segment named
+.I name
+in
+.IR map .
+A return of -1 indicates that no
+segment matches
+.IR name .
+.PP
+.I Unusemap
+marks segment number
+.I seg
+in map
+.I map
+unused. Other
+segments in the map remain unaffected.
+.PP
+.I Loadmap
+initializes a default map containing
+segments named `text' and `data' that
+map the instruction and data segments
+of the executable described in the
+.B Fhdr
+structure pointed to by
+.IR fp .
+Usually that structure was loaded by
+.IR crackhdr
+and can be passed to this function without
+modification.
+If
+.I map
+is non-zero, that map, which must have been
+dynamically allocated, is resized to contain two segments;
+otherwise a new map is allocated.
+This function returns zero if allocation fails.
+.I Loadmap
+is usually used to build a map for accessing
+a static executable, for example, an executable
+program file.
+.PP
+.I Attachproc
+constructs a map for accessing a
+running process. It
+returns the address of a
+.I Map
+containing segments mapping the
+address space of the running process
+whose process ID is
+.BR pid .
+If
+.B kflag
+is non-zero, the process is assumed to be
+a kernel process.
+.B Corefd
+is an file descriptor opened to
+.BR /proc/\fIpid\fP/mem .
+.B Fp
+points to the
+.I Fhdr
+structure describing the header
+of the executable. For most architectures
+the resulting
+.I Map
+contains four segments named `text', `data',
+`regs' and `fpregs'. The latter two provide access to
+the general and floating point registers, respectively.
+If the executable is a kernel process (indicated by a
+non-zero
+.B kflag
+argument), the data segment extends to the maximum
+supported address, currently 0xffffffff, and the
+register sets are read-only. In user-level programs,
+the data segment extends to the
+top of the stack or 0x7fffffff if the stack top
+cannot be found, and the register sets are readable
+and writable.
+.I Attachproc
+returns zero if it is unable to build the map
+for the specified process.
+.PP
+.IR Get1 ,
+.IR get2 ,
+.IR get4 ,
+and
+.I get8
+retrieve the data stored at address
+.I addr
+in the executable associated
+with
+.IR map .
+.I Get1
+retrieves
+.I n
+bytes of data beginning at
+.I addr
+into
+.IR buf .
+.IR Get2 ,
+.I get4
+and
+.I get8
+retrieve 16-bit, 32-bit and 64-bit values respectively,
+into the location pointed to by
+.IR val .
+The value is byte-swapped if the source
+byte order differs from that of the current architecture.
+This implies that the value returned by
+.IR get2 ,
+.IR get4 ,
+and
+.I get8
+may not be the same as the byte sequences
+returned by
+.I get1
+when
+.I n
+is two, four or eight; the former may be byte-swapped, the
+latter reflects the byte order of the target architecture.
+If the file descriptor associated with the applicable segment in
+.I map
+is negative, the address itself is placed in the
+return location. These functions return the number
+of bytes read or a \-1 when there is an error.
+.PP
+.IR Put1 ,
+.IR put2 ,
+.IR put4 ,
+and
+.I put8
+write to
+the executable associated with
+.IR map .
+The address is translated using the
+map parameters and multi-byte quantities are
+byte-swapped, if necessary, before they are written.
+.I Put1
+transfers
+.I n
+bytes stored at
+.IR buf ;
+.IR put2 ,
+.IR put4 ,
+and
+.I put8
+write the 16-bit, 32-bit or 64-bit quantity contained in
+.IR val ,
+respectively. The number of bytes transferred is returned.
+A \-1 return value indicates an error.
+.PP
+.IR Beswab ,
+.IR beswal ,
+and
+.I beswav
+return the
+.BR ushort ,
+.BR long ,
+and
+.B vlong
+big-endian representation of
+.IR val ,
+respectively.
+.IR Leswab ,
+.IR leswal ,
+and
+.I leswav
+return the little-endian representation of the
+.BR ushort ,
+.BR long ,
+and
+.B vlong
+contained in
+.IR val .
+.SH SOURCE
+.B /sys/src/libmach
+.SH "SEE ALSO"
+.IR 2c (1),
+.IR symbol (2),
+.IR object (2),
+.IR errstr (2),
+.IR proc (3),
+.IR a.out (6)
+.SH DIAGNOSTICS
+These routines set
+.IR errstr .
diff --git a/sys/man/2/malloc b/sys/man/2/malloc
new file mode 100755
index 000000000..4ae226591
--- /dev/null
+++ b/sys/man/2/malloc
@@ -0,0 +1,230 @@
+.TH MALLOC 2
+.SH NAME
+malloc, mallocalign, mallocz, free, realloc, calloc, msize, setmalloctag, setrealloctag, getmalloctag, getrealloctag, malloctopoolblock \- memory allocator
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLvoid* 'u
+.B
+void* malloc(ulong size)
+.PP
+.B
+void* mallocalign(ulong size, ulong align, long offset, ulong span)
+.PP
+.B
+void* mallocz(ulong size, int clr)
+.PP
+.B
+void free(void *ptr)
+.PP
+.B
+void* realloc(void *ptr, ulong size)
+.PP
+.B
+void* calloc(ulong nelem, ulong elsize)
+.PP
+.B
+ulong msize(void *ptr)
+.PP
+.B
+void setmalloctag(void *ptr, ulong tag)
+.PP
+.B
+ulong getmalloctag(void *ptr)
+.PP
+.B
+void setrealloctag(void *ptr, ulong tag)
+.PP
+.B
+ulong getrealloctag(void *ptr)
+.PP
+.B
+void* malloctopoolblock(void*)
+.PP
+.SH DESCRIPTION
+.I Malloc
+and
+.I free
+provide a simple memory allocation package.
+.I Malloc
+returns a pointer to a new block of at least
+.I size
+bytes.
+The block is suitably aligned for storage of any type of object.
+No two active pointers from
+.I malloc
+will have the same value.
+The call
+.B malloc(0)
+returns a valid pointer rather than null.
+.PP
+The argument to
+.I free
+is a pointer to a block previously allocated by
+.IR malloc ;
+this space is made available for further allocation.
+It is legal to free a null pointer; the effect is a no-op.
+The contents of the space returned by
+.I malloc
+are undefined.
+.I Mallocz
+behaves as
+.IR malloc ,
+except that if
+.I clr
+is non-zero, the memory returned will be zeroed.
+.PP
+.I Mallocalign
+allocates a block of at least
+.I n
+bytes of memory respecting alignment contraints.
+If
+.I align
+is non-zero,
+the returned pointer is aligned to be equal to
+.I offset
+modulo
+.IR align .
+If
+.I span
+is non-zero,
+the
+.I n
+byte block allocated will not span a
+.IR span -byte
+boundary.
+.PP
+.I Realloc
+changes the size of the block pointed to by
+.I ptr
+to
+.I size
+bytes and returns a pointer to the (possibly moved)
+block.
+The contents will be unchanged up to the
+lesser of the new and old sizes.
+.I Realloc
+takes on special meanings when one or both arguments are zero:
+.TP
+.B "realloc(0,\ size)
+means
+.LR malloc(size) ;
+returns a pointer to the newly-allocated memory
+.TP
+.B "realloc(ptr,\ 0)
+means
+.LR free(ptr) ;
+returns null
+.TP
+.B "realloc(0,\ 0)
+no-op; returns null
+.PD
+.PP
+.I Calloc
+allocates space for
+an array of
+.I nelem
+elements of size
+.IR elsize .
+The space is initialized to zeros.
+.I Free
+frees such a block.
+.PP
+When a block is allocated, sometimes there is some extra unused space at the end.
+.I Msize
+grows the block to encompass this unused space and returns the new number
+of bytes that may be used.
+.PP
+The memory allocator maintains two word-sized fields
+associated with each block, the ``malloc tag'' and the ``realloc tag''.
+By convention, the malloc tag is the PC that allocated the block,
+and the realloc tag the PC that last reallocated the block.
+These may be set or examined with
+.IR setmalloctag ,
+.IR getmalloctag ,
+.IR setrealloctag ,
+and
+.IR getrealloctag .
+When allocating blocks directly with
+.I malloc
+and
+.IR realloc ,
+these tags will be set properly.
+If a custom allocator wrapper is used,
+the allocator wrapper can set the tags
+itself (usually by passing the result of
+.IR getcallerpc (2)
+to
+.IR setmalloctag )
+to provide more useful information about
+the source of allocation.
+.PP
+.I Malloctopoolblock
+takes the address of a block returned by
+.I malloc
+and returns the address of the corresponding
+block allocated by the
+.IR pool (2)
+routines.
+.SH SOURCE
+.B /sys/src/libc/port/malloc.c
+.SH SEE ALSO
+.IR leak (1),
+.I trump
+(in
+.IR acid (1)),
+.IR brk (2),
+.IR getcallerpc (2),
+.IR pool (2)
+.SH DIAGNOSTICS
+.I Malloc, realloc
+and
+.I calloc
+return 0 if there is no available memory.
+.I Errstr
+is likely to be set.
+If the allocated blocks have no malloc or realloc tags,
+.I getmalloctag
+and
+.I getrealloctag
+return
+.BR ~0 .
+.PP
+After including
+.BR pool.h ,
+the call
+.B poolcheck(mainmem)
+can be used to scan the storage arena for inconsistencies
+such as data written beyond the bounds of allocated blocks.
+It is often useful to combine this with with setting
+.EX
+ mainmem->flags |= POOL_NOREUSE;
+.EE
+at the beginning of your program.
+This will cause malloc not to reallocate blocks even
+once they are freed;
+.B poolcheck(mainmem)
+will then detect writes to freed blocks.
+.PP
+The
+.I trump
+library for
+.I acid
+can be used to obtain traces of malloc execution; see
+.IR acid (1).
+.SH BUGS
+The different specification of
+.I calloc
+is bizarre.
+.PP
+User errors can corrupt the storage arena.
+The most common gaffes are (1) freeing an already freed block,
+(2) storing beyond the bounds of an allocated block, and (3)
+freeing data that was not obtained from the allocator.
+When
+.I malloc
+and
+.I free
+detect such corruption, they abort.
diff --git a/sys/man/2/matrix b/sys/man/2/matrix
new file mode 100755
index 000000000..6291aa6de
--- /dev/null
+++ b/sys/man/2/matrix
@@ -0,0 +1,350 @@
+.TH MATRIX 2
+.SH NAME
+ident, matmul, matmulr, determinant, adjoint, invertmat, xformpoint, xformpointd, xformplane, pushmat, popmat, rot, qrot, scale, move, xform, ixform, persp, look, viewport \- Geometric transformations
+.SH SYNOPSIS
+.PP
+.B
+#include <draw.h>
+.PP
+.B
+#include <geometry.h>
+.PP
+.B
+void ident(Matrix m)
+.PP
+.B
+void matmul(Matrix a, Matrix b)
+.PP
+.B
+void matmulr(Matrix a, Matrix b)
+.PP
+.B
+double determinant(Matrix m)
+.PP
+.B
+void adjoint(Matrix m, Matrix madj)
+.PP
+.B
+double invertmat(Matrix m, Matrix inv)
+.PP
+.B
+Point3 xformpoint(Point3 p, Space *to, Space *from)
+.PP
+.B
+Point3 xformpointd(Point3 p, Space *to, Space *from)
+.PP
+.B
+Point3 xformplane(Point3 p, Space *to, Space *from)
+.PP
+.B
+Space *pushmat(Space *t)
+.PP
+.B
+Space *popmat(Space *t)
+.PP
+.B
+void rot(Space *t, double theta, int axis)
+.PP
+.B
+void qrot(Space *t, Quaternion q)
+.PP
+.B
+void scale(Space *t, double x, double y, double z)
+.PP
+.B
+void move(Space *t, double x, double y, double z)
+.PP
+.B
+void xform(Space *t, Matrix m)
+.PP
+.B
+void ixform(Space *t, Matrix m, Matrix inv)
+.PP
+.B
+int persp(Space *t, double fov, double n, double f)
+.PP
+.B
+void look(Space *t, Point3 eye, Point3 look, Point3 up)
+.PP
+.B
+void viewport(Space *t, Rectangle r, double aspect)
+.SH DESCRIPTION
+These routines manipulate 3-space affine and projective transformations,
+represented as 4\(mu4 matrices, thus:
+.IP
+.EX
+.ta 6n
+typedef double Matrix[4][4];
+.EE
+.PP
+.I Ident
+stores an identity matrix in its argument.
+.I Matmul
+stores
+.I a\(mub
+in
+.IR a .
+.I Matmulr
+stores
+.I b\(mua
+in
+.IR b .
+.I Determinant
+returns the determinant of matrix
+.IR m .
+.I Adjoint
+stores the adjoint (matrix of cofactors) of
+.I m
+in
+.IR madj .
+.I Invertmat
+stores the inverse of matrix
+.I m
+in
+.IR minv ,
+returning
+.IR m 's
+determinant.
+Should
+.I m
+be singular (determinant zero),
+.I invertmat
+stores its
+adjoint in
+.IR minv .
+.PP
+The rest of the routines described here
+manipulate
+.I Spaces
+and transform
+.IR Point3s .
+A
+.I Point3
+is a point in three-space, represented by its
+homogeneous coordinates:
+.IP
+.EX
+typedef struct Point3 Point3;
+struct Point3{
+ double x, y, z, w;
+};
+.EE
+.PP
+The homogeneous coordinates
+.RI ( x ,
+.IR y ,
+.IR z ,
+.IR w )
+represent the Euclidean point
+.RI ( x / w ,
+.IR y / w ,
+.IR z / w )
+if
+.IR w ≠0,
+and a ``point at infinity'' if
+.IR w =0.
+.PP
+A
+.I Space
+is just a data structure describing a coordinate system:
+.IP
+.EX
+typedef struct Space Space;
+struct Space{
+ Matrix t;
+ Matrix tinv;
+ Space *next;
+};
+.EE
+.PP
+It contains a pair of transformation matrices and a pointer
+to the
+.IR Space 's
+parent. The matrices transform points to and from the ``root
+coordinate system,'' which is represented by a null
+.I Space
+pointer.
+.PP
+.I Pushmat
+creates a new
+.IR Space .
+Its argument is a pointer to the parent space. Its result
+is a newly allocated copy of the parent, but with its
+.B next
+pointer pointing at the parent.
+.I Popmat
+discards the
+.B Space
+that is its argument, returning a pointer to the stack.
+Nominally, these two functions define a stack of transformations,
+but
+.B pushmat
+can be called multiple times
+on the same
+.B Space
+multiple times, creating a transformation tree.
+.PP
+.I Xformpoint
+and
+.I Xformpointd
+both transform points from the
+.B Space
+pointed to by
+.I from
+to the space pointed to by
+.IR to .
+Either pointer may be null, indicating the root coordinate system.
+The difference between the two functions is that
+.B xformpointd
+divides
+.IR x ,
+.IR y ,
+.IR z ,
+and
+.I w
+by
+.IR w ,
+if
+.IR w ≠0,
+making
+.RI ( x ,
+.IR y ,
+.IR z )
+the Euclidean coordinates of the point.
+.PP
+.I Xformplane
+transforms planes or normal vectors. A plane is specified by the
+coefficients
+.RI ( a ,
+.IR b ,
+.IR c ,
+.IR d )
+of its implicit equation
+.IR ax+by+cz+d =0.
+Since this representation is dual to the homogeneous representation of points,
+.B libgeometry
+represents planes by
+.B Point3
+structures, with
+.RI ( a ,
+.IR b ,
+.IR c ,
+.IR d )
+stored in
+.RI ( x ,
+.IR y ,
+.IR z ,
+.IR w ).
+.PP
+The remaining functions transform the coordinate system represented
+by a
+.BR Space .
+Their
+.B Space *
+argument must be non-null \(em you can't modify the root
+.BR Space .
+.I Rot
+rotates by angle
+.I theta
+(in radians) about the given
+.IR axis ,
+which must be one of
+.BR XAXIS ,
+.B YAXIS
+or
+.BR ZAXIS .
+.I Qrot
+transforms by a rotation about an arbitrary axis, specified by
+.B Quaternion
+.IR q .
+.PP
+.I Scale
+scales the coordinate system by the given scale factors in the directions of the three axes.
+.IB Move
+translates by the given displacement in the three axial directions.
+.PP
+.I Xform
+transforms the coordinate system by the given
+.BR Matrix .
+If the matrix's inverse is known
+.I a
+.IR priori ,
+calling
+.I ixform
+will save the work of recomputing it.
+.PP
+.I Persp
+does a perspective transformation.
+The transformation maps the frustum with apex at the origin,
+central axis down the positive
+.I y
+axis, and apex angle
+.I fov
+and clipping planes
+.IR y = n
+and
+.IR y = f
+into the double-unit cube.
+The plane
+.IR y = n
+maps to
+.IR y '=-1,
+.IR y = f
+maps to
+.IR y '=1.
+.PP
+.I Look
+does a view-pointing transformation. The
+.B eye
+point is moved to the origin.
+The line through the
+.I eye
+and
+.I look
+points is aligned with the y axis,
+and the plane containing the
+.BR eye ,
+.B look
+and
+.B up
+points is rotated into the
+.IR x - y
+plane.
+.PP
+.I Viewport
+maps the unit-cube window into the given screen viewport.
+The viewport rectangle
+.I r
+has
+.IB r .min
+at the top left-hand corner, and
+.IB r .max
+just outside the lower right-hand corner.
+Argument
+.I aspect
+is the aspect ratio
+.RI ( dx / dy )
+of the viewport's pixels (not of the whole viewport).
+The whole window is transformed to fit centered inside the viewport with equal
+slop on either top and bottom or left and right, depending on the viewport's
+aspect ratio.
+The window is viewed down the
+.I y
+axis, with
+.I x
+to the left and
+.I z
+up. The viewport
+has
+.I x
+increasing to the right and
+.I y
+increasing down. The window's
+.I y
+coordinates are mapped, unchanged, into the viewport's
+.I z
+coordinates.
+.SH SOURCE
+.B /sys/src/libgeometry/matrix.c
+.SH "SEE ALSO
+.IR arith3 (2)
diff --git a/sys/man/2/memdraw b/sys/man/2/memdraw
new file mode 100755
index 000000000..ac1b73961
--- /dev/null
+++ b/sys/man/2/memdraw
@@ -0,0 +1,448 @@
+.TH MEMDRAW 2
+.SH NAME
+Memimage,
+Memdata,
+Memdrawparam,
+memimageinit,
+wordaddr,
+byteaddr,
+memimagemove,
+allocmemimage,
+allocmemimaged,
+readmemimage,
+creadmemimage,
+writememimage,
+freememimage,
+memsetchan,
+loadmemimage,
+cloadmemimage,
+unloadmemimage,
+memfillcolor,
+memarc,
+mempoly,
+memellipse,
+memfillpoly,
+memimageline,
+memimagedraw,
+drawclip,
+memlinebbox,
+memlineendsize,
+allocmemsubfont,
+openmemsubfont,
+freememsubfont,
+memsubfontwidth,
+getmemdefont,
+memimagestring,
+iprint,
+hwdraw \- drawing routines for memory-resident images
+.SH SYNOPSIS
+.nf
+.B #include <u.h>
+.B #include <libc.h>
+.B #include <draw.h>
+.B #include <memdraw.h>
+.PP
+.ft L
+typedef struct Memdata
+{
+ ulong *base; /* allocated data pointer */
+ uchar *bdata; /* first byte of actual data; word-aligned */
+ int ref; /* number of Memimages using this data */
+ void* imref; /* last image that pointed at this */
+ int allocd; /* is this malloc'd? */
+} Memdata;
+
+enum {
+ Frepl = 1<<0, /* is replicated */
+ Fsimple = 1<<1, /* is 1x1 */
+ Fgrey = 1<<2, /* is grey */
+ Falpha = 1<<3, /* has explicit alpha */
+ Fcmap = 1<<4, /* has cmap channel */
+ Fbytes = 1<<5, /* has only 8-bit channels */
+};
+
+typedef struct Memimage
+{
+ Rectangle r; /* rectangle in data area, local coords */
+ Rectangle clipr; /* clipping region */
+ int depth; /* number of bits of storage per pixel */
+ int nchan; /* number of channels */
+ ulong chan; /* channel descriptions */
+
+ Memdata *data; /* pointer to data */
+ int zero; /* data->bdata+zero==&byte containing (0,0) */
+ ulong width; /* width in words of a single scan line */
+ Memlayer *layer; /* nil if not a layer*/
+ ulong flags;
+ \fI...\fP
+} Memimage;
+
+typedef struct Memdrawparam
+{
+ Memimage *dst;
+ Rectangle r;
+ Memimage *src;
+ Rectangle sr;
+ Memimage *mask;
+ Rectangle mr;
+ \fI...\fP
+} Memdrawparam;
+
+.ta \w'\fLMemsubfont* 'u
+int drawdebug;
+.ft
+.PP
+.ft L
+.nf
+void memimageinit(void)
+ulong* wordaddr(Memimage *i, Point p)
+uchar* byteaddr(Memimage *i, Point p)
+void memimagemove(void *from, void *to)
+.PP
+.ft L
+.nf
+Memimage* allocmemimage(Rectangle r, ulong chan)
+Memimage* allocmemimaged(Rectangle r, ulong chan, Memdata *data)
+Memimage* readmemimage(int fd)
+Memimage* creadmemimage(int fd)
+int writememimage(int fd, Memimage *i)
+void freememimage(Memimage *i)
+int memsetchan(Memimage*, ulong)
+.PP
+.ft L
+.nf
+int loadmemimage(Memimage *i, Rectangle r,
+ uchar *buf, int nbuf)
+int cloadmemimage(Memimage *i, Rectangle r,
+ uchar *buf, int nbuf)
+int unloadmemimage(Memimage *i, Rectangle r,
+ uchar *buf, int nbuf)
+void memfillcolor(Memimage *i, ulong color)
+.PP
+.ft L
+.nf
+void memarc(Memimage *dst, Point c, int a, int b, int thick,
+ Memimage *src, Point sp, int alpha, int phi, Drawop op)
+void mempoly(Memimage *dst, Point *p, int np, int end0,
+ int end1, int radius, Memimage *src, Point sp, Drawop op)
+void memellipse(Memimage *dst, Point c, int a, int b,
+ int thick, Memimage *src, Point sp, Drawop op)
+void memfillpoly(Memimage *dst, Point *p, int np, int wind,
+ Memimage *src, Point sp, Drawop op)
+void memimageline(Memimage *dst, Point p0, Point p1, int end0,
+ int end1, int radius, Memimage *src, Point sp, Drawop op)
+void memimagedraw(Memimage *dst, Rectangle r, Memimage *src,
+ Point sp, Memimage *mask, Point mp, Drawop op)
+.PP
+.ft L
+.nf
+int drawclip(Memimage *dst, Rectangle *dr, Memimage *src,
+ Point *sp, Memimage *mask, Point *mp,
+ Rectangle *sr, Rectangle *mr)
+Rectangle memlinebbox(Point p0, Point p1, int end0, int end1,
+ int radius)
+int memlineendsize(int end)
+.PP
+.ft L
+.nf
+Memsubfont* allocmemsubfont(char *name, int n, int height,
+ int ascent, Fontchar *info, Memimage *i)
+Memsubfont* openmemsubfont(char *name)
+void freememsubfont(Memsubfont *f)
+Point memsubfontwidth(Memsubfont *f, char *s)
+Memsubfont* getmemdefont(void)
+Point memimagestring(Memimage *dst, Point p, Memimage *color,
+ Point cp, Memsubfont *f, char *cs)
+.PP
+.ft L
+.nf
+int iprint(char *fmt, ...)
+int hwdraw(Memdrawparam *param)
+.ft R
+.SH DESCRIPTION
+The
+.B Memimage
+type defines memory-resident rectangular pictures and the methods to draw upon them;
+.BR Memimage s
+differ from
+.BR Image s
+(see
+.IR draw (2))
+in that they are manipulated directly in user memory rather than by
+RPCs to the
+.B /dev/draw
+hierarchy.
+The
+.B memdraw
+library is the basis for the kernel
+.IR draw (3)
+driver and also used by a number of programs that must manipulate
+images without a display.
+.PP
+The
+.BR r,
+.BR clipr ,
+.BR depth ,
+.BR nchan ,
+and
+.BR chan
+structure elements are identical to
+the ones of the same name
+in the
+.B Image
+structure.
+.PP
+The
+.B flags
+element of the
+.B Memimage
+structure holds a number of bits of information about the image.
+In particular, it subsumes the
+purpose of the
+.B repl
+element of
+.B Image
+structures.
+.PP
+.I Memimageinit
+initializes various static data that the library depends on,
+as well as the replicated solid color images
+.BR memopaque ,
+.BR memtransparent ,
+.BR memblack ,
+and
+.BR memwhite .
+It should be called before referring to any of these images
+and before calling any of the other library functions.
+.PP
+Each
+.B Memimage
+points at a
+.B Memdata
+structure that in turn points at the actual pixel data for the image.
+This allows multiple images to be associated with the same
+.BR Memdata .
+The first word of the data pointed at by
+the
+.B base
+element of
+.B Memdata
+points back at the
+.B Memdata
+structure, so that the
+memory allocator (see
+.IR pool (2))
+can compact image memory
+using
+.IR memimagemove .
+.PP
+Because images can have different coordinate systems,
+the
+.B zero
+element of the
+.B Memimage
+structure contains the offset that must be added
+to the
+.B bdata
+element of the corresponding
+.B Memdata
+structure in order to yield a pointer to the data for the pixel (0,0).
+Adding
+.BR width
+machine words
+to this pointer moves it down one scan line.
+The
+.B depth
+element can be used to determine how to move the
+pointer horizontally.
+Note that this method works even for images whose rectangles
+do not include the origin, although one should only dereference
+pointers corresponding to pixels within the image rectangle.
+.I Wordaddr
+and
+.IR byteaddr
+perform these calculations,
+returning pointers to the word and byte, respectively,
+that contain the beginning of the data for a given pixel.
+.PP
+.I Allocmemimage
+allocages
+images with a given rectangle and channel descriptor
+(see
+.B strtochan
+in
+.IR graphics (2)),
+creating a fresh
+.B Memdata
+structure and associated storage.
+.I Allocmemimaged
+is similar but uses the supplied
+.I Memdata
+structure rather than a new one.
+The
+.I readmemimage
+function reads an uncompressed bitmap
+from the given file descriptor,
+while
+.I creadmemimage
+reads a compressed bitmap.
+.I Writememimage
+writes a compressed representation of
+.I i
+to file descriptor
+.IR fd .
+For more on bitmap formats, see
+.IR image (6).
+.I Freememimage
+frees images returned by any of these routines.
+The
+.B Memimage
+structure contains some tables that are used
+to store precomputed values depending on the channel descriptor.
+.I Memsetchan
+updates the
+.B chan
+element of the structure as well as these tables,
+returning \-1 if passed a bad channel descriptor.
+.PP
+.I Loadmemimage
+and
+.I cloadmemimage
+replace the pixel data for a given rectangle of an image
+with the given buffer of uncompressed or compressed
+data, respectively.
+When calling
+.IR cloadmemimage ,
+the buffer must contain an
+integral number of
+compressed chunks of data that exactly cover the rectangle.
+.I Unloadmemimage
+retrieves the uncompressed pixel data for a given rectangle of an image.
+All three return the number of bytes consumed on success,
+and \-1 in case of an error.
+.PP
+.I Memfillcolor
+fills an image with the given color, a 32-bit number as
+described in
+.IR color (2).
+.PP
+.IR Memarc ,
+.IR mempoly ,
+.IR memellipse ,
+.IR memfillpoly ,
+.IR memimageline ,
+and
+.I memimagedraw
+are identical to the
+.IR arc ,
+.IR poly ,
+.IR ellipse ,
+.IR fillpoly ,
+.IR line ,
+and
+.IR gendraw ,
+routines described in
+.IR draw (2),
+except that they operate on
+.BR Memimage s
+rather than
+.BR Image s.
+Similarly,
+.IR allocmemsubfont ,
+.IR openmemsubfont ,
+.IR freememsubfont ,
+.IR memsubfontwidth ,
+.IR getmemdefont ,
+and
+.I memimagestring
+are the
+.B Memimage
+analogues of
+.IR allocsubfont ,
+.IR openfont ,
+.IR freesubfont ,
+.IR strsubfontwidth ,
+.IR getdefont ,
+and
+.B string
+(see
+.IR subfont (2)
+and
+.IR graphics (2)),
+except that they operate
+only on
+.BR Memsubfont s
+rather than
+.BR Font s.
+.PP
+.I Drawclip
+takes the images involved in a draw operation,
+together with the destination rectangle
+.B dr
+and source
+and mask alignment points
+.B sp
+and
+.BR mp ,
+and
+clips them according to the clipping rectangles of the images involved.
+It also fills in the rectangles
+.B sr
+and
+.B mr
+with rectangles congruent to the returned destination rectangle
+but translated so the upper left corners are the returned
+.B sp
+and
+.BR mp .
+.I Drawclip
+returns zero when the clipped rectangle is empty.
+.I Memlinebbox
+returns a conservative bounding box containing a line between
+two points
+with given end styles
+and radius.
+.I Memlineendsize
+calculates the extra length added to a line by attaching
+an end of a given style.
+.PP
+The
+.I hwdraw
+and
+.I iprint
+functions are no-op stubs that may be overridden by clients
+of the library.
+.I Hwdraw
+is called at each call to
+.I memimagedraw
+with the current request's parameters.
+If it can satisfy the request, it should do so
+and return 1.
+If it cannot satisfy the request, it should return 0.
+This allows (for instance) the kernel to take advantage
+of hardware acceleration.
+.I Iprint
+should format and print its arguments;
+it is given much debugging output when
+the global integer variable
+.B drawdebug
+is non-zero.
+In the kernel,
+.I iprint
+prints to a serial line rather than the screen, for obvious reasons.
+.SH SOURCE
+.B /sys/src/libmemdraw
+.SH SEE ALSO
+.IR addpt (2),
+.IR color (2),
+.IR draw (2),
+.IR graphics (2),
+.IR memlayer (2),
+.IR stringsize (2),
+.IR subfont (2),
+.IR color (6),
+.IR utf (6)
+.SH BUGS
+.I Memimagestring
+is unusual in using a subfont rather than a font,
+and in having no parameter to align the source.
diff --git a/sys/man/2/memlayer b/sys/man/2/memlayer
new file mode 100755
index 000000000..b652bc0be
--- /dev/null
+++ b/sys/man/2/memlayer
@@ -0,0 +1,305 @@
+.TH MEMLAYER 2
+.SH NAME
+memdraw, memlalloc, memldelete, memlexpose, memlfree, memlhide, memline, memlnorefresh, memload, memunload, memlorigin, memlsetrefresh, memltofront, memltofrontn, memltorear, memltorearn \- windows of memory-resident images
+.SH SYNOPSIS
+.nf
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <draw.h>
+.br
+.B #include <memdraw.h>
+.br
+.B #include <memlayer.h>
+.PP
+.ft L
+typedef struct Memscreen Memscreen;
+typedef struct Memlayer Memlayer;
+typedef void (*Refreshfn)(Memimage*, Rectangle, void*);
+.ta 4n +\w'\fLRefreshfn 'u +\w'\fL*frontmost; 'u
+
+struct Memscreen
+{
+ Memimage *frontmost; /* frontmost layer on screen */
+ Memimage *rearmost; /* rearmost layer on screen */
+ Memimage *image; /* upon which all layers are drawn */
+ Memimage *fill; /* if non-zero, picture to use when repainting */
+};
+
+struct Memlayer
+{
+ Rectangle screenr; /* true position of layer on screen */
+ Point delta; /* add delta to go from image coords to screen */
+ Memscreen *screen; /* screen this layer belongs to */
+ Memimage *front; /* window in front of this one */
+ Memimage *rear; /* window behind this one*/
+ int clear; /* layer is fully visible */
+ Memimage *save; /* save area for obscured parts */
+ Refreshfn refreshfn; /* fn to refresh obscured parts if save==nil */
+ void *refreshptr; /* argument to refreshfn */
+};
+.ft
+.ta \w'\fLMemimage* 'u
+.PP
+.B
+Memimage* memlalloc(Memscreen *s, Rectangle r, Refreshfn fn, void *arg, ulong col)
+.PP
+.B void memlnorefresh(Memimage *i, Rectangle r, void *arg)
+.PP
+.B
+int memlsetrefresh(Memimage *i, Refreshfn fn, void *arg)
+.PP
+.B
+int memldelete(Memimage *i)
+.PP
+.B
+int memlfree(Memimage *i)
+.PP
+.B
+int memlexpose(Memimage *i, Rectangle r)
+.PP
+.B
+int memlhide(Memimage *i, Rectangle r)
+.PP
+.B
+void memltofront(Memimage *i)
+.PP
+.B
+void memltofrontn(Memimage**ia, int n)
+.PP
+.B
+void memltorear(Memimage *i)
+.PP
+.B
+void memltorearn(Memimage **ia , int n)
+.PP
+.B
+int memlorigin(Memimage *i, Point log, Point phys)
+.PP
+.B
+void memdraw(Image *dst, Rectangle r,
+.br
+.B
+ Image *src, Point sp, Image *mask, Point mp, Drawop op)
+.fi
+.B
+int memload(Memimage *i, Rectangle r,
+.br
+.B
+ uchar *buf, int n, int iscompressed)
+.PP
+.B
+int memunload(Memimage *i, Rectangle r,
+.br
+.B
+ uchar *buf, int n)
+.PP
+.SH DESCRIPTION
+These functions build upon the
+.IR memdraw (2)
+interface to maintain overlapping graphical windows on in-memory images.
+They are used by the kernel to implement the windows interface presented by
+.IR draw (3)
+and
+.IR window (2)
+and probably have little use outside of the kernel.
+.PP
+The basic function is to extend the definition of a
+.B Memimage
+(see
+.IR memdraw (2))
+to include overlapping windows defined by the
+.B Memlayer
+type.
+The first fields of the
+.B Memlayer
+structure are identical to those in
+.BR Memimage ,
+permitting a function that expects a
+.B Memimage
+to be passed a
+.BR Memlayer ,
+and vice versa.
+Both structures have a
+.B save
+field, which is nil in a
+.B Memimage
+and points to `backing store' in a
+.BR Memlayer .
+The layer routines accept
+.B Memimages
+or
+.BR Memlayers ;
+if the image is a
+.B Memimage
+the underlying
+.B Memimage
+routine is called; otherwise the layer routines recursively
+subdivide the geometry, reducing the operation into a smaller
+component that ultimately can be performed on a
+.BR Memimage ,
+either the display on which the window appears, or the backing store.
+.PP
+.B Memlayers
+are associated with a
+.B Memscreen
+that holds the data structures to maintain the windows and connects
+them to the associated
+.BR image .
+The
+.B fill
+color is used to paint the background when a window is deleted.
+There is no function to establish a
+.BR Memscreen ;
+to create one, allocate the memory, zero
+.B frontmost
+and
+.BR rearmost ,
+set
+.B fill
+to a valid fill color or image, and set
+.B image
+to the
+.B Memimage
+(or
+.BR Memlayer )
+on which the windows will be displayed.
+.PP
+.I Memlalloc
+allocates a
+.B Memlayer
+of size
+.I r
+on
+.B Memscreen
+.IR s .
+If
+.I col
+is not
+.BR DNofill ,
+the new window will be initialized by painting it that color.
+.PP
+The refresh function
+.I fn
+and associated argument
+.I arg
+will be called by routines in the library to restore portions of the window
+uncovered due to another window being deleted or this window being pulled to the front of the stack.
+The function, when called,
+receives a pointer to the image (window) being refreshed, the rectangle that has been uncovered,
+and the
+.I arg
+recorded when the window was created.
+A couple of predefined functions provide built-in management methods:
+.I memlnorefresh
+does no backup at all, useful for making efficient temporary windows;
+while a
+.I nil
+function specifies that the backing store
+.RB ( Memlayer.save )
+will be used to keep the obscured data.
+Other functions may be provided by the client.
+.I Memlsetrefresh
+allows one to change the function associated with the window.
+.PP
+.I Memldelete
+deletes the window
+.IR i ,
+restoring the underlying display.
+.I Memlfree
+frees the data structures without unlinking the window from the associated
+.B Memscreen
+or doing any graphics.
+.PP
+.I Memlexpose
+restores rectangle
+.I r
+within the window, using the backing store or appropriate refresh method.
+.I Memlhide
+goes the other way, backing up
+.I r
+so that that portion of the screen may be modified without losing the data in this window.
+.PP
+.I Memltofront
+pulls
+.I i
+to the front of the stack of windows, making it fully visible.
+.I Memltofrontn
+pulls the
+.I n
+windows in the array
+.I ia
+to the front as a group, leaving their internal order unaffected.
+.I Memltorear
+and
+.I memltorearn
+push the windows to the rear.
+.PP
+.I Memlorigin
+changes the coordinate systems associated with the window
+.IR i .
+The points
+.I log
+and
+.I phys
+represent the upper left corner
+.RB ( min )
+of the window's internal coordinate system and its physical location on the screen.
+Changing
+.I log
+changes the interpretation of coordinates within the window; for example, setting it to
+(0,\ 0) makes the upper left corner of the window appear to be the origin of the coordinate
+system, regardless of its position on the screen.
+Changing
+.I phys
+changes the physical location of the window on the screen.
+When a window is created, its logical and physical coordinates are the same, so
+.EX
+ memlorigin(i, i->r.min, i->r.min)
+.EE
+would be a no-op.
+.PP
+.I Memdraw
+and
+.I memline
+are implemented in the layer library but provide the main entry points for drawing on
+memory-resident windows.
+They have the signatures of
+.I memimagedraw
+and
+.I memimageline
+(see
+.IR memdraw (2))
+but accept
+.B Memlayer
+or
+.B Memimage
+arguments both.
+.PP
+.I Memload
+and
+.I memunload
+are similarly layer-savvy versions of
+.I loadmemimage
+and
+.IR unloadmemimage .
+The
+.I iscompressed
+flag to
+.I memload
+specifies whether the
+.I n
+bytes of data in
+.I buf
+are in compressed image format
+(see
+.IR image (6)).
+.SH SOURCE
+.B /sys/src/libmemlayer
+.SH SEE ALSO
+.IR graphics (2),
+.IR memdraw (2),
+.IR stringsize (2),
+.IR window (2),
+.IR draw (3)
diff --git a/sys/man/2/memory b/sys/man/2/memory
new file mode 100755
index 000000000..42bcc0555
--- /dev/null
+++ b/sys/man/2/memory
@@ -0,0 +1,126 @@
+.TH MEMORY 2
+.SH NAME
+memccpy, memchr, memcmp, memcpy, memmove, memset \- memory operations
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLvoid* 'u
+.B
+void* memccpy(void *s1, void *s2, int c, ulong n)
+.PP
+.B
+void* memchr(void *s, int c, ulong n)
+.PP
+.B
+int memcmp(void *s1, void *s2, ulong n)
+.PP
+.B
+void* memcpy(void *s1, void *s2, ulong n)
+.PP
+.B
+void* memmove(void *s1, void *s2, ulong n)
+.PP
+.B
+void* memset(void *s, int c, ulong n)
+.SH DESCRIPTION
+These functions operate efficiently on memory areas
+(arrays of bytes bounded by a count, not terminated by a zero byte).
+They do not check for the overflow of any receiving memory area.
+.PP
+.I Memccpy
+copies bytes from memory area
+.I s2
+into
+.IR s1 ,
+stopping after the first occurrence of byte
+.I c
+has been copied, or after
+.I n
+bytes have been copied, whichever comes first.
+It returns a pointer to the byte after
+the copy of
+.I c
+in
+.IR s1 ,
+or zero if
+.I c
+was not found in the first
+.I n
+bytes of
+.IR s2 .
+.PP
+.I Memchr
+returns a pointer to the first
+occurrence of byte
+.I c
+in the first
+.I n
+bytes of memory area
+.IR s,
+or zero if
+.I c
+does not occur.
+.PP
+.I Memcmp
+compares its arguments, looking at the first
+.I n
+bytes only, and returns an integer
+less than, equal to, or greater than 0,
+according as
+.I s1
+is lexicographically less than, equal to, or
+greater than
+.IR s2 .
+The comparison is bytewise unsigned.
+.PP
+.I Memcpy
+copies
+.I n
+bytes from memory area
+.I s2
+to
+.IR s1 .
+It returns
+.IR s1 .
+.PP
+.I Memmove
+works like
+.IR memcpy ,
+except that it is guaranteed to work if
+.I s1
+and
+.IR s2
+overlap.
+.PP
+.I Memset
+sets the first
+.I n
+bytes in memory area
+.I s
+to the value of byte
+.IR c .
+It returns
+.IR s .
+.SH SOURCE
+All these routines have portable C implementations in
+.BR /sys/src/libc/port .
+Most also have machine-dependent assembly language implementations in
+.BR /sys/src/libc/$objtype .
+.SH SEE ALSO
+.IR strcat (2)
+.SH BUGS
+ANSI C does not require
+.I memcpy
+to handle overlapping source and destination; on Plan 9, it does, so
+.I memmove
+and
+.I memcpy
+behave identically.
+.PP
+If
+.I memcpy
+and
+.I memmove
+are handed a negative count, they abort.
diff --git a/sys/man/2/mktemp b/sys/man/2/mktemp
new file mode 100755
index 000000000..683620ac7
--- /dev/null
+++ b/sys/man/2/mktemp
@@ -0,0 +1,40 @@
+.TH MKTEMP 2
+.SH NAME
+mktemp \- make a unique file name
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+char* mktemp(char *template)
+.fi
+.SH DESCRIPTION
+.I Mktemp
+replaces
+.I template
+by a unique file name, and returns the
+address of the template.
+The template should look like a file name with eleven trailing
+.LR X s.
+The
+.LR X s
+are replaced by a letter followed by the current process id.
+Letters from
+.L a
+to
+.L z
+are tried until a name that can be accessed
+(see
+.IR access (2))
+is generated.
+If no such name can be generated,
+.I mktemp
+returns
+\f5"/"\f1 .
+.SH SOURCE
+.B /sys/src/libc/port/mktemp.c
+.SH "SEE ALSO"
+.IR getpid (2),
+.IR access (2)
diff --git a/sys/man/2/mouse b/sys/man/2/mouse
new file mode 100755
index 000000000..76625b683
--- /dev/null
+++ b/sys/man/2/mouse
@@ -0,0 +1,249 @@
+.TH MOUSE 2
+.SH NAME
+initmouse, readmouse, closemouse, moveto, getrect, drawgetrect, menuhit, setcursor \- mouse control
+.SH SYNOPSIS
+.nf
+.B
+#include <u.h>
+.B
+#include <libc.h>
+.B
+#include <draw.h>
+.B
+#include <thread.h>
+.B
+#include <mouse.h>
+.B
+#include <cursor.h>
+.PP
+.B
+Mousectl *initmouse(char *file, Image *i)
+.PP
+.B
+int readmouse(Mousectl *mc)
+.PP
+.B
+int atomouse();
+.PP
+.B
+void closemouse(Mousectl *mc)
+.PP
+.B
+void moveto(Mousectl *mc, Point pt)
+.PP
+.B
+void setcursor(Mousectl *mc, Cursor *c)
+.PP
+.B
+Rectangle getrect(int but, Mousectl *mc)
+.PP
+.B
+void drawgetrect(Rectangle r, int up)
+.PP
+.B
+int menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr)
+.fi
+.SH DESCRIPTION
+These functions access and control a mouse in a multi-threaded environment.
+They use the message-passing
+.B Channel
+interface in the threads library
+(see
+.IR thread (2));
+programs that wish a more event-driven, single-threaded approach should use
+.IR event (2).
+.PP
+The state of the mouse is recorded in a structure,
+.BR Mouse ,
+defined in
+.BR <mouse.h> :
+.IP
+.EX
+.ta 6n +\w'Rectangle 'u +\w'buttons; 'u
+typedef struct Mouse Mouse;
+struct Mouse
+{
+ int buttons; /* bit array: LMR=124 */
+ Point xy;
+ ulong msec;
+};
+.EE
+.PP
+The
+.B Point
+.B xy
+records the position of the cursor,
+.B buttons
+the state of the buttons (three bits representing, from bit 0 up, the buttons from left to right,
+0 if the button is released, 1 if it is pressed),
+and
+.BR msec ,
+a millisecond time stamp.
+.PP
+The routine
+.B initmouse
+returns a structure through which one may access the mouse:
+.IP
+.EX
+typedef struct Mousectl Mousectl;
+struct Mousectl
+{
+ Mouse;
+ Channel *c; /* chan(Mouse)[16] */
+ Channel *resizec; /* chan(int)[2] */
+
+ char *file;
+ int mfd; /* to mouse file */
+ int cfd; /* to cursor file */
+ int pid; /* of slave proc */
+ Image* image; /* of associated window/display */
+};
+.EE
+.PP
+The arguments to
+.I initmouse
+are a
+.I file
+naming the device file connected to the mouse and an
+.I Image
+(see
+.IR draw (2))
+on which the mouse will be visible.
+Typically the file is
+nil,
+which requests the default
+.BR /dev/mouse ;
+and the image is the window in which the program is running, held in the variable
+.B screen
+after a call to
+.IR initdraw .
+.PP
+Once the
+.B Mousectl
+is set up,
+mouse motion will be reported by messages of type
+.B Mouse
+sent on the
+.B Channel
+.BR Mousectl.c .
+Typically, a message will be sent every time a read of
+.B /dev/mouse
+succeeds, which is every time the state of the mouse changes.
+.PP
+When the window is resized, a message is sent on
+.BR Mousectl.resizec .
+The actual value sent may be discarded; the receipt of the message
+tells the program that it should call
+.B getwindow
+(see
+.IR graphics (2))
+to reconnect to the window.
+.PP
+.I Readmouse
+updates the
+.B Mouse
+structure held in the
+.BR Mousectl ,
+blocking if the state has not changed since the last
+.I readmouse
+or message sent on the channel.
+It calls
+.B flushimage
+(see
+.IR graphics (2))
+before blocking, so any buffered graphics requests are displayed.
+.PP
+.I Closemouse
+closes the file descriptors associated with the mouse, kills the slave processes,
+and frees the
+.B Mousectl
+structure.
+.PP
+.I Moveto
+moves the mouse cursor on the display to the position specified by
+.IR pt .
+.PP
+.I Setcursor
+sets the image of the cursor to that specified by
+.IR c .
+If
+.I c
+is nil, the cursor is set to the default.
+The format of the cursor data is spelled out in
+.B <cursor.h>
+and described in
+.IR graphics (2).
+.PP
+.I Getrect
+returns the dimensions of a rectangle swept by the user, using the mouse,
+in the manner
+.IR rio (1)
+or
+.IR sam (1)
+uses to create a new window.
+The
+.I but
+argument specifies which button the user must press to sweep the window;
+any other button press cancels the action.
+The returned rectangle is all zeros if the user cancels.
+.PP
+.I Getrect
+uses successive calls to
+.I drawgetrect
+to maintain the red rectangle showing the sweep-in-progress.
+The rectangle to be drawn is specified by
+.I rc
+and the
+.I up
+parameter says whether to draw (1) or erase (0) the rectangle.
+.PP
+.I Menuhit
+provides a simple menu mechanism.
+It uses a
+.B Menu
+structure defined in
+.BR <mouse.h> :
+.IP
+.EX
+typedef struct Menu Menu;
+struct Menu
+{
+ char **item;
+ char *(*gen)(int);
+ int lasthit;
+};
+.EE
+.PP
+.IR Menuhit
+behaves the same as its namesake
+.I emenuhit
+described in
+.IR event (2),
+with two exceptions.
+First, it uses a
+.B Mousectl
+to access the mouse rather than using the event interface;
+and second,
+it creates the menu as a true window on the
+.B Screen
+.I scr
+(see
+.IR window (2)),
+permitting the menu to be displayed in parallel with other activities on the display.
+If
+.I scr
+is null,
+.I menuhit
+behaves like
+.IR emenuhit ,
+creating backing store for the menu, writing the menu directly on the display, and
+restoring the display when the menu is removed.
+.PP
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR draw (2),
+.IR event (2),
+.IR keyboard (2),
+.IR thread (2).
diff --git a/sys/man/2/mp b/sys/man/2/mp
new file mode 100755
index 000000000..9db58d106
--- /dev/null
+++ b/sys/man/2/mp
@@ -0,0 +1,610 @@
+.TH MP 2
+.SH NAME
+mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, strtomp, mpfmt,mptoa, betomp, mptobe, letomp, mptole, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree \- extended precision arithmetic
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.PP
+.ta +\w'\fLCRTpre* \fP'u
+.B
+mpint* mpnew(int n)
+.PP
+.B
+void mpfree(mpint *b)
+.PP
+.B
+void mpsetminbits(int n)
+.PP
+.B
+void mpbits(mpint *b, int n)
+.PP
+.B
+void mpnorm(mpint *b)
+.PP
+.B
+mpint* mpcopy(mpint *b)
+.PP
+.B
+void mpassign(mpint *old, mpint *new)
+.PP
+.B
+mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b)
+.PP
+.B
+mpint* strtomp(char *buf, char **rptr, int base, mpint *b)
+.PP
+.B
+char* mptoa(mpint *b, int base, char *buf, int blen)
+.PP
+.B
+int mpfmt(Fmt*)
+.PP
+.B
+mpint* betomp(uchar *buf, uint blen, mpint *b)
+.PP
+.B
+int mptobe(mpint *b, uchar *buf, uint blen, uchar **bufp)
+.PP
+.B
+mpint* letomp(uchar *buf, uint blen, mpint *b)
+.PP
+.B
+int mptole(mpint *b, uchar *buf, uint blen, uchar **bufp)
+.PP
+.B
+uint mptoui(mpint*)
+.PP
+.B
+mpint* uitomp(uint, mpint*)
+.PP
+.B
+int mptoi(mpint*)
+.PP
+.B
+mpint* itomp(int, mpint*)
+.PP
+.B
+mpint* vtomp(vlong, mpint*)
+.PP
+.B
+vlong mptov(mpint*)
+.PP
+.B
+mpint* uvtomp(uvlong, mpint*)
+.PP
+.B
+uvlong mptouv(mpint*)
+.PP
+.B
+void mpadd(mpint *b1, mpint *b2, mpint *sum)
+.PP
+.B
+void mpmagadd(mpint *b1, mpint *b2, mpint *sum)
+.PP
+.B
+void mpsub(mpint *b1, mpint *b2, mpint *diff)
+.PP
+.B
+void mpmagsub(mpint *b1, mpint *b2, mpint *diff)
+.PP
+.B
+void mpleft(mpint *b, int shift, mpint *res)
+.PP
+.B
+void mpright(mpint *b, int shift, mpint *res)
+.PP
+.B
+void mpmul(mpint *b1, mpint *b2, mpint *prod)
+.PP
+.B
+void mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
+.PP
+.B
+void mpmod(mpint *b, mpint *m, mpint *remainder)
+.PP
+.B
+void mpdiv(mpint *dividend, mpint *divisor, mpint *quotient,
+.br
+.B
+ mpint *remainder)
+.PP
+.B
+int mpcmp(mpint *b1, mpint *b2)
+.PP
+.B
+int mpmagcmp(mpint *b1, mpint *b2)
+.PP
+.B
+void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x,
+.br
+.B
+ mpint *y)
+.PP
+.B
+void mpinvert(mpint *b, mpint *m, mpint *res)
+.PP
+.B
+int mpsignif(mpint *b)
+.PP
+.B
+int mplowbits0(mpint *b)
+.PP
+.B
+void mpdigdiv(mpdigit *dividend, mpdigit divisor,
+.br
+.B
+ mpdigit *quotient)
+.PP
+.B
+void mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen,
+.br
+.B
+ mpdigit *sum)
+.PP
+.B
+void mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen,
+.br
+.B
+ mpdigit *diff)
+.PP
+.B
+void mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p)
+.PP
+.B
+int mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
+.PP
+.B
+void mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen,
+.br
+.B
+ mpdigit *p)
+.PP
+.B
+int mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen)
+.PP
+.B
+CRTpre* crtpre(int nfactors, mpint **factors)
+.PP
+.B
+CRTres* crtin(CRTpre *crt, mpint *x)
+.PP
+.B
+void crtout(CRTpre *crt, CRTres *r, mpint *x)
+.PP
+.B
+void crtprefree(CRTpre *cre)
+.PP
+.B
+void crtresfree(CRTres *res)
+.PP
+.B
+mpint *mpzero, *mpone, *mptwo
+.DT
+.SH DESCRIPTION
+These routines perform extended precision integer arithmetic.
+The basic type is
+.BR mpint ,
+which points to an array of
+.BR mpdigit s,
+stored in little-endian order:
+.IP
+.EX
+typedef struct mpint mpint;
+struct mpint
+{
+ int sign; /* +1 or -1 */
+ int size; /* allocated digits */
+ int top; /* significant digits */
+ mpdigit *p;
+ char flags;
+};
+.EE
+.PP
+The sign of 0 is +1.
+.PP
+The size of
+.B mpdigit
+is architecture-dependent and defined in
+.BR /$cputype/include/u.h .
+.BR Mpint s
+are dynamically allocated and must be explicitly freed. Operations
+grow the array of digits as needed.
+.PP
+In general, the result parameters are last in the
+argument list.
+.PP
+Routines that return an
+.B mpint
+will allocate the
+.B mpint
+if the result parameter is
+.BR nil .
+This includes
+.IR strtomp ,
+.IR itomp ,
+.IR uitomp ,
+and
+.IR btomp .
+These functions, in addition to
+.I mpnew
+and
+.IR mpcopy ,
+will return
+.B nil
+if the allocation fails.
+.PP
+Input and result parameters may point to the same
+.BR mpint .
+The routines check and copy where necessary.
+.PP
+.I Mpnew
+creates an
+.B mpint
+with an initial allocation of
+.I n
+bits.
+If
+.I n
+is zero, the allocation will be whatever was specified in the
+last call to
+.I mpsetminbits
+or to the initial value, 1056.
+.I Mpfree
+frees an
+.BR mpint .
+.I Mpbits
+grows the allocation of
+.I b
+to fit at least
+.I n
+bits. If
+.B b->top
+doesn't cover
+.I n
+bits,
+.I mpbits
+increases it to do so.
+Unless you are writing new basic operations, you
+can restrict yourself to
+.B mpnew(0)
+and
+.BR mpfree(b) .
+.PP
+.I Mpnorm
+normalizes the representation by trimming any high order zero
+digits. All routines except
+.B mpbits
+return normalized results.
+.PP
+.I Mpcopy
+creates a new
+.B mpint
+with the same value as
+.I b
+while
+.I mpassign
+sets the value of
+.I new
+to be that of
+.IR old .
+.PP
+.I Mprand
+creates an
+.I n
+bit random number using the generator
+.IR gen .
+.I Gen
+takes a pointer to a string of uchar's and the number
+to fill in.
+.PP
+.I Strtomp
+and
+.I mptoa
+convert between
+.SM ASCII
+and
+.B mpint
+representations using the base indicated.
+Only the bases 10, 16, 32, and 64 are
+supported. Anything else defaults to 16.
+.IR Strtomp
+skips any leading spaces or tabs.
+.IR Strtomp 's
+scan stops when encountering a digit not valid in the
+base. If
+.I rptr
+is not zero,
+.I *rptr
+is set to point to the character immediately after the
+string converted.
+If the parse pterminates before any digits are found,
+.I strtomp
+return
+.BR nil .
+.I Mptoa
+returns a pointer to the filled buffer.
+If the parameter
+.I buf
+is
+.BR nil ,
+the buffer is allocated.
+.I Mpfmt
+can be used with
+.IR fmtinstall (2)
+and
+.IR print (2)
+to print hexadecimal representations of
+.BR mpint s.
+The conventional verb is
+.LR B ,
+for which
+.I mp.h
+provides a
+.LR pragma .
+.PP
+.I Mptobe
+and
+.I mptole
+convert an
+.I mpint
+to a byte array. The former creates a big endian representation,
+the latter a little endian one.
+If the destination
+.I buf
+is not
+.BR nil ,
+it specifies the buffer of length
+.I blen
+for the result. If the representation
+is less than
+.I blen
+bytes, the rest of the buffer is zero filled.
+If
+.I buf
+is
+.BR nil ,
+then a buffer is allocated and a pointer to it is
+deposited in the location pointed to by
+.IR bufp .
+Sign is ignored in these conversions, i.e., the byte
+array version is always positive.
+.PP
+.IR Betomp ,
+and
+.I letomp
+convert from a big or little endian byte array at
+.I buf
+of length
+.I blen
+to an
+.IR mpint .
+If
+.I b
+is not
+.IR nil ,
+it refers to a preallocated
+.I mpint
+for the result.
+If
+.I b
+is
+.BR nil ,
+a new integer is allocated and returned as the result.
+.PP
+The integer conversions are:
+.TF Mptouv
+.TP
+.I mptoui
+.BR mpint -> "unsigned int"
+.TP
+.I uitomp
+.BR "unsigned int" -> mpint
+.TP
+.I mptoi
+.BR mpint -> "int"
+.TP
+.I itomp
+.BR "int" -> mpint
+.TP
+.I mptouv
+.BR mpint -> "unsigned vlong"
+.TP
+.I uvtomp
+.BR "unsigned vlong" -> mpint
+.TP
+.I mptov
+.BR mpint -> "vlong"
+.TP
+.I vtomp
+.BR "vlong" -> mpint
+.PD
+.PP
+When converting to the base integer types, if the integer is too large,
+the largest integer of the appropriate sign
+and size is returned.
+.PP
+The mathematical functions are:
+.TF mpmagadd
+.TP
+.I mpadd
+.BR "sum = b1 + b2" .
+.TP
+.I mpmagadd
+.BR "sum = abs(b1) + abs(b2)" .
+.TP
+.I mpsub
+.BR "diff = b1 - b2" .
+.TP
+.I mpmagsub
+.BR "diff = abs(b1) - abs(b2)" .
+.TP
+.I mpleft
+.BR "res = b<<shift" .
+.TP
+.I mpright
+.BR "res = b>>shift" .
+.TP
+.I mpmul
+.BR "prod = b1*b2" .
+.TP
+.I mpexp
+if
+.I m
+is nil,
+.BR "res = b**e" .
+Otherwise,
+.BR "res = b**e mod m" .
+.TP
+.I mpmod
+.BR "remainder = b % m" .
+.TP
+.I mpdiv
+.BR "quotient = dividend/divisor" .
+.BR "remainder = dividend % divisor" .
+.TP
+.I mpcmp
+returns -1, 0, or +1 as
+.I b1
+is less than, equal to, or greater than
+.IR b2 .
+.TP
+.I mpmagcmp
+the same as
+.I mpcmp
+but ignores the sign and just compares magnitudes.
+.PD
+.PP
+.I Mpextendedgcd
+computes the greatest common denominator,
+.IR d ,
+of
+.I a
+and
+.IR b .
+It also computes
+.I x
+and
+.I y
+such that
+.BR "a*x + b*y = d" .
+Both
+.I a
+and
+.I b
+are required to be positive.
+If called with negative arguments, it will
+return a gcd of 0.
+.PP
+.I Mpinverse
+computes the multiplicative inverse of
+.I b
+.B mod
+.IR m .
+.PP
+.I Mpsignif
+returns the number of significant bits in
+.IR b .
+.I Mplowbits0
+returns the number of consecutive zero bits
+at the low end of the significant bits.
+For example, for 0x14,
+.I mpsignif
+returns 5 and
+.I mplowbits0
+returns 2.
+For 0,
+.I mpsignif
+and
+.I mplowbits0
+both return 0.
+.PP
+The remaining routines all work on arrays of
+.B mpdigit
+rather than
+.BR mpint 's.
+They are the basis of all the other routines. They are separated out
+to allow them to be rewritten in assembler for each architecture. There
+is also a portable C version for each one.
+.TF mpvecdigmuladd
+.TP
+.I mpdigdiv
+.BR "quotient = dividend[0:1] / divisor" .
+.TP
+.I mpvecadd
+.BR "sum[0:alen] = a[0:alen-1] + b[0:blen-1]" .
+We assume alen >= blen and that sum has room for alen+1 digits.
+.TP
+.I mpvecsub
+.BR "diff[0:alen-1] = a[0:alen-1] - b[0:blen-1]" .
+We assume that alen >= blen and that diff has room for alen digits.
+.TP
+.I mpvecdigmuladd
+.BR "p[0:n] += m * b[0:n-1]" .
+This multiplies a an array of digits times a scalar and adds it to another array.
+We assume p has room for n+1 digits.
+.TP
+.I mpvecdigmulsub
+.BR "p[0:n] -= m * b[0:n-1]" .
+This multiplies a an array of digits times a scalar and subtracts it fromo another array.
+We assume p has room for n+1 digits. It returns +1 is the result is positive and
+-1 if negative.
+.TP
+.I mpvecmul
+.BR "p[0:alen*blen] = a[0:alen-1] * b[0:blen-1]" .
+We assume that p has room for alen*blen+1 digits.
+.TP
+.I mpveccmp
+This returns -1, 0, or +1 as a - b is negative, 0, or positive.
+.PD
+.PP
+.IR mptwo ,
+.I mpone
+and
+.I mpzero
+are the constants 2, 1 and 0. These cannot be freed.
+.SS "Chinese remainder theorem
+.PP
+When computing in a non-prime modulus,
+.IR n,
+it is possible to perform the computations on the residues modulo the prime
+factors of
+.I n
+instead. Since these numbers are smaller, multiplication and exponentiation
+can be much faster.
+.PP
+.I Crtin
+computes the residues of
+.I x
+and returns them in a newly allocated structure:
+.IP
+.EX
+typedef struct CRTres CRTres;
+{
+ int n; /* number of residues */
+ mpint *r[n]; /* residues */
+};
+.EE
+.PP
+.I Crtout
+takes a residue representation of a number and converts it back into
+the number. It also frees the residue structure.
+.PP
+.I Crepre
+saves a copy of the factors and precomputes the constants necessary
+for converting the residue form back into a number modulo
+the product of the factors. It returns a newly allocated structure
+containing values.
+.PP
+.I Crtprefree
+and
+.I crtresfree
+free
+.I CRTpre
+and
+.I CRTres
+structures respectively.
+.SH SOURCE
+.B /sys/src/libmp
diff --git a/sys/man/2/muldiv b/sys/man/2/muldiv
new file mode 100755
index 000000000..93444bd55
--- /dev/null
+++ b/sys/man/2/muldiv
@@ -0,0 +1,31 @@
+.TH MULDIV 2
+.SH NAME
+muldiv, umuldiv \- high-precision multiplication and division
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+long muldiv(long a, long b, long c)
+.PP
+.B
+ulong umuldiv(ulong a, ulong b, ulong c)
+.SH DESCRIPTION
+.I Muldiv
+returns
+.BR a*b/c ,
+using a
+.B vlong
+to hold the intermediate result.
+.I Umuldiv
+is the equivalent for unsigned integers.
+They can be used to scale integer values without worry about
+overflowing the intermediate result.
+.PP
+On some architectures, these routines can generate a trap if the
+final result does not fit in a
+.B long
+or
+.BR ulong ;
+on others they will silently truncate.
diff --git a/sys/man/2/nan b/sys/man/2/nan
new file mode 100755
index 000000000..90e39b994
--- /dev/null
+++ b/sys/man/2/nan
@@ -0,0 +1,52 @@
+.TH NAN 2
+.SH NAME
+NaN, Inf, isNaN, isInf \- not-a-number and infinity functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLdouble 'u
+.B
+double NaN(void)
+.PP
+.B
+double Inf(int)
+.PP
+.B
+int isNaN(double)
+.PP
+.B
+int isInf(double, int)
+.SH DESCRIPTION
+The IEEE floating point standard defines values called
+`not-a-number' and positive and negative `infinity'.
+These values can be produced by such things as overflow
+and division by zero.
+Also, the library functions sometimes return them when
+the arguments are not in the domain, or the result is
+out of range.
+By default, manipulating these values may cause a floating point exception
+on some processors but
+.I setfcr
+(see
+.IR getfcr (2))
+can change that behavior.
+.PP
+.I NaN
+returns a double that is not-a-number.
+.I IsNaN
+returns true if its argument is not-a-number.
+.PP
+.IR Inf ( i )
+returns positive infinity if
+.I i
+is greater than or equal to zero,
+else negative infinity.
+.I IsInf
+returns true if its first argument is infinity
+with the same sign as the second argument.
+.SH SOURCE
+.B /sys/src/libc/port/nan.c
+.SH "SEE ALSO"
+.IR getfcr (2)
diff --git a/sys/man/2/ndb b/sys/man/2/ndb
new file mode 100755
index 000000000..8024816a8
--- /dev/null
+++ b/sys/man/2/ndb
@@ -0,0 +1,498 @@
+.TH NDB 2
+.SH NAME
+ndbopen, ndbcat, ndbchanged, ndbclose, ndbreopen, ndbsearch, ndbsnext, ndbgetvalue, ndbfree, ipattr, ndbgetipaddr, ndbipinfo, csipinfo, ndbhash, ndbparse, csgetvalue, ndbfindattr, dnsquery, ndbdiscard, ndbconcatenate, ndbreorder, ndbsubstitute, ndbgetval, csgetval, ndblookval \- network database
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bio.h>
+.br
+.B #include <ndb.h>
+.ta \w'\fLNdbtuplexx 'u
+.PP
+.B
+Ndb* ndbopen(char *file)
+.PP
+.B
+Ndb* ndbcat(Ndb *db1, Ndb *db2)
+.PP
+.B
+int ndbchanged(Ndb *db)
+.PP
+.B
+int ndbreopen(Ndb *db)
+.PP
+.B
+void ndbclose(Ndb *db)
+.PP
+.B
+Ndbtuple* ndbsearch(Ndb *db, Ndbs *s, char *attr, char *val)
+.PP
+.B
+Ndbtuple* ndbsnext(Ndbs *s, char *attr, char *val)
+.PP
+.B
+char* ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char *val,
+.br
+.B
+ char *rattr, Ndbtuple **tp)
+.PP
+.B
+char* csgetvalue(char *netroot, char *attr, char *val,
+.B
+ char *rattr, Ndbtuple **tp)
+.PP
+.B
+char* ipattr(char *name)
+.PP
+.B
+Ndbtuple* ndbgetipaddr(Ndb *db, char *sys);
+.PP
+.B
+Ndbtuple* ndbipinfo(Ndb *db, char *attr, char *val, char **attrs,
+.br
+.B int nattr)
+.PP
+.B
+Ndbtuple* csipinfo(char *netroot, char *attr, char *val,
+.br
+.B char **attrs, int nattr)
+.PP
+.B
+ulong ndbhash(char *val, int hlen)
+.PP
+.B
+Ndbtuple* ndbparse(Ndb *db)
+.PP
+.B
+Ndbtuple* dnsquery(char *netroot, char *domainname, char *type)
+.PP
+.B
+Ndbtuple* ndbfindattr(Ndbtuple *entry, Ndbtuple *line, char *attr)
+.PP
+.B
+void ndbfree(Ndbtuple *db)
+.PP
+.B
+Ndbtuple* ndbdiscard(Ndbtuple *t, Ndbtuple *a)
+.PP
+.B
+Ndbtuple* ndbconcatenate(Ndbtuple *a, Ndbtuple *b)
+.PP
+.B
+Ndbtuple* ndbreorder(Ndbtuple *t, Ndbtuple *a)
+.PP
+.B
+Ndbtuple* ndbsubstitute(Ndbtuple *t, Ndbtuple *from, Ndbtuple *to)
+.PP
+.B
+void ndbsetmalloctag(Ndbtuple *t, uintptr tag)
+.SH DESCRIPTION
+These routines are used by network administrative programs to search
+the network database.
+They operate on the database files described in
+.IR ndb (6).
+.PP
+.I Ndbopen
+opens the database
+.I file
+and calls
+.IR malloc (2)
+to allocate a buffer for it.
+If
+.I file
+is zero, all network database files are opened.
+.PP
+.I Ndbcat
+concatenates two open databases. Either argument may be nil.
+.PP
+.I Ndbreopen
+throws out any cached information
+for the database files associated with
+.I db
+and reopens the files.
+.PP
+.I Ndbclose
+closes any database files associated with
+.I db
+and frees all storage associated with them.
+.PP
+.I Ndbsearch
+and
+.I ndbsnext
+search a database for an entry containing the
+attribute/value pair,
+.IR attr = val .
+.I Ndbsearch
+is used to find the first match and
+.I ndbsnext
+is used to find each successive match.
+On a successful search both return a linked list of
+.I Ndbtuple
+structures acquired by
+.IR malloc (2)
+that represent the attribute/value pairs in the
+entry.
+On failure they return zero.
+.IP
+.EX
+typedef struct Ndbtuple Ndbtuple;
+struct Ndbtuple {
+ char attr[Ndbalen];
+ char *val;
+ Ndbtuple *entry;
+ Ndbtuple *line;
+ ulong ptr; /* for the application; starts 0 */
+ char valbuf[Ndbvlen]; /* initial allocation for val */
+};
+.EE
+.LP
+The
+.I entry
+pointers chain together all pairs in the entry in a null-terminated list.
+The
+.I line
+pointers chain together all pairs on the same line
+in a circular list.
+Thus, a program can implement 2 levels of binding for
+pairs in an entry.
+In general, pairs on the same line are bound tighter
+than pairs on different lines.
+.PP
+The argument
+.I s
+of
+.I ndbsearch
+has type
+.I Ndbs
+and should be pointed to valid storage before calling
+.IR ndbsearch ,
+which will fill it with information used by
+.I ndbsnext
+to link successive searches.
+The structure
+.I Ndbs
+looks like:
+.IP
+.EX
+typedef struct Ndbs Ndbs;
+struct Ndbs {
+ Ndb *db; /* data base file being searched */
+ ...
+ Ndbtuple *t; /* last attribute value pair found */
+};
+.EE
+.LP
+The
+.I t
+field points to the pair within the entry matched by the
+.I ndbsearch
+or
+.IR ndbsnext .
+.PP
+.I Ndbgetvalue
+searches the database for an entry containing not only an
+attribute/value pair,
+.IR attr = val ,
+but also a pair with the attribute
+.IR rattr .
+If successful, it returns a malloced copy of the NUL-terminated value associated with
+.IR rattr .
+If
+.I tp
+is non nil,
+.I *tp
+will point to the entry. Otherwise the entry will be freed.
+.PP
+.I Csgetvalue
+is like
+.I ndbgetvalue
+but queries the connection server
+instead of looking directly at the database.
+Its first argument specifies the network root to use.
+If the argument is 0, it defaults to
+\f5"/net"\f1.
+.PP
+.I Ndbfree
+frees a list of tuples returned by one of the other
+routines.
+.PP
+.I Ipattr
+takes the name of an IP system and returns the attribute
+it corresponds to:
+.RS
+.TP
+.B dom
+domain name
+.TP
+.B ip
+Internet number
+.TP
+.B sys
+system name
+.RE
+.PP
+.I Ndbgetipaddr
+looks in
+.I db
+for an entry matching
+.I sys
+as the value of a
+.B sys=
+or
+.B dom=
+attribute/value pair and returns all IP addresses in the entry.
+If
+.I sys
+is already an IP address, a tuple containing just
+that address is returned.
+.PP
+.I Ndbipinfo
+looks up Internet protocol information about a system.
+This is an IP aware search. It looks first for information
+in the system's database entry and then in the database entries
+for any IP subnets or networks containing the system.
+The system is identified by the
+attribute/value pair,
+.IR attr = val .
+.I Ndbipinfo
+returns a list of tuples whose attributes match the
+attributes in the
+.I n
+element array
+.IR attrs .
+If any
+.I attrs
+begin with
+.LR @ ,
+the
+.L @
+is excluded from the attribute name,
+but causes any corresponding value returned
+to be a resolved IP address(es), not a name.
+For example, consider the following database entries describing a network,
+a subnetwork, and a system.
+.IP
+.EX
+ipnet=big ip=10.0.0.0
+ dns=dns.big.com
+ smtp=smtp.big.com
+ipnet=dept ip=10.1.1.0 ipmask=255.255.255.0
+ smtp=smtp1.big.com
+ip=10.1.1.4 dom=x.big.com
+ bootf=/386/9pc
+.EE
+.PP
+Calling
+.IP
+.EX
+ndbipinfo(db, "dom", "x.big.com", ["bootf" "smtp" "dns"], 3)
+.EE
+.PP
+will return the tuples
+.BR bootf=/386/9pc ,
+.BR smtp=smtp1.big.com ,
+and
+.BR dns=dns.big.com .
+.PP
+.I Csipinfo
+is to
+.I ndbipinfo
+as
+.I csgetval
+is to
+.IR ndbgetval .
+.PP
+The next three routines are used by programs that create the
+hash tables and database files.
+.I Ndbhash
+computes a hash offset into a table of length
+.I hlen
+for the string
+.IR val .
+.I Ndbparse
+reads and parses the next entry from the database file.
+Multiple calls to
+.IR ndbparse
+parse sequential entries in the database file.
+A zero is returned at end of file.
+.PP
+.I Dnsquery
+submits a query about
+.I domainname
+to the
+.I ndb/dns
+mounted at
+.IB netroot /dns.
+It returns a linked list of
+.I Ndbtuple's
+representing a single database entry.
+The tuples are logically arranged into lines using the
+.B line
+field in the structure.
+The possible
+.IR type 's
+of query are and the attributes on each returned tuple line is:
+.TP
+.B ip
+find the IP addresses. Returns
+domain name
+.RI ( dom )
+and ip address
+.RI ( ip )
+.TP
+.B mx
+look up the mail exchangers. Returns preference
+.RI ( pref )
+and exchanger
+.RI ( mx )
+.TP
+.B ptr
+do a reverse query. Here
+.I domainname
+must be an
+.SM ASCII
+IP address. Returns reverse name
+.RI ( ptr )
+and domain name
+.RI ( dom )
+.TP
+.B cname
+get the system that this name is a nickname for. Returns the nickname
+.RI ( dom )
+and the real name
+.RI ( cname )
+.TP
+.B soa
+return the start of area record for this field. Returns
+area name
+.RI ( dom ),
+primary name server
+.RI ( ns ),
+serial number
+.RI ( serial ),
+refresh time in seconds
+.RI ( refresh ),
+retry time in seconds
+.RI ( retry ),
+expiration time in seconds
+.RI ( expire ),
+and minimum time to lie
+.RI ( ttl ).
+.TP
+.B ns
+name servers. Returns domain name
+.RI ( dom )
+and name server
+.RI ( ns )
+.PP
+.I Ndbfindattr
+searches
+.I entry
+for the tuple
+with attribute
+.I attr
+and returns a pointer to the tuple.
+If
+.I line
+points to a particular line in the entry, the
+search starts there and then wraps around to the beginning
+of the entry.
+.PP
+All of the routines provided to search the database
+provide an always consistent view of the relevant
+files. However, it may be advantageous for an application
+to read in the whole database using
+.I ndbopen
+and
+.I ndbparse
+and provide its own search routines. The
+.I ndbchanged
+routine can be used by the application to periodically
+check for changes. It returns zero
+if none of the files comprising the database have
+changes and non-zero if they have.
+.PP
+Finally, a number of routines are provided for manipulating tuples.
+.PP
+.I Ndbdiscard
+removes attr/val pair
+.I a
+from tuple
+.I t
+and frees it.
+If
+.I a
+isn't in
+.I t
+it is just freed.
+.PP
+.I Ndbconcatenate
+concatenates two tuples and returns the result. Either
+or both tuples may be nil.
+.PP
+.I Ndbreorder
+reorders a tuple
+.IR t
+to make the line containing attr/val pair
+.I a
+first in the entry and making
+.I a
+first in its line.
+.PP
+.I Ndbsubstitute
+replaces a single att/val pair
+.I from
+in
+.I t
+with the tuple
+.IR to .
+All attr/val pairs in
+.I to
+end up on the same line.
+.I from
+is freed.
+.PP
+.I Ndbsetmalloctag
+sets the malloc tag
+(see
+.I setmalloctag
+in
+.IR malloc (2))
+of each tuple in the list
+.I t
+to
+.IR tag .
+.SH FILES
+.BR /lib/ndb " directory of network database files
+.SH SOURCE
+.B /sys/src/libndb
+.SH SEE ALSO
+.IR ndb (6),
+.IR ndb (8)
+.SH DIAGNOSTICS
+.IR Ndbgetvalue ,
+.IR csgetvalue ,
+and
+.I ndblookvalue
+set
+.I errstr
+to
+.L "buffer too short"
+if the buffer provided isn't long enough for the
+returned value.
+.SH BUGS
+.IR Ndbgetval ,
+.IR csgetval ,
+and
+.I ndblookval
+are deprecated versions of
+.IR ndbgetvalue ,
+.IR csgetvalue ,
+and
+.IR ndblookvalue .
+They expect a fixed 64 byte long result
+buffer and existed when the values of a
+.I Ndbtuple
+structure were fixed length.
diff --git a/sys/man/2/notify b/sys/man/2/notify
new file mode 100755
index 000000000..fb78de427
--- /dev/null
+++ b/sys/man/2/notify
@@ -0,0 +1,244 @@
+.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 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.
diff --git a/sys/man/2/object b/sys/man/2/object
new file mode 100755
index 000000000..29a6bde3b
--- /dev/null
+++ b/sys/man/2/object
@@ -0,0 +1,150 @@
+.TH OBJECT 2
+.SH NAME
+objtype, readobj, objtraverse, isar, nextar, readar \- object file interpretation functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bio.h>
+.br
+.B #include <mach.h>
+.PP
+.ta \w'\fLmachines 'u
+.B
+int objtype(Biobuf *bp, char **name)
+.PP
+.B
+int readobj(Biobuf *bp, int objtype)
+.PP
+.B
+void objtraverse(void(*)(Sym*, void*), void*)
+.PP
+.B
+int isar(Biobuf *bp)
+.PP
+.B
+int nextar(Biobuf *bp, int offset, char *buf)
+.PP
+.B
+int readar(Biobuf *bp, int objtype, int end)
+.SH DESCRIPTION
+These functions provide machine-independent access to object files
+in a directory or an archive.
+.IR Mach (2)
+and
+.IR symbol (2)
+describe additional library functions
+for interpreting executable files and executing images.
+.PP
+Object files contain no formal symbol table; instead, references
+to symbols must be extracted from the encoded object representation
+and resolved. The resulting symbol information is loaded
+into a dummy symbol table where it is available for processing by an
+application. The organization of the dummy symbol
+table is identical
+to that produced by the loader and described in
+.IR symbol (2)
+and
+.IR a.out (6):
+a vector of
+.B Sym
+data structures defining the name, type and relative offset of
+each symbol.
+.PP
+.I Objtype
+reads the header at the current position of the
+file associated with
+.I bp
+(see
+.IR Bio (2))
+to see if it is an intermediate object file.
+If it is, a code indicating the architecture type of the file
+is returned and the second argument, if it is non-zero,
+is set pointing to a string describing the type of the file.
+If the header does not indicate an object file,
+\-1 is returned.
+The header may be at the start of an object
+file or at the beginning of an archive member. The
+file is rewound to its starting
+position after decoding the header.
+.PP
+.I Readobj
+constructs a symbol table for the object file associated with
+.IR bp .
+The second argument contains the type code produced by
+function
+.IR objtype .
+The file must be positioned at the start of the object file.
+Each invocation of
+.I readobj
+destroys the symbol definitions for any previous file.
+.PP
+.I Objtraverse
+scans the symbol table previously built by
+.I readobj
+or
+.IR readar .
+.I Objtraverse
+requires two arguments:
+the address of a call-back function and a
+generic pointer. The call-back function
+is invoked once for each symbol in the symbol table with
+the address of a
+.I Sym
+data structure as the first argument and the
+generic pointer as the second.
+.PP
+.I Isar
+reads the header at the current point in the file
+associated with
+.I bp
+and returns 1 if it is an archive or zero otherwise.
+The file is positioned at the end of the archive
+header and at the beginning of the first member of the archive.
+.PP
+.I Nextar
+extracts information describing the archive member stored
+at
+.I offset
+in the file associated with
+.IR bp .
+If the header describing the member can be
+extracted and decoded, the size of the member is
+returned. Adding this value to
+.I offset
+yields the offset of the beginning of the next member
+in the archive. On return the input file is positioned
+at the end of the member header
+and the name of the member is stored in
+.IR buf ,
+a buffer of
+.B SARNAME
+characters.
+If there are no more members,
+.I nextar
+returns zero; a negative return indicates a missing
+or malformed header.
+.PP
+.I Readar
+constructs the symbol table of the object file stored
+at the current position in the archive associated with
+.IR bp .
+This function operates exactly as
+.IR readobj ;
+the only difference is the extra argument,
+.IR end ,
+specifying the offset to the beginning of the
+next member in the archive.
+.I Readar
+leaves the file positioned at that point.
+.SH SOURCE
+.B /sys/src/libmach
+.SH "SEE ALSO"
+.IR mach (2),
+.IR symbol (2),
+.IR bio (2),
+.IR a.out (6)
+.SH DIAGNOSTICS
+These routines set
+.IR errstr .
diff --git a/sys/man/2/open b/sys/man/2/open
new file mode 100755
index 000000000..10852cffa
--- /dev/null
+++ b/sys/man/2/open
@@ -0,0 +1,148 @@
+.TH OPEN 2
+.SH NAME
+open, create, close \- open a file for reading or writing, create file
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int open(char *file, int omode)
+.PP
+.B
+int create(char *file, int omode, ulong perm)
+.PP
+.B
+int close(int fd)
+.SH DESCRIPTION
+.I Open
+opens the
+.I file
+for I/O and returns an associated file descriptor.
+.I Omode
+is one of
+.BR OREAD ,
+.BR OWRITE ,
+.BR ORDWR ,
+or
+.BR OEXEC ,
+asking for permission to read, write, read and write, or execute, respectively.
+In addition, there are three values that can be ORed with the
+.IR omode :
+.B OTRUNC
+says to truncate the file
+to zero length before opening it;
+.B OCEXEC
+says to close the file when an
+.IR exec (2)
+or
+.I execl
+system call is made;
+and
+.B ORCLOSE
+says to remove the file when it is closed (by everyone who has a copy of the file descriptor).
+.I Open
+fails if the file does not exist or the user does not have
+permission to open it for the requested purpose
+(see
+.IR stat (2)
+for a description of permissions).
+The user must have write permission on the
+.I file
+if the
+.B OTRUNC
+bit is set.
+For the
+.I open
+system call
+(unlike the implicit
+.I open
+in
+.IR exec (2)),
+.B OEXEC
+is actually identical to
+.BR OREAD .
+.PP
+.I Create
+creates a new
+.I file
+or prepares to rewrite an existing
+.IR file ,
+opens it according to
+.I omode
+(as described for
+.IR open ),
+and returns an associated file descriptor.
+If the file is new,
+the owner is set to the userid of the creating process group;
+the group to that of the containing directory;
+the permissions to
+.I perm
+ANDed with the permissions of the containing directory.
+If the file already exists,
+it is truncated to 0 length,
+and the permissions, owner, and group remain unchanged.
+The created file is a directory if the
+.B DMDIR
+bit is set in
+.IR perm ,
+an exclusive-use file if the
+.B DMEXCL
+bit is set, and an append-only file if the
+.B DMAPPEND
+bit is set.
+Exclusive-use files may be open for I/O by only one client at a time,
+but the file descriptor may become invalid if no I/O is done
+for an extended period; see
+.IR open (5).
+.PP
+.I Create
+fails if the path up to the last element of
+.I file
+cannot be evaluated, if the user doesn't have write permission
+in the final directory, if the file already exists and
+does not permit the access defined by
+.IR omode ,
+of if there there are no free file descriptors.
+In the last case, the file may be created even when
+an error is returned.
+If the file is new and the directory in which it is created is
+a union directory (see
+.IR intro (2))
+then the constituent directory where the file is created
+depends on the structure of the union: see
+.IR bind (2).
+.PP
+Since
+.I create
+may succeed even if the file exists, a special mechanism is necessary
+for those applications that require an atomic create operation.
+If the
+.B OEXCL
+.RB ( 0x1000 )
+bit is set in the
+.I mode
+for a
+.IR create,
+the call succeeds only if the file does not already exist;
+see
+.IR open (5)
+for details.
+.PP
+.I Close
+closes the file associated with a file descriptor.
+Provided the file descriptor is a valid open descriptor,
+.I close
+is guaranteed to close it; there will be no error.
+Files are closed automatically upon termination of a process;
+.I close
+allows the file descriptor to be reused.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2),
+.IR bind (2),
+.IR stat (2)
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
diff --git a/sys/man/2/perror b/sys/man/2/perror
new file mode 100755
index 000000000..9d2856cb3
--- /dev/null
+++ b/sys/man/2/perror
@@ -0,0 +1,92 @@
+.TH PERROR 2
+.SH NAME
+perror, syslog, sysfatal \- system error messages
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+void perror(char *s)
+.PP
+.B
+void syslog(int cons, char *logname, char *fmt, ...)
+.PP
+.B
+void sysfatal(char *fmt, ...)
+.SH DESCRIPTION
+.I Perror
+produces a short error message
+on the standard error file
+describing the last error encountered during a call
+to the system.
+First the argument string
+.I s
+is printed, then a colon, then the message and a newline.
+If
+.I s
+is nil, only the error message and newline are printed.
+.PP
+.I Syslog
+logs messages in the file named by
+.I logname
+in the directory
+.BR /sys/log ;
+the file must already exist and should be append-only.
+.I Logname
+must contain no slashes.
+The message is a line with several fields:
+the name of the machine writing the message;
+the date and time;
+the message specified by the
+.IR print (2)
+format
+.I fmt
+and any following arguments;
+and a final newline.
+If
+.I cons
+is set or the log file cannot be opened, the message is also printed
+on the system console.
+.I Syslog
+can be used safely in multi-threaded programs.
+.PP
+.I Sysfatal
+prints to standard error the name of the running program,
+a colon and a space,
+the message described by the
+.IR print (2)
+format string
+.I fmt
+and subsequent arguments, and a newline.
+It then calls
+.IR exits (2)
+with the formatted message as argument.
+The program's name is the value of
+.BR argv0 ,
+which will be set if the program uses the
+.IR arg (2)
+interface to process its arguments.
+If
+.B argv0
+is null, it is ignored and the following colon and space are suppressed.
+.SH SOURCE
+.B /sys/src/libc/port/perror.c
+.br
+.B /sys/src/libc/9sys/syslog.c
+.br
+.B /sys/src/libc/9sys/sysfatal.c
+.SH "SEE ALSO"
+.IR intro (2),
+.IR errstr (2),
+the
+.B %r
+format in
+.IR print (2)
+.SH BUGS
+.I Perror
+is a holdover; the
+.B %r
+format in
+.IR print (2)
+is preferred.
diff --git a/sys/man/2/pipe b/sys/man/2/pipe
new file mode 100755
index 000000000..d91fc0811
--- /dev/null
+++ b/sys/man/2/pipe
@@ -0,0 +1,74 @@
+.TH PIPE 2
+.SH NAME
+pipe \- create an interprocess channel
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int pipe(int fd[2])
+.SH DESCRIPTION
+.I Pipe
+creates a buffered channel for interprocess I/O communication.
+Two file descriptors are returned in
+.IR fd .
+Data written to
+.B fd[1]
+is available for reading from
+.B fd[0]
+and data written to
+.B fd[0]
+is available for reading from
+.BR fd[1] .
+.PP
+After the pipe has been established,
+cooperating processes
+created by subsequent
+.IR fork (2)
+calls may pass data through the
+pipe with
+.I read
+and
+.I write
+calls.
+The bytes placed on a pipe
+by one
+.I write
+are contiguous even if many processes are writing.
+Write boundaries are preserved: each read terminates
+when the read buffer is full or after reading the last byte
+of a write, whichever comes first.
+.PP
+The number of bytes available to a
+.IR read (2)
+is reported
+in the
+.B Length
+field returned by
+.I fstat
+or
+.I dirfstat
+on a pipe (see
+.IR stat (2)).
+.PP
+When all the data has been read from a pipe and the writer has closed the pipe or exited,
+.IR read (2)
+will return 0 bytes. Writes to a pipe with no reader will generate a note
+.BR "sys: write on closed pipe" .
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2),
+.IR read (2),
+.IR pipe (3)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
+.SH BUGS
+If a read or a write of a pipe is interrupted, some unknown
+number of bytes may have been transferred.
+.br
+When a read from a pipe returns 0 bytes, it usually means end of file
+but is indistinguishable from reading the result of an explicit
+write of zero bytes.
diff --git a/sys/man/2/plumb b/sys/man/2/plumb
new file mode 100755
index 000000000..c9d521650
--- /dev/null
+++ b/sys/man/2/plumb
@@ -0,0 +1,240 @@
+.TH PLUMB 2
+.SH NAME
+eplumb, plumbfree, plumbopen, plumbsend, plumbsendtext, plumblookup, plumbpack, plumbpackattr, plumbaddattr, plumbdelattr, plumbrecv, plumbunpack, plumbunpackpartial, plumbunpackattr, Plumbmsg \- plumb messages
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <plumb.h>
+.PP
+.ta \w'\fLPlumbattr* 'u
+.PP
+.B
+int plumbopen(char *port, int omode)
+.PP
+.B
+int plumbsend(int fd, Plumbmsg *m)
+.PP
+.B
+int plumbsendtext(int fd, char *src, char *dst, char *wdir, char *data)
+.PP
+.B
+void plumbfree(Plumbmsg *m)
+.PP
+.B
+Plumbmsg* plumbrecv(int fd)
+.PP
+.B
+char* plumbpack(Plumbmsg *m, int *np)
+.PP
+.B
+Plumbmsg* plumbunpack(char *buf, int n)
+.PP
+.B
+Plumbmsg* plumbunpackpartial(char *buf, int n, int *morep)
+.PP
+.B
+char* plumbpackattr(Plumbattr *a)
+.PP
+.B
+Plumbattr* plumbunpackattr(char *a)
+.PP
+.B
+char* plumblookup(Plumbattr *a, char *name)
+.PP
+.B
+Plumbattr* plumbaddattr(Plumbattr *a, Plumbattr *new)
+.PP
+.B
+Plumbattr* plumbdelattr(Plumbattra *a, char *name)
+.PP
+.B
+int eplumb(int key, char *port)
+.SH DESCRIPTION
+These routines manipulate
+.IR plumb (6)
+messages, transmitting them, receiving them, and
+converting them between text and these data structures:
+.IP
+.EX
+.ta 6n +\w'\fLPlumbattr 'u +\w'ndata; 'u
+typedef
+struct Plumbmsg
+{
+ char *src;
+ char *dst;
+ char *wdir;
+ char *type;
+ Plumbattr *attr;
+ int ndata;
+ char *data;
+} Plumbmsg;
+
+typedef
+struct Plumbattr
+{
+ char *name;
+ char *value;
+ Plumbattr *next;
+} Plumbattr;
+.EE
+.PP
+.I Plumbopen
+opens the named plumb
+.IR port ,
+using
+.IR open (2)
+mode
+.IR omode .
+If
+.I port
+begins with a slash, it is taken as a literal file name;
+otherwise
+.I plumbopen
+searches for the location of the
+.IR plumber (4)
+service and opens the port there.
+.PP
+For programs using the
+.IR event (2)
+interface,
+.I eplumb
+registers, using the given
+.IR key ,
+receipt of messages from the named
+.IR port .
+.PP
+.I Plumbsend
+formats and writes message
+.I m
+to the file descriptor
+.IR fd ,
+which will usually be the result of
+.B plumbopen("send",
+.BR OWRITE) .
+.I Plumbsendtext
+is a simplified version for text-only messages; it assumes
+.B type
+is
+.BR text ,
+sets
+.B attr
+to nil,
+and sets
+.B ndata
+to
+.BI strlen( data )\f1.
+.PP
+.I Plumbfree
+frees all the data associated with the message
+.IR m ,
+all the components of which must therefore have been allocated with
+.IR malloc (2).
+.PP
+.I Plumbrecv
+returns the next message available on the file descriptor
+.IR fd ,
+or nil for error.
+.PP
+.I Plumbpack
+encodes message
+.I m
+as a character string in the format of
+.IR plumb (6) ,
+setting
+.BI * np
+to the length in bytes of the string.
+.I Plumbunpack
+does the inverse, translating the
+.I n
+bytes of
+.I buf
+into a
+.BR Plumbmsg .
+.PP
+.I Plumbunpackpartial
+enables unpacking of messages that arrive in pieces.
+The first call to
+.I plumbunpackpartial
+for a given message must be sufficient to unpack the header;
+subsequent calls permit unpacking messages with long data sections.
+For each call,
+.I buf
+points to the beginning of the complete message received so far, and
+.I n
+reports the total number of bytes received for that message.
+If the message is complete, the return value will be as in
+.IR plumbunpack .
+If not, and
+.I morep
+is not null, the return value will be
+.B nil
+and
+.BR * morep
+will be set to the number of bytes remaining to be read for this message to be complete
+(recall that the byte count is in the header).
+Those bytes should be read by the caller, placed at location
+.IB buf + n \f1,
+and the message unpacked again.
+If an error is encountered, the return value will be
+.B nil
+and
+.BI * morep
+will be zero.
+.PP
+.I Plumbpackattr
+converts the list
+.I a
+of
+.B Plumbattr
+structures into a null-terminated string.
+If an attribute value contains white space, quote characters, or equal signs,
+the value will be quoted appropriately.
+A newline character will terminate processing.
+.I Plumbunpackattr
+converts the null-terminated string
+.I a
+back into a list of
+.I Plumbattr
+structures.
+.PP
+.I Plumblookup
+searches the
+.B Plumbattr
+list
+.I a
+for an attribute with the given
+.I name
+and returns the associated value.
+The returned string is the original value, not a copy.
+If the attribute has no value, the returned value will be the empty string;
+if the attribute does not occur in the list at all, the value will be nil.
+.PP
+.I Plumbaddattr
+appends the
+.I new
+.B Plumbattr
+(which may be a list) to the attribute list
+.IR a
+and returns the new list.
+.I Plumbattr
+searches the list
+.I a
+for the first attribute with name
+.I name
+and deletes it from the list, returning the resulting list.
+.I Plumbdelattr
+is a no-op if no such attribute exists.
+.SH SOURCE
+.B /sys/src/libplumb
+.SH SEE ALSO
+.IR plumb (1),
+.IR event (2),
+.IR plumber (4),
+.IR plumb (6)
+.SH DIAGNOSTICS
+When appropriate, including when a
+.I plumbsend
+fails, these routine set
+.IR errstr .
diff --git a/sys/man/2/pool b/sys/man/2/pool
new file mode 100755
index 000000000..544fcf565
--- /dev/null
+++ b/sys/man/2/pool
@@ -0,0 +1,356 @@
+.TH POOL 2
+.SH NAME
+poolalloc, poolallocalign, poolfree, poolmsize, poolrealloc, poolcompact, poolcheck, poolblockcheck,
+pooldump \- general memory management routines
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <pool.h>
+.PP
+.B
+void* poolalloc(Pool* pool, ulong size)
+.PP
+.B
+void* poolallocalign(Pool *pool, ulong size,
+.br
+.B
+ ulong align, long offset, ulong span)
+.PP
+.B
+void poolfree(Pool* pool, void* ptr)
+.PP
+.B
+ulong poolmsize(Pool* pool, void* ptr)
+.PP
+.B
+void* poolrealloc(Pool* pool, void* ptr, ulong size)
+.PP
+.B
+void poolcompact(Pool* pool)
+.PP
+.B
+void poolcheck(Pool *pool)
+.PP
+.B
+void poolblockcheck(Pool *pool, void *ptr)
+.PP
+.B
+void pooldump(Pool *pool);
+.SH DESCRIPTION
+These routines provide a general memory management facility.
+Memory is retrieved from a coarser allocator (e.g.
+.I sbrk
+or the kernel's
+.IR xalloc )
+and then allocated to callers.
+The routines are locked and thus may safely be used in
+multiprocess programs.
+.PP
+.I Poolalloc
+attempts to allocate a block of size
+.BR size ;
+it returns a pointer to the block when successful and nil otherwise.
+The call
+.B "poolalloc(0)
+returns a non-nil pointer.
+.I Poolfree
+returns an allocated block to the pool.
+It is an error to free a block more than once or to free a
+pointer not returned by
+.IR poolalloc .
+The call
+.B "poolfree(nil)
+is legal and is a no-op.
+.PP
+.I Poolallocalign
+attempts to allocate a block of size
+.B size
+with the given alignment constraints.
+If
+.I align
+is non-zero,
+the returned pointer is aligned to be equal to
+.I offset
+modulo
+.IR align .
+If
+.I span
+is non-zero,
+the
+.I n
+byte block allocated will not span a
+.IR span -byte
+boundary.
+.PP
+.I Poolrealloc
+attempts to resize to
+.B nsize
+bytes the block associated with
+.BR ptr ,
+which must have been previously returned by
+.I poolalloc
+or
+.IR poolrealloc .
+If the block's size can be adjusted, a (possibly different) pointer to the new block is returned.
+The contents up to the lesser of the old and new sizes are unchanged.
+After a successful call to
+.IR poolrealloc ,
+the return value should be used rather than
+.B ptr
+to access the block.
+If the request cannot be satisfied,
+.I poolrealloc
+returns nil, and the old pointer remains valid.
+.PP
+When blocks are allocated, there is often some extra space left at the end
+that would usually go unused.
+.IR Poolmsize
+grows the block to encompass this extra space and returns the new size.
+.PP
+The
+.I poolblockcheck
+and
+.I poolcheck
+routines validate a single allocated block or the entire pool, respectively.
+They call
+.B panic
+(see below)
+if corruption is detected.
+.I Pooldump
+prints a summary line for every block in the
+pool, using the
+.B print
+function (see below).
+.PP
+The
+.B Pool
+structure itself provides much of the setup interface.
+.IP
+.EX
+.ta \w'\fL 'u +\w'\fLulong 'u +\w'\fLlastcompact; 'u
+typedef struct Pool Pool;
+struct Pool {
+ char* name;
+ ulong maxsize; /* of entire Pool */
+ ulong cursize; /* of Pool */
+ ulong curfree; /* total free bytes in Pool */
+ ulong curalloc; /* total allocated bytes in Pool */
+ ulong minarena; /* smallest size of new arena */
+ ulong quantum; /* allocated blocks should be multiple of */
+ ulong minblock; /* smallest newly allocated block */
+ int flags;
+ int nfree; /* number of calls to free */
+ int lastcompact; /* nfree at time of last poolcompact */
+ void* (*alloc)(ulong);
+ int (*merge)(void*, void*);
+ void (*move)(void* from, void* to);
+ void (*lock)(Pool*);
+ void (*unlock)(Pool*);
+ void (*print)(Pool*, char*, ...);
+ void (*panic)(Pool*, char*, ...);
+ void (*logstack)(Pool*);
+ void* private;
+};
+.ta \w'\fL 'u +\w'POOL_ANTAGONISM 'u
+enum { /* flags */
+ POOL_ANTAGONISM = 1<<0,
+ POOL_PARANOIA = 1<<1,
+ POOL_VERBOSITY = 1<<2,
+ POOL_DEBUGGING = 1<<3,
+ POOL_LOGGING = 1<<4,
+ POOL_TOLERANCE = 1<<5,
+ POOL_NOREUSE = 1<<6,
+};
+.EE
+.PP
+The pool obtains arenas of memory to manage by calling the the given
+.B alloc
+routine.
+The total number of requested bytes will not exceed
+.BR maxsize .
+Each allocation request will be for at least
+.B minarena
+bytes.
+.PP
+When a new arena is allocated, the pool routines try to
+merge it with the surrounding arenas, in an attempt to combat fragmentation.
+If
+.B merge
+is non-nil, it is called with the addresses of two blocks from
+.B alloc
+that the pool routines suspect might be adjacent.
+If they are not mergeable,
+.B merge
+must return zero.
+If they are mergeable,
+.B merge
+should merge them into one block in its own bookkeeping
+and return non-zero.
+.PP
+To ease fragmentation and make
+block reuse easier, the sizes requested of the pool routines are rounded up to a multiple of
+.B quantum
+before
+the carrying out requests.
+If, after rounding, the block size is still less than
+.B minblock
+bytes,
+.B minblock
+will be used as the block size.
+.PP
+.I Poolcompact
+defragments the pool, moving blocks in order to aggregate
+the free space.
+Each time it moves a block, it notifies the
+.B move
+routine that the contents have moved.
+At the time that
+.B move
+is called, the contents have already moved,
+so
+.B from
+should never be dereferenced.
+If no
+.B move
+routine is supplied (i.e. it is nil), then calling
+.I poolcompact
+is a no-op.
+.PP
+When the pool routines need to allocate a new arena but cannot,
+either because
+.B alloc
+has returned nil or because doing so would use more than
+.B maxsize
+bytes,
+.I poolcompact
+is called once to defragment the memory
+and the request is retried.
+.PP
+.I Pools
+are protected by the pool routines calling
+.B lock
+(when non-nil)
+before modifying the pool, and
+calling
+.B unlock
+when finished.
+.PP
+When internal corruption is detected,
+.B panic
+is called with a
+.IR print (2)
+style argument that specifies what happened.
+It is assumed that
+.B panic
+never returns.
+When the pool routines wish to convey a message
+to the caller (usually because logging is turned on; see below),
+.B print
+is called, also with a
+.IR print (2)
+style argument.
+.PP
+.B Flags
+is a bit vector that tweaks the behavior of the pool routines
+in various ways.
+Most are useful for debugging in one way or another.
+When
+.B POOL_ANTAGONISM
+is set,
+.I poolalloc
+fills blocks with non-zero garbage before releasing them to the user,
+and
+.I poolfree
+fills the blocks on receipt.
+This tickles both user programs and the innards of the allocator.
+Specifically, each 32-bit word of the memory is marked with a pointer value exclusive-or'ed
+with a constant.
+The pointer value is the pointer to the beginning of the allocated block
+and the constant varies in order to distinguish different markings.
+Freed blocks use the constant
+.BR 0xF7000000 ,
+newly allocated blocks
+.BR 0xF9000000 ,
+and newly created unallocated blocks
+.BR 0xF1000000 .
+For example, if
+.B POOL_ANTAGONISM
+is set and
+.I poolalloc
+returns a block starting at
+.BR 0x00012345 ,
+each word of the block will contain the value
+.BR 0xF90012345 .
+Recognizing these numbers in memory-related crashes can
+help diagnose things like double-frees or dangling pointers.
+.PP
+Setting
+.B POOL_PARANOIA
+causes the allocator to walk the entire pool whenever locking or unlocking itself,
+looking for corruption.
+This slows runtime by a few orders of magnitude
+when many blocks are in use.
+If
+.B POOL_VERBOSITY
+is set,
+the entire pool structure is printed
+(via
+.BR print )
+each time the pool is locked or unlocked.
+.B POOL_DEBUGGING
+enables internal
+debugging output,
+whose format is unspecified and volatile.
+It should not be used by most programs.
+When
+.B POOL_LOGGING
+is set, a single line is printed via
+.B print
+at the beginning and end of each pool call.
+If
+.B logstack
+is not nil,
+it will be called as well.
+This provides a mechanism for external programs to search for leaks.
+(See
+.IR leak (1)
+for one such program.)
+.PP
+The pool routines are strict about the amount of space callers use.
+If even a single byte is written past the end of the allotted space of a block, they
+will notice when that block is next used in a call to
+.I poolrealloc
+or
+.I free
+(or at the next entry into the allocator, when
+.B POOL_PARANOIA
+is set),
+and
+.B panic
+will be called.
+Since forgetting to allocate space for the
+terminating NUL on strings is such a common error,
+if
+.B POOL_TOLERANCE
+is set and a single NUL is found written past the end of a block,
+.B print
+will be called with a notification, but
+.B panic
+will not be.
+.PP
+When
+.B POOL_NOREUSE
+is set,
+.B poolfree
+fills the passed block with garbage rather than
+return it to the free pool.
+.SH SOURCE
+.B /sys/src/libc/port/pool.c
+.SH SEE ALSO
+.IR malloc (2),
+.IR brk (2)
+.PP
+.B /sys/src/libc/port/malloc.c
+is a complete example.
diff --git a/sys/man/2/postnote b/sys/man/2/postnote
new file mode 100755
index 000000000..6b4de1d41
--- /dev/null
+++ b/sys/man/2/postnote
@@ -0,0 +1,49 @@
+.TH POSTNOTE 2
+.SH NAME
+postnote \- send a note to a process or process group
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+int postnote(int who, int pid, char *note)
+.fi
+.SH DESCRIPTION
+.I Postnote
+sends a note to a process or process group.
+If
+.I who
+is
+.BR PNPROC ,
+then
+.I note
+is written to
+.BI /proc/ pid /note\f1.
+If
+.I who
+is
+.BI PNGROUP ,
+the note is delivered to the
+process group by writing
+.I note
+to
+.BI /proc/ pid /notepg\f1.
+For
+.B PNGROUP
+only, if the calling process is in the target group, the note is
+.I not
+delivered to that process.
+.PP
+If the write is successful, zero is returned.
+Otherwise \-1 is returned.
+.SH SOURCE
+.B /sys/src/libc/9sys/postnote.c
+.SH "SEE ALSO"
+.IR notify (2),
+.IR intro (2),
+.IR proc (3)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/prime b/sys/man/2/prime
new file mode 100755
index 000000000..40e31f0e9
--- /dev/null
+++ b/sys/man/2/prime
@@ -0,0 +1,100 @@
+.TH PRIME 2
+.SH NAME
+genprime, gensafeprime, genstrongprime, DSAprimes, probably_prime, smallprimetest \- prime number generation
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+int smallprimetest(mpint *p)
+.PP
+.B
+int probably_prime(mpint *p, int nrep)
+.PP
+.B
+void genprime(mpint *p, int n, int nrep)
+.PP
+.B
+void gensafeprime(mpint *p, mpint *alpha, int n, int accuracy)
+.PP
+.B
+void genstrongprime(mpint *p, int n, int nrep)
+.PP
+.B
+void DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen])
+.SH DESCRIPTION
+.PP
+Public key algorithms abound in prime numbers. The following routines
+generate primes or test numbers for primality.
+.PP
+.I Smallprimetest
+checks for divisibility by the first 10000 primes. It returns 0
+if
+.I p
+is not divisible by the primes and \-1 if it is.
+.PP
+.I Probably_prime
+uses the Miller-Rabin test to test
+.IR p .
+It returns non-zero if
+.I P
+is probably prime. The probability of it not being prime is
+1/4**\fInrep\fR.
+.PP
+.I Genprime
+generates a random
+.I n
+bit prime. Since it uses the Miller-Rabin test,
+.I nrep
+is the repetition count passed to
+.IR probably_prime .
+.I Gensafegprime
+generates an
+.IR n -bit
+prime
+.I p
+and a generator
+.I alpha
+of the multiplicative group of integers mod \fIp\fR;
+there is a prime \fIq\fR such that \fIp-1=2*q\fR.
+.I Genstrongprime
+generates a prime,
+.IR p ,
+with the following properties:
+.IP \-
+(\fIp\fR-1)/2 is prime. Therefore
+.IR p -1
+has a large prime factor,
+.IR p '.
+.IP \-
+.IR p '-1
+has a large prime factor
+.IP \-
+.IR p +1
+has a large prime factor
+.PP
+.I DSAprimes
+generates two primes,
+.I q
+and
+.IR p,
+using the NIST recommended algorithm for DSA primes.
+.I q
+divides
+.IR p -1.
+The random seed used is also returned, so that skeptics
+can later confirm the computation. Be patient; this is a
+slow algorithm.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR aes (2)
+.IR blowfish (2),
+.IR des (2),
+.IR elgamal (2),
+.IR rsa (2)
diff --git a/sys/man/2/print b/sys/man/2/print
new file mode 100755
index 000000000..0188b5318
--- /dev/null
+++ b/sys/man/2/print
@@ -0,0 +1,452 @@
+.TH PRINT 2
+.SH NAME
+print, fprint, sprint, snprint, seprint, smprint, runesprint, runesnprint, runeseprint, runesmprint, vfprint, vsnprint, vseprint, vsmprint, runevsnprint, runevseprint, runevsmprint \- print formatted output
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLchar* 'u
+.B
+int print(char *format, ...)
+.PP
+.B
+int fprint(int fd, char *format, ...)
+.PP
+.B
+int sprint(char *s, char *format, ...)
+.PP
+.B
+int snprint(char *s, int len, char *format, ...)
+.PP
+.B
+char* seprint(char *s, char *e, char *format, ...)
+.PP
+.B
+char* smprint(char *format, ...)
+.PP
+.B
+int runesprint(Rune *s, char *format, ...)
+.PP
+.B
+int runesnprint(Rune *s, int len, char *format, ...)
+.PP
+.B
+Rune* runeseprint(Rune *s, Rune *e, char *format, ...)
+.PP
+.B
+Rune* runesmprint(char *format, ...)
+.PP
+.B
+int vfprint(int fd, char *format, va_list v)
+.PP
+.B
+int vsnprint(char *s, int len, char *format, va_list v)
+.PP
+.B
+char* vseprint(char *s, char *e, char *format, va_list v)
+.PP
+.B
+char* vsmprint(char *format, va_list v)
+.PP
+.B
+int runevsnprint(Rune *s, int len, char *format, va_list v)
+.PP
+.B
+Rune* runevseprint(Rune *s, Rune *e, char *format, va_list v)
+.PP
+.B
+Rune* runevsmprint(Rune *format, va_list v)
+.PP
+.B
+.SH DESCRIPTION
+.I Print
+writes text to the standard output.
+.I Fprint
+writes to the named output
+file descriptor;
+a buffered form
+is described in
+.IR bio (2).
+.I Sprint
+places text
+followed by the NUL character
+.RB ( \e0 )
+in consecutive bytes starting at
+.IR s ;
+it is the user's responsibility to ensure that
+enough storage is available.
+Each function returns the number of bytes
+transmitted (not including the NUL
+in the case of
+.IR sprint ),
+or
+a negative value if an output error was encountered.
+.PP
+.I Snprint
+is like
+.IR sprint ,
+but will not place more than
+.I len
+bytes in
+.IR s .
+Its result is always NUL-terminated and holds the maximal
+number of complete UTF-8 characters that can fit.
+.I Seprint
+is like
+.IR snprint ,
+except that the end is indicated by a pointer
+.I e
+rather than a count and the return value points to the terminating NUL of the
+resulting string.
+.I Smprint
+is like
+.IR sprint ,
+except that it prints into and returns a string of the required length, which is
+allocated by
+.IR malloc (2).
+.PP
+The routines
+.IR runesprint ,
+.IR runesnprint ,
+.IR runeseprint ,
+and
+.I runesmprint
+are the same as
+.IR sprint ,
+.IR snprint ,
+.IR seprint
+and
+.I smprint
+except that their output is rune strings instead of byte strings.
+.PP
+Finally, the routines
+.IR vfprint ,
+.IR vsnprint ,
+.IR vseprint ,
+.IR vsmprint ,
+.IR runevsnprint ,
+.IR runevseprint ,
+and
+.IR runevsmprint
+are like their
+.BR v-less
+relatives except they take as arguments a
+.B va_list
+parameter, so they can be called within a variadic function.
+The Example section shows a representative usage.
+.PP
+Each of these functions
+converts, formats, and prints its
+trailing arguments
+under control of a
+.IR format
+string.
+The
+format
+contains two types of objects:
+plain characters, which are simply copied to the
+output stream,
+and conversion specifications,
+each of which results in fetching of
+zero or more
+arguments.
+The results are undefined if there are arguments of the
+wrong type or too few
+arguments for the format.
+If the format is exhausted while
+arguments remain, the excess
+is ignored.
+.PP
+Each conversion specification has the following format:
+.IP
+.B "% [flags] verb
+.PP
+The verb is a single character and each flag is a single character or a
+(decimal) numeric string.
+Up to two numeric strings may be used;
+the first is called
+.IR width ,
+the second
+.IR precision .
+A period can be used to separate them, and if the period is
+present then
+.I width
+and
+.I precision
+are taken to be zero if missing, otherwise they are `omitted'.
+Either or both of the numbers may be replaced with the character
+.BR * ,
+meaning that the actual number will be obtained from the argument list
+as an integer.
+The flags and numbers are arguments to
+the
+.I verb
+described below.
+.PP
+The numeric verbs
+.BR d ,
+.BR o ,
+.BR b ,
+.BR x ,
+and
+.B X
+format their arguments in decimal,
+octal, binary, hexadecimal, and upper case hexadecimal.
+Each interprets the flags
+.BR 0 ,
+.BR h ,
+.BR hh ,
+.BR l ,
+.BR u ,
+.BR + ,
+.BR - ,
+.BR , ,
+and
+.B #
+to mean pad with zeros,
+short, byte, long, unsigned, always print a sign, left justified, commas every three digits,
+and alternate format.
+Also, a space character in the flag
+position is like
+.BR + ,
+but prints a space instead of a plus sign for non-negative values.
+If neither
+short nor long is specified,
+then the argument is an
+.BR int .
+If unsigned is specified,
+then the argument is interpreted as a
+positive number and no sign is output.
+If two
+.B l
+flags are given,
+then the argument is interpreted as a
+.B vlong
+(usually an 8-byte, sometimes a 4-byte integer).
+If
+.I precision
+is not omitted, the number is padded on the left with zeros
+until at least
+.I precision
+digits appear.
+Then, if alternate format is specified,
+for
+.B o
+conversion, the number is preceded by a
+.B 0
+if it doesn't already begin with one;
+for
+.B x
+conversion, the number is preceded by
+.BR 0x ;
+for
+.B X
+conversion, the number is preceded by
+.BR 0X .
+Finally, if
+.I width
+is not omitted, the number is padded on the left (or right, if
+left justification is specified) with enough blanks to
+make the field at least
+.I width
+characters long.
+.PP
+The floating point verbs
+.BR f ,
+.BR e ,
+.BR E ,
+.BR g ,
+and
+.B G
+take a
+.B double
+argument.
+Each interprets the flags
+.BR + ,
+.BR - ,
+and
+.B #
+to mean
+always print a sign,
+left justified,
+and
+alternate format.
+.I Width
+is the minimum field width and,
+if the converted value takes up less than
+.I width
+characters, it is padded on the left (or right, if `left justified')
+with spaces.
+.I Precision
+is the number of digits that are converted after the decimal place for
+.BR e ,
+.BR E ,
+and
+.B f
+conversions,
+and
+.I precision
+is the maximum number of significant digits for
+.B g
+and
+.B G
+conversions.
+The
+.B f
+verb produces output of the form
+.RB [ - ] digits [ .digits\fR].
+.B E
+conversion appends an exponent
+.BR E [ - ] digits ,
+and
+.B e
+conversion appends an exponent
+.BR e [ - ] digits .
+The
+.B g
+verb will output the argument in either
+.B e
+or
+.B f
+with the goal of producing the smallest output.
+Also, trailing zeros are omitted from the fraction part of
+the output, and a trailing decimal point appears only if it is followed
+by a digit.
+The
+.B G
+verb is similar, but uses
+.B E
+format instead of
+.BR e .
+When alternate format is specified, the result will always contain a decimal point,
+and for
+.B g
+and
+.B G
+conversions, trailing zeros are not removed.
+.PP
+The
+.B s
+verb copies a nul-terminated string
+(pointer to
+.BR char )
+to the output.
+The number of characters copied
+.RI ( n )
+is the minimum
+of the size of the string and
+.IR precision .
+These
+.I n
+characters are justified within a field of
+.I width
+characters as described above.
+If a
+.I precision
+is given, it is safe for the string not to be nul-terminated
+as long as it is at least
+.I precision
+characters (not bytes!) long.
+The
+.B S
+verb is similar, but it interprets its pointer as an array
+of runes (see
+.IR utf (6));
+the runes are converted to
+.SM UTF
+before output.
+.PP
+The
+.B c
+verb copies a single
+.B char
+(promoted to
+.BR int )
+justified within a field of
+.I width
+characters as described above.
+The
+.B C
+verb is similar, but works on runes.
+.PP
+The
+.B p
+verb formats a single pointer or pointer-sized integer
+.RB ( uintptr ,
+see
+.IR intro (2))
+in hexadecimal.
+.PP
+The
+.B r
+verb takes no arguments; it copies the error string returned by a call to
+.IR errstr (2).
+.PP
+Custom verbs may be installed using
+.IR fmtinstall (2).
+.SH EXAMPLE
+This function prints an error message with a variable
+number of arguments and then quits.
+.IP
+.EX
+.ta 6n +6n +6n
+void fatal(char *msg, ...)
+{
+ char buf[1024], *out;
+ va_list arg;
+
+ out = seprint(buf, buf+sizeof(buf), "Fatal error: ");
+ va_start(arg, msg);
+ out = vseprint(out, buf+sizeof(buf), msg, arg);
+ va_end(arg);
+ write(2, buf, out-buf);
+ exits("fatal error");
+}
+.EE
+.SH SOURCE
+.B /sys/src/libc/fmt
+.SH SEE ALSO
+.IR fmtinstall (2),
+.IR fprintf (2),
+.IR utf (6),
+.IR errstr (2)
+.SH DIAGNOSTICS
+Routines that write to a file descriptor or call
+.IR malloc
+set
+.IR errstr .
+.SH BUGS
+The formatting is close to that specified for ANSI
+.IR fprintf (2);
+the main difference is that
+.B b
+is not in ANSI and
+.B u
+is a flag here instead of a verb.
+Also, and distinctly not a bug,
+.I print
+and friends generate
+.SM UTF
+rather than
+.SM ASCII.
+.PP
+There is no
+.BR runeprint ,
+.BR runefprint ,
+etc. because runes are byte-order dependent and should not be written directly to a file; use the
+UTF output of
+.I print
+or
+.I fprint
+instead.
+Also,
+.I sprint
+is deprecated for safety reasons; use
+.IR snprint ,
+.IR seprint ,
+or
+.I smprint
+instead.
+Safety also precludes the existence of
+.IR runesprint .
diff --git a/sys/man/2/privalloc b/sys/man/2/privalloc
new file mode 100755
index 000000000..20dd0bf2f
--- /dev/null
+++ b/sys/man/2/privalloc
@@ -0,0 +1,36 @@
+.TH PRIVALLOC 2
+.SH NAME
+privalloc, privfree \- per-process private storage management
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.ta \w'voidmmm'u
+.PP
+.B
+void** privalloc(void)
+.PP
+.B
+void privfree(void **p)
+.SH DESCRIPTION
+.I Privalloc
+returns a pointer to a per-process private storage location.
+The location is not shared among processes,
+even if they share the same data segments.
+It returns
+.B nil
+if there are no free slots available.
+.PP
+.I Privfree
+releases a location allocated with
+.IR privalloc .
+It is legal to call
+.I privfree
+with
+.I p
+set to
+.BR nil .
+.SH SOURCE
+.B /sys/src/libc/9sys/privalloc.c
+.SH SEE ALSO
+.IR exec (2)
diff --git a/sys/man/2/proto b/sys/man/2/proto
new file mode 100755
index 000000000..563a19174
--- /dev/null
+++ b/sys/man/2/proto
@@ -0,0 +1,131 @@
+.TH PROTO 2
+.SH NAME
+rdproto \- parse and process a proto file listing
+.SH SYNOPSIS
+.nf
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <disk.h>
+.ft
+.PP
+.B
+typedef void Protoenum(char *new, char *old, Dir *d, void *a)
+.PP
+.B
+typedef void Protowarn(char *msg, void *a)
+.PP
+.B
+int rdproto(char *proto, char *root, Protoenum *enm,
+.br
+.B
+ Protowarn *warn, void *a)
+.SH DESCRIPTION
+.I Rdproto
+reads and interprets the named
+.I proto
+file relative to the
+root directory
+.IR root .
+.PP
+Each line of the
+.I proto
+file specifies a file to copy.
+Blank lines and lines beginning with
+.B #
+are ignored.
+Indentation (usually tabs) is significant,
+with each level of indentation corresponding to a level in the file tree.
+Fields within a line are separated by white space.
+The first field is the last path element in the destination file tree.
+The second field specifies the permissions.
+The third field is the owner of the file,
+and the fourth is the group owning the file.
+The fifth field is the name of the file from which to copy;
+this file is read from the current name space,
+not the source file tree.
+All fields except the first are optional.
+Specifying
+.B -
+for permissions, owner, or group
+causes
+.I rdproto
+to fetch the corresponding information
+from the file rather than override it.
+(This is the default behavior when the fields
+are not present; explicitly specifying
+.B -
+is useful when one wishes to set, say,
+the file owner without setting the permissions.)
+.PP
+Names beginning with a
+.L $
+are expanded as environment variables.
+If the first file specified in a directory is
+.LR * ,
+all of the files in that directory are considered listed.
+If the first file is
+.LR + ,
+all of the files are copied, and all subdirectories
+are recursively considered listed.
+All files are considered relative to
+.IR root .
+.PP
+For each file named by the
+.IR proto ,
+.I enm
+is called with
+.I new
+pointing at the name of the file (without the root prefix),
+.I old
+pointing at the name of the source file (with the root prefix,
+when applicable),
+and
+.I Dir
+at the desired directory information for the new file.
+Only the
+.BR name ,
+.BR uid ,
+.BR gid ,
+.BR mode ,
+.BR mtime ,
+and
+.B length
+fields are guaranteed to be valid.
+The argument
+.I a
+is the same argument passed to
+.IR rdproto ;
+typically it points at some extra state
+used by the enumeration function.
+.PP
+When files or directories do not exist or
+cannot be read by
+.IR rdproto ,
+it formats a warning message, calls
+.IR warn ,
+and continues processing;
+if
+.I warn
+is nil,
+.I rdproto
+prints the warning message to standard error.
+.PP
+.I Rdproto
+returns zero
+if
+.I proto
+was processed, \-1 if it could not be opened.
+.SH FILES
+.TF /sys/lib/sysconfig/proto/portproto
+.TP
+.B /sys/lib/sysconfig/proto/
+directory of prototype files.
+.TP
+.B /sys/lib/sysconfig/proto/portproto
+generic prototype file.
+.SH SOURCE
+.B /sys/src/libdisk/proto.c
+.SH SEE ALSO
+.IR mk9660 (8),
+.IR mkfs (8)
diff --git a/sys/man/2/pushssl b/sys/man/2/pushssl
new file mode 100755
index 000000000..efd552943
--- /dev/null
+++ b/sys/man/2/pushssl
@@ -0,0 +1,45 @@
+.TH PUSHSSL 2
+.SH NAME
+pushssl \- attach SSL version 2 encryption to a communication channel
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int pushssl(int fd, char *alg, char *secin, char *secout, int *cfd)
+.SH DESCRIPTION
+.I Pushssl
+opens an
+.IR ssl (3)
+device, connects it to the communications channel
+.IR fd ,
+and starts up encryption and message authentication as specified
+in
+.IR alg .
+The algorithms are separated by a space and either can be first.
+See
+.IR ssl (3)
+for the possible algorithms.
+.I Secin
+and
+.I secout
+contain the encryption keys for the two directions.
+If either is nil, the other is used in both directions.
+If
+.I cfd
+is non-nil, the SSL control channel is opened and its fd
+returned.
+.PP
+.I Pushssl
+returns a file descriptor for the SSL data channel. Anything written to this
+descriptor will get encrypted and authenticated and then written to the
+file descriptor,
+.IR fd .
+.SH SOURCE
+.B /sys/src/libc/9sys
+.SH "SEE ALSO"
+.IR dial (2),
+.IR ssl (3),
+.SH DIAGNOSTICS
+return \-1 on failure.
diff --git a/sys/man/2/pushtls b/sys/man/2/pushtls
new file mode 100755
index 000000000..d9de3717c
--- /dev/null
+++ b/sys/man/2/pushtls
@@ -0,0 +1,254 @@
+.TH PUSHTLS 2
+.SH NAME
+pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, readcert, readcertchain \- attach TLS1 or SSL3 encryption to a communication channel
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+int pushtls(int fd, char *hashalg, char *encalg,
+.B
+ int isclient, char *secret, char *dir)
+.PP
+.nf
+.B #include <mp.h>
+.B #include <libsec.h>
+.PP
+.B
+int tlsClient(int fd, TLSconn *conn)
+.PP
+.B
+int tlsServer(int fd, TLSconn *conn)
+.PP
+.B
+uchar *readcert(char *filename, int *pcertlen)
+.PP
+.B
+PEMchain *readcertchain(char *filename)
+.PP
+.B
+Thumbprint *initThumbprints(char *ok, char *crl)
+.PP
+.B
+void freeThumbprints(Thumbprint *table)
+.PP
+.B
+int okThumbprint(uchar *hash, Thumbprint *table)
+.SH DESCRIPTION
+Transport Layer Security (TLS) comprises a record layer protocol,
+doing message digesting and encrypting in the kernel,
+and a handshake protocol,
+doing initial authentication and secret creation at
+user level and then starting a data channel in the record protocol.
+TLS is nearly the same as SSL 3.0, and the software should interoperate
+with implementations of either standard.
+.PP
+To use just the record layer, as described in
+.IR tls (3),
+call
+.I pushtls
+to open the record layer device, connect to the communications channel
+.IR fd ,
+and start up encryption and message authentication as specified
+in
+.IR hashalg ,
+.IR encalg ,
+and
+.IR secret .
+These parameters must have been arranged at the two ends of the
+conversation by other means.
+For example,
+.I hashalg
+could be
+.BR sha1 ,
+.I encalg
+could be
+.BR rc4_128 ,
+and
+.I secret
+could be the base-64 encoding of two (client-to-server and server-to-client)
+20-byte digest keys and two corresponding 16-byte encryption keys.
+.I Pushtls
+returns a file descriptor for the TLS data channel. Anything written to this
+descriptor will get encrypted and authenticated and then written to the
+file descriptor,
+.IR fd .
+If
+.I dir
+is non-zero, the path name of the connection directory is copied into
+.IR dir .
+This path name is guaranteed to be less than 40 bytes long.
+.SS Certificates
+.\" and other horseshit
+Alternatively, call
+.I tlsClient
+to speak the full handshake protocol,
+negotiate the algorithms and secrets,
+and return a new data file descriptor for the data channel.
+.I Conn
+points to a (caller-allocated) struct:
+.IP
+.EX
+typedef struct TLSconn {
+ char dir[40]; /* OUT connection directory */
+ uchar *cert; /* IN/OUT certificate */
+ uchar *sessionID; /* IN/OUT session ID */
+ int certlen, sessionIDlen;
+ void (*trace)(char*fmt, ...);
+ PEMChain *chain;
+ char *sessionType; /* opt IN session type */
+ uchar *sessionKey; /* opt IN/OUT session key */
+ int sessionKeylen; /* opt IN session key length */
+ char *sessionConst; /* opt IN session constant */
+} TLSconn;
+.EE
+.PP
+defined in
+.IR tls.h .
+On input, the caller can provide options such as
+.IR cert ,
+the local certificate, and
+.IR sessionID ,
+used by a client to resume a previously negotiated security association.
+On output, the connection directory is set, as with
+.B listen
+(see
+.IR dial (2)).
+The input
+.I cert
+is freed and a freshly allocated copy of the remote's certificate
+is returned in
+.IR conn ,
+to be checked by the caller
+according to its needs.
+One way to check the remote certificate is to use
+.I initThumbprints
+and
+.I freeThumbprints
+which allocate and free, respectively, a table of hashes
+from files of known trusted and revoked certificates.
+.I okThumbprint
+confirms that a particular hash is in the table.
+.PP
+.I TlsClient
+will optionally compute a session key for use
+by higher-level protocols.
+To compute a session key, the caller must set
+.I sessionType
+to a known session type;
+.I sessionKeylen
+to the desired key length;
+.I sessionKey
+to a buffer of length
+.IR sessionKeylen ;
+and
+.I sessionConst
+to the desired salting constant.
+The only supported session type is
+.BR ttls ,
+as used by 802.1x.
+.PP
+.I TlsServer
+executes the server side of the handshake.
+The caller must initialize
+.IB conn ->cert \fR,
+usually by calling
+.I readcert
+to read and decode the PEM-encoded certificate from
+.IR filename ,
+return a pointer to
+.IR malloc ed
+storage containing the certificate,
+and store its length through
+.IR pcertlen .
+The private key corresponding to
+.I cert.pem
+should have been previously loaded into factotum.
+(See
+.IR rsa (8)
+for more about key generation.)
+.PP
+.I Readcertchain
+will read a PEM-encoded chain of certificates from
+.I filename
+and return a pointer to a linked list of
+.IR malloc ed
+.B PEMChain
+structures, defined in
+.IR tls.h :
+.IP
+.EX
+typedef struct PEMChain PEMChain;
+struct PEMChain {
+ PEMChain*next;
+ uchar *pem;
+ int pemlen;
+};
+.EE
+.LP
+By setting
+.IP
+.EX
+conn->chain = readcertchain("intermediate-certs.pem");
+.EE
+.LP
+the server can present extra certificate evidence
+to establish the chain of trust to a root authority
+known to the client.
+.PP
+.I Conn
+is not required for the ongoing conversation and may
+be freed by the application whenever convenient.
+.SH EXAMPLES
+Start the client half of TLS and check the remote certificate:
+.IP
+.EX
+uchar hash[SHA1dlen];
+
+conn = (TLSconn*)mallocz(sizeof *conn, 1);
+fd = tlsClient(fd, conn);
+sha1(conn->cert, conn->certlen, hash, nil);
+if(!okThumbprint(hash,table))
+ exits("suspect server");
+\fI...application begins...\fP
+.EE
+.PP
+Run the server side:
+.IP
+.EX
+fd = accept(lcfd, ldir);
+conn = (TLSconn*)mallocz(sizeof *conn, 1);
+conn->cert = readcert("cert.pem", &conn->certlen);
+fd = tlsServer(fd, conn);
+\fI...application begins...\fP
+.EE
+.SH FILES
+.TF /sys/lib/tls
+.TP
+.B /sys/lib/tls
+thumbprints of trusted services
+.TP
+.B /sys/lib/ssl
+PEM certificate files
+.SH SOURCE
+.B /sys/src/libc/9sys/pushtls.c
+.br
+.B /sys/src/libsec/port
+.SH "SEE ALSO"
+.IR dial (2),
+.IR tls (3),
+.IR factotum (4),
+.IR thumbprint (6)
+.SH DIAGNOSTICS
+Return \-1 on failure.
+.SH BUGS
+Client certificates and client sessionIDs are not yet
+implemented.
+.PP
+Note that in the TLS protocol
+.I sessionID
+itself is public; it is used as a pointer to
+secrets stored in
+.IR factotum .
diff --git a/sys/man/2/qball b/sys/man/2/qball
new file mode 100755
index 000000000..95f00561e
--- /dev/null
+++ b/sys/man/2/qball
@@ -0,0 +1,75 @@
+.TH QBALL 2
+.SH NAME
+qball \- 3-d rotation controller
+.SH SYNOPSIS
+.B
+#include <draw.h>
+.br
+.B
+#include <geometry.h>
+.PP
+.B
+void qball(Rectangle r, Mouse *mousep,
+.br
+.B
+ Quaternion *orientation,
+.br
+.B
+ void (*redraw)(void), Quaternion *ap)
+.SH DESCRIPTION
+.I Qball
+is an interactive controller that allows arbitrary 3-space rotations to be specified with
+the mouse. Imagine a sphere with its center at the midpoint of rectangle
+.IR r ,
+and diameter the smaller of
+.IR r 's
+dimensions. Dragging from one point on the sphere to another specifies the endpoints of a
+great-circle arc. (Mouse points outside the sphere are projected to the nearest point
+on the sphere.) The axis of rotation is normal to the plane of the arc, and the
+angle of rotation is twice the angle of the arc.
+.PP
+Argument
+.I mousep
+is a pointer to the mouse event that triggered the interaction. It should
+have some button set.
+.I Qball
+will read more events into
+.IR mousep ,
+and return when no buttons are down.
+.PP
+While
+.I qball
+is reading mouse events, it calls out to the caller-supplied routine
+.IR redraw ,
+which is expected to update the screen to reflect the changing orientation.
+Argument
+.I orientation
+is the orientation that
+.I redraw
+should examine, represented as a unit Quaternion (see
+.IR quaternion(9.2)).
+The caller may set it to any orientation.
+It will be updated before each call to
+.I redraw
+(and on return) by multiplying by the rotation specified with the mouse.
+.PP
+It is possible to restrict
+.I qball's
+attention to rotations about a particular axis.
+If
+.I ap
+is null, the rotation is unconstrained.
+Otherwise, the rotation will be about the same axis as
+.IR *ap .
+This is accomplished by projecting points on the sphere to
+the nearest point also on the plane through the sphere's center
+and normal to the axis.
+.SH SOURCE
+.B /sys/src/libgeometry/qball.c
+.SH SEE ALSO
+.IR quaternion (2)
+.br
+Ken Shoemake,
+``Animating Rotation with Quaternion Curves'',
+.I
+SIGGRAPH '85 Conference Proceedings.
diff --git a/sys/man/2/qsort b/sys/man/2/qsort
new file mode 100755
index 000000000..9f0aedaeb
--- /dev/null
+++ b/sys/man/2/qsort
@@ -0,0 +1,33 @@
+.TH QSORT 2
+.SH NAME
+qsort \- quicker sort
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+.nf
+void qsort(void *base, long nel, long width,
+.B
+ int (*compar)(void*, void*))
+.fi
+.SH DESCRIPTION
+.I Qsort
+(quicker sort)
+sorts an array into nondecreasing order.
+The first argument is a pointer to the base of the data;
+the second is the number of elements;
+the third is the width of an element
+in bytes;
+the last is the name of a comparison routine
+to be called with pointers
+to elements being compared.
+The routine must return
+an integer less than, equal to, or greater than 0
+according as the first argument is to be considered
+less than, equal to, or greater than the second.
+.SH SOURCE
+.B /sys/src/libc/port/qsort.c
+.SH "SEE ALSO"
+.IR sort (1)
diff --git a/sys/man/2/quaternion b/sys/man/2/quaternion
new file mode 100755
index 000000000..3b637b184
--- /dev/null
+++ b/sys/man/2/quaternion
@@ -0,0 +1,151 @@
+.TH QUATERNION 2
+.SH NAME
+qtom, mtoq, qadd, qsub, qneg, qmul, qdiv, qunit, qinv, qlen, slerp, qmid, qsqrt \- Quaternion arithmetic
+.SH SYNOPSIS
+.B
+#include <draw.h>
+.br
+.B
+#include <geometry.h>
+.PP
+.B
+Quaternion qadd(Quaternion q, Quaternion r)
+.PP
+.B
+Quaternion qsub(Quaternion q, Quaternion r)
+.PP
+.B
+Quaternion qneg(Quaternion q)
+.PP
+.B
+Quaternion qmul(Quaternion q, Quaternion r)
+.PP
+.B
+Quaternion qdiv(Quaternion q, Quaternion r)
+.PP
+.B
+Quaternion qinv(Quaternion q)
+.PP
+.B
+double qlen(Quaternion p)
+.PP
+.B
+Quaternion qunit(Quaternion q)
+.PP
+.B
+void qtom(Matrix m, Quaternion q)
+.PP
+.B
+Quaternion mtoq(Matrix mat)
+.PP
+.B
+Quaternion slerp(Quaternion q, Quaternion r, double a)
+.PP
+.B
+Quaternion qmid(Quaternion q, Quaternion r)
+.PP
+.B
+Quaternion qsqrt(Quaternion q)
+.SH DESCRIPTION
+The Quaternions are a non-commutative extension field of the Real numbers, designed
+to do for rotations in 3-space what the complex numbers do for rotations in 2-space.
+Quaternions have a real component
+.I r
+and an imaginary vector component \fIv\fP=(\fIi\fP,\fIj\fP,\fIk\fP).
+Quaternions add componentwise and multiply according to the rule
+(\fIr\fP,\fIv\fP)(\fIs\fP,\fIw\fP)=(\fIrs\fP-\fIv\fP\v'-.3m'.\v'.3m'\fIw\fP, \fIrw\fP+\fIvs\fP+\fIv\fP×\fIw\fP),
+where \v'-.3m'.\v'.3m' and × are the ordinary vector dot and cross products.
+The multiplicative inverse of a non-zero quaternion (\fIr\fP,\fIv\fP)
+is (\fIr\fP,\fI-v\fP)/(\fIr\^\fP\u\s-22\s+2\d-\fIv\fP\v'-.3m'.\v'.3m'\fIv\fP).
+.PP
+The following routines do arithmetic on quaternions, represented as
+.IP
+.EX
+.ta 6n
+typedef struct Quaternion Quaternion;
+struct Quaternion{
+ double r, i, j, k;
+};
+.EE
+.TF qunit
+.TP
+Name
+Description
+.TP
+.B qadd
+Add two quaternions.
+.TP
+.B qsub
+Subtract two quaternions.
+.TP
+.B qneg
+Negate a quaternion.
+.TP
+.B qmul
+Multiply two quaternions.
+.TP
+.B qdiv
+Divide two quaternions.
+.TP
+.B qinv
+Return the multiplicative inverse of a quaternion.
+.TP
+.B qlen
+Return
+.BR sqrt(q.r*q.r+q.i*q.i+q.j*q.j+q.k*q.k) ,
+the length of a quaternion.
+.TP
+.B qunit
+Return a unit quaternion
+.RI ( length=1 )
+with components proportional to
+.IR q 's.
+.PD
+.PP
+A rotation by angle \fIθ\fP about axis
+.I A
+(where
+.I A
+is a unit vector) can be represented by
+the unit quaternion \fIq\fP=(cos \fIθ\fP/2, \fIA\fPsin \fIθ\fP/2).
+The same rotation is represented by \(mi\fIq\fP; a rotation by \(mi\fIθ\fP about \(mi\fIA\fP is the same as a rotation by \fIθ\fP about \fIA\fP.
+The quaternion \fIq\fP transforms points by
+(0,\fIx',y',z'\fP) = \%\fIq\fP\u\s-2-1\s+2\d(0,\fIx,y,z\fP)\fIq\fP.
+Quaternion multiplication composes rotations.
+The orientation of an object in 3-space can be represented by a quaternion
+giving its rotation relative to some `standard' orientation.
+.PP
+The following routines operate on rotations or orientations represented as unit quaternions:
+.TF slerp
+.TP
+.B mtoq
+Convert a rotation matrix (see
+.IR matrix (2))
+to a unit quaternion.
+.TP
+.B qtom
+Convert a unit quaternion to a rotation matrix.
+.TP
+.B slerp
+Spherical lerp. Interpolate between two orientations.
+The rotation that carries
+.I q
+to
+.I r
+is \%\fIq\fP\u\s-2-1\s+2\d\fIr\fP, so
+.B slerp(q, r, t)
+is \fIq\fP(\fIq\fP\u\s-2-1\s+2\d\fIr\fP)\u\s-2\fIt\fP\s+2\d.
+.TP
+.B qmid
+.B slerp(q, r, .5)
+.TP
+.B qsqrt
+The square root of
+.IR q .
+This is just a rotation about the same axis by half the angle.
+.PD
+.SH SOURCE
+.B /sys/src/libgeometry/quaternion.c
+.SH SEE ALSO
+.IR matrix (2),
+.IR qball (2)
diff --git a/sys/man/2/quote b/sys/man/2/quote
new file mode 100755
index 000000000..ee96421a9
--- /dev/null
+++ b/sys/man/2/quote
@@ -0,0 +1,167 @@
+.TH QUOTE 2
+.SH NAME
+quotestrdup, quoterunestrdup, unquotestrdup, unquoterunestrdup, quotestrfmt, quoterunestrfmt, quotefmtinstall, doquote, needsrcquote \- quoted character strings
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+char *quotestrdup(char *s)
+.PP
+.B
+Rune *quoterunestrdup(Rune *s)
+.PP
+.B
+char *unquotestrdup(char *s)
+.PP
+.B
+Rune *unquoterunestrdup(Rune *s)
+.PP
+.B
+int quotestrfmt(Fmt*)
+.PP
+.B
+int quoterunestrfmt(Fmt*)
+.PP
+.B
+void quotefmtinstall(void)
+.PP
+.B
+int (*doquote)(int c)
+.PP
+.B
+int needsrcquote(int c)
+.PP
+.SH DESCRIPTION
+These routines manipulate character strings, either adding or removing
+quotes as necessary.
+In the quoted form, the strings are in the style of
+.IR rc (1) ,
+with single quotes surrounding the string.
+Embedded single quotes are indicated by a doubled single quote.
+For instance,
+.IP
+.EX
+Don't worry!
+.EE
+.PP
+when quoted becomes
+.IP
+.EX
+\&'Don''t worry!'
+.EE
+.PP
+The empty string is represented by two quotes,
+.BR '' .
+.PP
+The first four functions act as variants of
+.B strdup
+(see
+.IR strcat (2)).
+Each returns a
+freshly allocated copy of the string, created using
+.IR malloc (2).
+.I Quotestrdup
+returns a quoted copy of
+.IR s ,
+while
+.I unquotestrdup
+returns a copy of
+.IR s
+with the quotes evaluated.
+The
+.I rune
+versions of these functions do the same for
+.CW Rune
+strings (see
+.IR runestrcat (2)).
+.PP
+The string returned by
+.I quotestrdup
+or
+.I quoterunestrdup
+has the following properties:
+.TP
+1.
+If the original string
+.IR s
+is empty, the returned string is
+.BR '' .
+.TP
+2.
+If
+.I s
+contains no quotes, blanks, or control characters,
+the returned string is identical to
+.IR s .
+.TP
+3.
+If
+.I s
+needs quotes to be added, the first character of the returned
+string will be a quote.
+For example,
+.B hello\ world
+becomes
+.B \&'hello\ world'
+not
+.BR hello'\ 'world .
+.PP
+The function pointer
+.I doquote
+is
+.B nil
+by default.
+If it is non-nil, characters are passed to that function to see if they should
+be quoted.
+This mechanism allows programs to specify that
+characters other than blanks, control characters, or quotes be quoted.
+Regardless of the return value of
+.IR *doquote ,
+blanks, control characters, and quotes are always quoted.
+.I Needsrcquote
+is provided as a
+.I doquote
+function that flags any character special to
+.IR rc (1).
+.PP
+.I Quotestrfmt
+and
+.I quoterunestrfmt
+are
+.IR print (2)
+formatting routines that produce quoted strings as output.
+They may be installed by hand, but
+.I quotefmtinstall
+installs them under the standard format characters
+.B q
+and
+.BR Q .
+(They are not installed automatically.)
+If the format string includes the alternate format character
+.BR # ,
+for example
+.BR %#q ,
+the printed string will always be quoted; otherwise quotes will only be provided if necessary
+to avoid ambiguity.
+In
+.B <libc.h>
+there are
+.B #pragma
+statements so the compiler can type-check uses of
+.B %q
+and
+.B %Q
+in
+.IR print (2)
+format strings.
+.SH SOURCE
+.B /sys/src/libc/port/quote.c
+.br
+.B /sys/src/libc/fmt/fmtquote.c
+.SH "SEE ALSO
+.IR rc (1),
+.IR malloc (2),
+.IR print (2),
+.IR strcat (2)
diff --git a/sys/man/2/rand b/sys/man/2/rand
new file mode 100755
index 000000000..aba8a8b9c
--- /dev/null
+++ b/sys/man/2/rand
@@ -0,0 +1,175 @@
+.TH RAND 2
+.SH NAME
+rand, lrand, frand, nrand, lnrand, srand, truerand, ntruerand, genrandom, prng, fastrand, nfastrand \- random number generators
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLdouble 'u
+.B
+int rand(void)
+.PP
+.B
+long lrand(void)
+.PP
+.B
+double frand(void)
+.PP
+.B
+int nrand(int val)
+.PP
+.B
+long lnrand(long val)
+.PP
+.B
+void srand(long seed)
+.PP
+.B
+ulong truerand(void)
+.PP
+.B
+ulong ntruerand(ulong val)
+.sp
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+void genrandom(uchar *buf, int nbytes)
+.PP
+.B
+void prng(uchar *buf, int nbytes)
+.PP
+.B
+ulong fastrand(void)
+.PP
+.B
+ulong nfastrand(ulong val)
+.SH DESCRIPTION
+.I Rand
+returns a uniform pseudo-random
+number
+.IR x ,
+.RI 0≤ x <2\u\s715\s10\d.
+.PP
+.I Lrand
+returns a uniform
+.B long
+.IR x ,
+.RI 0≤ x <2\u\s731\s10\d.
+.PP
+.I Frand
+returns a uniform
+.B double
+.IR x ,
+.RI 0.0≤ x <1.0,
+This function calls
+.I lrand
+twice to generate a number with as many as 62 significant bits of mantissa.
+.PP
+.I Nrand
+returns a uniform integer
+.IR x ,
+.RI 0≤ x < val.
+.I Lnrand
+is the same, but returns a
+.BR long .
+.PP
+The algorithm is additive feedback with:
+.IP
+x[n] = (x[n\(mi273] + x[n\(mi607]) mod
+.if t 2\u\s731\s0\d
+.if n 2^31
+.LP
+giving a period of
+.if t 2\u\s730\s10\d \(mu (2\u\s7607\s10\d \- 1).
+.if n 2^30 × (2^607 - 1).
+.PP
+The generators are initialized by calling
+.I srand
+with whatever you like as argument.
+To get a different starting value each time,
+.IP
+.L
+srand(time(0))
+.LP
+will work as long as it is not called more often
+than once per second.
+Calling
+.IP
+.L
+srand(1)
+.LP
+will initialize the generators to their
+starting state.
+.PP
+.I Truerand
+returns a random unsigned long read from
+.BR /dev/random .
+Due to the nature of
+.BR /dev/random ,
+truerand can only return a few hundred bits a
+second.
+.PP
+.I Ntruerand
+returns a uniform random integer
+.IR x ,
+.RI 0≤ x < val ≤ 2\u\s732\s10\d-1.
+.PP
+.I Genrandom
+fills a buffer with bytes from the X9.17 pseudo-random
+number generator. The X9.17 generator is seeded by 24
+truly random bytes read from
+.BR /dev/random .
+.PP
+.I Prng
+uses the native
+.IR rand (2)
+pseudo-random number generator to fill the buffer. Used with
+.IR srand ,
+this function can produce a reproducible stream of pseudo random
+numbers useful in testing.
+.PP
+Both
+.I genrandom
+and
+.I prng
+may be passed to
+.I mprand
+(see
+.IR mp (2)).
+.PP
+.I Fastrand
+uses
+.I genrandom
+to return a uniform
+.B "unsigned long
+.IR x ,
+.RI 0≤ x < 2\u\s732\s10\d-1.
+.PP
+.I Nfastrand
+uses
+.I genrandom
+to return a uniform
+.B "unsigned long
+.IR x ,
+.RI 0≤ x < val ≤ 2\u\s732\s10\d-1.
+.SH SOURCE
+.B /sys/src/libc/port/*rand.c
+.br
+.B /sys/src/libc/9sys/truerand.c
+.br
+.B /sys/src/libsec/port/genrandom.c
+.br
+.B /sys/src/libsec/port/prng.c
+.br
+.B /sys/src/libsec/port/*fastrand.c
+.SH "SEE ALSO
+.IR cons (3),
+.IR mp (2)
+.SH BUGS
+.I Truerand
+and
+.I ntruerand
+maintain a static file descriptor.
diff --git a/sys/man/2/rc4 b/sys/man/2/rc4
new file mode 100755
index 000000000..d35b43e4c
--- /dev/null
+++ b/sys/man/2/rc4
@@ -0,0 +1,55 @@
+.TH RC4 2
+.SH NAME
+setupRC4state, rc4, rc4skip, rc4back - alleged rc4 encryption
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.B
+void setupRC4state(RC4state *s, uchar *seed, int slen)
+.PP
+.B
+void rc4(RC4state *s, uchar *data, int dlen)
+.PP
+.B
+void rc4skip(RC4state *s, int nbytes)
+.PP
+.B
+void rc4back(RC4state *s, int nbytes)
+.SH DESCRIPTION
+.PP
+This is an algorithm alleged to be Rivest's RC4 encryption function. It is
+a pseudo-random number generator with a 256 byte state and a long
+cycle. The input buffer is XOR'd with the output of the
+generator both to encrypt and to decrypt. The seed, entered
+using
+.IR setupRC4state ,
+can be any length. The generator can be run forward using
+.IR rc4 ,
+skip over bytes using
+.I rc4skip
+to account lost transmissions,
+or run backwards using
+.I rc4back
+to cover retransmitted data.
+The
+.I RC4state
+structure keeps track of the algorithm.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR mp (2),
+.IR aes (2),
+.IR blowfish (2),
+.IR des (2),
+.IR dsa (2),
+.IR elgamal (2),
+.IR rsa (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2)
diff --git a/sys/man/2/read b/sys/man/2/read
new file mode 100755
index 000000000..1ae092862
--- /dev/null
+++ b/sys/man/2/read
@@ -0,0 +1,96 @@
+.TH READ 2
+.SH NAME
+read, readn, write, pread, pwrite \- read or write file
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+long read(int fd, void *buf, long nbytes)
+.PP
+.B
+long readn(int fd, void *buf, long nbytes)
+.PP
+.B
+long write(int fd, void *buf, long nbytes)
+.PP
+.B
+long pread(int fd, void *buf, long nbytes, vlong offset)
+.PP
+.B
+long pwrite(int fd, void *buf, long nbytes, vlong offset)
+.SH DESCRIPTION
+.I Read
+reads
+.I nbytes
+bytes of data
+from the offset in the file associated with
+.I fd
+into memory at
+.IR buf .
+The offset is advanced by the number of bytes read.
+It is not guaranteed
+that all
+.I nbytes
+bytes will be read; for example
+if the file refers to the console, at most one line
+will be returned.
+In any event the number of bytes read is returned.
+A return value of
+0 is conventionally interpreted as end of file.
+.PP
+.I Readn
+is just like read, but does successive
+.I read
+calls until
+.I nbytes
+have been read, or a read system call
+returns a non-positive count.
+.PP
+.I Write
+writes
+.I nbytes
+bytes of data starting at
+.I buf
+to the file associated with
+.I fd
+at the file offset.
+The offset is advanced by the number of bytes written.
+The number of characters actually written is returned.
+It should be regarded as an error
+if this is not the same as requested.
+.PP
+.I Pread
+and
+.I Pwrite
+are equivalent to a
+.IR seek (2)
+to
+.I offset
+followed by a
+.I read
+or
+.IR write .
+By combining the operations in a single atomic call, they more closely
+match the 9P protocol
+(see
+.IR intro (5))
+and, more important,
+permit multiprocess programs to execute multiple concurrent
+read and write operations on the same file descriptor
+without interference.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.br
+.B /sys/src/libc/port/readn.c
+.SH SEE ALSO
+.IR intro (2),
+.IR dirread (2),
+.IR dup (2),
+.IR open (2),
+.IR pipe (2),
+.IR readv (2)
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
diff --git a/sys/man/2/readcolmap b/sys/man/2/readcolmap
new file mode 100755
index 000000000..5ea74cb33
--- /dev/null
+++ b/sys/man/2/readcolmap
@@ -0,0 +1,76 @@
+.TH READCOLMAP 2
+.SH NAME
+RGB, readcolmap, writecolmap \- access display color map
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <draw.h>
+.PP
+.PP
+.ta \w'\fLvoid 'u
+.PP
+.B
+int readcolmap(Display *d, RGB *map)
+.PP
+.B
+int writecolmap(Display *d, RGB *map)
+.fi
+.SH DESCRIPTION
+Colors are described by their red, green, and blue
+light intensities, in an
+.B RGB
+datum:
+.IP
+.EX
+.ta 6n
+typedef
+struct RGB {
+ ulong red;
+ ulong green;
+ ulong blue;
+} RGB;
+.EE
+.PP
+Black is represented by zero in all three positions and
+white has the maximum
+.B unsigned
+.B long
+value in all three positions.
+.PP
+A color map is an array of
+.BR RGB s,
+of length
+.if t \x'-.8n'2\u\s-1\fIdepth\fP\s+1\d,
+.if n 2^\fIdepth\fP,
+giving the colors for pixels 0, 1, 2, etc.
+On displays with color mapped pixels
+(typically 8-bit displays),
+one retrieves RGB color information
+by treating the pixel data as an offset
+into the color map.
+.PP
+.I Readcolmap
+reads the color map for the given display into the provided
+.IR map ,
+which must have enough space to hold it.
+.I Writecolmap
+associates the given color map with the given display, if possible.
+(The hardware might not allow this.)
+Both return 0 on success, or \-1 on error, setting
+.IR errstr .
+.PP
+Changing the hardware color map does not change
+the color map used by the
+.IR draw (2)
+operator to convert between
+mapped and true color or greyscale images,
+which is described in
+.IR color (6).
+.SH SOURCE
+.B /sys/src/libdraw
+.SH "SEE ALSO"
+.IR graphics (2),
+.IR draw (3),
+.IR color (6)
diff --git a/sys/man/2/readv b/sys/man/2/readv
new file mode 100755
index 000000000..31dcb8842
--- /dev/null
+++ b/sys/man/2/readv
@@ -0,0 +1,82 @@
+.TH READV 2
+.SH NAME
+readv, writev, preadv, pwritev \- scatter/gather read and write
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.ft L
+typedef
+struct IOchunk
+{
+ void *addr;
+ ulong len;
+} IOchunk;
+.fi
+.PP
+.B
+long readv(int fd, IOchunk *io, int nio)
+.PP
+.B
+long preadv(int fd, IOchunk *io, int nio, vlong off)
+.PP
+.B
+long writev(int fd, IOchunk *io, int nio)
+.PP
+.B
+long pwritev(int fd, IOchunk *io, int nio, vlong off)
+.SH DESCRIPTION
+These functions supplement the standard read and write operations of
+.IR read (2)
+with facilities for scatter/gather I/O.
+The set of I/O buffers is collected into an array of
+.B IOchunk
+structures passed as an argument.
+.PP
+.I Readv
+reads data from
+.I fd
+and returns the total number of bytes received.
+The received data is stored in the successive
+.I nio
+elements of the
+.B IOchunk
+array, storing
+.IB io [0].len
+bytes at
+.IB io [0].addr\f1,
+the next
+.IB io [1].len
+at
+.IB io [1].addr\f1,
+and so on.
+.I Preadv
+does the same, but implicitly seeks to I/O offset
+.I off
+by analogy with
+.IR readv .
+.PP
+.I Writev
+and
+.I pwritev
+are the analogous write routines.
+.SH SOURCE
+.B /sys/src/libc/9sys/readv.c
+.br
+.B /sys/src/libc/9sys/writev.c
+.SH SEE ALSO
+.IR intro (2),
+.IR read (2)
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
+.SH BUGS
+The implementations use
+.IR malloc (2)
+to build a single buffer for a standard call to
+.B read
+or
+.BR write .
+They are placeholders for possible future system calls.
diff --git a/sys/man/2/regexp b/sys/man/2/regexp
new file mode 100755
index 000000000..6558dc710
--- /dev/null
+++ b/sys/man/2/regexp
@@ -0,0 +1,212 @@
+.TH REGEXP 2
+.SH NAME
+regcomp, regcomplit, regcompnl, regexec, regsub, rregexec, rregsub, regerror \- regular expression
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <regexp.h>
+.PP
+.ta \w'\fLRegprog 'u
+.B
+Reprog *regcomp(char *exp)
+.PP
+.B
+Reprog *regcomplit(char *exp)
+.PP
+.B
+Reprog *regcompnl(char *exp)
+.PP
+.nf
+.B
+int regexec(Reprog *prog, char *string, Resub *match, int msize)
+.PP
+.nf
+.B
+void regsub(char *source, char *dest, int dlen, Resub *match, int msize)
+.PP
+.nf
+.B
+int rregexec(Reprog *prog, Rune *string, Resub *match, int msize)
+.PP
+.nf
+.B
+void rregsub(Rune *source, Rune *dest, int dlen, Resub *match, int msize)
+.PP
+.B
+void regerror(char *msg)
+.SH DESCRIPTION
+.I Regcomp
+compiles a
+regular expression and returns
+a pointer to the generated description.
+The space is allocated by
+.IR malloc (2)
+and may be released by
+.IR free .
+Regular expressions are exactly as in
+.IR regexp (6).
+.PP
+.I Regcomplit
+is like
+.I regcomp
+except that all characters are treated literally.
+.I Regcompnl
+is like
+.I regcomp
+except that the
+.B .
+metacharacter matches all characters, including newlines.
+.PP
+.I Regexec
+matches a null-terminated
+.I string
+against the compiled regular expression in
+.IR prog .
+If it matches,
+.I regexec
+returns
+.B 1
+and fills in the array
+.I match
+with character pointers to the substrings of
+.I string
+that correspond to the
+parenthesized subexpressions of
+.IR exp :
+.BI match[ i ].sp
+points to the beginning and
+.BI match[ i ].ep
+points just beyond
+the end of the
+.IR i th
+substring.
+(Subexpression
+.I i
+begins at the
+.IR i th
+left parenthesis, counting from 1.)
+Pointers in
+.B match[0]
+pick out the substring that corresponds to
+the whole regular expression.
+Unused elements of
+.I match
+are filled with zeros.
+Matches involving
+.LR * ,
+.LR + ,
+and
+.L ?
+are extended as far as possible.
+The number of array elements in
+.I match
+is given by
+.IR msize .
+The structure of elements of
+.I match
+is:
+.IP
+.EX
+typedef struct {
+ union {
+ char *sp;
+ Rune *rsp;
+ };
+ union {
+ char *ep;
+ Rune *rep;
+ };
+} Resub;
+.EE
+.LP
+If
+.B match[0].sp
+is nonzero on entry,
+.I regexec
+starts matching at that point within
+.IR string .
+If
+.B match[0].ep
+is nonzero on entry,
+the last character matched is the one
+preceding that point.
+.PP
+.I Regsub
+places in
+.I dest
+a substitution instance of
+.I source
+in the context of the last
+.I regexec
+performed using
+.IR match .
+Each instance of
+.BI \e n\f1,
+where
+.I n
+is a digit, is replaced by the
+string delimited by
+.BI match[ n ].sp
+and
+.BI match[ n ].ep\f1.
+Each instance of
+.L &
+is replaced by the string delimited by
+.B match[0].sp
+and
+.BR match[0].ep .
+The substitution will always be null terminated and
+trimmed to fit into dlen bytes.
+.PP
+.IR Regerror ,
+called whenever an error is detected in
+.IR regcomp ,
+writes the string
+.I msg
+on the standard error file and exits.
+.I Regerror
+can be replaced to perform
+special error processing.
+If the user supplied
+.I regerror
+returns rather than exits,
+.I regcomp
+will return 0.
+.PP
+.I Rregexec
+and
+.I rregsub
+are variants of
+.I regexec
+and
+.I regsub
+that use strings of
+.B Runes
+instead of strings of
+.BR chars .
+With these routines, the
+.I rsp
+and
+.I rep
+fields of the
+.I match
+array elements should be used.
+.SH SOURCE
+.B /sys/src/libregexp
+.SH "SEE ALSO"
+.IR grep (1)
+.SH DIAGNOSTICS
+.I Regcomp
+returns
+.B 0
+for an illegal expression
+or other failure.
+.I Regexec
+returns 0
+if
+.I string
+is not matched.
+.SH BUGS
+There is no way to specify or match a NUL character; NULs terminate patterns and strings.
diff --git a/sys/man/2/remove b/sys/man/2/remove
new file mode 100755
index 000000000..7547e46a7
--- /dev/null
+++ b/sys/man/2/remove
@@ -0,0 +1,31 @@
+.TH REMOVE 2
+.SH NAME
+remove \- remove a file
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int remove(char *file)
+.SH DESCRIPTION
+.I Remove
+removes
+.I file
+from the directory containing it and discards the contents of the file.
+The user must have write permission in the containing directory.
+If
+.I file
+is a directory, it must be empty.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2),
+.IR remove (5),
+the description of
+.B ORCLOSE
+in
+.IR open (2).
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/rendezvous b/sys/man/2/rendezvous
new file mode 100755
index 000000000..1bba3fc90
--- /dev/null
+++ b/sys/man/2/rendezvous
@@ -0,0 +1,58 @@
+.TH RENDEZVOUS 2
+.SH NAME
+rendezvous \- user level process synchronization
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+void* rendezvous(void* tag, void* value)
+.SH DESCRIPTION
+The rendezvous system call allows two processes to synchronize and
+exchange a value.
+In conjunction with the shared memory system calls
+(see
+.IR segattach (2)
+and
+.IR fork (2)),
+it enables parallel programs to control their scheduling.
+.PP
+Two processes wishing to synchronize call
+.I rendezvous
+with a common
+.IR tag ,
+typically an address in
+memory they share.
+One process will arrive at the rendezvous first;
+it suspends execution until a second arrives.
+When a second process meets the rendezvous
+the
+.I value
+arguments are exchanged between the processes and returned
+as the result of the respective
+.I rendezvous
+system calls.
+Both processes are awakened when
+the rendezvous succeeds.
+.PP
+The set of tag values which two processes may use to rendezvous\(emtheir tag space\(emis
+inherited when a process forks, unless
+.B RFREND
+is set in the argument to
+.BR rfork ;
+see
+.IR fork (2).
+.PP
+If a rendezvous is interrupted the return value is
+.BR ~0 ,
+so that value should not be used in normal communication.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR fork (2),
+.IR lock (2),
+.IR segattach (2)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/rsa b/sys/man/2/rsa
new file mode 100755
index 000000000..957ac05c2
--- /dev/null
+++ b/sys/man/2/rsa
@@ -0,0 +1,219 @@
+.TH RSA 2
+.SH NAME
+asn1dump,
+asn1toRSApriv,
+decodePEM,
+rsadecrypt,
+rsaencrypt,
+rsagen,
+rsaprivalloc,
+rsaprivfree,
+rsaprivtopub,
+rsapuballoc,
+rsapubfree,
+X509toRSApub,
+X509gen,
+X509verify \- RSA encryption algorithm
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <mp.h>
+.br
+.B #include <libsec.h>
+.PP
+.ta +\w'\fLRSApriv* \fP'u
+.B
+RSApriv* rsagen(int nlen, int elen, int nrep)
+.PP
+.B
+mpint* rsaencrypt(RSApub *k, mpint *in, mpint *out)
+.PP
+.B
+mpint* rsadecrypt(RSApriv *k, mpint *in, mpint *out)
+.PP
+.B
+RSApub* rsapuballoc(void)
+.PP
+.B
+void rsapubfree(RSApub*)
+.PP
+.B
+RSApriv* rsaprivalloc(void)
+.PP
+.B
+void rsaprivfree(RSApriv*)
+.PP
+.B
+RSApub* rsaprivtopub(RSApriv*)
+.PP
+.B
+RSApub* X509toRSApub(uchar *cert, int ncert, char *name, int nname)
+.PP
+.B
+RSApriv* asn1toRSApriv(uchar *priv, int npriv)
+.PP
+.B
+void asn1dump(uchar *der, int len)
+.PP
+.B
+uchar* decodePEM(char *s, char *type, int *len, char **new_s)
+.PP
+.B
+uchar* X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
+.PP
+.B
+uchar* X509req(RSApriv *priv, char *subj, int *certlen);
+.PP
+.B
+char* X509verify(uchar *cert, int ncert, RSApub *pk)
+.DT
+.SH DESCRIPTION
+RSA is a public key encryption algorithm. The owner of a key publishes
+the public part of the key:
+.IP
+.EX
+struct RSApub
+{
+ mpint *n; /* modulus */
+ mpint *ek; /* exp (encryption key) */
+};
+.EE
+.LP
+This part can be used for encrypting data (with
+.IR rsaencrypt )
+to be sent to the owner.
+The owner decrypts (with
+.IR rsadecrypt )
+using his private key:
+.IP
+.EX
+struct RSApriv
+{
+ RSApub pub;
+ mpint *dk; /* exp (decryption key) */
+
+ /* precomputed crt values */
+ mpint *p;
+ mpint *q;
+ mpint *kp; /* k mod p-1 */
+ mpint *kq; /* k mod q-1 */
+ mpint *c2; /* for converting residues to number */
+};
+.EE
+.PP
+Keys are generated using
+.IR rsagen .
+.I Rsagen
+takes both bit length of the modulus, the bit length of the
+public key exponent, and the number of repetitions of the Miller-Rabin
+primality test to run. If the latter is 0, it does the default number
+of rounds.
+.I Rsagen
+returns a newly allocated structure containing both
+public and private keys.
+.I Rsaprivtopub
+returns a newly allocated copy of the public key
+corresponding to the private key.
+.PP
+The routines
+.IR rsaalloc ,
+.IR rsafree ,
+.IR rsapuballoc ,
+.IR rsapubfree ,
+.IR rsaprivalloc ,
+and
+.I rsaprivfree
+are provided to aid in user provided key I/O.
+.PP
+Given a binary X.509
+.IR cert ,
+the routine
+.I X509toRSApub
+returns the public key and, if
+.I name
+is not nil, the CN part of the Distinguished Name of the
+certificate's Subject.
+(This is conventionally a userid or a host DNS name.)
+No verification is done of the certificate signature; the
+caller should check the fingerprint,
+.IR sha1(cert) ,
+against a table or check the certificate by other means.
+X.509 certificates are often stored in PEM format; use
+.I dec64
+to convert to binary before computing the fingerprint or calling
+.IR X509toRSApub .
+For the special case of
+certificates signed by a known trusted key
+(in a single step, without certificate chains),
+.I X509verify
+checks the signature on
+.IR cert .
+It returns nil if successful, else an error string.
+.PP
+.I X509gen
+creates a self-signed X.509 certificate, given an RSA keypair
+.IR priv ,
+a issuer/subject string
+.IR subj ,
+and the starting and ending validity dates,
+.IR valid .
+Length of the allocated binary certificate is stored in
+.IR certlen .
+The subject line is conventionally of the form
+.IP
+.EX
+C=US ST=NJ L=07922 O=Lucent OU='Bell Labs' CN=Eric
+.EE
+.LP
+using the quoting conventions of
+.I tokenize
+in
+.IR getfields (2).
+.PP
+.I Asn1toRSApriv
+converts an ASN1 formatted RSA private key into the corresponding
+.B RSApriv
+structure.
+.PP
+.I Asn1dump
+prints an ASN1 object to standard output.
+.PP
+.I DecodePEM
+takes a zero terminated string,
+.IR s ,
+and decodes the PEM (privacy-enhanced mail) formatted section for
+.I type
+within it.
+If successful, it returns
+.IR malloc ed
+storage containing the decoded section,
+which the caller must free,
+and sets
+.BI * len
+to its decoded length.
+Otherwise
+.B nil
+is returned and
+.BI * len
+is undefined.
+If not nil,
+.I new_s
+is set to the first character beyond the
+.I type
+section.
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR mp (2),
+.IR aes (2),
+.IR blowfish (2),
+.IR des (2),
+.IR dsa (2),
+.IR elgamal (2),
+.IR rc4 (2),
+.IR sechash (2),
+.IR prime (2),
+.IR rand (2),
+.IR rsa (8)
diff --git a/sys/man/2/rune b/sys/man/2/rune
new file mode 100755
index 000000000..ca290115d
--- /dev/null
+++ b/sys/man/2/rune
@@ -0,0 +1,193 @@
+.TH RUNE 2
+.SH NAME
+runetochar, chartorune, runelen, runenlen, fullrune, utfecpy, utflen, utfnlen, utfrune, utfrrune, utfutf \- rune/UTF conversion
+.SH SYNOPSIS
+.ta \w'\fLchar*xx'u
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int runetochar(char *s, Rune *r)
+.PP
+.B
+int chartorune(Rune *r, char *s)
+.PP
+.B
+int runelen(long r)
+.PP
+.B
+int runenlen(Rune *r, int n)
+.PP
+.B
+int fullrune(char *s, int n)
+.PP
+.B
+char* utfecpy(char *s1, char *es1, char *s2)
+.PP
+.B
+int utflen(char *s)
+.PP
+.B
+int utfnlen(char *s, long n)
+.PP
+.B
+char* utfrune(char *s, long c)
+.PP
+.B
+char* utfrrune(char *s, long c)
+.PP
+.B
+char* utfutf(char *s1, char *s2)
+.SH DESCRIPTION
+These routines convert to and from a
+.SM UTF
+byte stream and runes.
+.PP
+.I Runetochar
+copies one rune at
+.I r
+to at most
+.B UTFmax
+bytes starting at
+.I s
+and returns the number of bytes copied.
+.BR UTFmax ,
+defined as
+.B 3
+in
+.BR <libc.h> ,
+is the maximum number of bytes required to represent a rune.
+.PP
+.I Chartorune
+copies at most
+.B UTFmax
+bytes starting at
+.I s
+to one rune at
+.I r
+and returns the number of bytes copied.
+If the input is not exactly in
+.SM UTF
+format,
+.I chartorune
+will convert to
+.B Runeerror
+(0xFFFD)
+and return 1.
+.PP
+.I Runelen
+returns the number of bytes
+required to convert
+.I r
+into
+.SM UTF.
+.PP
+.I Runenlen
+returns the number of bytes
+required to convert the
+.I n
+runes pointed to by
+.I r
+into
+.SM UTF.
+.PP
+.I Fullrune
+returns 1 if the string
+.I s
+of length
+.I n
+is long enough to be decoded by
+.I chartorune
+and 0 otherwise.
+This does not guarantee that the string
+contains a legal
+.SM UTF
+encoding.
+This routine is used by programs that
+obtain input a byte at
+a time and need to know when a full rune
+has arrived.
+.PP
+The following routines are analogous to the
+corresponding string routines with
+.B utf
+substituted for
+.B str
+and
+.B rune
+substituted for
+.BR chr .
+.PP
+.I Utfecpy
+copies UTF sequences until a null sequence has been copied, but writes no
+sequences beyond
+.IR es1 .
+If any sequences are copied,
+.I s1
+is terminated by a null sequence, and a pointer to that sequence is returned.
+Otherwise, the original
+.I s1
+is returned.
+.PP
+.I Utflen
+returns the number of runes that
+are represented by the
+.SM UTF
+string
+.IR s .
+.PP
+.I Utfnlen
+returns the number of complete runes that
+are represented by the first
+.I n
+bytes of
+.SM UTF
+string
+.IR s .
+If the last few bytes of the string contain an incompletely coded rune,
+.I utfnlen
+will not count them; in this way, it differs from
+.IR utflen ,
+which includes every byte of the string.
+.PP
+.I Utfrune
+.RI ( utfrrune )
+returns a pointer to the first (last)
+occurrence of rune
+.I c
+in the
+.SM UTF
+string
+.IR s ,
+or 0 if
+.I c
+does not occur in the string.
+The NUL byte terminating a string is considered to
+be part of the string
+.IR s .
+.PP
+.I Utfutf
+returns a pointer to the first occurrence of
+the
+.SM UTF
+string
+.I s2
+as a
+.SM UTF
+substring of
+.IR s1 ,
+or 0 if there is none.
+If
+.I s2
+is the null string,
+.I utfutf
+returns
+.IR s1 .
+.SH SOURCE
+.B /sys/src/libc/port/rune.c
+.br
+.B /sys/src/libc/port/utfrune.c
+.SH SEE ALSO
+.IR utf (6),
+.IR tcs (1)
diff --git a/sys/man/2/runestrcat b/sys/man/2/runestrcat
new file mode 100755
index 000000000..043de093d
--- /dev/null
+++ b/sys/man/2/runestrcat
@@ -0,0 +1,67 @@
+.TH RUNESTRCAT 2
+.SH NAME
+runestrcat,
+runestrncat,
+runestrcmp,
+runestrncmp,
+runestrcpy,
+runestrncpy,
+runestrecpy,
+runestrlen,
+runestrchr,
+runestrrchr,
+runestrdup,
+runestrstr \- rune string operations
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLRune* \fP'u
+.B
+Rune* runestrcat(Rune *s1, Rune *s2)
+.PP
+.B
+Rune* runestrncat(Rune *s1, Rune *s2, long n)
+.PP
+.B
+int runestrcmp(Rune *s1, Rune *s2)
+.PP
+.B
+int runestrncmp(Rune *s1, Rune *s2, long n)
+.PP
+.B
+Rune* runestrcpy(Rune *s1, Rune *s2)
+.PP
+.B
+Rune* runestrncpy(Rune *s1, Rune *s2, long n)
+.PP
+.B
+Rune* runestrecpy(Rune *s1, Rune *es1, Rune *s2)
+.PP
+.B
+long runestrlen(Rune *s)
+.PP
+.B
+Rune* runestrchr(Rune *s, Rune c)
+.PP
+.B
+Rune* runestrrchr(Rune *s, Rune c)
+.PP
+.B
+Rune* runestrdup(Rune *s)
+.PP
+.B
+Rune* runestrstr(Rune *s1, Rune *s2)
+.SH DESCRIPTION
+These functions are rune string analogues of
+the corresponding functions in
+.IR strcat (2).
+.SH SOURCE
+.B /sys/src/libc/port
+.SH SEE ALSO
+.IR memory (2),
+.IR rune (2),
+.IR strcat (2)
+.SH BUGS
+The outcome of overlapping moves varies among implementations.
diff --git a/sys/man/2/scribble b/sys/man/2/scribble
new file mode 100755
index 000000000..6f394add5
--- /dev/null
+++ b/sys/man/2/scribble
@@ -0,0 +1,162 @@
+.TH SCRIBBLE 2
+.SH NAME
+scribblealloc,
+recognize \- character recognition
+.SH SYNOPSIS
+.PP
+.EX
+.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <scribble.h>
+
+Scribble *scribblealloc(void);
+Rune recognize(Scribble *);
+.EE
+.SH DESCRIPTION
+.PP
+The scribble library implements simple character recognition.
+All characters are drawn using a single stroke of the pen (mouse button 1)
+as on a palmtop computer.
+A reference card is in
+.BR /sys/src/libscribble/quickref.gif .
+.PP
+The library is not really intended for standalone use. Its primary
+use is by the scribble graphical control (see
+.IR control (2)).
+.PP
+.B Scribblealloc
+allocates and returns an appropriately initialized
+.B Scribble
+structure:
+.IP
+.EX
+.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n
+#define CS_LETTERS 0
+#define CS_DIGITS 1
+#define CS_PUNCTUATION 2
+
+struct Scribble {
+ /* private state */
+ Point *pt;
+ int ppasize;
+ Stroke ps;
+ Graffiti *graf;
+ int capsLock;
+ int puncShift;
+ int tmpShift;
+ int ctrlShift;
+ int curCharSet;
+};
+.EE
+.PP
+This structure encodes the points making up the stroke
+to be recognized, as well as the \f2character group\fP in which
+the stroke should be searched.
+.PP
+There are three such groups:
+.IR letters ,
+.IR digits ,
+and
+.IR punctuation .
+The current group is encoded in the
+.B curCharSet
+field of the
+.B Scribble
+structure.
+Special strokes are recognized to switch between groups.
+In addition, the charater recognized is influenced by
+.I mode
+parameters and modifies them.
+These are identified by the
+.BR capsLock ,
+.BR puncShift ,
+.BR tmpShift ,
+and
+.B ctrlShift
+fields of the
+.B Scribble
+structure.
+When
+.B puncShift
+is non-zero, the character is recognized in the punctuation
+character set.
+Similarly,
+when the character recognized is printable and
+.B ctrlShift
+is set, the associated control character is returned as if the
+control key were depressed,
+and when the character is a letter and
+.B capsLock
+or
+.B tmpShift
+is set, the upper-case version is returned.
+The
+.B puncShift
+and
+.B tmpShift
+flags are turned off
+once a character has been recognized; the others are left set.
+.PP
+The character to be recognized is encoded as an array of pen_points in the
+.B ps
+field.
+To allow easy drawing of the stroke as it is drawn,
+the
+.I pt
+and
+.I ppasize
+fields are available to the application code for storing an array
+of points for a call to
+.B poly
+(see
+.IR draw (2)).
+.PP
+.I Recognize
+recognizes the character provided in the
+.B ps
+field of the
+.B Scribble
+structure; it
+returns the rune or zero if nothing was recognized.
+.SH FILES
+.B /sys/src/libscribble/quickref.gif
+serves as a quick reference card.
+.PP
+.B /sys/lib/scribble/classifiers
+contains the stroke definitions.
+.SH SOURCE
+.B /sys/src/libscribble
+.PP
+This library is adapted from software reproduced by permission:
+.PP
+.B Graffiti.c
+is based on the file
+.B Scribble.c
+copyrighted
+by Keith Packard:
+.IP
+Copyright © 1999 Keith Packard
+.PP
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Keith Packard not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. Keith Packard makes no
+representations about the suitability of this software for any purpose. It
+is provided "as is" without express or implied warranty.
+.PP
+Portions of the software Copyright © 1994 by Sun Microsystems Computer Company.
+.PP
+Portions of the software Copyright © 2000 by Compaq Computer Corporation.
+.SH SEE ALSO
+.B Keyboard
+and
+.B prompter
+in
+.IR bitsyload (1),
+.IR draw (2),
+.IR control (2)
diff --git a/sys/man/2/scsi b/sys/man/2/scsi
new file mode 100755
index 000000000..280ba5f57
--- /dev/null
+++ b/sys/man/2/scsi
@@ -0,0 +1,186 @@
+.TH SCSI 2
+.SH NAME
+openscsi, closescsi, scsiready, scsi, scsicmd, scsierror \- SCSI device operations
+.SH SYNOPSIS
+.nf
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <disk.h>
+.ft
+.PP
+.ft L
+typedef struct Scsi {
+ char *inquire;
+ int rawfd;
+ int nchange;
+ ulong changetime;
+};
+.ft
+.PP
+.B
+Scsi* openscsi(char *devdir)
+.PP
+.B
+void closescsi(Scsi *s)
+.PP
+.B
+int scsiready(Scsi *s)
+.PP
+.ft L
+int scsi(Scsi *s, uchar *cmd, int ncmd,
+.br
+ void *data, int ndata, int dir)
+.PP
+.ft L
+int scsicmd(Scsi *s, uchar *cmd, int ncmd,
+.br
+ void *data, int ndata, int dir)
+.PP
+.B
+char* scsierror(int asc, int ascq)
+.PP
+.B
+int scsiverbose;
+.SH DESCRIPTION
+These routines provide an interface
+to a SCSI or ATAPI device via
+.IR sd (3).
+.PP
+.I Openscsi
+attempts to open the file
+.IB devdir /raw
+and use it to send raw SCSI commands.
+On success, it reads the device's inquiry
+string and stores it in
+.I inquire
+in the returned
+.B Scsi
+structure.
+.I Closescsi
+closes the connection and frees the
+.B Scsi
+structure.
+.PP
+.I Scsiready
+sends the ``unit ready'' command up to three times,
+returning zero if the unit responds that it is ready,
+or \-1 on error.
+.PP
+.I Scsierror
+returns a textual description of the SCSI status
+denoted by the ASC and ASCQ sense codes.
+The description is found by consulting
+.BR /sys/lib/scsicodes .
+The returned string will be overwritten by
+the next call to
+.IR scsierror .
+.PP
+.I Scsi
+and
+.I scsicmd
+execute a single SCSI command on the named device.
+There should be
+.I ncmd
+bytes of
+command data in
+.IR cmd ;
+if
+.I dir
+is
+.BR Sread ,
+a successful operation
+will store up to
+.I ndata
+bytes into
+.IR data ,
+returning the number of bytes stored.
+If
+.I dir
+is
+.BR Swrite ,
+the
+.I ndata
+bytes beginning at
+.I data
+are transmitted as the data argument to
+the command, and the
+number of bytes written is returned.
+If
+.I dir
+is
+.BR Snone ,
+.I data
+and
+.I ndata
+are ignored.
+On error,
+.I scsi
+and
+.I scsicmd
+return \-1.
+.I Scsicmd
+simply issues the command and
+returns the result;
+.I scsi
+works a bit harder and
+is the more commonly used routine.
+.I Scsi
+attempts to send the command;
+if it is successful,
+.I scsi
+returns what
+.I scsicmd
+returned.
+Otherwise,
+.I scsi
+sends a request sense command to
+obtain the reason for the failure,
+sends a unit ready command in
+an attempt to bring the unit out of any
+inconsistent states, and tries again.
+If the second try fails,
+.I scsi
+sends the request
+sense and unit ready commands
+again
+and then uses
+.I scsierror
+to set
+.I errstr
+with a reason for failure.
+.PP
+The
+.B nchange
+and
+.B changetime
+fields
+in the
+.B Scsi
+structure
+record the number of times a media
+change has been detected, and the
+time when the current media was
+inserted into the drive (really the
+first time a SCSI command was issued
+after it was inserted).
+They are maintained by
+.IR scsi .
+.PP
+If
+.I scsiverbose
+is set,
+these commands will produce a fair
+amount of debugging output on file descriptor 2
+when SCSI commands fail.
+.SH FILES
+.TP
+.B /sys/lib/scsicodes
+List of textual messages corresponding to SCSI error codes;
+consulted by
+.BR scsierror .
+.SH SOURCE
+.B /sys/src/libdisk/scsi.c
+.SH SEE ALSO
+.IR sd (3),
+.IR scuzz (8)
diff --git a/sys/man/2/sechash b/sys/man/2/sechash
new file mode 100755
index 000000000..7524881f8
--- /dev/null
+++ b/sys/man/2/sechash
@@ -0,0 +1,203 @@
+.TH SECHASH 2
+.SH NAME
+md4, md5,
+sha1, sha2_224, sha2_256, sha2_384, sha2_512,
+aes, hmac_x, hmac_md5,
+hmac_sha1, hmac_sha2_224, hmac_sha2_256, hmac_sha2_384, hmac_sha2_512,
+hmac_aes, md5pickle, md5unpickle,
+sha1pickle, sha1unpickle \- cryptographically secure hashes
+.SH SYNOPSIS
+.nr Wd \w'\fLDS* \fP'u
+.nr In \w'\fLDS* \fP'u
+.ta \n(Wdu \w'\fLSHA1state* \fP'u +\n(Wdu +\n(Wdu +\n(Wdu +\n(Wdu
+.
+.de Ti
+.PP
+.in +\\n(Inu
+.ti -\\n(Inu
+.B
+.nh
+..
+.
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <mp.h>
+#include <libsec.h>
+#define DS DigestState /* only to abbreviate SYNOPSIS */
+.fi
+.
+.Ti
+DS* md4(uchar *data, ulong dlen, uchar *digest, DS *state)
+.Ti
+DS* md5(uchar *data, ulong dlen, uchar *digest, DS *state)
+.PP
+.B
+char* md5pickle(MD5state *state)
+.PP
+.B
+MD5state* md5unpickle(char *p);
+.Ti
+DS* sha1(uchar *data, ulong dlen, uchar *digest, DS *state)
+.PP
+.B
+char* sha1pickle(SHA1state *state)
+.PP
+.B
+SHA1state* sha1unpickle(char *p);
+.Ti
+DS* sha2_224(uchar *data, ulong dlen, uchar *digest, DS *state)
+.Ti
+DS* sha2_256(uchar *data, ulong dlen, uchar *digest, DS *state)
+.Ti
+DS* sha2_384(uchar *data, ulong dlen, uchar *digest, DS *state)
+.Ti
+DS* sha2_512(uchar *data, ulong dlen, uchar *digest, DS *state)
+.Ti
+DS* aes(uchar *data, ulong dlen, uchar *digest, DS *state)
+.Ti
+DS* hmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DS *s, DS*(*x)(uchar*, ulong, uchar*, DS*), int xlen)
+.Ti
+DS* hmac_md5(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.Ti
+DS* hmac_sha1(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.Ti
+DS* hmac_sha2_224(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.Ti
+DS* hmac_sha2_256(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.Ti
+DS* hmac_sha2_384(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.Ti
+DS* hmac_sha2_512(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.Ti
+DS* hmac_aes(uchar *data, ulong dlen, uchar *key, ulong klen, uchar *digest, DS *state)
+.SH DESCRIPTION
+.DT
+We support several secure hash functions. The output of a
+hash is called a
+.IR digest .
+A hash is secure if, given the hashed data and the digest,
+it is difficult to predict the change to the digest resulting
+from some change to the data without rehashing
+the whole data. Therefore, if a secret is part of the hashed
+data, the digest can be used as an integrity check of the data by anyone
+possessing the secret.
+.PP
+The routines
+.IR md4 ,
+.IR md5 ,
+.IR sha1 ,
+.IR sha2_224 ,
+.IR sha2_256 ,
+.IR sha2_384 ,
+.IR sha2_512 ,
+.IR aes ,
+.IR hmac_md5 ,
+.IR hmac_sha1 ,
+.IR hmac_sha2_224 ,
+.IR hmac_sha2_256 ,
+.IR hmac_sha2_384 ,
+.IR hmac_sha2_512 ,
+and
+.I hmac_aes
+differ only in the length of the resulting digest
+and in the security of the hash.
+.I Sha2_*
+and
+.I hmac_sha2_*
+are the SHA-2 functions; the number after the final underscore
+is the number of bits in the resulting digest.
+Usage for each is the same.
+The first call to the routine should have
+.B nil
+as the
+.I state
+parameter. This call returns a state which can be used to chain
+subsequent calls.
+The last call should have digest
+.RL non- nil .
+.I Digest
+must point to a buffer of at least the size of the digest produced.
+This last call will free the state and copy the result into
+.IR digest .
+.PP
+The constants
+.IR MD4dlen ,
+.IR MD5dlen ,
+.IR SHA1dlen ,
+.IR SHA2_224dlen ,
+.IR SHA2_256dlen ,
+.IR SHA2_384dlen,
+.IR SHA2_512dlen ,
+and
+.I AESdlen
+define the lengths of the digests.
+.PP
+.IR Hmac_md5 ,
+.IR hmac_sha1 ,
+.IR hmac_sha2_224 ,
+.IR hmac_sha2_256 ,
+.IR hmac_sha2_384 ,
+.IR hmac_sha2_512 ,
+and
+.I hmac_aes
+are used slightly differently. These hash algorithms are keyed and require
+a key to be specified on every call.
+The digest lengths for these hashes are the obvious ones from
+the above list of length constants.
+These routines all call
+.I hmac_x
+internally, but
+.I hmac_x
+is not intended for general use.
+.PP
+The functions
+.I md5pickle
+and
+.I sha1pickle
+marshal the state of a digest for transmission.
+.I Md5unpickle
+and
+.I sha1unpickle
+unmarshal a pickled digest.
+All four routines return a pointer to a newly
+.IR malloc (2)'d
+object.
+.SH EXAMPLES
+To hash a single buffer using
+.IR md5 :
+.IP
+.EX
+uchar digest[MD5dlen];
+
+md5(data, len, digest, nil);
+.EE
+.PP
+To chain a number of buffers together,
+bounded on each end by some secret:
+.IP
+.EX
+char buf[256];
+uchar digest[MD5dlen];
+DigestState *s;
+
+s = md5("my password", 11, nil, nil);
+while((n = read(fd, buf, 256)) > 0)
+ md5(buf, n, nil, s);
+md5("drowssap ym", 11, digest, s);
+.EE
+.SH SOURCE
+.B /sys/src/libsec
+.SH SEE ALSO
+.IR aes (2),
+.IR blowfish (2),
+.IR des (2),
+.IR elgamal (2),
+.IR rc4 (2),
+.IR rsa (2)
+.PD 0
+.TF /lib/rfc/rfc2104
+.TP
+.B /lib/rfc/rfc2104
+HMAC specification
diff --git a/sys/man/2/seek b/sys/man/2/seek
new file mode 100755
index 000000000..8597376e7
--- /dev/null
+++ b/sys/man/2/seek
@@ -0,0 +1,46 @@
+.TH SEEK 2
+.SH NAME
+seek \- change file offset
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+vlong seek(int fd, vlong n, int type)
+.SH DESCRIPTION
+.I Seek
+sets the offset for the file
+associated with
+.I fd
+as follows:
+.IP
+If
+.I type
+is 0, the offset is set to
+.I n
+bytes.
+.IP
+If
+.I type
+is 1, the pointer is set to its current location plus
+.IR n .
+.IP
+If
+.I type
+is 2, the pointer is set to the size of the
+file plus
+.IR n .
+.PP
+The new file offset value is returned.
+.PP
+Seeking in a directory is not allowed.
+Seeking in a pipe is a no-op.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2),
+.IR open (2)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/segattach b/sys/man/2/segattach
new file mode 100755
index 000000000..b6199fefb
--- /dev/null
+++ b/sys/man/2/segattach
@@ -0,0 +1,168 @@
+.TH SEGATTACH 2
+.SH NAME
+segattach, segdetach, segfree \- map/unmap a segment in virtual memory
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLlong 'u
+.B
+void* segattach(int attr, char *class, void *va, ulong len)
+.PP
+.B
+int segdetach(void *addr)
+.PP
+.B
+int segfree(void *va, ulong len)
+.PP
+.SH DESCRIPTION
+.I Segattach
+creates a new memory segment, adds it
+to the calling process's address space, and returns its lowest address.
+Segments belong to system-dependent classes.
+Segment classes
+.B memory
+(plain memory)
+and
+.B shared
+(shared memory)
+are available on all systems.
+.PP
+Shared segments are inherited by the children of the attaching process
+and remain untouched across a
+.IR fork (2).
+An
+.IR exec (2)
+will release a shared segment if it overlaps the segments
+in the file being
+.IR exec'ed ;
+otherwise the segment will be inherited.
+.PP
+Some machines provide a segment class
+.BR lock .
+Lock segments allow access to special lock hardware provided
+by some multiprocessors, in particular the SGI Power Series machines.
+.PP
+Systems may also provide interfaces to special hardware devices like
+frame buffers through the
+.I segattach
+interface.
+Device memory mapped by this method is typically uncached by default.
+.PP
+If the specified
+.I class
+is unknown,
+.I segattach
+draws an error.
+.PP
+.I Attr
+specifies the new segment's attributes.
+The only attributes implemented on all classes of segment is
+.BR SG_RONLY ,
+which allows only read access on the segment, and
+.BR SG_CEXEC ,
+which causes the segment to be detached when the process does an
+.IR exec (2).
+Specific devices may implement
+attributes to control caching and allocation, but these will vary
+between devices.
+.PP
+.I Va
+and
+.I len
+specify the position of the segment in the process's address space.
+.I Va
+is rounded down to the nearest page boundary and
+.IB va + len
+is rounded up.
+The system does not permit segments to overlap.
+If
+.I va
+is zero, the system will choose a suitable address.
+.PP
+.I Segdetach
+removes a segment from a process's address space. Memory used by
+the segment is freed.
+.I Addr
+may be any address within the bounds of the segment.
+.PP
+The system will not permit the initial stack segment to be detached
+from the address space.
+.PP
+.I Segfree
+tells the system that it may free any physical memory within the span
+.RI [ va ,
+.IR va+len ),
+but leaves that portion of the process's address space valid.
+The system will not free any memory outside that span,
+and may not free all or even any of the specified memory.
+If free'd memory is later referenced,
+it will be initialized as appropriate for the segment type.
+For example data and text segments will be read from the executable file,
+and bss segments will be filled with zero bytes.
+.PP
+The MIPS R2000 and R3000 have no hardware instructions
+to implement locks. The following method can be used
+to build them from software.
+First, try to
+.I segattach
+a segment of class
+.BR lock .
+If this succeeds, the machine is an SGI Power Series and
+the memory contains hardware locks.
+Each 4096-byte page has 64
+.B long
+words at its beginning; each word implements
+a test-and-set semaphore when read; the low bit of the word
+is zero on success, one on failure.
+If the
+.I segattach
+fails, there is no hardware support but the operating system
+helps:
+Any
+.B COP3
+instruction will be trapped by the kernel and interpreted
+as a test-and-set.
+In the trap,
+.B R1
+points to a
+.BR long ;
+on return,
+.B R1
+is greater or equal zero on success, negative on failure.
+The following assembly language implements such a test-and-set.
+.IP
+.EX
+.ta 8n +8n +8n +8n +8n +8n +8n
+/*
+ * MIPS test and set
+ */
+ TEXT tas(SB), $0
+ MOVW R1, sema+0(FP) /* save arg on stack */
+btas:
+ MOVW sema+0(FP), R1
+ MOVB R0, 1(R1)
+ NOR R0, R0, R0 /* NOP */
+ WORD $(023<<26) /* MFC3 R0, R0 */
+ BLTZ R1, btas
+ RET
+.EE
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR lock (2),
+.IR segbrk (2),
+.IR segflush (2)
+.br
+.BR /proc/*/segment
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
+.I Segattach
+returns
+.B (void*)-1
+on error.
+.SH BUGS
+There is a small fixed limit on the number of segments that may be attached,
+as well as a maximum segment size.
diff --git a/sys/man/2/segbrk b/sys/man/2/segbrk
new file mode 100755
index 000000000..9cdb18f0b
--- /dev/null
+++ b/sys/man/2/segbrk
@@ -0,0 +1,66 @@
+.TH SEGBRK 2
+.SH NAME
+segbrk \- change memory allocation
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLvoid* 'u
+.B
+void* segbrk(void *saddr, void *addr)
+.PP
+.SH DESCRIPTION
+.I Segbrk
+sets the system's idea of the lowest unused location of a segment
+to
+.I addr
+rounded up to the next multiple of a page size, typically 4096 bytes.
+The segment is identified by
+.I saddr
+which may be any valid address within the segment.
+.PP
+A call to
+.I segbrk
+with a zero
+.I addr
+argument returns the address
+of the top of bss.
+.PP
+The system will prevent segments from overlapping and will not allow the
+length of the
+text, data, or stack segment to be altered.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR brk (2),
+.IR segattach (2),
+.IR segflush (2)
+.br
+.BR /proc/*/segment
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
+.I Segbrk
+returns
+.B (void*)-1
+on error.
+.SH BUGS
+.I Segbrk
+is not fully defined or implemented.
+In particular,
+it cannot always return the top of bss
+when called with a zero
+.I addr
+argument.
+The
+.I segbrk
+system call may go away or be re-implemented
+to give more general segment control,
+subsuming the functions of
+.IR brk (2),
+.IR segflush (2)
+and
+.I segfree
+in
+.IR segattach (2).
diff --git a/sys/man/2/segflush b/sys/man/2/segflush
new file mode 100755
index 000000000..536825483
--- /dev/null
+++ b/sys/man/2/segflush
@@ -0,0 +1,42 @@
+.TH SEGFLUSH 2
+.SH NAME
+segflush \- flush instruction and data caches
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int segflush(void *va, ulong len)
+.PP
+.SH DESCRIPTION
+.I Segflush
+invalidates any instruction cache and writes back any data
+cache associated with pages contained in a segment.
+All subsequent new pages in the segment will also be flushed when first referenced.
+.PP
+.I Va
+is an address within the segment to be flushed;
+it is rounded down to the nearest page boundary.
+.I Len
+specifies the length in bytes of
+the memory to flush;
+.IB va + len
+is rounded up to the nearest page boundary.
+.I Segflush
+works correctly when the memory straddles multiple segments.
+.PP
+Correct use of
+.I segflush
+depends on an understanding of the cache architecture of the specific
+machine.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR segattach (2),
+.IR segbrk (2)
+.br
+.BR /proc/*/segment
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
diff --git a/sys/man/2/semacquire b/sys/man/2/semacquire
new file mode 100755
index 000000000..386734800
--- /dev/null
+++ b/sys/man/2/semacquire
@@ -0,0 +1,106 @@
+.TH SEMACQUIRE 2
+.SH NAME
+semacquire, semrelease \- user level semaphores
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int semacquire(long *addr, int block);
+.PP
+.B
+long semrelease(long *addr, long count);
+.SH DESCRIPTION
+.I Semacquire
+and
+.I semrelease
+facilitate scheduling between processes sharing memory.
+Processes arrange to share memory by using
+.I rfork
+with the
+.B RFMEM
+flag
+(see
+.IR fork (2)),
+.IR segattach (2),
+or
+.IR thread (2).
+.PP
+The semaphore's value is the integer pointed at by
+.IR addr .
+.I Semacquire
+atomically waits until the semaphore has a positive value
+and then decrements that value.
+It returns 1 if the semaphore was acquired and \-1 on error
+(e.g., if it was interrupted).
+If
+.I block
+is zero
+and the semaphore is not immediately available,
+.I semacquire
+returns 0 instead of waiting.
+.I Semrelease
+adds
+.I count
+to the semaphore's value
+and returns the new value.
+.PP
+.I Semacquire
+and
+.I semrelease
+can be thought of as efficient, correct replacements for:
+.IP
+.EX
+int
+semacquire(long *addr, int block)
+{
+ while(*addr == 0){
+ if(!block)
+ return 0;
+ if(interrupted)
+ return -1;
+ }
+ --*addr;
+ return 1;
+}
+
+int
+semrelease(long *addr, int count)
+{
+ return *addr += count;
+}
+.EE
+.PP
+Like
+.IR rendezvous (2),
+.I semacquire
+and
+.I semrelease
+are not typically used directly.
+Instead, they are intended to be used to coordinate
+scheduling in higher-level abstractions such as
+locks, rendezvous points, and channels
+(see
+.IR lock (2)
+and
+.IR thread (2)).
+Also like
+.I rendezvous ,
+.I semacquire
+and
+.I semrelease
+cannot be used to coordinate between threads
+in a single process.
+Use locks, rendezvous points, or channels instead.
+.SH SOURCE
+.B /sys/src/9/port/sysproc.c
+.SH SEE ALSO
+.IR fork (2),
+.IR lock (2),
+.IR rendezvous (2),
+.IR segattach (2),
+.IR thread (2)
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
diff --git a/sys/man/2/setjmp b/sys/man/2/setjmp
new file mode 100755
index 000000000..48e4f969f
--- /dev/null
+++ b/sys/man/2/setjmp
@@ -0,0 +1,98 @@
+.TH SETJMP 2
+.SH NAME
+setjmp, longjmp, notejmp \- non-local goto
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLvoid 'u
+.B
+int setjmp(jmp_buf env)
+.PP
+.B
+void longjmp(jmp_buf env, int val)
+.PP
+.B
+void notejmp(void *uregs, jmp_buf env, int val)
+.SH DESCRIPTION
+These routines are useful for dealing with errors
+and interrupts encountered in
+a low-level subroutine of a program.
+.PP
+.I Setjmp
+saves its stack environment in
+.I env
+for later use by
+.IR longjmp .
+It returns value 0.
+.PP
+.I Longjmp
+restores the environment saved by the last call of
+.IR setjmp .
+It then causes execution to
+continue as if the call of
+.I setjmp
+had just returned with value
+.IR val .
+The invoker of
+.I setjmp
+must not itself have returned in the interim.
+All accessible data have values as of the time
+.I longjmp
+was called.
+.PP
+.I Notejmp
+is the same as
+.I longjmp
+except that it is to be called from within a note handler (see
+.IR notify (2)).
+The
+.I uregs
+argument should be the first argument passed to the note handler.
+.PP
+.I Setjmp
+and
+.I longjmp
+can also be used to switch stacks.
+Several macros are defined in
+.B /$objtype/include/u.h
+that can be used to build
+.B jmp_bufs
+by hand. The following code establishes a
+.B jmp_buf
+.i label
+that may be called by
+.I longjmp
+to begin execution in a function
+.BR f
+with 1024 bytes of stack:
+.IP
+.EX
+#include <u.h>
+#include <libc.h>
+
+jmp_buf label;
+#define NSTACK 1024
+char stack[NSTACK];
+
+void
+setlabel(void)
+{
+ label[JMPBUFPC] = ((ulong)f+JMPBUFDPC);
+ /* -2 leaves room for old pc and new pc in frame */
+ label[JMPBUFSP] =
+ (ulong)(&stack[NSTACK-2*sizeof(ulong*)]);
+}
+.EE
+.SH SOURCE
+.B /sys/src/libc/$objtype/setjmp.s
+.br
+.B /sys/src/libc/$objtype/notejmp.c
+.SH SEE ALSO
+.IR notify (2)
+.SH BUGS
+.PP
+.I Notejmp
+cannot recover from an address trap or bus error (page fault) on the 680x0
+architectures.
diff --git a/sys/man/2/sin b/sys/man/2/sin
new file mode 100755
index 000000000..ac2c2c505
--- /dev/null
+++ b/sys/man/2/sin
@@ -0,0 +1,64 @@
+.TH SIN 2
+.SH NAME
+sin, cos, tan, asin, acos, atan, atan2 \- trigonometric functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+double sin(double x)
+.PP
+.B
+double cos(double x)
+.PP
+.B
+double tan(double x)
+.PP
+.B
+double asin(double x)
+.PP
+.B
+double acos(double x)
+.PP
+.B
+double atan(double x)
+.PP
+.B
+double atan2(double y, double x)
+.SH DESCRIPTION
+.I Sin, cos
+and
+.I tan
+return trigonometric functions of radian arguments.
+The magnitude of the argument should be checked
+by the caller to make sure the result is meaningful.
+.PP
+.I Asin
+returns the arc sine in the range
+\-π/2 to π/2.
+.PP
+.I Acos
+returns the arc cosine in the range
+0 to π.
+.PP
+.I Atan
+returns the arc tangent in the range
+\-π/2 to π/2.
+.PP
+.I Atan2
+returns the arc tangent of
+.I y/x
+in the range
+\-π to π.
+.SH SOURCE
+.B /sys/src/libc/port
+.SH SEE ALSO
+.IR intro (2)
+.SH BUGS
+The value of
+.I tan
+for arguments greater than about
+.if t 2\u\s-231\s+2\d
+.if n 2^31
+is garbage.
diff --git a/sys/man/2/sinh b/sys/man/2/sinh
new file mode 100755
index 000000000..7dd4184b5
--- /dev/null
+++ b/sys/man/2/sinh
@@ -0,0 +1,23 @@
+.TH SINH 2
+.SH NAME
+sinh, cosh, tanh \- hyperbolic functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+double sinh(double x)
+.PP
+.B
+double cosh(double x)
+.PP
+.B
+double tanh(double x)
+.SH DESCRIPTION
+These functions compute the designated hyperbolic functions
+for real arguments.
+.SH SOURCE
+.B /sys/src/libc/port
+.SH SEE ALSO
+.IR intro (2)
diff --git a/sys/man/2/sleep b/sys/man/2/sleep
new file mode 100755
index 000000000..013df3c5b
--- /dev/null
+++ b/sys/man/2/sleep
@@ -0,0 +1,45 @@
+.TH SLEEP 2
+.SH NAME
+sleep, alarm \- delay, ask for delayed note
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int sleep(long millisecs)
+.PP
+.B
+long alarm(unsigned long millisecs)
+.SH DESCRIPTION
+.I Sleep
+suspends the current process for the number
+of milliseconds specified by the argument.
+The actual suspension time may be a little more or less than
+the requested time. If
+.I millisecs
+is 0, the process
+gives up the CPU if another process is waiting to run, returning
+immediately if not.
+Sleep returns \-1 if interrupted, 0 otherwise.
+.PP
+.I Alarm
+causes an
+.B alarm
+note (see
+.IR notify (2))
+to be sent to the invoking process after the number of milliseconds
+given by the argument.
+Successive calls to
+.I alarm
+reset the alarm clock.
+A zero argument clears the alarm.
+The return value is the amount of time previously remaining in
+the alarm clock.
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.SH SEE ALSO
+.IR intro (2)
+.SH DIAGNOSTICS
+These functions set
+.IR errstr .
diff --git a/sys/man/2/stat b/sys/man/2/stat
new file mode 100755
index 000000000..26823e109
--- /dev/null
+++ b/sys/man/2/stat
@@ -0,0 +1,326 @@
+.TH STAT 2
+.SH NAME
+stat, fstat, wstat, fwstat, dirstat, dirfstat, dirwstat, dirfwstat, nulldir \- get and put file status
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+int stat(char *name, uchar *edir, int nedir)
+.PP
+.B
+int fstat(int fd, uchar *edir, int nedir)
+.PP
+.B
+int wstat(char *name, uchar *edir, int nedir)
+.PP
+.B
+int fwstat(int fd, uchar *edir, int nedir)
+.PP
+.B
+Dir* dirstat(char *name)
+.PP
+.B
+Dir* dirfstat(int fd)
+.PP
+.B
+int dirwstat(char *name, Dir *dir)
+.PP
+.B
+int dirfwstat(int fd, Dir *dir)
+.PP
+.B
+void nulldir(Dir *d)
+.SH DESCRIPTION
+Given a file's
+.IR name ,
+or an open file descriptor
+.IR fd ,
+these routines retrieve or modify file status information.
+.IR Stat ,
+.IR fstat ,
+.IR wstat ,
+and
+.I fwstat
+are the system calls; they deal with machine-independent
+.IR "directory entries" .
+Their format is defined by
+.IR stat (5).
+.I Stat
+and
+.I fstat
+retrieve information about
+.I name
+or
+.I fd
+into
+.IR edir ,
+a buffer of length
+.IR nedir ,
+defined in
+.BR <libc.h> .
+.I Wstat
+and
+.I fwstat
+write information back, thus changing file attributes according to the contents of
+.IR edir .
+The data returned from the kernel includes its leading 16-bit length field
+as described in
+.IR intro (5).
+For symmetry, this field must also be present when passing data to the kernel in a call to
+.I wstat
+and
+.IR fwstat ,
+but its value is ignored.
+.PP
+.IR Dirstat ,
+.IR dirfstat ,
+.IR dirwstat ,
+and
+.I dirfwstat
+are similar to their counterparts, except that they
+operate on
+.I Dir
+structures:
+.IP
+.EX
+.ta 6n +\w'ulong 'u +\w'mtime; 'u
+typedef
+struct Dir {
+ /* system-modified data */
+ uint type; /* server type */
+ uint dev; /* server subtype */
+ /* file data */
+ Qid qid; /* unique id from server */
+ ulong mode; /* permissions */
+ ulong atime; /* last read time */
+ ulong mtime; /* last write time */
+ vlong length; /* file length: see <u.h> */
+ char *name; /* last element of path */
+ char *uid; /* owner name */
+ char *gid; /* group name */
+ char *muid; /* last modifier name */
+} Dir;
+.EE
+.PP
+The returned structure is allocated by
+.IR malloc (2);
+freeing it also frees the associated strings.
+.PP
+This structure and
+the
+.B Qid
+structure
+are defined in
+.BR <libc.h> .
+If the file resides on permanent storage and is not a directory,
+the length returned by
+.I stat
+is the number of bytes in the file.
+For directories, the length returned is zero.
+For files that are streams (e.g., pipes and network connections),
+the length is the number of bytes that can be read without blocking.
+.PP
+Each file is the responsibility of some
+.IR server :
+it could be a file server, a kernel device, or a user process.
+.B Type
+identifies the server type, and
+.B dev
+says which of a group of servers of the same type is the one
+responsible for this file.
+.B Qid
+is a structure containing
+.B path
+and
+.B vers
+fields:
+.B path
+is guaranteed to be
+unique among all path names currently on the file server, and
+.B vers
+changes each time the file is modified.
+The
+.B path
+is a
+.B long
+.B long
+(64 bits,
+.BR vlong )
+and the
+.B vers
+is an
+.B unsigned long
+(32 bits,
+.BR ulong ).
+Thus, if two files have the same
+.BR type ,
+.BR dev ,
+and
+.B qid
+they are the same file.
+.PP
+The bits in
+.B mode
+are defined by
+.PP
+.ta 6n +\w'\fL0x80000000 'u
+.nf
+\fL 0x80000000\fP directory
+\fL 0x40000000\fP append only
+\fL 0x20000000\fP exclusive use (locked)
+
+\fL 0400\fP read permission by owner
+\fL 0200\fP write permission by owner
+\fL 0100\fP execute permission (search on directory) by owner
+\fL 0070\fP read, write, execute (search) by group
+\fL 0007\fP read, write, execute (search) by others
+.fi
+.PP
+There are constants defined in
+.B <libc.h>
+for these bits:
+.BR DMDIR ,
+.BR DMAPPEND ,
+and
+.B DMEXCL
+for the first three; and
+.BR DMREAD ,
+.BR DMWRITE ,
+and
+.B DMEXEC
+for the read, write, and execute bits for others.
+.PP
+The two time fields are measured in seconds since the epoch
+(Jan 1 00:00 1970 GMT).
+.B Mtime
+is the time of the last change of content.
+Similarly,
+.B atime
+is set whenever the contents are accessed;
+also, it is set whenever
+.B mtime
+is set.
+.PP
+.B Uid
+and
+.B gid
+are the names of the owner and group of the file;
+.B muid
+is the name of the user that last modified the file (setting
+.BR mtime ).
+Groups are also users, but each server is free to associate
+a list of users with any user name
+.IR g ,
+and that list is the
+set of users in the group
+.IR g .
+When an initial attachment is made to a server,
+the user string in the process group is communicated to the server.
+Thus, the server knows, for any given file access, whether the accessing
+process is the owner of, or in the group of, the file.
+This selects which sets of three bits in
+.B mode
+is used to check permissions.
+.PP
+Only some of the fields may be changed with the
+.I wstat
+calls.
+The
+.B name
+can be changed by anyone with write permission in the parent directory.
+The
+.B mode
+and
+.B mtime
+can be changed by the owner or the group leader of the file's current
+group.
+The
+.I gid
+can be changed: by the owner if also a member of the new group; or
+by the group leader of the file's current group
+if also leader of the new group
+(see
+.IR intro (5)
+for more information about permissions and
+.IR users (6)
+for users and groups).
+The
+.B length
+can be changed by anyone with write permission, provided the operation
+is implemented by the server.
+(See
+.IR intro (5)
+for permission information, and
+.IR users (6)
+for user and group information).
+.PP
+Special values in the fields of the
+.B Dir
+passed to
+.I wstat
+indicate that the field is not intended to be changed by the call.
+The values are the maximum unsigned integer of appropriate size
+for integral values (usually
+.BR ~0 ,
+but beware of conversions and size mismatches
+when comparing values) and the empty or nil string for string values.
+The routine
+.I nulldir
+initializes all the elements of
+.I d
+to these ``don't care'' values.
+Thus one may change the mode, for example, by using
+.I nulldir
+to initialize a
+.BR Dir ,
+then setting the mode, and then doing
+.IR wstat ;
+it is not necessary to use
+.I stat
+to retrieve the initial values first.
+.SH SOURCE
+.TF /sys/src/libc/9syscall
+.TP
+.B /sys/src/libc/9syscall
+for the
+.RB non- dir
+routines
+.TP
+.B /sys/src/libc/9sys
+for the routines prefixed
+.B dir
+.SH SEE ALSO
+.IR intro (2),
+.IR fcall (2),
+.IR dirread (2),
+.IR stat (5)
+.SH DIAGNOSTICS
+The
+.I dir
+functions return a pointer to the data for a successful call, or
+.B nil
+on error.
+The others
+return the number of bytes copied on success, or \-1 on error.
+All set
+.IR errstr .
+.PP
+If the buffer for
+.I stat
+or
+.I fstat
+is too short for the returned data, the return value will be
+.B BIT16SZ
+(see
+.IR fcall (2))
+and the two bytes
+returned will contain the initial count field of the
+returned data;
+retrying with
+.B nedir
+equal to
+that value plus
+.B BIT16SZ
+(for the count itself) should succeed.
diff --git a/sys/man/2/strcat b/sys/man/2/strcat
new file mode 100755
index 000000000..57bd38e4a
--- /dev/null
+++ b/sys/man/2/strcat
@@ -0,0 +1,269 @@
+.TH STRCAT 2
+.SH NAME
+strcat, strncat, strcmp, strncmp, cistrcmp, cistrncmp, strcpy, strncpy, strecpy, strlen, strchr, strrchr, strpbrk, strspn, strcspn, strtok, strdup, strstr, cistrstr \- string operations
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.ta \w'\fLchar* \fP'u
+.B
+char* strcat(char *s1, char *s2)
+.PP
+.B
+char* strncat(char *s1, char *s2, long n)
+.PP
+.B
+int strcmp(char *s1, char *s2)
+.PP
+.B
+int strncmp(char *s1, char *s2, long n)
+.PP
+.B
+int cistrcmp(char *s1, char *s2)
+.PP
+.B
+int cistrncmp(char *s1, char *s2, long n)
+.PP
+.B
+char* strcpy(char *s1, char *s2)
+.PP
+.B
+char* strecpy(char *s1, char *es1, char *s2)
+.PP
+.B
+char* strncpy(char *s1, char *s2, long n)
+.PP
+.B
+long strlen(char *s)
+.PP
+.B
+char* strchr(char *s, char c)
+.PP
+.B
+char* strrchr(char *s, char c)
+.PP
+.B
+char* strpbrk(char *s1, char *s2)
+.PP
+.B
+long strspn(char *s1, char *s2)
+.PP
+.B
+long strcspn(char *s1, char *s2)
+.PP
+.B
+char* strtok(char *s1, char *s2)
+.PP
+.B
+char* strdup(char *s)
+.PP
+.B
+char* strstr(char *s1, char *s2)
+.PP
+.B
+char* cistrstr(char *s1, char *s2)
+.SH DESCRIPTION
+The arguments
+.I s1, s2
+and
+.I s
+point to null-terminated strings.
+The functions
+.IR strcat ,
+.IR strncat ,
+.IR strcpy ,
+.IR strecpy ,
+and
+.I strncpy
+all alter
+.IR s1 .
+.I Strcat
+and
+.I strcpy
+do not check for overflow of
+the array pointed to by
+.IR s1 .
+.PP
+.I Strcat
+appends a copy of string
+.I s2
+to the end of string
+.IR s1 .
+.I Strncat
+appends at most
+.I n
+bytes.
+Each returns a pointer to the null-terminated result.
+.PP
+.I Strcmp
+compares its arguments and returns an integer
+less than, equal to, or greater than 0,
+according as
+.I s1
+is lexicographically less than, equal to, or
+greater than
+.IR s2 .
+.I Strncmp
+makes the same comparison but examines at most
+.I n
+bytes.
+.I Cistrcmp
+and
+.I cistrncmp
+ignore ASCII case distinctions when comparing strings.
+The comparisons are made with unsigned bytes.
+.PP
+.I Strcpy
+copies string
+.I s2
+to
+.IR s1 ,
+stopping after the null byte has been copied.
+.I Strncpy
+copies exactly
+.I n
+bytes,
+truncating
+.I s2
+or adding
+null bytes to
+.I s1
+if necessary.
+The result will not be null-terminated if the length
+of
+.I s2
+is
+.I n
+or more.
+Each function returns
+.IR s1 .
+.PP
+.I Strecpy
+copies bytes until a null byte has been copied, but writes no bytes beyond
+.IR es1 .
+If any bytes are copied,
+.I s1
+is terminated by a null byte, and a pointer to that byte is returned.
+Otherwise, the original
+.I s1
+is returned.
+.PP
+.I Strlen
+returns the number of bytes in
+.IR s ,
+not including the terminating null byte.
+.PP
+.I Strchr
+.RI ( strrchr )
+returns a pointer to the first (last)
+occurrence of byte
+.I c
+in string
+.IR s ,
+or
+.L 0
+if
+.I c
+does not occur in the string.
+The null byte terminating a string is considered to
+be part of the string.
+.PP
+.I Strpbrk
+returns a pointer to the first occurrence in string
+.I s1
+of any byte from string
+.IR s2 ,
+.L 0
+if no byte from
+.I s2
+exists in
+.IR s1 .
+.PP
+.I Strspn
+.RI ( strcspn )
+returns the length of the initial segment of string
+.I s1
+which consists entirely of bytes from (not from) string
+.IR s2 .
+.PP
+.I Strtok
+considers the string
+.I s1
+to consist of a sequence of zero or more text tokens separated
+by spans of one or more bytes from the separator string
+.IR s2 .
+The first call, with pointer
+.I s1
+specified, returns a pointer to the first byte of the first
+token, and will have written a
+null byte into
+.I s1
+immediately following the returned token.
+The function
+keeps track of its position in the string
+between separate calls; subsequent calls,
+signified by
+.I s1
+being
+.LR 0 ,
+will work through the string
+.I s1
+immediately following that token.
+The separator string
+.I s2
+may be different from call to call.
+When no token remains in
+.IR s1 ,
+.L 0
+is returned.
+.PP
+.I Strdup
+returns a pointer to a distinct copy of the null-terminated string
+.I s
+in space obtained from
+.IR malloc (2)
+or
+.L 0
+if no space can be obtained.
+.PP
+.I Strstr
+returns a pointer to the first occurrence of
+.I s2
+as a substring of
+.IR s1 ,
+or 0 if there is none.
+If
+.I s2
+is the null string,
+.I strstr
+returns
+.IR s1 .
+.I Cistrstr
+operates analogously, but ignores ASCII case differences when comparing strings.
+.SH SOURCE
+All these routines have portable C implementations in
+.BR /sys/src/libc/port .
+Many also have machine-dependent assembly language
+implementations in
+.BR /sys/src/libc/$objtype .
+.SH SEE ALSO
+.IR memory (2),
+.IR rune (2),
+.IR runestrcat (2),
+.IR string (2)
+.SH BUGS
+These routines know nothing about
+.SM UTF.
+Use the routines in
+.IR rune (2)
+as appropriate.
+Note, however, that the definition of
+.SM UTF
+guarantees that
+.I strcmp
+compares
+.SM UTF
+strings correctly.
+.PP
+The outcome of overlapping moves varies among implementations.
diff --git a/sys/man/2/string b/sys/man/2/string
new file mode 100755
index 000000000..ffae39bf3
--- /dev/null
+++ b/sys/man/2/string
@@ -0,0 +1,236 @@
+.TH STRING 2
+.SH NAME
+s_alloc, s_append, s_array, s_copy, s_error, s_free, s_incref, s_memappend, s_nappend, s_new, s_newalloc, s_parse, s_reset, s_restart, s_terminate, s_tolower, s_putc, s_unique, s_grow, s_read, s_read_line, s_getline \- extensible strings
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <String.h>
+.PP
+.B
+String* s_new(void)
+.br
+.B
+void s_free(String *s)
+.br
+.B
+String* s_newalloc(int n)
+.br
+.B
+String* s_array(char *p, int n)
+.br
+.B
+String* s_grow(String *s, int n)
+.PP
+.B
+void s_putc(String *s, int c)
+.br
+.B
+void s_terminate(String *s)
+.br
+.B
+String* s_reset(String *s)
+.br
+.B
+String* s_restart(String *s)
+.br
+.B
+String* s_append(String *s, char *p)
+.br
+.B
+String* s_nappend(String *s, char *p, int n)
+.br
+.B
+String* s_memappend(String *s, char *p, int n)
+.br
+.B
+String* s_copy(char *p)
+.br
+.B
+String* s_parse(String *s1, String *s2)
+.br
+.PP
+.B
+void s_tolower(String *s)
+.PP
+.B
+String* s_incref(String *s)
+.br
+.B
+String* s_unique(String *s)
+.PP
+.B
+#include <bio.h>
+.PP
+.B
+int s_read(Biobuf *b, String *s, int n)
+.br
+.B
+char* s_read_line(Biobuf *b, String *s)
+.br
+.B
+char* s_getline(Biobuf *b, String *s)
+.SH DESCRIPTION
+.PP
+These routines manipulate extensible strings.
+The basic type is
+.BR String ,
+which points to an array of characters. The string
+maintains pointers to the beginning and end of the allocated
+array. In addition a finger pointer keeps track of where
+parsing will start (for
+.IR s_parse )
+or new characters will be added (for
+.IR s_putc ,
+.IR s_append ,
+and
+.IR s_nappend ).
+The structure, and a few useful macros are:
+.sp
+.EX
+typedef struct String {
+ Lock;
+ char *base; /* base of String */
+ char *end; /* end of allocated space+1 */
+ char *ptr; /* ptr into String */
+ ...
+} String;
+
+#define s_to_c(s) ((s)->base)
+#define s_len(s) ((s)->ptr-(s)->base)
+#define s_clone(s) s_copy((s)->base)
+.EE
+.PP
+.I S_to_c
+is used when code needs a reference to the character array.
+Using
+.B s->base
+directly is frowned upon since it exposes too much of the implementation.
+.SS "allocation and freeing
+.PP
+A string must be allocated before it can be used.
+One normally does this using
+.IR s_new ,
+giving the string an initial allocation of
+128 bytes.
+If you know that the string will need to grow much
+longer, you can use
+.I s_newalloc
+instead, specifying the number of bytes in the
+initial allocation.
+.PP
+.I S_free
+causes both the string and its character array to be freed.
+.PP
+.I S_grow
+grows a string's allocation by a fixed amount. It is useful if
+you are reading directly into a string's character array but should
+be avoided if possible.
+.PP
+.I S_array
+is used to create a constant array, that is, one whose contents
+won't change. It points directly to the character array
+given as an argument. Tread lightly when using this call.
+.SS "Filling the string
+After its initial allocation, the string points to the beginning
+of an allocated array of characters starting with
+.SM NUL.
+.PP
+.I S_putc
+writes a character into the string at the
+pointer and advances the pointer to point after it.
+.PP
+.I S_terminate
+writes a
+.SM NUL
+at the pointer but doesn't advance it.
+.PP
+.I S_restart
+resets the pointer to the begining of the string but doesn't change the contents.
+.PP
+.I S_reset
+is equivalent to
+.I s_restart
+followed by
+.IR s_terminate .
+.PP
+.I S_append
+and
+.I s_nappend
+copy characters into the string at the pointer and
+advance the pointer. They also write a
+.SM NUL
+at
+the pointer without advancing the pointer beyond it.
+Both routines stop copying on encountering a
+.SM NUL.
+.I S_memappend
+is like
+.I s_nappend
+but doesn't stop at a
+.SM NUL.
+.PP
+If you know the initial character array to be copied into a string,
+you can allocate a string and copy in the bytes using
+.IR s_copy .
+This is the equivalent of a
+.I s_new
+followed by an
+.IR s_append .
+.PP
+.I S_parse
+copies the next white space terminated token from
+.I s1
+to
+the end of
+.IR s2 .
+White space is defined as space, tab,
+and newline. Both single and double quoted strings are treated as
+a single token. The bounding quotes are not copied.
+There is no escape mechanism.
+.PP
+.I S_tolower
+converts all
+.SM ASCII
+characters in the string to lower case.
+.SS Multithreading
+.PP
+.I S_incref
+is used by multithreaded programs to avoid having the string memory
+released until the last user of the string performs an
+.IR s_free .
+.I S_unique
+returns a unique copy of the string: if the reference count it
+1 it returns the string, otherwise it returns an
+.I s_clone
+of the string.
+.SS "Bio interaction
+.PP
+.I S_read
+reads the requested number of characters through a
+.I Biobuf
+into a string. The string is grown as necessary.
+An eof or error terminates the read.
+The number of bytes read is returned.
+The string is null terminated.
+.PP
+.I S_read_line
+reads up to and including the next newline and returns
+a pointer to the beginning of the bytes read.
+An eof or error terminates the read.
+The string is null terminated.
+.PP
+.I S_getline
+reads up to the next newline and returns
+a pointer to the beginning of the bytes read. Leading
+spaces and tabs and the trailing newline are all discarded.
+.I S_getline
+will recursively read through files included with
+.B #include
+and discard all other lines beginning with
+.BR # .
+.SH SOURCE
+.B /sys/src/libString
+.SH SEE ALSO
+.IR bio (2)
diff --git a/sys/man/2/stringsize b/sys/man/2/stringsize
new file mode 100755
index 000000000..128528151
--- /dev/null
+++ b/sys/man/2/stringsize
@@ -0,0 +1,69 @@
+.TH STRINGSIZE 2
+.SH NAME
+stringsize, stringwidth, stringnwidth, runestringsize, runestringwidth, runestringnwidth \- graphical size of strings
+.SH SYNOPSIS
+.nf
+.PP
+.ft L
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+.ft P
+.ta \w'\fLPoint 'u
+.PP
+.B
+Point stringsize(Font *f, char *s)
+.PP
+.B
+int stringwidth(Font *f, char *s)
+.PP
+.B
+int stringnwidth(Font *f, char *s, int n)
+.PP
+.B
+Point runestringsize(Font *f, Rune *s)
+.PP
+.B
+int runestringwidth(Font *f, Rune *s)
+.PP
+.B
+int runestringnwidth(Font *f, Rune *s, int n)
+.SH DESCRIPTION
+These routines compute the geometrical extent of character strings when drawn on the display. The most straightforward,
+.BR stringsize ,
+returns a
+.B Point
+representing the vector from upper left to lower right of the NUL-terminated string
+.I s
+drawn in font
+.IR f .
+.B Stringwidth
+returns just the
+.I x
+component.
+.B Stringnwidth
+returns the width of the first
+.I n
+characters of
+.IR s .
+.PP
+The routines beginning with
+.B rune
+are analogous, but accept an array of runes rather than
+.SM UTF\c
+-encoded bytes.
+.SH FILES
+.BR /lib/font/bit " directory of fonts
+.SH SOURCE
+.B /sys/src/libdraw
+.SH "SEE ALSO"
+.IR addpt (2),
+.IR cachechars (2),
+.IR subfont (2),
+.IR draw (2),
+.IR draw (3),
+.IR image (6),
+.IR font (6)
+.SH DIAGNOSTICS
+Because strings are loaded dynamically, these routines may generate I/O
+to the server and produce calls to the graphics error function.
diff --git a/sys/man/2/subfont b/sys/man/2/subfont
new file mode 100755
index 000000000..fb43b2a3c
--- /dev/null
+++ b/sys/man/2/subfont
@@ -0,0 +1,235 @@
+.TH SUBFONT 2
+.SH NAME
+allocsubfont, freesubfont, installsubfont, lookupsubfont, uninstallsubfont, subfontname, readsubfont, readsubfonti, writesubfont, stringsubfont, strsubfontwidth, mkfont \- subfont manipulation
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <draw.h>
+.PP
+.ta \w'\fLSubfont* 'u
+.B
+Subfont* allocsubfont(char *name, int n, int height, int ascent,
+.br
+.B
+ Fontchar *info, Image *i)
+.PP
+.B
+void freesubfont(Subfont *f)
+.PP
+.B
+void installsubfont(char *name, Subfont *f)
+.PP
+.B
+Subfont* lookupsubfont(Subfont *f)
+.PP
+.B
+void uninstallsubfont(Subfont *f)
+.PP
+.B
+Subfont* readsubfont(Display *d, char *name, int fd, int dolock)
+.PP
+.B
+Subfont* readsubfonti(Display *d, char *name, int fd, Image *im,
+.br
+.B
+ int dolock)
+.PP
+.B
+int writesubfont(int fd, Subfont *f)
+.PP
+.B
+Point stringsubfont(Image *dst, Point p, Image *src,
+.br
+.B
+ Subfont *f, char *str)
+.PP
+.B
+Point strsubfontwidth(Subfont *f, char *s)
+.PP
+.B
+Font* mkfont(Subfont *f, Rune min)
+.SH DESCRIPTION
+Subfonts are the components of fonts that hold the character images.
+A font comprises an array of subfonts; see
+.IR cachechars (2).
+A new
+.B Subfont
+is allocated and initialized with
+.IR allocsubfont .
+See
+.IR cachechars (2)
+for the meaning of
+.IR n ,
+.IR height ,
+.IR ascent ,
+and
+.IR info ,
+and the arrangement of characters in
+image
+.IR i .
+The
+.I name
+is used to identify the subfont in the subfont cache; see the descriptions
+.I lookupsubfont
+and
+.IR installsubfont
+.RI ( q.v. ).
+The appropriate fields of the returned
+.B Subfont
+structure are set to
+the passed arguments, and the image is registered as a subfont
+with the graphics device
+.IR draw (3).
+.I Allocsubfont
+returns 0 on failure.
+.PP
+.I Freesubfont
+frees a subfont and all its associated structure including the
+associated image.
+Since
+.I freesbufont
+calls
+.I free
+on
+.BR f->info ,
+if
+.B f->info
+was not allocated by
+.IR malloc (2)
+it should be zeroed before calling
+.IR subffree .
+.PP
+A number of subfonts are kept in external files.
+The convention for naming subfont files is:
+.IP
+.B /lib/font/bit/\fIname\fP/\fIclass\fP.\fIsize\fP.\fIdepth
+.PD
+.PP
+where
+.I size
+is approximately the height in pixels of the lower case letters
+(without ascenders or descenders).
+If there is only one version of the subfont, the
+.BI \&. depth
+extension is elided.
+.I Class
+describes the range of runes encoded in the subfont:
+.BR ascii ,
+.BR latin1 ,
+.BR greek ,
+etc.
+.PP
+Subfonts are cached within the program, so a subfont shared between fonts will be loaded only once.
+.I Installsubfont
+stores subfont
+.I f
+under the given
+.IR name ,
+typically the file name from which it was read.
+.I Uninstallsubfont
+removes the subfont from the cache.
+Finally,
+.I lookupsubfont
+searches for a subfont with the given
+.I name
+in the cache and returns it, or nil if no such subfont exists.
+.PP
+.I Subfontname
+is used to locate subfonts given their names within the fonts.
+The default version constructs a name given the
+.IR cfname ,
+its name within the font,
+.IR fname ,
+the name of the font, and the maximum depth suitable for this subfont.
+This interface allows a partially specified name within a font to be resolved
+at run-time to the name of a file holding a suitable subfont.
+Although it is principally a routine internal to the library,
+.I subfontname
+may be substituted by the application to provide a less file-oriented subfont naming scheme.
+.PP
+The format of a subfont file is described in
+.IR font (6).
+Briefly, it contains a image with all the characters in it,
+followed by a subfont header, followed by character information.
+.I Readsubfont
+reads a subfont from the file descriptor
+.IR fd .
+The
+.I name
+is used to identify the font in the cache.
+The
+.I dolock
+argument specifies whether the routine should synchronize
+use of the
+.I Display
+with other processes; for single-threaded applications it may
+always be zero.
+.I Readsubfonti
+does the same for a subfont whose associated image is already in memory; it is passed as the
+argument
+.IR im .
+In other words,
+.I readsubfonti
+reads only the header and character information from the file descriptor.
+.PP
+.I Writesubfont
+writes on
+.I fd
+the part of a subfont file that comes after the image. It should be preceded by
+a call to
+.IR writeimage
+(see
+.IR allocimage (2)).
+.PP
+.I Stringsubfont
+is analogous to
+.B string
+(see
+.IR draw (2))
+for subfonts. Rather than use the underlying font caching primitives,
+it calls
+.B draw
+for each character.
+It is intended for stand-alone environments such as operating system kernels.
+.I Strsubfontwidth
+returns the width of the string
+.I s
+in
+as it would appear if drawn with
+.I stringsubfont
+in
+.B Subfont
+.BR f .
+.PP
+.I Mkfont
+takes as argument a
+.B Subfont
+.I s
+and returns a pointer to a
+.B Font
+that maps the character images in
+.I s
+into the
+.B Runes
+.I min
+to
+.IB min + s ->n-1\f1.
+.SH FILES
+.TF /lib/font/bit
+.TP
+.B /lib/font/bit
+bitmap font file tree
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR allocimage (2),
+.IR draw (2),
+.IR cachechars (2),
+.IR image (6),
+.IR font (6)
+.SH DIAGNOSTICS
+All of the functions use the graphics error function (see
+.IR graphics (2)).
diff --git a/sys/man/2/symbol b/sys/man/2/symbol
new file mode 100755
index 000000000..a25e73598
--- /dev/null
+++ b/sys/man/2/symbol
@@ -0,0 +1,436 @@
+.TH SYMBOL 2
+.SH NAME
+syminit, getsym, symbase, pc2sp, pc2line, textseg, line2addr, lookup, findlocal,
+getauto, findsym, localsym, globalsym, textsym, file2pc, fileelem, filesym,
+fileline, fnbound \- symbol table access functions
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.br
+.B #include <bio.h>
+.br
+.B #include <mach.h>
+.PP
+.ta \w'\fLmachines 'u
+.B
+int syminit(int fd, Fhdr *fp)
+.PP
+.B
+Sym *getsym(int index)
+.PP
+.B
+Sym *symbase(long *nsyms)
+.PP
+.B
+int fileelem(Sym **fp, uchar *encname, char *buf, int n)
+.PP
+.B
+int filesym(int index, char *buf, int n)
+.PP
+.B
+long pc2sp(ulong pc)
+.PP
+.B
+long pc2line(ulong pc)
+.PP
+.B
+void textseg(ulong base, Fhdr *fp)
+.PP
+.B
+long line2addr(ulong line, ulong basepc)
+.PP
+.B
+int lookup(char *fn, char *var, Symbol *s)
+.PP
+.B
+int findlocal(Symbol *s1, char *name, Symbol *s2)
+.PP
+.B
+int getauto(Symbol *s1, int off, int class, Symbol *s2)
+.PP
+.B
+int findsym(long addr, int class, Symbol *s)
+.PP
+.B
+int localsym(Symbol *s, int index)
+.PP
+.B
+int globalsym(Symbol *s, int index)
+.PP
+.B
+int textsym(Symbol *s, int index)
+.PP
+.B
+long file2pc(char *file, ulong line)
+.PP
+.B
+int fileline(char *str, int n, ulong addr)
+.PP
+.B
+int fnbound(long addr, ulong *bounds)
+.SH DESCRIPTION
+These functions provide machine-independent access to the
+symbol table of an executable file or executing process.
+The latter is accessible by opening the device
+.B /proc/\fIpid\fP/text
+as described in
+.IR proc (3).
+.IR Mach (2)
+and
+.IR object (2)
+describe additional library functions
+for processing executable and object files.
+.PP
+.IR Syminit ,
+.IR getsym ,
+.IR symbase ,
+.IR fileelem ,
+.IR pc2sp ,
+.IR pc2line ,
+and
+.I line2addr
+process the symbol table contained in an executable file
+or the
+.B text
+image of an executing program.
+The symbol table is stored internally as an array of
+.B Sym
+data structures as defined in
+.IR a.out (6).
+.PP
+.I Syminit
+uses the data in the
+.B Fhdr
+structure filled by
+.I crackhdr
+(see
+.IR mach (2))
+to read the raw symbol tables from the open file descriptor
+.IR fd .
+It returns the count of the number of symbols
+or \-1 if an error occurs.
+.PP
+.I Getsym
+returns the address of the
+.IR i th
+.B Sym
+structure or zero if
+.I index
+is out of range.
+.PP
+.I Symbase
+returns the address of the first
+.B Sym
+structure in the symbol table. The number of
+entries in the symbol table is returned in
+.IR nsyms .
+.PP
+.I Fileelem
+converts a file name, encoded as described in
+.IR a.out (6),
+to a character string.
+.I Fp
+is the base of
+an array of pointers to file path components ordered by path index.
+.I Encname
+is the address of an array of encoded
+file path components in the form of a
+.B z
+symbol table entry.
+.I Buf
+and
+.I n
+specify the
+address of a receiving character buffer and its length.
+.I Fileelem
+returns the length of the null-terminated string
+that is at most
+.IR n \-1
+bytes long.
+.PP
+.I Filesym
+is a higher-level interface to
+.IR fileelem .
+It fills
+.I buf
+with the name of the
+.IR i th
+file and returns the length of the null-terminated string
+that is at most
+.IR n \-1
+bytes long.
+File names are retrieved in no particular order, although
+the order of retrieval does not vary from one pass to the next.
+A zero is returned when
+.I index
+is too large or too small or an error occurs during file name
+conversion.
+.PP
+.I Pc2sp
+returns an offset associated with
+a given value of the program counter. Adding this offset
+to the current value of the stack pointer gives the address
+of the current stack frame. This approach only applies
+to the 68020 architecture; other architectures
+use a fixed stack frame offset by a constant contained
+in a dummy local variable (called
+.BR .frame )
+in the symbol table.
+.PP
+.I Pc2line
+returns the line number of the statement associated
+with the instruction address
+.IR pc .
+The
+line number is the absolute line number in the
+source file as seen by the compiler after pre-processing; the
+original line number in the source file may be derived from this
+value using the history stacks contained in the symbol table.
+.PP
+.I Pc2sp
+and
+.I pc2line
+must know the start and end addresses of the text segment
+for proper operation. These values are calculated from the
+file header by function
+.IR syminit .
+If the text segment address is changed, the application
+program must invoke
+.I textseg
+to recalculate the boundaries of the segment.
+.I Base
+is the new base address of the text segment and
+.I fp
+points to the
+.I Fhdr
+data structure filled by
+.IR crackhdr .
+.PP
+.I Line2addr
+converts a line number to an instruction address. The
+first argument is the absolute line number in
+a file. Since a line number does not uniquely identify
+an instruction location (e.g., every source file has line 1),
+a second argument specifies a text address
+from which the search begins. Usually this
+is the address of the first function in the file of interest.
+.PP
+.IR Pc2sp ,
+.IR pc2line ,
+and
+.I line2addr
+return \-1 in the case of an error.
+.PP
+.IR Lookup ,
+.IR findlocal ,
+.IR getauto ,
+.IR findsym ,
+.IR localsym ,
+.IR globalsym ,
+.IR textsym ,
+.IR file2pc ,
+and
+.I fileline
+operate on data structures riding above the raw symbol table.
+These data structures occupy memory
+and impose a startup penalty but speed retrievals
+and provide higher-level access to the basic symbol
+table data.
+.I Syminit
+must be called
+prior to using these functions.
+The
+.B Symbol
+data structure:
+.IP
+.EX
+typedef struct {
+ void *handle; /* private */
+ struct {
+ char *name;
+ long value;
+ char type;
+ char class;
+ };
+} Symbol;
+.EE
+.LP
+describes a symbol table entry.
+The
+.B value
+field contains the offset of the symbol within its
+address space: global variables relative to the beginning
+of the data segment, text beyond the start of the text
+segment, and automatic variables and parameters relative
+to the stack frame. The
+.B type
+field contains the type of the symbol as defined in
+.IR a.out (6).
+The
+.B class
+field assigns the symbol to a general class;
+.BR CTEXT ,
+.BR CDATA ,
+.BR CAUTO ,
+and
+.B CPARAM
+are the most popular.
+.PP
+.I Lookup
+fills a
+.B Symbol
+structure with symbol table information. Global variables
+and functions are represented by a single name; local variables
+and parameters are uniquely specified by a function and
+variable name pair. Arguments
+.I fn
+and
+.I var
+contain the
+name of a function and variable, respectively.
+If both
+are non-zero, the symbol table is searched for a parameter
+or automatic variable. If only
+.I var
+is
+zero, the text symbol table is searched for function
+.IR fn .
+If only
+.I fn
+is zero, the global variable table
+is searched for
+.IR var .
+.PP
+.I Findlocal
+fills
+.I s2
+with the symbol table data of the automatic variable
+or parameter matching
+.IR name .
+.I S1
+is a
+.B Symbol
+data structure describing a function or a local variable;
+the latter resolves to its owning function.
+.PP
+.I Getauto
+searches the local symbols associated with function
+.I s1
+for an automatic variable or parameter located at stack
+offset
+.IR off .
+.I Class
+selects the class of
+variable:
+.B CAUTO
+or
+.BR CPARAM .
+.I S2
+is the address of a
+.B Symbol
+data structure to receive the symbol table information
+of the desired symbol.
+.PP
+.I Findsym
+returns the symbol table entry of type
+.I class
+stored near
+.IR addr .
+The selected symbol is a global variable or function
+with address nearest to and less than or equal to
+.IR addr .
+Class specification
+.B CDATA
+searches only the global variable symbol table; class
+.B CTEXT
+limits the search to the text symbol table.
+Class specification
+.B CANY
+searches the text table first, then the global table.
+.PP
+.I Localsym
+returns the
+.IR i th
+local variable in the function
+associated with
+.IR s .
+.I S
+may reference a function or a local variable; the latter
+resolves to its owning function.
+If the
+.IR i th
+local symbol exists,
+.I s
+is filled with the data describing it.
+.PP
+.I Globalsym
+loads
+.I s
+with the symbol table information of the
+.IR i th
+global variable.
+.PP
+.I Textsym
+loads
+.I s
+with the symbol table information of the
+.IR i th
+text symbol. The text symbols are ordered
+by increasing address.
+.PP
+.I File2pc
+returns a text address associated with
+.I line
+in file
+.IR file ,
+or -1 on an error.
+.PP
+.I Fileline
+converts text address
+.I addr
+to its equivalent
+line number in a source file. The result,
+a null terminated character string of
+the form
+.LR file:line ,
+is placed in buffer
+.I str
+of
+.I n
+bytes.
+.PP
+.I Fnbound
+returns the start and end addresses of the function containing
+the text address supplied as the first argument. The second
+argument is an array of two unsigned longs;
+.I fnbound
+places the bounding addresses of the function in the first
+and second elements of this array. The start address is the
+address of the first instruction of the function; the end
+address is the address of the start of the next function
+in memory, so it is beyond the end of the target function.
+.I Fnbound
+returns 1 if the address is within a text function, or zero
+if the address selects no function.
+.PP
+Functions
+.I file2pc
+and
+.I fileline
+may produce inaccurate results when applied to
+optimized code.
+.PP
+Unless otherwise specified, all functions return 1
+on success, or 0 on error. When an error occurs,
+a message describing it is stored in the system
+error buffer where it is available via
+.IR errstr .
+.SH SOURCE
+.B /sys/src/libmach
+.SH "SEE ALSO"
+.IR mach (2),
+.IR object (2),
+.IR errstr (2),
+.IR proc (3),
+.IR a.out (6)
diff --git a/sys/man/2/thread b/sys/man/2/thread
new file mode 100755
index 000000000..b06e31b96
--- /dev/null
+++ b/sys/man/2/thread
@@ -0,0 +1,642 @@
+.TH THREAD 2
+.SH NAME
+alt,
+chanclose,
+chancreate,
+chanfree,
+chaninit,
+chanclosing,
+chanprint,
+mainstacksize,
+proccreate,
+procdata,
+procexec,
+procexecl,
+procrfork,
+recv,
+recvp,
+recvul,
+send,
+sendp,
+sendul,
+nbrecv,
+nbrecvp,
+nbrecvul,
+nbsend,
+nbsendp,
+nbsendul,
+threadcreate,
+threaddata,
+threadexits,
+threadexitsall,
+threadgetgrp,
+threadgetname,
+threadint,
+threadintgrp,
+threadkill,
+threadkillgrp,
+threadmain,
+threadnotify,
+threadid,
+threadpid,
+threadsetgrp,
+threadsetname,
+threadwaitchan,
+yield \- thread and proc management
+.SH SYNOPSIS
+.EX
+.ta 4n +4n +4n +4n +4n +4n +4n
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+.sp
+typedef enum {
+ CHANEND,
+ CHANSND,
+ CHANRCV,
+ CHANNOP,
+ CHANNOBLK,
+} ChanOp;
+.sp
+.ta \w' 'u +\w'Channel 'u
+typedef struct Alt Alt;
+struct Alt {
+ Channel *c; /* channel */
+ void *v; /* pointer to value */
+ ChanOp op; /* operation */
+ char *err; /* did the op fail? */
+ /*
+ * the next variables are used internally to alt
+ * they need not be initialized
+ */
+ Channel **tag; /* pointer to rendez-vous tag */
+ int entryno; /* entry number */
+};
+.fi
+.de XX
+.ift .sp 0.5
+.ifn .sp
+..
+.PP
+.nf
+.ft L
+.ta \w'\fLChannel* 'u +4n +4n +4n +4n
+void threadmain(int argc, char *argv[])
+int mainstacksize
+int proccreate(void (*fn)(void*), void *arg, uint stacksize)
+int procrfork(void (*fn)(void*), void *arg, uint stacksize,
+ int rforkflag)
+int threadcreate(void (*fn)(void*), void *arg, uint stacksize)
+void threadexits(char *status)
+void threadexitsall(char *status)
+void yield(void)
+.XX
+int threadid(void)
+int threadgrp(void)
+int threadsetgrp(int group)
+int threadpid(int id)
+.XX
+int threadint(int id)
+void threadintgrp(int group)
+void threadkill(int id)
+int threadkillgrp(int group)
+.XX
+void threadsetname(char *name, ...)
+char* threadgetname(void)
+.XX
+void** threaddata(void)
+void** procdata(void)
+.XX
+int chaninit(Channel *c, int elsize, int nel)
+Channel* chancreate(int elsize, int nel)
+void chanfree(Channel *c)
+.XX
+int alt(Alt *alts)
+int recv(Channel *c, void *v)
+void* recvp(Channel *c)
+ulong recvul(Channel *c)
+int nbrecv(Channel *c, void *v)
+void* nbrecvp(Channel *c)
+ulong nbrecvul(Channel *c)
+int send(Channel *c, void *v)
+int sendp(Channel *c, void *v)
+int sendul(Channel *c, ulong v)
+int nbsend(Channel *c, void *v)
+int nbsendp(Channel *c, void *v)
+int nbsendul(Channel *c, ulong v)
+int chanprint(Channel *c, char *fmt, ...)
+int chanclose(Channel *c);
+int chanclosing(Channel *c);
+.XX
+void procexecl(Channel *cpid, char *file, ...)
+void procexec(Channel *cpid, char *file, char *args[])
+Channel* threadwaitchan(void)
+.XX
+int threadnotify(int (*f)(void*, char*), int in)
+.EE
+.SH DESCRIPTION
+The thread library provides parallel programming support similar to that
+of the languages
+Alef and Newsqueak.
+.I Threads
+and
+.I procs
+occupy a shared address space,
+communicating and synchronizing through
+.I channels
+and shared variables.
+.PP
+A
+.I proc
+is a Plan 9 process that contains one or more cooperatively-scheduled
+.IR threads .
+Programs using threads must replace
+.I main
+by
+.IR threadmain .
+The thread library provides a
+.I main
+function that sets up a proc with a single thread executing
+.I threadmain
+on a stack of size
+.I mainstacksize
+(default eight kilobytes).
+To set
+.IR mainstacksize ,
+declare a global variable
+initialized to the desired value
+.RI ( e.g. ,
+.B int
+.B mainstacksize
+.B =
+.BR 1024 ).
+.SS Creation
+.I Threadcreate
+creates a new thread in the calling proc, returning a unique integer
+identifying the thread; the thread
+executes
+.I fn(arg)
+on a stack of size
+.IR stacksize .
+Thread stacks are allocated in shared memory, making it valid to pass
+pointers to stack variables between threads and procs.
+.I Procrfork
+creates a new proc, and inside that proc creates
+a single thread as
+.I threadcreate
+would,
+returning the id of the created thread.
+.I Procrfork
+creates the new proc by calling
+.B rfork
+(see
+.IR fork (2))
+with flags
+.BR RFPROC|RFMEM|RFNOWAIT| \fIrforkflag\fR.
+(The thread library depends on all its procs
+running in the same rendezvous group.
+Do not include
+.B RFREND
+in
+.IR rforkflag .)
+.I Proccreate
+is identical to
+.I procrfork
+with
+.I rforkflag
+set to zero.
+Be aware that the calling thread may continue
+execution before
+the newly created proc and thread
+are scheduled.
+Because of this,
+.I arg
+should not point to data on the stack of a function that could
+return before the new process is scheduled.
+.PP
+.I Threadexits
+terminates the calling thread.
+If the thread is the last in its proc,
+.I threadexits
+also terminates the proc, using
+.I status
+as the exit status.
+.I Threadexitsall
+terminates all procs in the program,
+using
+.I status
+as the exit status.
+.SS Scheduling
+The threads in a proc are coroutines, scheduled non-preemptively
+in a round-robin fashion.
+A thread must explicitly relinquish control of the processor
+before another thread in the same proc is run.
+Calls that do this are
+.IR yield ,
+.IR proccreate ,
+.IR procexec ,
+.IR procexecl ,
+.IR threadexits ,
+.IR alt ,
+.IR send ,
+and
+.I recv
+(and the calls related to
+.I send
+and
+.IR recv \(emsee
+their descriptions further on),
+plus these from
+.IR lock (2):
+.IR qlock ,
+.IR rlock ,
+.IR wlock ,
+.IR rsleep .
+Procs are scheduled by the operating system.
+Therefore, threads in different procs can preempt one another
+in arbitrary ways and should synchronize their
+actions using
+.B qlocks
+(see
+.IR lock (2))
+or channel communication.
+System calls such as
+.IR read (2)
+block the entire proc;
+all threads in a proc block until the system call finishes.
+.PP
+As mentioned above, each thread has a unique integer thread id.
+Thread ids are not reused; they are unique across the life of the program.
+.I Threadid
+returns the id for the current thread.
+Each thread also has a thread group id.
+The initial thread has a group id of zero.
+Each new thread inherits the group id of
+the thread that created it.
+.I Threadgrp
+returns the group id for the current thread;
+.I threadsetgrp
+sets it.
+.I Threadpid
+returns the pid of the Plan 9 process containing
+the thread identified by
+.IR id ,
+or \-1
+if no such thread is found.
+.PP
+.I Threadint
+interrupts a thread that is blocked in a channel operation
+or system call.
+.I Threadintgrp
+interrupts all threads with the given group id.
+.I Threadkill
+marks a thread to die when it next relinquishes the processor
+(via one of the calls listed above).
+If the thread is blocked in a channel operation or system call,
+it is also interrupted.
+.I Threadkillgrp
+kills all threads with the given group id.
+Note that
+.I threadkill
+and
+.I threadkillgrp
+will not terminate a thread that never relinquishes
+the processor.
+.SS Names and per-thread data
+Primarily for debugging,
+threads can have string names associated with them.
+.I Threadgetname
+returns the current thread's name;
+.I threadsetname
+sets it.
+The pointer returned by
+.I threadgetname
+is only valid until the next call to
+.IR threadsetname .
+.PP
+.I Threaddata
+returns a pointer to a per-thread pointer
+that may be modified by threaded programs for
+per-thread storage.
+Similarly,
+.I procdata
+returns a pointer to a per-proc pointer.
+.SS Executing new programs
+.I Procexecl
+and
+.I procexec
+are threaded analogues of
+.I exec
+and
+.I execl
+(see
+.IR exec (2));
+on success,
+they replace the calling thread (which must be the only thread in its proc)
+and invoke the external program, never returning.
+On error, they return \-1.
+If
+.I cpid
+is not null, the pid of the invoked program
+will be sent along
+.I cpid
+once the program has been started, or \-1 will be sent if an
+error occurs.
+.I Procexec
+and
+.I procexecl
+will not access their arguments after sending a result
+along
+.IR cpid .
+Thus, programs that malloc the
+.I argv
+passed to
+.I procexec
+can safely free it once they have
+received the
+.I cpid
+response.
+Note that the mount point
+.B /mnt/temp
+must exist;
+.I procexec(l)
+mount pipes there.
+.PP
+.I Threadwaitchan
+returns a channel of pointers to
+.B Waitmsg
+structures (see
+.IR wait (2)).
+When an exec'ed process exits, a pointer to a
+.B Waitmsg
+is sent to this channel.
+These
+.B Waitmsg
+structures have been allocated with
+.IR malloc (2)
+and should be freed after use.
+.SS Channels
+A
+.B Channel
+is a buffered or unbuffered queue for fixed-size messages.
+Procs and threads
+.I send
+messages into the channel and
+.I recv
+messages from the channel. If the channel is unbuffered, a
+.I send
+operation blocks until the corresponding
+.I recv
+operation occurs and
+.IR "vice versa" .
+.I Chaninit
+initializes a
+.B Channel
+for messages of size
+.I elsize
+and with a buffer holding
+.I nel
+messages.
+If
+.I nel
+is zero, the channel is unbuffered.
+.IR Chancreate
+allocates a new channel and initializes it.
+.I Chanfree
+frees a channel that is no longer used.
+.I Chanfree
+can be called by either sender or receiver after the last item has been
+sent or received. Freeing the channel will be delayed if there is a thread
+blocked on it until that thread unblocks (but
+.I chanfree
+returns immediately).
+.PP
+.I Send
+sends the element pointed at by
+.I v
+to the channel
+.IR c .
+If
+.I v
+is null, zeros are sent.
+.I Recv
+receives an element from
+.I c
+and stores it in
+.IR v .
+If
+.I v
+is null,
+the received value is discarded.
+.I Send
+and
+.I recv
+return 1 on success, \-1 if interrupted.
+.I Nbsend
+and
+.I nbrecv
+behave similarly, but return 0 rather than blocking.
+.PP
+.IR Sendp ,
+.IR nbsendp ,
+.IR sendul ,
+and
+.I nbsendul
+send a pointer or an unsigned long; the channel must
+have been initialized with the appropriate
+.IR elsize .
+.IR Recvp ,
+.IR nbrecvp ,
+.IR recvul ,
+and
+.I nbrecvul
+receive a pointer or an unsigned long;
+they return zero when a zero is received,
+when interrupted, or
+(for
+.I nbrecvp
+and
+.IR nbrecvul )
+when the operation would have blocked.
+To distinguish between these three cases,
+use
+.I recv
+or
+.IR nbrecv .
+.PP
+.I Alt
+can be used to recv from or send to one of a number of channels,
+as directed by an array of
+.B Alt
+structures,
+each of which describes a potential send or receive operation.
+In an
+.B Alt
+structure,
+.B c
+is the channel;
+.B v
+the value pointer (which may be null); and
+.B op
+the operation:
+.B CHANSND
+for a send operation,
+.B CHANRCV
+for a recv operation;
+.B CHANNOP
+for no operation
+(useful
+when
+.I alt
+is called with a varying set of operations).
+The array of
+.B Alt
+structures is terminated by an entry with
+.I op
+.B CHANEND
+or
+.BR CHANNOBLK .
+If at least one
+.B Alt
+structure can proceed, one of them is
+chosen at random to be executed.
+.I Alt
+returns the index of the chosen structure.
+If no operations can proceed and the list is terminated with
+.BR CHANNOBLK ,
+.I alt
+returns the index of the terminating
+.B CHANNOBLK
+structure.
+Otherwise,
+.I alt
+blocks until one of the operations can proceed,
+eventually returning the index of the structure executes.
+.I Alt
+returns \-1 when interrupted.
+The
+.B tag
+and
+.B entryno
+fields in the
+.B Alt
+structure are used internally by
+.I alt
+and need not be initialized.
+They are not used between
+.I alt
+calls.
+.PP
+.I Chanprint
+formats its arguments in the manner of
+.IR print (2)
+and sends the result to the channel
+.IR c .
+The string delivered by
+.I chanprint
+is allocated with
+.IR malloc (2)
+and should be freed upon receipt.
+.PP
+.I Chanclose
+prevents further elements being sent to the channel
+.IR c .
+After closing a channel,
+.I send
+and
+.I recv
+never block.
+.I Send
+always
+returns \-1.
+.I Recv
+returns \-1 if the channel is empty.
+.I Alt
+may choose a
+.B CHANSND
+or
+.B CHANRCV
+that failed because the channel was closed.
+In this case, the
+.B err
+field of the
+.B Alt
+entry points to an error string stating that the
+channel was closed and the operation was completed
+with failure.
+If all entries have been selected and failed because
+they were closed,
+.I alt
+returns \-1.
+.SS Errors, notes and resources
+Thread library functions do not return on failure;
+if errors occur, the entire program is aborted.
+.PP
+.I Chanclosing
+returns \-1 if no one called
+.I closed
+on the channel, and otherwise
+the number of elements still in the channel.
+.PP
+Threaded programs should use
+.I threadnotify
+in place of
+.I atnotify
+(see
+.IR notify (2)).
+.PP
+It is safe to use
+.B sysfatal
+(see
+.IR perror (2))
+in threaded programs.
+.I Sysfatal
+will print the error string and call
+.IR threadexitsall .
+.PP
+It is safe to use
+.IR rfork
+(see
+.IR fork (2))
+to manage the namespace, file descriptors, note group, and environment of a
+single process.
+That is, it is safe to call
+.I rfork
+with the flags
+.BR RFNAMEG ,
+.BR RFFDG ,
+.BR RFCFDG ,
+.BR RFNOTEG ,
+.BR RFENVG ,
+and
+.BR RFCENVG.
+(To create new processes, use
+.I proccreate
+and
+.IR procrfork .)
+As mentioned above,
+the thread library depends on all procs being in the
+same rendezvous group; do not change the rendezvous
+group with
+.IR rfork .
+.SH FILES
+.TF /sys/lib/acid/thread
+.TP
+.B /sys/lib/acid/thread
+useful
+.IR acid (1)
+functions for debugging threaded programs.
+.TP
+.B /sys/src/libthread/example.c
+a full example program.
+.TP
+.B /mnt/temp
+a place for
+.I procexec
+to create pipes.
+.SH SOURCE
+.B /sys/src/libthread
+.SH SEE ALSO
+.IR intro (2),
+.IR ioproc (2),
+.IR lock (2)
diff --git a/sys/man/2/time b/sys/man/2/time
new file mode 100755
index 000000000..d2af5a5f4
--- /dev/null
+++ b/sys/man/2/time
@@ -0,0 +1,44 @@
+.TH TIME 2
+.SH NAME
+time, nsec \- time in seconds and nanoseconds since epoch
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.nf
+.B
+long time(long *tp)
+.PP
+.B
+vlong nsec(void)
+.SH DESCRIPTION
+Both
+.I time
+and
+.I nsec
+return the time since the epoch 00:00:00 GMT, Jan. 1, 1970.
+The return value of the former is in seconds and the latter in nanoseconds.
+For
+.IR time ,
+if
+.I tp
+is not zero then
+.BI * tp
+is also set to the answer.
+.PP
+These functions work by reading
+.BR /dev/bintime ,
+opening that file when they are first called.
+.SH SOURCE
+.B /sys/src/libc/9sys/time.c
+.br
+.B /sys/src/libc/9sys/nsec.c
+.SH SEE ALSO
+.IR cputime (2),
+.IR cons (3)
+.SH DIAGNOSTICS
+Sets
+.IR errstr .
+.SH BUGS
+These routines maintain a static file descriptor.
diff --git a/sys/man/2/tmpfile b/sys/man/2/tmpfile
new file mode 100755
index 000000000..390b2346c
--- /dev/null
+++ b/sys/man/2/tmpfile
@@ -0,0 +1,60 @@
+.TH TMPFILE 2
+.SH NAME
+tmpfile, tmpnam \- Stdio temporary files
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <stdio.h>
+.PP
+.ta \w'\fLFILE 'u
+.B
+FILE *tmpfile(void)
+.PP
+.B
+char *tmpnam(char *s)
+.SH DESCRIPTION
+.I Tmpfile
+creates a temporary file that will automatically
+be removed when the file is closed or the program exits.
+The return value is a Stdio
+.B FILE*
+opened in update mode (see
+.IR fopen (2)).
+.PP
+.I Tmpnam
+generates a string that is a valid file name and that is not
+the same as the name of an existing file.
+If
+.I s
+is zero, it returns a pointer to a string which may be overwritten by
+subsequent calls to
+.IR tmpnam .
+If
+.I s
+is non-zero, it should point to an array of at least
+.B L_tmpnam
+(defined in
+.BR <stdio.h> )
+characters, and the answer will be copied there.
+.SH FILES
+.TF /tmp/tf000000000000
+.TP
+.B /tmp/tf000000000000
+template for
+.I tmpfile
+file names.
+.TP
+.B /tmp/tn000000000000
+template for
+.I tmpnam
+file names.
+.SH SOURCE
+.B /sys/src/libstdio
+.SH BUGS
+The files created by
+.I tmpfile
+are not removed until
+.IR exits (2)
+is executed; in particular, they are not removed on
+.I fclose
+or if the program terminates abnormally.
diff --git a/sys/man/2/usb b/sys/man/2/usb
new file mode 100755
index 000000000..d6f949f98
--- /dev/null
+++ b/sys/man/2/usb
@@ -0,0 +1,460 @@
+.TH USB 2
+.SH NAME
+usbcmd,
+classname,
+closedev,
+configdev,
+devctl,
+finddevs,
+loaddevstr,
+matchdevcsp,
+opendev,
+opendevdata,
+openep,
+startdevs,
+unstall,
+class,
+subclass,
+proto,
+CSP \- USB device driver library
+.SH SYNOPSIS
+.EX
+.ta 8n +8n +8n +8n +8n +8n +8n
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include "../lib/usb.h"
+.sp 0.3v
+struct Dev {
+ Ref;
+ char* dir; /* path for the endpoint dir */
+ int id; /* usb id for device or ep. number */
+ int dfd; /* descriptor for the data file */
+ int cfd; /* descriptor for the control file */
+ int maxpkt; /* cached from usb description */
+ Usbdev* usb; /* USB description */
+ void* aux; /* for the device driver */
+ void (*free)(void*); /* idem. to release aux */
+};
+.sp 0.3v
+struct Usbdev {
+ ulong csp; /* USB class/subclass/proto */
+ int vid; /* vendor id */
+ int did; /* product (device) id */
+ int dno; /* device release number */
+ char* vendor;
+ char* product;
+ char* serial;
+ int ls; /* low speed */
+ int class; /* from descriptor */
+ int nconf; /* from descriptor */
+ Conf* conf[Nconf]; /* configurations */
+ Ep* ep[Nep]; /* all endpoints in device */
+ Desc* ddesc[Nddesc]; /* (raw) device specific descriptors */
+};
+.sp 0.3v
+struct Ep {
+ uchar addr; /* endpt address */
+ uchar dir; /* direction, Ein/Eout */
+ uchar type; /* Econtrol, Eiso, Ebulk, Eintr */
+ uchar isotype; /* Eunknown, Easync, Eadapt, Esync */
+ int id;
+ int maxpkt; /* max. packet size */
+ Conf* conf; /* the endpoint belongs to */
+ Iface* iface; /* the endpoint belongs to */
+};
+.sp 0.3v
+struct Altc {
+ int attrib;
+ int interval;
+ void* aux; /* for the driver program */
+};
+.sp 0.3v
+struct Iface {
+ int id; /* interface number */
+ ulong csp; /* USB class/subclass/proto */
+ Altc* altc[Naltc];
+ Ep* ep[Nep];
+ void* aux; /* for the driver program */
+};
+.sp 0.3v
+struct Conf {
+ int cval; /* value for set configuration */
+ int attrib;
+ int milliamps; /* maximum power in this config. */
+ Iface* iface[Niface]; /* up to 16 interfaces */
+};
+.sp 0.3v
+struct Desc {
+ Conf* conf; /* where this descriptor was read */
+ Iface* iface; /* last iface before desc in conf. */
+ Ep* ep; /* last endpt before desc in conf. */
+ Altc* altc; /* last alt.c. before desc in conf. */
+ DDesc data; /* unparsed standard USB descriptor */
+};
+.sp 0.3v
+struct DDesc {
+ uchar bLength;
+ uchar bDescriptorType;
+ uchar bbytes[1];
+ /* extra bytes allocated here to keep the rest of it */
+};
+.sp 0.3v
+#define Class(csp) ((csp)&0xff)
+#define Subclass(csp) (((csp)>>8)&0xff)
+#define Proto(csp) (((csp)>>16)&0xff)
+#define CSP(c, s, p) ((c) | ((s)<<8) | ((p)<<16))
+#define GET2(p) ...
+#define PUT2(p,v) ...
+#define GET4(p) ...
+#define PUT4(p,v) ...
+#define dprint if(usbdebug)fprint
+#define ddprint if(usbdebug > 1)fprint
+.sp 0.3v
+int Ufmt(Fmt *f);
+char* classname(int c);
+void closedev(Dev *d);
+int configdev(Dev *d);
+int devctl(Dev *dev, char *fmt, ...);
+void* emallocz(ulong size, int zero);
+char* estrdup(char *s);
+int finddevs(int (*matchf)(char*,void*), void *farg, char** dirs, int ndirs);
+char* hexstr(void *a, int n);
+char* loaddevstr(Dev *d, int sid);
+int matchdevcsp(char *info, void *a);
+Dev* opendev(char *fn);
+int opendevdata(Dev *d, int mode);
+Dev* openep(Dev *d, int id);
+void startdevs(char *args, char *argv[], int argc,
+ int (*mf)(char*,void*), void*ma, int (*df)(Dev*,int,char**));
+int unstall(Dev *dev, Dev *ep, int dir);
+int usbcmd(Dev *d, int type, int req,
+ int value, int index, uchar *data, int count);
+.sp 0.3v
+extern int usbdebug; /* more messages for bigger values */
+.EE
+.SH DESCRIPTION
+This library provides convenience structures and functions to write
+USB device drivers.
+It is not intended for user programs using USB devices.
+See
+.IR usb (3)
+for a description of the interfaces provided for that purpose.
+For drivers that provide a file system and may be embedded into
+.IR usbd ,
+the library includes a file system implementation toolkit described in
+.IR usbfs (2).
+.PP
+Usb drivers rely on
+.IR usb (3)
+to perform I/O through USB as well as on
+.IR usbd (4)
+to perform the initial configuration for the device's setup endpoint.
+The rest of the work is up to the driver and is where this library may help.
+.PP
+In most cases, a driver locates the devices of interest and configures them
+by calling
+.I startdevs
+and
+then sets up additional endpoints as needed (by calling
+.IR openep )
+to finally perform I/O by reading and writing the
+data files for the endpoints.
+.PP
+An endpoint as provided by
+.IR usb (3)
+is represented by a
+.B Dev
+data structure.
+The setup endpoint for a
+device represents the USB device, because it is the means to
+configure and operate the device.
+This structure is reference counted.
+Functions creating
+.B Devs
+adjust the number of references to one, initially.
+The driver is free to call
+.IR incref
+(in
+.IR lock (2))
+to add references and
+.I closedev
+to drop references (and release resources when the last one vanishes).
+As an aid to the driver, the field
+.B aux
+may keep driver-specific data and the function
+.B free
+will be called (if not null) to release the
+.B aux
+structure when the reference count goes down to zero.
+.PP
+.I Dev.dir
+holds the path for the endpoint's directory.
+.PP
+The field
+.B id
+keeps the device number for setup endpoints and the endpoint number
+for all other endpoints.
+For example, it would be
+.B 3
+for
+.B /dev/usb/ep3.0
+and
+.B 1
+for
+.BR /dev/usb/ep3.1 .
+It is easy to remember this because the former is created to operate
+on the device, while the later has been created as a particular endpoint
+to perform I/O.
+.PP
+Fields
+.B dfd
+and
+.B cfd
+keep the data and
+control file descriptors, respectively.
+When a
+.B Dev
+is created the control file is open, initially.
+Opening the data
+file requires calling
+.I opendevdata
+with the appropriate mode.
+.PP
+When the device configuration information has been loaded (see below),
+.B maxpkt
+holds the maximum packet size (in bytes) for the endpoint and
+.B usb
+keeps the rest of the USB information.
+.PP
+Most of the information in
+.B usb
+comes from parsing
+various device and configuration descriptors provided by the device,
+by calling one of the functions described later.
+Only descriptors unknown
+to the library are kept unparsed at
+.B usb.ddesc
+as an aid for the driver
+(which should know how to parse them and what to do with the information).
+.SS Configuration
+.I Startdevs
+is a wrapper that locates devices of interest, loads their configuration
+information, and starts a
+.IR thread (2)'s
+.I proc
+for each device located so that it executes
+.I f
+as its main entry point. The entry point is called with a pointer to
+the
+.B Dev
+for the device it has to process,
+.BR argc ,
+and
+.BR argv .
+Devices are located either from the arguments (after options) in
+.IR argv ,
+if any,
+or by calling the helper function
+.I mf
+with the argument
+.I ma
+to determine (for each device available) if the device belongs to
+the driver or not. If the function returns -1 then the device is not for us.
+.PP
+In many cases,
+.I matchdevcsp
+may be supplied as
+.I mf
+along with a (null terminated) vector of CSP values supplied as
+.IR ma .
+This function returns 0 for any device with a CSP matching one in the
+vector supplied as an argument and -1 otherwise.
+In other cases (eg., when a particular vendor and device ids are the
+ones identifying the device) the driver must include its own function
+and supply it as an argument to
+.IR startdevs .
+The first argument of the function corresponds to the information
+known about the device (the second line in its
+.B ctl
+file).
+.I Openep
+creates the endpoint number
+.I id
+for the device
+.I d
+and returns a
+.B Dev
+structure to operate on it (with just the control file open).
+.PP
+.I Opendev
+creates a
+.B Dev
+for the endpoint with directory
+.IR fn .
+Usually, the endpoint is a setup endpoint representing a device. The endpoint
+control file is open, but the data file is not. The USB description is void.
+In most cases drivers call
+.I startdevs
+and
+.I openep
+and do not call this function directly.
+.PP
+.I Configdev
+opens the data file for the device supplied and
+loads and parses its configuration information.
+After calling it, the device is ready for I/O and the USB description in
+.B Dev.usb
+is valid.
+When using
+.IR startdevs
+it is not desirable to call this function (because
+.IR startdevs
+already calls it).
+.PP
+Control requests for an endpoint may be written by calling
+.I devctl
+in the style of
+.IR print (2).
+It is better not to call
+.I print
+directly because the control request should be issued as a single
+.I write
+system call.
+See
+.IR usb (3)
+for a list of available control requests (not to be confused with
+USB control transfers performed on a control endpoint).
+.SS Input/Output
+.I Opendevdata
+opens the data file for the device according to the given
+.IR mode .
+The mode must match that of the endpoint, doing otherwise is considered
+an error.
+Actual I/O is performed by reading/writing the descriptor kept in the
+.B dfd
+field of
+.BR Dev .
+.PP
+For control endpoints,
+it is not necessary to call
+.I read
+and
+.I write
+directly.
+Instead,
+.I usbcmd
+issues a USB control request to the device
+.I d
+(not to be confused with a
+.IR usb (3)
+control request sent to its control file).
+.I Usbcmd
+retries the control request several times upon failure because some devices
+require it.
+The format of requests is fixed per the USB standard:
+.I type
+is the type of request and
+.I req
+identifies the request. Arguments
+.I value
+and
+.I index
+are parameters to the request and the last two arguments,
+.I data
+and
+.IR count ,
+are similar to
+.I read
+and
+.I write
+arguments.
+However,
+.I data
+may be
+.B nil
+if no transfer (other than the control request) has to take place.
+The library header file includes numerous symbols defined to help writing
+the type and arguments for a request.
+.PP
+The return value from
+.I usbcmd
+is the number of bytes transferred, zero to indicate a stall and -1
+to indicate an error.
+.PP
+A common request is to unstall an endpoint that has been stalled
+due to some reason by the device (eg., when read or write indicate
+a count of zero bytes read or written on the endpoint). The function
+.I unstall
+does this.
+It is given the device that stalled the endpoint,
+.IR dev ,
+the
+stalled endpoint,
+.IR ep ,
+and the direction of the stall (one of
+.B Ein
+or
+.BR Eout ).
+The function takes care of notifying the device of the unstall as well
+as notifying the kernel.
+.SS Tools
+.I Class
+returns the class part of the number given, representing a CSP.
+.I Subclass
+does the same for the device subclass and
+.I Proto
+for the protocol.
+The counterpart is
+.IR CSP ,
+which builds a CSP from the device class, subclass, and protocol.
+For some classes,
+.I classname
+knows the name (for those with constants in the library header file).
+.PP
+The macros
+.I GET2
+and
+.I PUT2
+get and put a (little-endian) two-byte value and are useful to
+parse descriptors and replies for control requests.
+.PP
+Functions
+.I emallocz
+and
+.I estrdup
+are similar to
+.I mallocz
+and
+.I strdup
+but abort program operation upon failure.
+.PP
+The function
+.I Ufmt
+is a format routine suitable for
+.IR fmtinstall (2)
+to print a
+.B Dev
+data structure.
+The auxiliary
+.I hexstr
+returns a string representing a dump (in hexadecimal) of
+.I n
+bytes starting at
+.IR a .
+The string is allocated using
+.IR malloc (2)
+and memory must be released by the caller.
+.PP
+.I Loaddevstr
+returns the string obtained by reading the device string descriptor number
+.IR sid .
+.SH SOURCE
+.B /sys/src/cmd/usb/lib
+.SH "SEE ALSO"
+.IR usbfs (2),
+.IR usb (3),
+.IR usb (4),
+.IR usbd (4).
+.SH BUGS
+Not heavily exercised yet.
diff --git a/sys/man/2/usbfs b/sys/man/2/usbfs
new file mode 100755
index 000000000..6c76280a8
--- /dev/null
+++ b/sys/man/2/usbfs
@@ -0,0 +1,341 @@
+.TH USBFS 2
+.SH NAME
+usbreadbuf,
+usbfsadd,
+usbfsdel,
+usbdirread,
+usbfsinit,
+usbdirfs,
+usbfs \- USB device driver file system library
+.SH SYNOPSIS
+.EX
+.ta 8n +8n +8n +8n +8n +8n +8n
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include "../lib/usb.h"
+#include "../lib/usbfs.h"
+.sp 0.3v
+enum {
+ Hdrsize = 128, /* plenty of room for headers */
+ Msgsize = 8 * 1024,
+ Bufsize = Hdrsize + Msgsize,
+ Namesz = 40,
+ Errmax = 128,
+ ONONE = ~0, /* omode in Fid when not open */
+};
+.sp 0.3v
+struct Fid {
+ int fid;
+ Qid qid;
+ int omode;
+ Fid* next;
+ void* aux;
+};
+.sp 0.3v
+struct Usbfs {
+ char name[Namesz];
+ uvlong qid;
+ Dev* dev;
+ void* aux;
+.sp 0.3v
+ int (*walk)(Usbfs *fs, Fid *f, char *name);
+ void (*clone)(Usbfs *fs, Fid *of, Fid *nf);
+ void (*clunk)(Usbfs *fs, Fid *f);
+ int (*open)(Usbfs *fs, Fid *f, int mode);
+ long (*read)(Usbfs *fs, Fid *f,
+ void *data, long count, vlong offset);
+ long (*write)(Usbfs *fs, Fid*f,
+ void *data, long count, vlong offset);
+ int (*stat)(Usbfs *fs, Qid q, Dir *d);
+ void (*end)(Usbfs *fs);
+};
+.sp 0.3v
+typedef int (*Dirgen)(Usbfs*, Qid, int, Dir*, void*);
+.sp 0.3v
+long usbreadbuf(void *data, long count,
+ vlong offset, void *buf, long n);
+void usbfsadd(Usbfs *dfs);
+void usbfsdel(Usbfs *dfs);
+int usbdirread(Usbfs*f, Qid q, char *data, long cnt,
+ vlong off, Dirgen gen, void *arg);
+void usbfsinit(char* srv, char *mnt, Usbfs *f, int flag);
+void usbfsdirdump(void);
+.sp 0.3v
+extern char Enotfound[], Etoosmall[], Eio[], Eperm[], Ebadcall[],
+ Ebadfid[], Einuse[], Eisopen[], Ebadctl[];
+.sp 0.3v
+extern Usbfs usbdirfs;
+extern int usbfsdebug;
+.EE
+.SH DESCRIPTION
+This library provides an alternative to
+.IR 9p (2)
+for implementing a file server within a USB driver.
+Drivers using this
+library may be embedded into
+.IR usbd (4).
+It may be also desirable to use this library when drivers are
+not embedded because it is tailored to work well with the
+library for handling USB devices.
+.PP
+A USB file system is described by a
+.I Usbfs
+structure.
+In most cases, the driver is not responsible for the root of the
+file tree.
+It is customary that a driver creates a file server
+for each device handled and links all of them to a root directory
+implemented by the
+.I usbdirfs
+file system implemented by the library.
+This root directory is bound to
+.B /dev
+in most cases.
+.PP
+.I Usbdirfs
+implements a root directory populated by named file trees,
+each one described by a
+.B Usbfs
+structure.
+.PP
+The field
+.B Usbfs.name
+contains the name for the root directory of the file system, usually
+a directory seen at
+.BI /dev/ name
+when the driver is embedded.
+.PP
+.B Usbfs.qid
+maintains a value used to decorate qids for the file tree.
+This may be ignored when
+.I usbdirfs
+is not used.
+Otherwise,
+.I usbdirfs
+assigns a unique value kept at the high 32 bits of
+.B Qid.path
+for all files on each file tree bound to it.
+Each
+.I Usbfs
+server must bitwise OR
+.B Usbfs.qid
+to all
+.B Qid.path
+values returned by its functions.
+In the same way,
+functions usually clear bits in
+.B Usbfs.qid
+before processing
+.B Qid.path
+values supplied as input.
+.PP
+The USB device handled by a file tree is referenced from
+.B Usbfs.dev
+(and a reference must be counted for it).
+This permits the following functions to quickly locate the device of
+interest, and also permits releasing the device when
+no request is outstanding.
+.PP
+The field
+.B Usbfs.aux
+is for the device to use.
+The rest of the fields implement the 9P protocol for the device.
+Not all the operations need be implemented.
+Only
+.IR walk ,
+.IR open ,
+.IR read ,
+.IR write ,
+and
+.IR stat ,
+must be implemented (and their corresponding fields in
+.B Usbfs
+may never be
+.BR nil ).
+These functions must return -1 upon failure
+and set the error string to reflect the cause of a failure.
+.PP
+In all the functions, a 9P fid is represented by a
+.B Fid
+structure.
+It contains the 9P
+.IR fid ,
+the corresponding
+.IR qid ,
+and an auxiliary pointer for the driver to use.
+Open
+.IR fid s
+have a valid open mode in
+.I omode
+while others have
+.B ONONE
+to indicate that the
+.I fid
+is not open.
+The library takes care of which
+fids
+exist and which ones do not.
+.PP
+.I Walk
+must walk
+.I f
+to
+.I name
+(a single name, not a file path)
+in the supplied
+.IR fs .
+Its implementation should update the qid in
+.I f
+to reflect the walk.
+This function must bitwise OR any returned Qid with
+.B Usbfs.qid ,
+if
+.I usbdirfs
+is used.
+.PP
+.I Clone
+must clone fid
+.I of
+onto
+.I nf
+so that,
+upon successful completion,
+.I nf
+also refers to the file that
+.I f
+refers to.
+An implementation must update the Qid of the cloned
+fid.
+If this function is not supplied, the library copies the
+.I aux
+field to the cloned fid.
+.PP
+.I Clunk
+clunks
+.IR f .
+It usually releases data kept in the
+.I aux
+field, but may be
+set to
+.B nil
+otherwise.
+.PP
+.I Open
+prepares the fid
+.I f
+for I/O according to
+.IR mode .
+The open mode in the fid is updated by the library upon return.
+The library checks trivial cases like opening already-open fids.
+The implementation performs most permission checking.
+.PP
+.I Read
+reads up to
+.I count
+bytes into
+.I data
+starting at
+.I offset
+in the file referenced by
+.IR f .
+.I Write
+is the counterpart.
+To read from directories,
+the function
+.I usbdirread
+may be called.
+It returns the return value of
+.I read
+or -1.
+.I usbdirread
+calls
+.I gen
+to iterate through files as needed.
+The
+.B Dirgen
+function will be called with index values of 0
+and up to ask for the first file and following files.
+To read from data already in buffers, the function
+.I usbreadbuf
+may help.
+It must be given the arguments supplied
+by the user, plus the buffer and buffer size.
+.PP
+.I Stat
+must fill
+.I d
+with the directory entry for the file identified by
+.IR q.
+As an aid,
+.I d
+is initialized to fake access and modification times,
+and user and group ids.
+Also, the field
+.B name
+in
+.I d
+is initialized to point to a 40-byte buffer.
+If the file name fits,
+it may be copied directly into
+.B d->name
+without allocating memory for that purpose.
+Otherwise
+.B d->name
+must be initialized to point to static memory.
+.PP
+The function
+.I end
+is called upon termination of the file tree to
+release resources.
+.PP
+Calling
+.I usbfsinit
+starts a file server for
+.I f
+that mounts itself at
+.I mnt
+and posts
+.I srv
+at
+.IR srv (3).
+In most cases, the file system supplied is
+.IR usbdirfs .
+The
+.I flag
+is used for
+.IR mount
+(see
+.IR bind (2)).
+Once
+.I usbdirfs
+is started, calls to
+.IR usbfsadd
+add a file tree implemented by
+.I dfs
+to the root directory of
+.I usbdirfs
+and
+calls to
+.I usbfsdel
+remove that binding (and release resources including
+the reference to the USB device).
+.PP
+Various error strings are declared as an aid.
+The global
+.B usbfsdebug
+may be set to trigger diagnostics and protocol tracing.
+.SH EXAMPLE
+See
+.B /sys/src/cmd/usb/disk
+for an example driver that uses this library.
+Looking at an example is strongly suggested
+to see how reference counts for the USB device
+and the file system are handled.
+.SH SOURCE
+.B /sys/src/cmd/usb/lib
+.SH "SEE ALSO"
+.IR usb (2),
+.IR usb (3),
+.IR usb (4),
+.IR usbd (4)
diff --git a/sys/man/2/venti b/sys/man/2/venti
new file mode 100755
index 000000000..7fd292404
--- /dev/null
+++ b/sys/man/2/venti
@@ -0,0 +1,72 @@
+.TH VENTI 2
+.SH NAME
+venti \- archival storage server
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.SH DESCRIPTION
+The Venti library provides support for writing Venti servers and clients.
+Other manual pages describe the library functions in detail.
+.PP
+.IR Venti-cache (2)
+describes a simple in-memory block cache to help clients.
+.PP
+.IR Venti-conn (2)
+describes routines for manipulating network connections
+between Venti clients and servers.
+.IR Venti-client (2)
+and
+.IR venti-server (2)
+describe routines for writing clients
+and servers on top of these.
+.PP
+.IR Venti-fcall (2)
+describes the C representation of Venti protocol messages
+and data structures.
+It also describes routines that convert between the C representation
+and the network and disk representations.
+.PP
+.IR Venti-file (2)
+describes routines for writing clients that manipulate
+Venti file trees
+(see
+.IR venti (6)).
+.PP
+.IR Venti-log (2)
+describes routines to access in-memory log buffers
+as well as the logging that is done automatically by
+the library.
+.PP
+.IR Venti-mem (2)
+describes wrappers around the canonical
+.IR malloc (2)
+routines that abort on error.
+.PP
+.IR Venti-packet (2)
+describes routines for
+manipulating zero-copy chains of
+data buffers.
+.PP
+.IR Venti-zero (2)
+describes routines to zero truncate and zero extend blocks
+(see
+.IR venti (6)).
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (1),
+.IR venti-cache (2),
+.IR venti-client (2),
+.IR venti-fcall (2),
+.IR venti-file (2)
+.IR venti-log (2),
+.IR venti-mem (2),
+.IR venti-packet (2),
+.IR venti-server (2),
+.IR venti-zero (2),
+.IR venti (6),
+.IR venti (8)
diff --git a/sys/man/2/venti-cache b/sys/man/2/venti-cache
new file mode 100755
index 000000000..bca14bd7a
--- /dev/null
+++ b/sys/man/2/venti-cache
@@ -0,0 +1,246 @@
+.TH VENTI-CACHE 2
+.SH NAME
+VtBlock, VtCache,
+vtblockcopy,
+vtblockdirty,
+vtblockduplock,
+vtblockput,
+vtblockwrite,
+vtcachealloc,
+vtcacheallocblock,
+vtcacheblocksize,
+vtcachefree,
+vtcacheglobal,
+vtcachelocal,
+vtcachesetwrite,
+vtglobaltolocal,
+vtlocaltoglobal \- Venti block cache
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLxxxx 'u
+.PP
+.ft L
+.nf
+typedef struct VtBlock
+{
+ uchar *data;
+ uchar type;
+ uchar score[VtScoreSize];
+ u32int addr;
+ ...
+} VtBlock;
+.ta +\w'\fLVtBlock* 'u +\w'\fLxxxxxxxx'u
+.PP
+.B
+VtCache* vtcachealloc(VtConn *z, int blocksize, ulong nblocks);
+.PP
+.B
+void vtcachefree(VtCache *c);
+.PP
+.B
+u32int vtcacheblocksize(VtCache *c);
+.PP
+.B
+u32int vtglobaltolocal(uchar score[VtScoreSize])
+.br
+.B
+void vtlocaltoglobal(u32int local, uchar score[VtScoreSize])
+.PP
+.B
+VtBlock* vtcacheallocblock(VtCache *c, int type);
+.PP
+.B
+VtBlock* vtcachelocal(VtCache *c, u32int addr, int type);
+.PP
+.B
+VtBlock* vtcacheglobal(VtCache *c, uchar[VtScoreSize], int type);
+.PP
+.B
+void vtblockput(VtBlock *b);
+.PP
+.B
+void vtblockduplock(VtBlock *b);
+.PP
+.B
+int vtblockwrite(VtBlock *b);
+.PP
+.B
+void vtcachesetwrite(VtCache *c,
+.br
+.B
+ int (*write)(VtConn*, uchar[VtScoreSize], uint, uchar*, int));
+.PP
+.B
+VtBlock* vtblockcopy(VtBlock *b);
+.PP
+.B
+int vtblockdirty(VtBlock *b);
+.SH DESCRIPTION
+These functions provide access to a simple in-memory
+cache of blocks already stored on a Venti server
+and blocks that will eventually be stored on a Venti server.
+.PP
+A
+.B VtBlock
+represents a venti data block.
+Blocks stored on a venti server,
+called
+.IR "global blocks" ,
+are named by the SHA1 hash of their contents.
+This hash is recorded as the block's
+.IR score .
+Such blocks are immutable.
+The cache also stores mutable blocks that have not yet been
+written to a venti server. These blocks are called
+.IR "local blocks" ,
+and have special scores that are 16 zero bytes
+followed by a 4-byte big-endian
+.IR address .
+The address is an index into the internal set of cache blocks.
+.PP
+The user-visible contents of a
+.B VtBlock
+are
+.BR data ,
+a pointer to the data;
+.BR type ,
+the venti block type;
+.BR score ,
+the block's score;
+and
+.BR addr ,
+the block's cache address.
+.PP
+.I Vtcachealloc
+allocates a new cache using the client connection
+.I z
+(see
+.IR venti-conn (2)
+and
+.IR venti-client (2)),
+with room for
+.I nblocks
+of maximum block size
+.I blocksize .
+.PP
+.I Vtcachefree
+frees a cache and all the associated blocks.
+.PP
+.I Vtcacheblocksize
+returns the cache's maximum block size.
+.PP
+.I Vtglobaltolocal
+returns the local address corresponding to the given
+local
+.IR score .
+If passed a global score,
+.I vtglobaltolocal
+returns the special constant
+.B NilBlock
+.RB ( ~0 ).
+.I Vtlocaltoglobal
+is the opposite, setting
+.I score
+to the local score for the cache address
+.IR local .
+.PP
+.I Vtcacheallocblock
+allocates a new local block with the given
+.IR type .
+.PP
+.I Vtcachelocal
+retrieves the local block at address
+.I addr
+from the cache.
+The given
+.I type
+must match the type of the block found at
+.IR addr .
+.PP
+.I Vtcacheglobal
+retrieves the block with the given
+.I score
+and
+.I dtype
+from the cache, consulting the Venti server
+if necessary.
+If passed a local score,
+.I vtcacheglobal
+invokes
+.I vtcachelocal
+appropriately.
+.PP
+The block references returned by
+.IR vtcacheallocblock ,
+.IR vtcachelocal ,
+and
+.I vtcacheglobal
+must be released when no longer needed.
+.I Vtblockput
+releases such a reference.
+.PP
+It is occasionally convenient to have multiple variables
+refer to the same block.
+.I Vtblockduplock
+increments the block's reference count so that
+an extra
+.I vtblockput
+will be required in order to release the block.
+.PP
+.I Vtblockwrite
+writes a local block to the Venti server,
+changing the block to a global block.
+It calls the cache's
+.I write
+function
+to write the block to the server.
+The default
+.I write
+function is
+.I vtwrite
+(see
+.IR venti-client (2));
+.I vtsetcachewrite
+sets it.
+.I Vtsetcachewrite
+is used by clients to install replacement functions
+that run writes in the background or perform other
+additional processing.
+.PP
+.I Vtblockcopy
+copies a block in preparation for modifying its contents.
+The old block may be a local or global block,
+but the new block will be a local block.
+.PP
+The cache only evicts global blocks.
+Local blocks can only leave the cache via
+.IR vtblockwrite ,
+which turns them into global blocks, making them candidates for
+eviction.
+.PP
+If a new cache block must be allocated (for
+.IR vtcacheallocblock ,
+.IR vtcachelocal ,
+.IR vtcacheglobal ,
+or
+.IR vtblockcopy ),
+but the cache is filled (with local blocks and blocks that
+have not yet been released with
+.IR vtblockput ),
+the library prints the score and reference count of
+every block in the cache and then aborts.
+A full cache indicates either that the cache is too small,
+or, more commonly, that cache blocks are being leaked.
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (2),
+.IR venti-client (2),
+.IR venti-conn (2),
+.IR venti-file (2),
+.IR venti (6)
diff --git a/sys/man/2/venti-client b/sys/man/2/venti-client
new file mode 100755
index 000000000..a77f63ca2
--- /dev/null
+++ b/sys/man/2/venti-client
@@ -0,0 +1,190 @@
+.TH VENTI-CLIENT 2
+.SH NAME
+vtconnect, vthello, vtread, vtwrite, vtreadpacket, vtwritepacket, vtsync, vtping, vtrpc, ventidoublechecksha1 \- Venti client
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLPacket* 'u +\w'\fLxxxxxxxx'u
+.PP
+.B
+Packet* vtrpc(VtConn *z, Packet *p)
+.PP
+.B
+int vthello(VtConn *z)
+.PP
+.B
+int vtconnect(VtConn *z)
+.PP
+.B
+int vtread(VtConn *z, uchar score[VtScoreSize],
+.br
+.B
+ uint type, uchar *buf, int n)
+.PP
+.B
+int vtwrite(VtConn *z, uchar score[VtScoreSize],
+.br
+.B
+ uint type, uchar *buf, int n)
+.PP
+.B
+Packet* vtreadpacket(VtConn *z, uchar score[VtScoreSize],
+.br
+.B
+ uint type, int n)
+.PP
+.B
+int vtwritepacket(VtConn *z, uchar score[VtScoreSize],
+.br
+.B
+ uint type, Packet *p)
+.PP
+.B
+int vtsync(VtConn *z)
+.PP
+.B
+int vtping(VtConn *z)
+.PP
+.B
+extern int ventidoublechecksha1; /* default 1 */
+.SH DESCRIPTION
+These routines execute the client side of the
+.IR venti (6)
+protocol.
+.PP
+.I Vtrpc
+executes a single Venti RPC transaction, sending the request
+packet
+.IR p
+and then waiting for and returning the response packet.
+.I Vtrpc
+will set the tag in the packet.
+.I Vtrpc
+frees
+.IR p ,
+even on error.
+.I Vtrpc
+is typically called only indirectly, via the functions below.
+.PP
+.I Vthello
+executes a
+.B hello
+transaction, setting
+.IB z ->sid
+to the name used by the server.
+.I Vthello
+is typically called only indirectly, via
+.IR vtconnect .
+.PP
+.I Vtconnect
+calls
+.I vtversion
+(see
+.IR venti-conn (2))
+and
+.IR vthello ,
+in that order, returning success only
+if both succeed.
+This sequence (calling
+.I vtversion
+and then
+.IR vthello )
+must be done before the functions below can be called.
+.PP
+.I Vtread
+reads the block with the given
+.I score
+and
+.I type
+from the server,
+stores the returned data
+in memory at
+.IR buf ,
+and returns the number of bytes read.
+If the server's block has size larger than
+.IR n ,
+.I vtread
+does not modify
+.I buf
+and
+returns an error.
+.PP
+.I Vtwrite
+writes the
+.I n
+bytes in
+.I buf
+as a block of the given
+.IR type ,
+setting
+.IR score .
+.PP
+.I Vtreadpacket
+and
+.I vtwritepacket
+are like
+.I vtread
+and
+.I vtwrite
+but return or accept the block contents in the
+form of a
+.BR Packet .
+They avoid making a copy of the data.
+.PP
+.I Vtsync
+causes the server to flush all pending write requests
+to disk before returning.
+.PP
+.I Vtping
+executes a ping transaction with the server.
+.PP
+By default,
+.I vtread
+and
+.I vtreadpacket
+check that the SHA1 hash of the returned data
+matches the requested
+.IR score ,
+and
+.I vtwrite
+and
+.I vtwritepacket
+check that the returned
+.I score
+matches the SHA1 hash of the written data.
+Setting
+.I ventidoublechecksha1
+to zero disables these extra checks,
+mainly for benchmarking purposes.
+Doing so in production code is not recommended.
+.PP
+These functions can be called from multiple threads
+or procs simultaneously to issue requests
+in parallel.
+Programs that issue requests from multiple threads
+in the same proc should start separate procs running
+.I vtsendproc
+and
+.I vtrecvproc
+as described in
+.IR venti-conn (2).
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (2),
+.IR venti-conn (2),
+.IR venti-packet (2),
+.IR venti (6)
+.SH DIAGNOSTICS
+.I Vtrpc
+and
+.I vtpacket
+return nil on error.
+The other routines return \-1 on error.
+.PP
+.I Vtwrite
+returns 0 on success: there are no partial writes.
diff --git a/sys/man/2/venti-conn b/sys/man/2/venti-conn
new file mode 100755
index 000000000..3e3d2eea2
--- /dev/null
+++ b/sys/man/2/venti-conn
@@ -0,0 +1,200 @@
+.TH VENTI-CONN 2
+.SH NAME
+VtConn, vtconn, vtdial, vtfreeconn, vtsend, vtrecv, vtversion,
+vtdebug, vthangup \- Venti network connections
+.SH SYNOPSIS
+.PP
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.PP
+.ft L
+.nf
+.ta +\w'\fL 'u
+typedef struct VtConn {
+ int debug;
+ char *version;
+ char *uid;
+ char *sid;
+ char addr[256];
+ ...
+} VtConn;
+.PP
+.ta \w'\fLextern int 'u
+.B
+VtConn* vtconn(int infd, int outfd)
+.PP
+.B
+VtConn* vtdial(char *addr)
+.PP
+.B
+int vtversion(VtConn *z)
+.PP
+.B
+int vtsend(VtConn *z, Packet *p)
+.PP
+.B
+Packet* vtrecv(VtConn *z)
+.PP
+.B
+void vtrecvproc(void *z)
+.PP
+.B
+void vtsendproc(void *z)
+.PP
+.B
+void vtdebug(VtConn *z, char *fmt, ...)
+.PP
+.B
+void vthangup(VtConn *z)
+.PP
+.B
+void vtfreeconn(VtConn *z)
+.PP
+.B
+extern int chattyventi; /* default 0 */
+.SH DESCRIPTION
+A
+.B VtConn
+structure represents a connection to a Venti server
+(when used by a client) or to a client (when used by a server).
+It contains the following user-visible fields:
+.BR debug ,
+a flag enabling debugging prints;
+.BR version ,
+the protocol version in use;
+.BR uid ,
+the (unverified) name of the client;
+.BR sid ,
+the (unverified) name of the server;
+and
+.BR addr ,
+the network address of the remote side.
+.PP
+.I Vtconn
+initializes a new connection structure using file descriptors
+.I infd
+and
+.I outfd
+(which may be the same)
+for reading and writing.
+.I Vtdial
+dials the given network address
+(see
+.IR dial (2))
+and returns a corresponding connection.
+It returns nil if the connection cannot be established.
+.PP
+.I Vtversion
+exchanges version information with the remote side
+as described in
+.IR venti (6).
+The negotiated version is stored in
+.IB z ->version \fR.
+.PP
+.I Vtsend
+writes a packet
+(see
+.IR venti-packet (2))
+on the connection
+.IR z .
+The packet
+.IR p
+should be a formatted Venti message as might
+be returned by
+.IR vtfcallpack ;
+.I vtsend
+will add the two-byte length field
+(see
+.IR venti (6))
+at the begnning.
+.I Vtsend
+frees
+.IR p ,
+even on error.
+.PP
+.I Vtrecv
+reads a packet from the connection
+.IR z .
+Analogous to
+.IR vtsend ,
+the data read from the connection must start with
+a two-byte length, but the returned packet will omit them.
+.PP
+By default,
+.I vtsend
+and
+.I vtrecv
+block until the packet can be written or read from the network.
+In a threaded program
+(see
+.IR thread (2)),
+this may not be desirable.
+If the caller arranges for
+.IR vtsendproc
+and
+.IR vtrecvproc
+to run in their own procs
+(typically by calling
+.IR proccreate ),
+then
+.I vtsend
+and
+.I vtrecv
+will yield the proc in which they are run
+to other threads when waiting on the network.
+The
+.B void*
+argument to
+.I vtsendproc
+and
+.I vtrecvproc
+must be the connection structure
+.IR z .
+.PP
+.I Vtdebug
+prints the formatted message to standard error
+when
+.IB z ->debug
+is set. Otherwise it is a no-op.
+.PP
+.I Vthangup
+hangs up a connection.
+It closes the associated file descriptors
+and shuts down send and receive procs if they have been
+started.
+Future calls to
+.IR vtrecv
+or
+.IR vtsend
+will return errors.
+Additional calls to
+.I vthangup
+will have no effect.
+.PP
+.I Vtfreeconn
+frees the connection structure, hanging it up first
+if necessary.
+.PP
+If the global variable
+.I chattyventi
+is set, the library prints all Venti RPCs to standard error
+as they are sent or received.
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (1),
+.IR venti (2),
+.IR venti-client (2),
+.IR venti-packet (2),
+.IR venti-server (2),
+.IR venti (6)
+.SH DIAGNOSTICS
+Routines that return pointers return nil on error.
+Routines returning integers return 0 on success, \-1 on error.
+All routines set
+.I errstr
+on error.
diff --git a/sys/man/2/venti-fcall b/sys/man/2/venti-fcall
new file mode 100755
index 000000000..148e49cdd
--- /dev/null
+++ b/sys/man/2/venti-fcall
@@ -0,0 +1,275 @@
+.TH VENTI-FCALL 2
+.SH NAME
+VtEntry, VtFcall, VtRoot,
+vtentrypack,
+vtentryunpack,
+vtfcallclear,
+vtfcallfmt,
+vtfcallpack,
+vtfcallunpack,
+vtfromdisktype,
+vttodisktype,
+vtgetstring,
+vtputstring,
+vtrootpack,
+vtrootunpack,
+vtparsescore,
+vtscorefmt \- venti data formats
+.SH SYNOPSIS
+.PP
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLxxxx'u
+.PP
+.ft L
+.nf
+enum
+{
+ VtEntrySize = 40,
+ VtRootSize = 300,
+ VtScoreSize = 20,
+};
+.PP
+.ft L
+.nf
+typedef struct VtEntry
+{
+ ulong gen; /* generation number */
+ ushort psize; /* pointer block size */
+ ushort dsize; /* data block size */
+ uchar type;
+ uchar flags;
+ uvlong size;
+ uchar score[VtScoreSize];
+} VtEntry;
+.PP
+.ft L
+.nf
+typedef struct VtRoot
+{
+ char name[128];
+ char type[128];
+ uchar score[VtScoreSize]; /* to a Dir block */
+ ushort blocksize; /* maximum block size */
+ uchar prev[VtScoreSize]; /* previous root block */
+} VtRoot;
+.ta +\w'\fLPacket* 'u
+.PP
+.B
+void vtentrypack(VtEntry *e, uchar *buf, int index)
+.br
+.B
+int vtentryunpack(VtEntry *e, uchar *buf, int index)
+.PP
+.B
+Packet* vtfcallpack(VtFcall *f)
+.br
+.B
+int vtfcallunpack(VtFcall *f, Packet *p)
+.PP
+.B
+void vtfcallclear(VtFcall *f)
+.PP
+.B
+uint vttodisktype(uint type)
+.br
+.B
+uint vtfromdisktype(uint type)
+.PP
+.B
+int vtputstring(Packet *p, char *s)
+.br
+.B
+int vtgetstring(Packet *p, char **s)
+.PP
+.B
+void vtrootpack(VtRoot *r, uchar *buf)
+.br
+.B
+int vtrootunpack(VtRoot *r, uchar *buf)
+.PP
+.B
+int vtparsescore(char *s, char **prefix, uchar score[VtScoreSize])
+.PP
+.B
+int vtfcallfmt(Fmt *fmt)
+.B
+int vtscorefmt(Fmt *fmt)
+.SH DESCRIPTION
+These routines convert between C representations of Venti
+structures and serialized representations used on disk and
+on the network.
+.PP
+.I Vtentrypack
+converts a
+.B VtEntry
+structure describing a Venti file
+(see
+.IR venti (6))
+into a 40-byte
+.RB ( VtEntrySize )
+structure at
+.IB buf + index *40 \fR.
+Vtentryunpack
+does the reverse conversion.
+.PP
+.I Vtfcallpack
+converts a
+.B VtFcall
+structure describing a Venti protocol message
+(see
+.IR venti (6))
+into a packet.
+.I Vtfcallunpack
+does the reverse conversion.
+.PP
+The fields in a
+.B VtFcall
+are named after the protocol fields described in
+.IR venti (6),
+except that the
+.B type
+field is renamed
+.BR blocktype .
+The
+.B msgtype
+field holds the one-byte message type:
+.BR VtThello ,
+.BR VtRhello ,
+and so on.
+.PP
+.I Vtfcallclear
+frees the strings
+.IB f ->error \fR,
+.IB f ->version \fR,
+.IB f ->uid \fR,
+.IB f ->sid \fR,
+the buffers
+.IB f ->crypto
+and
+.IB f ->codec \fR,
+and the packet
+.IB f ->data \fR.
+.PP
+The block type enumeration defined in
+.B <venti.h>
+(presented in
+.IR venti (6))
+differs from the one used on disk and in the network
+protocol.
+The disk and network representation uses different
+constants and does not distinguish between
+.BI VtDataType+ n
+and
+.BI VtDirType+ n
+blocks.
+.I Vttodisktype
+converts a
+.B <venti.h>
+enumeration value to the disk value;
+.I vtfromdisktype
+converts a disk value to the enumeration value,
+always using the
+.B VtDirType
+pointers.
+The
+.B VtFcall
+field
+.B blocktype
+is an enumeration value
+.RI ( vtfcallpack
+and
+.I vtfcallunpack
+convert to and from the disk values used in packets
+automatically),
+so most programs will not need to call these functions.
+.PP
+.I Vtputstring
+appends the Venti protocol representation of the string
+.I s
+to the packet
+.IR p .
+.I Vtgetstring
+reads a string from the packet, returning a pointer to a copy
+of the string in
+.BI * s \fR.
+The copy must be freed by the caller.
+These functions are used by
+.I vtfcallpack
+and
+.IR vtfcallunpack ;
+most programs will not need to call them directly.
+.PP
+.I Vtrootpack
+converts a
+.B VtRoot
+structure describing a Venti file tree
+into the 300-byte
+.RB ( VtRootSize )
+buffer pointed to by
+.IR buf .
+.I Vtrootunpack does the reverse conversion.
+.PP
+.I Vtparsescore
+parses the 40-digit hexadecimal string
+.IR s ,
+writing its value
+into
+.IR score .
+If the hexadecimal string is prefixed with
+a text label followed by a colon, a copy of that
+label is returned in
+.BI * prefix \fR.
+If
+.I prefix
+is nil, the label is ignored.
+.PP
+.I Vtfcallfmt
+and
+.I vtscorefmt
+are
+.IR print (2)
+formatters to print
+.B VtFcall
+structures and scores.
+.I Vtfcallfmt
+assumes that
+.I vtscorefmt
+is installed as
+.BR %V .
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (1),
+.IR venti (2),
+.IR venti (6)
+.SH DIAGNOSTICS
+.IR Vtentrypack ,
+.IR vtfcallpack ,
+.IR vtrootpack ,
+and
+.I vtfcallclear
+cannot fail.
+.PP
+.IR Vtentryunpack ,
+.IR vtrootunpack ,
+.IR vtputstring ,
+.IR vtgetstring ,
+and
+.I vtparsescore
+return 0 on success, \-1 on error.
+.PP
+.I Vtfcallpack
+returns a packet on success, nil on error.
+.PP
+.I Vttodisktype
+and
+.I vtfromdisktype
+return
+.B VtCorruptType
+(255)
+when presented with invalid input.
diff --git a/sys/man/2/venti-file b/sys/man/2/venti-file
new file mode 100755
index 000000000..ab5f4d8c7
--- /dev/null
+++ b/sys/man/2/venti-file
@@ -0,0 +1,325 @@
+.TH VENTI-FILE 2
+.SH NAME
+VtFile,
+vtfileblock,
+vtfileblockscore,
+vtfileclose,
+vtfilecreate,
+vtfilecreateroot,
+vtfileflush,
+vtfileflushbefore,
+vtfilegetdirsize,
+vtfilegetentry,
+vtfilegetsize,
+vtfileincref,
+vtfilelock,
+vtfilelock2,
+vtfileopen,
+vtfileopenroot,
+vtfileread,
+vtfileremove,
+vtfilesetdirsize,
+vtfilesetentry,
+vtfilesetsize,
+vtfiletruncate,
+vtfileunlock,
+vtfilewrite \- Venti files
+.SH SYNOPSIS
+.ta +\w'\fLVtBlock* 'u
+.PP
+.B
+VtFile* vtfilecreateroot(VtCache *c, int psize, int dsize, int type);
+.PP
+.B
+VtFile* vtfileopenroot(VtCache *c, VtEntry *e);
+.PP
+.B
+VtFile* vtfileopen(VtFile *f, u32int n, int mode);
+.PP
+.B
+VtFile* vtfilecreate(VtFile *f, int psize, int dsize, int type);
+.PP
+.B
+void vtfileincref(VtFile *f);
+.PP
+.B
+void vtfileclose(VtFile *f);
+.PP
+.B
+int vtfileremove(VtFile *f);
+.PP
+.B
+VtBlock* vtfileblock(VtFile *f, u32int n, int mode);
+.PP
+.B
+long vtfileread(VtFile *f, void *buf, long n, vlong offset);
+.PP
+.B
+long vtfilewrite(VtFile *f, void *buf, long n, vlong offset);
+.PP
+.B
+int vtfileflush(VtFile *f);
+.PP
+.B
+int vtfileflushbefore(VtFile *f, vlong offset);
+.PP
+.B
+int vtfiletruncate(VtFile *f);
+.PP
+.B
+uvlong vtfilegetsize(VtFile *f);
+.PP
+.B
+int vtfilesetsize(VtFile *f, vlong size);
+.PP
+.B
+u32int vtfilegetdirsize(VtFile *f);
+.PP
+.B
+int vtfilesetdirsize(VtFile *f, u32int size);
+.PP
+.B
+int vtfilegetentry(VtFile *f, VtEntry *e);
+.PP
+.B
+int vtfilesetentry(VtFile *f, VtEntry *e);
+.PP
+.B
+int vtfileblockscore(VtFile *f, u32int n,
+ uchar score[VtScoreSize]);
+.PP
+.B
+int vtfilelock(VtFile *f, int mode);
+.PP
+.B
+int vtfilelock2(VtFile *f, VtFile *f, int mode);
+.PP
+.B
+void vtfileunlock(VtFile *f);
+.SH DESCRIPTION
+These routines provide a simple interface to create and
+manipulate Venti file trees (see
+.IR venti (6)).
+.PP
+.I Vtfilecreateroot
+creates a new Venti file.
+.I Type
+must be either
+.B VtDataType
+or
+.BR VtDirType ,
+specifying a data or directory file.
+.I Dsize
+is the block size to use for leaf (data or directory) blocks in the hash tree;
+.I psize
+is the block size to use for internal (pointer) blocks.
+.PP
+.I Vtfileopenroot
+opens an existing Venti file described by
+.IR e .
+.PP
+.I Vtfileopen
+opens the Venti file described by the
+.IR n th
+entry in the directory
+.IR f .
+.I Mode
+should be one of
+.BR VtOREAD ,
+.BR VtOWRITE ,
+or
+.BR VtORDWR ,
+indicating how the returned file is to be used.
+The
+.BR VtOWRITE
+and
+.BR VtORDWR
+modes can only be used if
+.IR f
+is open with mode
+.BR VtORDWR .
+.PP
+.I Vtfilecreate
+creates a new file in the directory
+.I f
+with block type
+.I type
+and block sizes
+.I dsize
+and
+.I psize
+(see
+.I vtfilecreateroot
+above).
+.PP
+Each file has an associated reference count
+and holds a reference to its parent in the file tree.
+.I Vtfileincref
+increments this reference count.
+.I Vtfileclose
+decrements the reference count.
+If there are no other references,
+.I vtfileclose
+releases the reference to
+.IR f 's
+parent and then frees the in-memory structure
+.IR f .
+The data stored in
+.I f
+is still accessible by reopening it.
+.PP
+.I Vtfileremove
+removes the file
+.I f
+from its parent directory.
+It also acts as
+.IR vtfileclose ,
+releasing the reference to
+.I f
+and potentially freeing the structure.
+.PP
+.I Vtfileblock
+returns the
+.IR n th
+block in the file
+.IR f .
+If there are not
+.I n
+blocks in the file and
+.I mode
+is
+.BR VtOREAD ,
+.I vtfileblock
+returns nil.
+If the mode is
+.B VtOWRITE
+or
+.BR VtORDWR ,
+.I vtfileblock
+grows the file as needed and then returns the block.
+.PP
+.I Vtfileread
+reads at most
+.I n
+bytes at offset
+.I offset
+from
+.I f
+into memory at
+.IR buf .
+It returns the number of bytes read.
+.PP
+.I Vtfilewrite
+writes the
+.I n
+bytes in memory at
+.I buf
+into the file
+.I f
+at offset
+.IR n .
+It returns the number of bytes written,
+or \-1 on error.
+Writing fewer bytes than requested will only happen
+if an error is encountered.
+.PP
+.I Vtfilewrite
+writes to an in-memory copy of the data blocks
+(see
+.IR venti-cache (2))
+instead of writing directly to Venti.
+.I Vtfileflush
+writes all copied blocks associated with
+.I f
+to the Venti server.
+.I Vtfileflushbefore
+flushes only those blocks corresponding to data in the file before
+byte
+.IR offset .
+Loops that
+.I vtfilewrite
+should call
+.I vtfileflushbefore
+regularly to avoid filling the block cache with unwritten blocks.
+.PP
+.I Vtfiletruncate
+changes the file
+.I f
+to have zero length.
+.PP
+.I Vtfilegetsize
+returns the length (in bytes) of file
+.IR f .
+.PP
+.I Vtfilesetsize
+sets the length (in bytes) of file
+.IR f .
+.PP
+.I Vtfilegetdirsize
+returns the length (in directory entries)
+of the directory
+.IR f .
+.PP
+.I Vtfilesetdirsize
+sets the length (in directory entries)
+of the directory
+.IR f .
+.PP
+.I Vtfilegetentry
+fills
+.I e
+with an entry that can be passed to
+.IR vtfileopenroot
+to reopen
+.I f
+at a later time.
+.PP
+.I Vtfilesetentry
+sets the entry associated with
+.I f
+to be
+.IR e .
+.PP
+.I Vtfileblockscore
+returns in
+.I score
+the score of the
+.IR n th
+block in the file
+.IR f .
+.PP
+Venti files are locked and unlocked
+via
+.I vtfilelock
+and
+.I vtfileunlock
+to moderate concurrent access.
+Only one thread at a time\(emthe one that has the file locked\(emcan
+read or modify the file.
+The functions that return files
+.RI ( vtfilecreateroot ,
+.IR vtfileopenroot ,
+.IR vtfilecreate ,
+and
+.IR vtfileopen )
+return them unlocked.
+When files are passed to any of the functions documented in
+this manual page, it is the caller's responsibility to ensure that
+they are already locked.
+.PP
+Internally, a file is locked by locking the
+block that contains its directory entry.
+When two files in the same
+directory both need to be locked,
+.I vtfilelock2
+must be used.
+It locks both its arguments, taking special care
+not to deadlock if their entries are stored
+in the same directory block.
+.SH SOURCE
+.B /sys/src/libventi/file.c
+.SH SEE ALSO
+.IR venti-cache (2),
+.IR venti-conn (2),
+.IR venti-client (2),
+.IR venti (6)
diff --git a/sys/man/2/venti-log b/sys/man/2/venti-log
new file mode 100755
index 000000000..a8763202c
--- /dev/null
+++ b/sys/man/2/venti-log
@@ -0,0 +1,136 @@
+.TH VENTI-LOG 2
+.SH NAME
+VtLog,
+VtLogChunk,
+vtlog,
+vtlogclose,
+vtlogdump,
+vtlognames,
+vtlogopen,
+vtlogprint,
+vtlogremove,
+vtlogopen,
+ventilogging \- Venti logs
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLVtLog* 'u
+.PP
+.B
+VtLog* vtlogopen(char *name, uint size);
+.PP
+.B
+void vtlogprint(VtLog *log, char *fmt, ...);
+.PP
+.B
+void vtlogclose(VtLog *log);
+.PP
+.B
+void vtlog(char *name, char *fmt, ...);
+.PP
+.B
+void vtlogremove(char *name);
+.PP
+.B
+char** vtlognames(int *n);
+.PP
+.B
+void vtlogdump(int fd, VtLog *log);
+.PP
+.B
+extern int ventilogging; /* default 0 */
+.PP
+.B
+extern char *VtServerLog; /* "libventi/server" */
+.SH DESCRIPTION
+These routines provide an in-memory circular log
+structure used by the Venti library and the Venti server
+to record events for debugging purposes.
+The logs are named by UTF strings.
+.PP
+.I Vtlogopen
+returns a reference to the log with the given
+.I name .
+If a log with that name does not exist and
+.I size
+is non-zero,
+.I vtlogopen
+creates a new log capable of holding at
+least
+.I size
+bytes and returns it.
+.I Vtlogclose
+releases the reference returned by
+.IR vtlogopen .
+.PP
+.I Vtlogprint
+writes to
+.IR log ,
+which must be open.
+.PP
+.I Vtlog
+is a convenient packaging of
+.I vtlogopen
+followed by
+.I vtlogprint
+and
+.IR vtlogclose .
+.PP
+.I Vtlogremove
+removes the log with the given
+.IR name ,
+freeing any associated storage.
+.PP
+.I Vtlognames
+returns a list of the names of all the logs.
+The length of the list is returned in
+.BI * n \fR.
+The list
+should be freed
+by calling
+.I vtfree
+on the returned pointer.
+The strings in the list will be freed by this call as well.
+(It is an error to call
+.I vtfree
+on any of the strings in the list.)
+.PP
+.I Vtlogdump
+prints
+.IR log ,
+which must be open, to the file descriptor
+.IR fd .
+.PP
+If
+.I ventilogging
+is set to zero (the default),
+.I vtlognames
+and
+.I vtlogdump
+can inspect existing logs, but
+.I vtlogopen
+always returns nil
+and
+.I vtlog
+is a no-op.
+The other functions are no-ops when
+passed nil log structures.
+.PP
+The server library
+(see
+.IR venti-conn (2)
+and
+.IR venti-server (2))
+writes debugging information to the log named
+.IR VtServerLog ,
+which defaults to the string
+.RB ` libventi/server '.
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (2),
+.IR venti (8)
diff --git a/sys/man/2/venti-mem b/sys/man/2/venti-mem
new file mode 100755
index 000000000..8544807c1
--- /dev/null
+++ b/sys/man/2/venti-mem
@@ -0,0 +1,68 @@
+.TH VENTI-MEM 2
+.SH NAME
+vtbrk,
+vtmalloc,
+vtmallocz,
+vtrealloc,
+vtstrdup,
+vtfree \- error-checking memory allocators
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLvoid* 'u
+.PP
+.B
+void* vtbrk(int size)
+.PP
+.B
+void* vtmalloc(int size)
+.PP
+.B
+void* vtmallocz(int size)
+.PP
+.B
+void* vtrealloc(void *ptr, int size)
+.PP
+.B
+char* vtstrdup(char *s)
+.PP
+.B
+void vtfree(void *ptr)
+.SH DESCRIPTION
+These routines allocate and free memory.
+On failure, they print an error message and call
+.IR sysfatal
+(from
+.IR perror (2)).
+They do not return.
+.PP
+.I Vtbrk
+returns a pointer to a new, permanently allocated block of at least
+.I size
+bytes.
+.PP
+.IR Vtmalloc ,
+.IR vtrealloc ,
+and
+.I vtstrdup
+are like
+.IR malloc ,
+.IR realloc ,
+and
+.IR strdup ,
+but, as noted above, do not return on error.
+.I Vtmallocz
+is like
+.I vtmalloc
+but zeros the block before returning it.
+Memory allocated with all four should be freed with
+.I vtfree
+when no longer needed.
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (2)
diff --git a/sys/man/2/venti-packet b/sys/man/2/venti-packet
new file mode 100755
index 000000000..53ada1eea
--- /dev/null
+++ b/sys/man/2/venti-packet
@@ -0,0 +1,281 @@
+.TH VENTI-PACKET 2
+.SH NAME
+Packet,
+packetalloc,
+packetappend,
+packetasize,
+packetcmp,
+packetconcat,
+packetconsume,
+packetcopy,
+packetdup,
+packetforeign,
+packetfragments,
+packetfree,
+packetheader,
+packetpeek,
+packetprefix,
+packetsha1,
+packetsize,
+packetsplit,
+packetstats,
+packettrailer,
+packettrim \- zero-copy network buffers
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLPacket* 'u +\w'\fLxxxx'u
+.PP
+.B
+.PP
+.B
+Packet* packetalloc(void);
+.PP
+.B
+void packetappend(Packet *p, uchar *buf, int n)
+.PP
+.B
+uint packetasize(Packet *p)
+.PP
+.B
+int packetcmp(Packet *p, Packet *q)
+.PP
+.B
+void packetconcat(Packet *p, Packet *q)
+.PP
+.B
+int packetconsume(Packet *p, uchar *buf, int n)
+.PP
+.B
+int packetcopy(Packet *p, uchar *buf, int offset, int n)
+.PP
+.B
+Packet* packetdup(Packet *p, int offset, int n)
+.PP
+.B
+Packet* packetforeign(uchar *buf, int n,
+.br
+.B
+ void (*free)(void *a), void *a)
+.PP
+.B
+int packetfragments(Packet *p, IOchunk *io, int nio,
+.br
+.B
+ int offset)
+.PP
+.B
+void packetfree(Packet *p)
+.PP
+.B
+uchar* packetheader(Packet *p, int n)
+.PP
+.B
+uchar* packetpeek(Packet *p, uchar *buf, int offset, int n)
+.PP
+.B
+void packetprefix(Packet *p, uchar *buf, int n)
+.PP
+.B
+void packetsha1(Packet *p, uchar sha1[20])
+.PP
+.B
+uint packetsize(Packet *p)
+.PP
+.B
+Packet* packetsplit(Packet *p, int n)
+.PP
+.B
+void packetstats(void)
+.PP
+.B
+uchar* packettrailer(Packet *p, int n)
+.PP
+.B
+int packettrim(Packet *p, int offset, int n)
+.SH DESCRIPTION
+A
+.B Packet
+is a chain of blocks of data.
+Each block, called a fragment,
+is contiguous in memory, but the entire packet
+may not be.
+This representation helps avoid unnecessary memory copies.
+.PP
+.I Packetalloc
+allocates an empty packet.
+.PP
+.I Packetappend
+appends the
+.I n
+bytes at
+.I buf
+to the end of
+.IR p .
+.PP
+.I Packetasize
+returns the number of data bytes allocated to
+.IR p .
+This may be larger than the number of bytes stored
+in
+.IR p
+because fragments may not be filled completely.
+.PP
+.I Packetcmp
+compares the data sections of two packets as
+.I memcmp
+(see
+.IR memory (2))
+would.
+.PP
+.I Packetconcat
+removes all data from
+.IR q ,
+appending it to
+.IR p .
+.PP
+.I Packetconsume
+removes
+.I n
+bytes from the beginning of
+.IR p ,
+storing them into
+.IR buf .
+.PP
+.I Packetcopy
+copies
+.I n
+bytes at
+.I offset
+in
+.I p
+to
+.IR buf .
+.PP
+.I Packetdup
+creates a new packet initialized with
+.I n
+bytes from
+.I offset
+in
+.IR p .
+.PP
+.I Packetforeign
+allocates a packet containing `foreign' data: the
+.I n
+bytes pointed to by
+.IR buf .
+Once the bytes are no longer needed, they are freed by calling
+.IB free ( a )\fR.
+.PP
+.I Packetfragments
+initializes up to
+.I nio
+of the
+.I io
+structures with pointers to the data in
+.IR p ,
+starting at
+.IR offset .
+It returns the total number of bytes represented
+by the returned structures.
+.I Packetfragments
+initializes any unused
+.I io
+structures with nil pointer and zero length.
+.PP
+.I Packetfree
+frees the packet
+.IR p .
+.PP
+.I Packetheader
+returns a pointer to the first
+.I n
+bytes of
+.IR p ,
+making them contiguous in memory
+if necessary.
+.PP
+.I Packetpeek
+returns a pointer to the
+.I n
+bytes at
+.I offset
+in
+.IR p .
+If the requested bytes are already stored contiguously in memory,
+the returned pointer points at the internal data storage for
+.IR p .
+Otherwise, the bytes are copied into
+.IR buf ,
+and
+.I packetpeek
+returns
+.IR buf .
+.PP
+.I Packetprefix
+inserts a copy of the
+.I n
+bytes at
+.I buf
+at the beginning of
+.IR p .
+.PP
+.I Packetsha1
+computes the SHA1 hash of the data contained in
+.IR p .
+.PP
+.I Packetsize
+returns the length, in bytes, of the data contained in
+.IR p .
+.PP
+.I Packetsplit
+returns a new packet initialized with
+.I n
+bytes removed from the beginning of
+.IR p .
+.PP
+.I Packetstats
+prints run-time statistics to standard output.
+.PP
+.I Packettrailer
+returns a pointer to the last
+.I n
+bytes of
+.IR p ,
+making them contiguous in memory
+if necessary.
+.PP
+.I Packettrim
+deletes all bytes from the packet
+.I p
+except the
+.I n
+bytes at offset
+.IR offset .
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (2)
+.SH DIAGNOSTICS
+These functions return errors only when passed
+invalid inputs,
+.IR e.g. ,
+requests for data at negative offsets or beyond the end of a packet.
+.PP
+Functions returning pointers return nil on error;
+functions returning integers return \-1 on error.
+Most functions returning integers return 0 on success.
+The exceptions are
+.I packetfragments
+and
+.IR packetcmp ,
+whose return values are described above.
+.PP
+When these functions run out of memory, they
+print error messages and call
+.IR sysfatal .
diff --git a/sys/man/2/venti-server b/sys/man/2/venti-server
new file mode 100755
index 000000000..cd62381ca
--- /dev/null
+++ b/sys/man/2/venti-server
@@ -0,0 +1,122 @@
+.TH VENTI-SERVER 2
+.SH NAME
+vtsrvhello, vtlisten, vtgetreq, vtrespond \- Venti server
+.SH SYNOPSIS
+.PP
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLVtReq* 'u
+.PP
+.ft L
+.nf
+typedef struct VtReq
+{
+ VtFcall tx;
+ VtFcall rx;
+ ...
+} VtReq;
+.PP
+.B
+int vtsrvhello(VtConn *z)
+.PP
+.B
+VtSrv* vtlisten(char *addr)
+.PP
+.B
+VtReq* vtgetreq(VtSrv *srv)
+.PP
+.B
+void vtrespond(VtReq *req)
+.SH DESCRIPTION
+These routines execute the server side of the
+.IR venti (6)
+protocol.
+.PP
+.I Vtsrvhello
+executes the server side of the initial
+.B hello
+transaction.
+It sets
+.IB z -> uid
+with the user name claimed by the other side.
+Each new connection must be initialized by running
+.I vtversion
+and then
+.IR vtsrvhello .
+The framework below takes care of this detail automatically;
+.I vtsrvhello
+is provided for programs that do not use the functions below.
+.PP
+.IR Vtlisten ,
+.IR vtgetreq ,
+and
+.I vtrespond
+provide a simple framework for writing Venti servers.
+.PP
+.I Vtlisten
+announces at the network address
+.IR addr ,
+returning a fresh
+.B VtSrv
+structure representing the service.
+.PP
+.I Vtgetreq
+waits for and returns
+the next
+.BR read ,
+.BR write ,
+.BR sync ,
+or
+.B ping
+request from any client connected to
+the service
+.IR srv .
+.B Hello
+and
+.B goodbye
+messages are handled internally and not returned to the client.
+The interface does not distinguish between the
+different clients that may be connected at any given time.
+The request can be found in the
+.I tx
+field of the returned
+.BR VtReq .
+.PP
+Once a request has been served and a response stored in
+.IB r ->rx \fR,
+the server should call
+.IR vtrespond
+to send the response to the client.
+.I Vtrespond
+frees the structure
+.I r
+as well as the packets
+.IB r ->tx.data
+and
+.IB r ->rx.data \fR.
+.SH EXAMPLE
+.B /sys/src/cmd/venti
+contains two simple Venti servers
+.B ro.c
+and
+.B devnull.c
+written using these routines.
+.I Ro
+is a read-only Venti proxy (it rejects
+.B write
+requests).
+.I Devnull
+is a dangerous write-only Venti server: it discards all
+blocks written to it and returns error on all reads.
+.SH SOURCE
+.B /sys/src/libventi
+.SH SEE ALSO
+.IR venti (2),
+.IR venti-conn (2),
+.IR venti-packet (2),
+.IR venti (6),
+.IR venti (8)
diff --git a/sys/man/2/venti-zero b/sys/man/2/venti-zero
new file mode 100755
index 000000000..b0b810bcf
--- /dev/null
+++ b/sys/man/2/venti-zero
@@ -0,0 +1,56 @@
+.TH VENTI-ZERO 2
+.SH NAME
+vtzerotruncate, vtzeroextend, vtzeroscore \- Venti block truncation
+.SH SYNOPSIS
+.ft L
+#include <u.h>
+.br
+#include <libc.h>
+.br
+#include <venti.h>
+.ta +\w'\fLuint 'u
+.PP
+.B
+uint vtzerotruncate(int type, uchar *buf, uint size)
+.PP
+.B
+void vtzeroextend(int type, uchar *buf, uint size, uint newsize)
+.PP
+.B
+extern uchar vtzeroscore[VtScoreSize];
+.SH DESCRIPTION
+These utility functions compute how to truncate or replace
+trailing zeros (for data blocks) or trailing zero scores
+(for pointer blocks) to canonicalize the blocks before
+storing them to Venti.
+.PP
+.I Vtzerotruncate
+returns the size of the
+.IR size -byte
+buffer pointed to by
+.I buf
+ignoring trailing zeros or zero scores,
+according to the given
+.IR type .
+.PP
+.I Vtzeroextend
+pads
+.I buf
+with zeros or zero scores,
+according to the given
+.IR type ,
+to grow it from
+.I size
+bytes to
+.I newsize
+bytes.
+.PP
+.I Vtzeroscore
+is the score of the zero-length block.
+.SH SOURCE
+.B /sys/src/libventi/zero.c
+.br
+.B /sys/src/libventi/zeroscore.c
+.SH SEE ALSO
+.IR venti (2),
+.IR venti (6)
diff --git a/sys/man/2/wait b/sys/man/2/wait
new file mode 100755
index 000000000..b6d34fba9
--- /dev/null
+++ b/sys/man/2/wait
@@ -0,0 +1,122 @@
+.TH WAIT 2
+.SH NAME
+await, wait, waitpid \- wait for a process to exit
+.SH SYNOPSIS
+.B #include <u.h>
+.br
+.B #include <libc.h>
+.PP
+.B
+Waitmsg* wait(void)
+.PP
+.B
+int waitpid(void)
+.PP
+.B
+int await(char *s, int n)
+.SH DESCRIPTION
+.I Wait
+causes a process to wait for any child process (see
+.IR fork (2))
+to exit.
+It returns a
+.B Waitmsg
+holding
+information about the exited child.
+A
+.B Waitmsg
+has this structure:
+.IP
+.EX
+.ta 6n +\w'long 'u +\w'msg[ERRLEN]; 'u
+typedef
+struct Waitmsg
+{
+ int pid; /* of loved one */
+ ulong time[3]; /* of loved one & descendants */
+ char *msg;
+} Waitmsg;
+.EE
+.PP
+.B Pid
+is the child's
+process id.
+The
+.B time
+array contains the time the child and its descendants spent in user code,
+the time spent in system calls, and the child's elapsed real time,
+all in units of milliseconds.
+.B Msg
+contains the message that the child specified in
+.IR exits (2).
+For a normal exit,
+.B msg[0]
+is zero,
+otherwise
+.B msg
+is the exit string
+prefixed by the process name, a blank, the process id, and a colon.
+.PP
+If there are no more children to wait for,
+.I wait
+returns immediately, with return value nil.
+.PP
+The
+.B Waitmsg
+structure is allocated by
+.IR malloc (2)
+and should be freed after use.
+For programs that only need the pid of the exiting program,
+.I waitpid
+returns just the pid and discards the rest of the information.
+.PP
+The underlying system call is
+.IR await ,
+which fills in the n-byte buffer
+.I s
+with a textual representation of the pid, times, and exit string.
+There is no terminal NUL.
+The return value is the length, in bytes, of the data.
+.PP
+The buffer filled in by
+.I await
+may be parsed (after appending a NUL) using
+.IR tokenize
+(see
+.IR getfields (2));
+the resulting fields are, in order, pid, the three times, and the exit string,
+which will be
+.B ''
+for normal exit.
+If the representation is longer than
+.I n
+bytes, it is truncated but, if possible, properly formatted.
+The information that does not fit in the buffer is discarded, so
+a subsequent call to
+.I await
+will return the information about the next exiting child, not the remainder
+of the truncated message.
+In other words, each call to
+.I await
+returns the information about one child, blocking if necessary if no child has exited.
+.PP
+If the calling process has no living children,
+.I await
+and
+.I waitpid
+return
+.BR -1 .
+.SH SOURCE
+.B /sys/src/libc/9syscall
+.br
+.B /sys/src/libc/9sys
+.SH "SEE ALSO"
+.IR fork (2),
+.IR exits (2),
+the
+.B wait
+file in
+.IR proc (3)
+.SH DIAGNOSTICS
+These routines set
+.IR errstr .
diff --git a/sys/man/2/window b/sys/man/2/window
new file mode 100755
index 000000000..5fe2b2bfe
--- /dev/null
+++ b/sys/man/2/window
@@ -0,0 +1,244 @@
+.TH WINDOW 2
+.SH NAME
+Screen, allocscreen, publicscreen, freescreen, allocwindow, bottomwindow, bottomnwindows, topwindow, topnwindows, originwindow \- window management
+.SH SYNOPSIS
+.nf
+.B
+#include <u.h>
+.B
+#include <libc.h>
+.B
+#include <draw.h>
+.PP
+.ft L
+.nf
+typedef
+struct Screen
+{
+ Display *display; /* display holding data */
+ int id; /* id of system-held Screen */
+ Image *image; /* unused; for reference only */
+ Image *fill; /* color to paint behind windows */
+} Screen;
+.fi
+.ta \w'\fLScreen* 'u
+.PP
+.B
+Screen* allocscreen(Image *image, Image *fill, int public)
+.PP
+.B
+Screen* publicscreen(Display *d, int id, ulong chan)
+.PP
+.B
+int freescreen(Screen *s)
+.PP
+.B
+Image* allocwindow(Screen *s, Rectangle r, int ref, int val)
+.PP
+.B
+void bottomwindow(Image *w)
+.PP
+.B
+void bottomnwindows(Image **wp, int nw)
+.PP
+.B
+void topwindow(Image *w)
+.PP
+.B
+void topnwindows(Image **wp, int nw)
+.PP
+.B
+int originwindow(Image *w, Point log, Point scr)
+.PP
+.ft L
+.nf
+enum
+{
+ /* refresh methods */
+ Refbackup = 0,
+ Refnone = 1,
+ Refmesg = 2
+};
+.fi
+.ft P
+.SH DESCRIPTION
+Windows are represented as
+.B Images
+and may be treated as regular images for all drawing operations.
+The routines discussed here permit the creation, deletion, and shuffling
+of windows, facilities that do not apply to regular images.
+.PP
+To create windows, it is first necessary to allocate a
+.B Screen
+data structure to gather them together.
+A
+.B Screen
+turns an arbitrary image into something that may have windows upon it.
+It is created by
+.BR allocscreen ,
+which takes an
+.I image
+upon which to place the windows (typically
+.BR display->image ),
+a
+.I fill
+image to paint the background behind all the windows on the image,
+and a flag specifying whether the result should be publicly visible.
+If it is public, an arbitrary other program connected to the same
+display may acquire a pointer to the same screen by calling
+.B publicscreen
+with the
+.B Display
+pointer and the
+.I id
+of the published
+.BR Screen ,
+as well as the expected channel descriptor, as a safety check.
+It will usually require some out-of-band coordination for programs to share a screen profitably.
+.B Freescreen
+releases a
+.BR Screen ,
+although it may not actually disappear from view until all the windows upon it have also been deallocated.
+.PP
+Unlike
+.BR allocwindow ,
+.B allocscreen
+does
+.I not
+initialize the appearance of the
+.BR Screen .
+.PP
+Windows are created by
+.BR allocwindow ,
+which takes a pointer to the
+.B Screen
+upon which to create the window, a rectangle
+.I r
+defining its geometry, an integer pixel value
+.I val
+to color the window initially, and a refresh method
+.BR ref .
+The refresh methods are
+.BR Refbackup ,
+which provides backing store and is the method used by
+.IR rio (1)
+for its clients;
+.BR Refnone ,
+which provides no refresh and is designed for temporary uses
+such as sweeping a display rectangle, for windows that are
+completely covered by other windows, and for windows that
+are already protected by backing store; and
+.BR Refmesg ,
+which causes messages to be delivered to the owner of the window
+when it needs to be repainted.
+.B Refmesg
+is not fully implemented.
+.PP
+The result of
+.B allocwindow
+is an
+.B Image
+pointer that may be treated like any other image.
+In particular, it is freed by calling
+.B freeimage
+(see
+.IR allocimage (2)).
+The following functions, however, apply only to windows, not regular images.
+.PP
+.B Bottomwindow
+pushes window
+.I w
+to the bottom of the stack of windows on its
+.BR Screen ,
+perhaps obscuring it.
+.B Topwindow
+pulls window
+.I w
+to the top, making it fully visible on its
+.BR Screen .
+(This
+.B Screen
+may itself be within a window that is not fully visible;
+.B topwindow
+will not affect the stacking of this parent window.)
+.B Bottomnwindows
+and
+.B Topnwindows
+are analogous, but push or pull a group of
+.I nw
+windows listed in the array
+.IR wp .
+The order within
+.IR wp
+is unaffected.
+.PP
+Each window is created as an
+.B Image
+whose
+.B Rectangle
+.B r
+corresponds to the rectangle given to
+.B allocwindow
+when it was created. Thus, a newly created window
+.I w
+resides on its
+.B Screen->image
+at
+.IB w ->r
+and has internal coordinates
+.IB w ->r .
+Both these may be changed by a call to
+.BR originwindow .
+The two
+.B Point
+arguments to
+.B originwindow
+define the upper left corner of the logical coordinate system
+.RI ( log )
+and screen position
+.RI ( scr ).
+Their usage is shown in the Examples section.
+.PP
+.IR Rio (1)
+creates its client windows with backing store,
+.BR Refbackup .
+The graphics initialization routine,
+.B initdraw
+(see
+.IR graphics (2)),
+builds a
+.B Screen
+upon this, and then allocates upon that another window indented
+to protect the border. That window is created
+.BR Refnone ,
+since the backing store created by
+.B rio
+protects its contents. That window is the one known in the
+library by the global name
+.B screen
+(a historic but confusing choice).
+.SH EXAMPLES
+To move a window to the upper left corner of the display,
+.EX
+ originwindow(w, w->r.min, Pt(0, 0));
+.EE
+To leave a window where it is on the screen but change its internal
+coordinate system so (0,\ 0) is the upper left corner of the window,
+.EX
+ originwindow(w, Pt(0, 0), w->r.min);
+.EE
+After this is done,
+.B w->r
+is translated to the origin and there will be no way to discover the
+actual screen position of the window unless it is recorded separately.
+.SH SOURCE
+.B /sys/src/libdraw
+.SH SEE ALSO
+.IR graphics (2),
+.IR draw (2),
+.IR cachechars (2),
+.IR draw (3)
+.SH BUGS
+The refresh method
+.B Refmesg
+should be finished.