Plan 9
Plan 9
Programmers Manual
Volume 1
Fourth Edition
Computing Science Research Center
Bell Laboratories
Lucent Technologies
Murray Hill, New Jersey
Copyright © 2002 Lucent Technologies Inc. All Rights Reserved.
Portions Copyright © 2000, 1998, 1995 Aladdin Enterprises. All Rights Reserved.
Portions Copyright © 1994 by Sun Microsystems Computer Company. All rights reserved.
Portions Copyright © 2000 Compaq Computer Corporation.
Portions Copyright © 1999, Keith Packard.
Cover Design: Gerard J. Holzmann
Trademarks referenced in this document:
Plan 9 is a trademark of Lucent Technologies Inc.
Aladdin Ghostscript is a trademark of Aladdin Enterprises.
ARM is a trademark of ARM Limited.
Avanstar is a registered trademark of Star Gate Technologies, Inc.
CGA and VGA are trademarks of International Business Machines Corporation.
Silicon Graphics, IRIS Indigo, IRIS, IRIX, Challenge, and Indigo
are registered trademarks of Silicon Graphics, Inc.
Indy and POWER Series are trademarks of Silicon Graphics, Inc.
Ethernet is a trademark of Xerox Corporation.
IBM, PS/2, and PowerPC are registered trademarks of
International Business Machines Corporation.
Intel and Pentium are registered trademarks of Intel Corporation.
8088, 80286, 80386, and 80486 are trademarks of Intel Corporation.
Lucida is a registered trademark of Bigelow & Holmes.
Pellucida is a trademark of Bigelow & Holmes.
MIPS, R3000, R4000, and R4400 are registered trademarks of MIPS Technologies, Inc.
R2000 and R6000 are trademarks of MIPS Technologies, Inc.
Microsoft, Microsoft Word and Microsoft Office, and MS-DOS are
registered trademarks of Microsoft Corporation.
NFS is a registered trademark of Sun Microsystems, Inc.
PDP and VAX are registered trademarks of Digital Equipment Corp.
PostScript is a registered trademark of Adobe Systems Incorporated.
R2000, R6000, R4000, and R4400 are trademarks of MIPS Technologies, Inc.
SecureNet is a trademark of Digital Pathways, Inc.
Sound Blaster is a registered trademark of Creative Labs, Inc.
SPARC is a registered trademark of SPARC International, Inc.
Unicode is a registered certification mark of Unicode, Inc.
UNIX is a registered trademark in the USA and other countries licensed
exclusively through X/Open Company Limited.
Preface to the Fourth (2002) Edition
Plan 9 continues to grow and adapt. The fourth major release of the system incorpo­
rates a number of changes, but the most central is the conversion to a new version of
the 9P file system protocol. This new version was motivated by a desire to support files
with name elements longer than 27 bytes (the old NAMELEN), but the opportunity was
taken to change a number of other things about the protocol, making it more efficient,
more flexible, and easier to encapsulate. One simple but indispensable new feature
made possible by the protocol change is that the system now records the user who last
modified a file; try ls -m to identify the culprit.
Many aspects of system security have been improved. The new security agent
factotum(4) maintains user passwords, while secstore(4) keeps them safe and enables
single sign-on to multiple domains and machines using a variety of secure protocols
and services.
Throughout the system, components have been rewritten and interfaces modified to
eliminate restrictions, improve performance, and clarify design. The full list is too long
to include here, but significant changes have occurred in a number of system calls
(wait(2), stat(2), mount(2), and errstr(2)), the thread library (thread(2)), formatted print­
ing (print(2) and fmtinstall(2)), security (many pages in section 2, including auth(2),
authsrv(2)), and many others.
The changes are sweeping and are accompanied by many new programs, tools, services,
and libraries. See the manual pages and the accompanying documents for more infor­
Bell Labs
Computing Science Research Center
Murray Hill NJ
April, 2002
Preface to the Third (2000) Edition
A great deal has happened to Plan 9 in the five years since its last release. Although
much of the system will seem familiar, hardly any aspect of it is unchanged. The kernel
has been heavily reworked; the graphical environment completely rewritten; many com­
mands added, deleted, or replaced; and the libraries greatly expanded. Underneath,
though, the same approach to computing remains: a distributed system that uses filelike naming to access and control resources both local and remote.
Some of the changes are sweeping:
Alef is gone, a casualty of the cost of maintaining multiple languages, compilers,
and libraries in a diverse world, but its model for processes, tasks, and communi­
cation lives on in a new thread library for C.
Support for color displays is much more general, building on a new alpha-blending
graphical operator called draw that replaces the old bitblt. Plan 9 screens are
now, discreetly, colorful.
A new mechanism called plumbing connects applications together in a variety of
ways, most obviously in the support of multimedia.
The interfaces to the panoply of rotating storage devices have been unified and
extended, while providing better support for having Plan 9 coexist with other oper­
ating systems on a single disk.
Perhaps most important, this release of the system is being done under an open
source agreement, providing cost-free source-level access to the software.
Plan 9 continues to be the work of many people. Besides those mentioned in the old
preface, these people deserve particular note: Russ Cox did much of the work updating
the graphics and creating the new disk and bootstrap model as well as providing a num­
ber of new commands; David Hogan ported Plan 9 to the Dec Alpha; and Sape Mullender
wrote the new thread library.
Other new contributors include Bruce Ellis, Charles Forsyth, Eric Van Hensbergen, and
Tad Hunt.
Bell Labs
Computing Science Research Center
Murray Hill NJ
June, 2000
Preface to the Second (1995) Edition
Plan 9 was born in the same lab where Unix began. Old Unix hands will recognize
the cultural heritage in this manual, where venerable Unix commands live on, described
in the classic Unix style. Underneath, though, lies a new kind of system, organized
around communication and naming rather than files and processes.
In Plan 9, distributed computing is a central premise, not an evolutionary add-on.
The system relies on a uniform protocol to refer to and communicate with objects,
whether they be data or processes, and whether or not they live on the same machine or
even similar machines. A single paradigm (writing to named places) unifies all kinds of
control and interprocess signaling.
Name spaces can be built arbitrarily. In particular all programs available to a given
user are customarily united in a single logical directory. Temporary files and untrusted
activities can be confined in isolated spaces. When a portable machine connects to the
central, archival file system, the machines local name space is joined smoothly to that
of the archival file system. The architecture affords other unusual abilities, including:
Objects in name spaces imported from other machines (even from foreign systems
such as MS-DOS) are transparently accessible.
Windows appear in name spaces on a par with files and processes.
A historical file system allows one to navigate the archival file system in time as
well as in space; backup files are always at hand.
A debugger can handle simultaneously active processes on disparate kinds of hard­
The character set of Plan 9 is Unicode, which covers most of the worlds major
scripts. The system has its own programming languages: a dialect of C with simple
inheritance, a simplified shell, and a CSP-like concurrent language, Alef. An ANSI-POSIX
emulator (APE) admits unreconstructed Unix code.
Plan 9 is the work of many people. The protocol was begun by Ken Thompson;
naming was integrated by Rob Pike and networking by Dave Presotto. Phil Winterbottom
simplified the management of name spaces and re-engineered the system. They were
joined by Tom Killian, Jim McKie, and Howard Trickey in bringing the system up on vari­
ous machines and making device drivers. Thompson made the C compiler; Pike, win­
dow systems; Tom Duff, the shell and raster graphics; Winterbottom, Alef; Trickey, Duff,
and Andrew Hume, APE. Bob Flandrena ported a myriad of programs to Plan 9. Other
contributors include Alan Berenbaum, Lorinda Cherry, Bill Cheswick, Sean Dorward,
David Gay, Paul Glick, Eric Grosse, John Hobby, Gerard Holzmann, Brian Kernighan, Bart
Locanthi, Doug McIlroy, Judy Paone, Sean Quinlan, Bob Restrick, Dennis Ritchie, Bjarne
Stroustrup, and Cliff Young.
Plan 9 is made available as is, without formal support, but substantial comments or
contributions may be communicated to the authors.
Doug McIlroy
March, 1995
intro introduction to Plan 9
Plan 9 is a distributed computing environment assembled from separate machines acting as termi­
nals, CPU servers, and file servers. A user works at a terminal, running a window system on a ras­
ter display. Some windows are connected to CPU servers; the intent is that heavy computing
should be done in those windows but it is also possible to compute on the terminal. A separate
file server provides file storage for terminals and CPU servers alike.
Name Spaces
In Plan 9, almost all objects look like files. The object retrieved by a given name is determined by
a mapping called the name space. A quick tour of the standard name space is in namespace(4).
Every program running in Plan 9 belongs to a process group (see rfork in fork(2)), and the name
space for each process group can be independently customized.
A name space is hierarchically structured. A full file name (also called a full path name) has the
/e1/e2/.../ en
This represents an object in a tree of files: the tree has a root, represented by the first /; the root
has a child file named e1, which in turn has child e2, and so on; the descendent en is the object
represented by the path name.
There are a number of Plan 9 services available, each of which provides a tree of files. A name
space is built by binding services (or subtrees of services) to names in the name-space-so-far.
Typically, a users home file server is bound to the root of the name space, and other services are
bound to conventionally named subdirectories. For example, there is a service resident in the
operating system for accessing hardware devices and that is bound to /dev by convention. Ker­
nel services have names (outside the name space) that are a # sign followed by a single letter; for
example, #c is conventionally bound to /dev.
Plan 9 has union directories: directories made of several directories all bound to the same name.
The directories making up a union directory are ordered in a list. When the bindings are made (see
bind(1)), flags specify whether a newly bound member goes at the head or the tail of the list or
completely replaces the list. To look up a name in a union directory, each member directory is
searched in list order until the name is found. A bind flag specifies whether file creation is allowed
in a member directory: a file created in the union directory goes in the first member directory in
list order that allows creation, if any.
The glue that holds Plan 9 together is a network protocol called 9P, described in section 5 of this
manual. All Plan 9 servers read and respond to 9P requests to navigate through a file tree and to
perform operations such as reading and writing files within the tree.
When a terminal is powered on or reset, it must be told the name of a file server to boot from, the
operating system kernel to boot, and a user name and password. How this dialog proceeds is
environment- and machine-dependent. Once it is complete, the terminal loads a Plan 9 kernel,
which sets some environment variables (see env(3)) and builds an initial name space. See
namespace(4), boot(8), and init(8) for details, but some important aspects of the initial name
space are:
The environment variable $cputype is set to the name of the kernels CPUs architecture:
one of alpha, mips, sparc, power (Power PC), 386 (386, 486, Pentium, ...) etc. The
environment variable $objtype is initially the same as $cputype.
The environment variable $terminal is set to a description of the machine running the
kernel, such as generic pc. Sometimes the middle word of $terminal encodes the
file from which the kernel is booted; e.g. alpha apc axp is bootstrapped from
The environment variable $service is set to terminal. (Other ways of accessing Plan
9 may set $service to one of cpu, con, or rx.)
The environment variable $user is set to the name of the user who booted the terminal.
The environment variable $home is set to that users home directory.
/$cputype/bin and /rc/bin are unioned into /bin.
/usr/$user/lib/profile after moving to the users home directory.
Here is a typical profile:
bind −a $home/bin/rc /bin
bind −a $home/bin/$cputype /bin
bind −c $home/tmp /tmp
font = /lib/font/bit/pelm/euro.9.font
case terminal
prompt=(’term% ’ ’ ’)
exec rio −f $font
case cpu
bind /mnt/term/dev/cons /dev/cons
bind /mnt/term/dev/consctl /dev/consctl
bind −a /mnt/term/mnt/wsys /dev
prompt=(’cpu% ’ ’
case con
prompt=(’cpu% ’ ’
The first three lines replace /tmp with a tmp in the users home directory and union personal
bin directories with /bin, to be searched after the standard bin directories. The next starts the
mail file system; see mail(1). Then different things happen, depending on the $service environ­
ment variable, such as running the window system rio(1) on a terminal.
To do heavy work such as compiling, the cpu(1) command connects a window to a CPU server; the
same environment variables are set (to different values) and the same profile is run. The initial
directory is the current directory in the terminal window where cpu was typed. The value of
$service will be cpu, so the second arm of the profile switch is executed. The root of the
terminals name space is accessible through /mnt/term, so the bind is a way of making the win­
dow systems graphics interface (see draw(3)) available to programs running on the CPU server.
The news(1) command reports current Plan 9 affairs.
The third possible service type, con, is set when the CPU server is called from a non-Plan-9
machine, such as through telnet (see con(1)).
Using Plan 9
The user commands of Plan 9 are reminiscent of those in Research Unix, version 10. There are a
number of differences, however.
The standard shell is rc(1), not the Bourne shell. The most noticeable differences appear only
when programming and macro processing.
The character-delete character is backspace, and the line-kill character is control-U; these cannot
be changed.
DEL is the interrupt character: typing it sends an interrupt to processes running in that window.
See keyboard (6) for instructions on typing characters like DEL on the various keyboards.
If a program dies with something like an address error, it enters a Broken state. It lingers, avail­
able for debugging with db(1) or acid(1). Broke (see kill(1)) cleans up broken processes.
The standard editor is one of acme(1) or sam(1). There is a variant of sam that permits running
the file-manipulating part of sam on a non-Plan-9 system:
sam −r tcp!kremvax
For historical reasons, sam uses a tab stop setting of 8 spaces, while the other editors and window
systems use 4 spaces. These defaults can be overridden by setting the value of the environment
variable $tabstop to the desired number of spaces per tab.
Machine names may be prefixed by the network name, here tcp; and net for the system default.
Login connections and remote execution on non-Plan-9 machines are usually done by saying, for
con kremvax
rx deepthought chess
(see con(1)).
9fs connects to file systems of remote systems (see srv(4)). For example,
9fs kremvax
sets things up so that the root of kremvaxs file tree is visible locally in /n/kremvax.
Faces(1) gives graphical notification of arriving mail.
The Plan 9 file server has an integrated backup facility. The command
9fs dump
binds to /n/dump a tree containing the daily backups on the file server. The dump tree has years
as top level file names, and month-day as next level file names. For example,
/n/dump/2000/0120 is the root of the file system as it appeared at dump time on January 20,
2000. If more than one dump is taken on the same day, dumps after the first have an extra digit.
To recover the version of this file as it was on June 15, 1999,
cp /n/dump/1999/0615/sys/man/1/0intro .
or use yesterday(1).
This section for general publicly accessible commands.
Section (2) for library functions, including system calls.
Section (3) for kernel devices (accessed via bind(1)).
Section (4) for file services (accessed via mount).
Section (5) for the Plan 9 file protocol.
Section (6) for file formats.
Section (7) for databases and database access programs.
Section (8) for things related to administering Plan 9.
/sys/doc for copies of papers referenced in this manual.
The back of this volume has a permuted index to aid searches.
Upon termination each program returns a string called the exit status. It was either supplied by a
call to exits(2) or was written to the commands /proc/pid/note file (see proc(3)), causing an
abnormal termination. The empty string is customary for successful execution; a non-empty
string gives a clue to the failure of the command.
0a, 1a, 2a, 5a, 6a, 7a, 8a, ka, qa, va assemblers
2a [ option ... ] [ name ... ]
These programs assemble the named files into object files for the corresponding architectures; see
2c(1) for the correspondence between an architecture and the character (1, 2, etc.) that specifies
it. The assemblers handle the most common C preprocessor directives and the associated
command-line options −D and −I. Other options are:
−o obj
Place output in file obj (allowed only if there is just one input file). Default is to take the
last element of the input path name, strip any trailing .s, and append .O, where O is first
letter of the assemblers name.
The directory /sys/include is searched for include files after machine-dependent files in
/sys/src/cmd/2a, etc.
2c(1), 2l(1).
Rob Pike, A manual for the Plan 9 assembler
The list of assemblers given above is only partial, not all architectures are supported on all sys­
tems, some have been retired and some are provided by third parties.
0c, 1c, 2c, 5c, 6c, 7c, 8c, kc, qc, vc C compilers
2c [ option ... ] [ file ... ]
These commands compile the named C files into object files for the corresponding architecture. If
there are multiple C files, the compilers will attempt to keep $NPROC compilations running con­
currently. Associated with each compiler is a string objtype, for example
0c spim
little-endian MIPS 3000 family
1c 68000
Motorola MC68000
2c 68020
Motorola MC68020
5c arm
little-endian ARM
6c amd64
AMD64 and compatibles (e.g., Intel EM64T)
7c alpha
Digital Alpha APX
8c 386
Intel i386, i486, Pentium, etc.
kc sparc
qc power
Power PC
vc mips
big-endian MIPS 3000 family
The compilers handle most preprocessing directives themselves; a complete preprocessor is avail­
able in cpp(1), which must be run separately.
Let the first letter of the compiler name be O= 0, 1, 2, 5, 6, 7, 8, k, q, or v. The output object
files end in .O. The letter is also the prefix of related programs: Oa is the assembler, Ol is the
loader. Plan 9 conventionally sets the $objtype environment variable to the objtype string
appropriate to the current machines type. Plan 9 also conventionally has /objtype directories,
which contain among other things: include, for machine-dependent include files; lib, for pub­
lic object code libraries; bin, for public programs; and mkfile, for preconditioning mk(1).
The compiler options are:
−o obj
Place output in file obj (allowed only if there is just one input file). Default is to take the
last element of the input file name, strip any trailing .c, and append .O.
Print warning messages about unused variables, etc.
Accept functions without a new-style ANSI C function prototype. By default, the compil­
ers reject functions used without a defined prototype, although ANSI C permits them.
−Dname Define the name to the preprocessor, as if by #define. If no definition is given, the
name is defined as 1.
Enable type-checking of calls to print(2) and other formatted print routines. See the dis­
cussion of extensions, below.
An #include file whose name does not begin with slash or is enclosed in double
quotes is always sought first in the directory of the file argument. If this fails, the −. flag
is given or the name is enclosed in <>, it is then sought in directories named in −I
options, then in /sys/include, and finally in /$objtype/include.
Suppress the automatic searching for include files in the directory of the file argument.
Suppress automatic registerization and optimization.
Print an assembly language version of the object code on standard output as well as
generating the .O file.
Pass type signatures on all external and global entities. The signature is based on the C
signof operator. See dynld(2).
By default, the compilers are non-standardly lax about type equality between void*
values and other pointers; this flag requires ANSI C conformance.
Invoke a standard ANSI C preprocessor before compiling.
Instead of compiling, print on standard output acid functions (see acid(1)) for examining
structures declared in the source files.
Like −a except suppress information about structures declared in included header files.
When used with −a or −aa, places acid functions in file.acid for input file.c, and not
on standard output.
The compilers support several extensions to ANSI C:
A structure or union may contain unnamed substructures and subunions. The fields of the sub­
structures or subunions can then be used as if they were members of the parent structure or
union (the resolution of a name conflict is unspecified). When a pointer to the outer structure
or union is used in a context that is only legal for the unnamed substructure, the compiler pro­
motes the type and adjusts the pointer value to point at the substructure. If the unnamed
structure or union is of a type with a tag name specified by a typedef statement, the
unnamed structure or union can be explicitly referenced by <struct variable>.<tagname>.
A structure value can be formed with an expression such as
(struct S){v1, v2, v3}
where the list elements are values for the fields of struct S.
Array initializers can specify the indices of the array in square brackets, as
int a[] = { [3] 1, [10] 5 };
which initializes the third and tenth elements of the eleven-element array a.
Structure initializers can specify the structure element by using the name following a period, as
struct { int x; int y; } s = { .y 1, .x 5 };
which initializes elements y and then x of the structure s. These forms also accept the new
ANSI C notation, which includes an equal sign:
int a[] = { [3] = 1, [10] = 5 };
struct { int x; int y; } s = { .y = 1, .x = 5 };
A global variable can be dedicated to a register by declaring it extern register in all
modules and libraries.
A #pragma of the form
#pragma lib "libbio.a"
records that the program needs to be loaded with file /$objtype/lib/libbio.a; such
lines, typically placed in library header files, obviate the −l option of the loaders. To help iden­
tify files in non-standard directories, within the file names in the #pragmas the string $M rep­
resents the name of the architecture (e.g., mips) and $O represents its identifying character
(e.g., v).
A #pragma of the form
#pragma varargck argpos error 2
tells the compiler that the second argument to error is a print-like format string (see
print(2)) that identifies the handling of subsequent arguments. The #pragma
#pragma varargck type "s" char*
says that the format verb s processes an argument of type char*. The #pragma
#pragma varargck flag ’c’
says that c is a flag character. These #pragmas are used, if the −F option is enabled, to
type-check calls to print and other such routines.
A #pragma with any of the following forms:
#pragma incomplete type
#pragma incomplete struct tag
#pragma incomplete union tag
where type is a typedefd name for a structure or union type, and tag is a structure or union
tag, tells the compiler that the corresponding type should have its signature calculated as an
incomplete type even if it is subsequently fully defined. This allows the type signature mecha­
nism to work in the presence of opaque types declared in header files, with their full definitions
visible only to the code which manipulates them. With some imported software it might be nec­
essary to turn off the signature generation completely for a large body of code (typically at the
start and end of a particular include file). If type is the word _off_, signature generation is
turned off; if type is the word _on_, the compiler will generate signatures.
The C++ comment (// to end of line) is accepted as well as the normal convention of /* */.
The compilers accept long long variables as a 64-bit type. The standard header typedefs
this to vlong. Arithmetic on vlong values is usually emulated by a run-time library, though
in at least 8c, only division and modulus use the run-time library and the other operators gen­
erate in-line code (and uvlong−expression divison−or−modulus (1<<constant) will turn into
in-line bit operations, as is done for shorter unsigned expressions).
For the 68020, produce a program prog from C files main.c and sub.c:
2c −FVw main.c sub.c
2l −o prog main.2 sub.2
/sys/src/cmd/2c, etc.
system area for machine-independent #include directives.
system area for machine-dependent #include directives.
machine-independent part
machine-dependent part
2a(1), 2l(1), cpp(1), mk(1), nm(1), pcc(1), db(1), acid(1)
Rob Pike, How to Use the Plan 9 C Compiler
The list of compilers given above is only partial, not all architectures are supported on all systems,
some have been retired and some are provided by third parties.
The default preprocessor only handles #define, #include, #undef, #ifdef, #line, and
#ifndef. For a full ANSI preprocessor, use the p option.
The default search order for include files differs to that of cpp(1).
Some features of C99, the 1999 ANSI C standard, are implemented.
switch expressions may not be either signedness of vlong on 32-bit architectures (8c at least).
The implementation of vlong assignment can use a static location and this can be disturbed by
interrupts (e.g., notes) (8c at least).
0l, 1l, 2l, 5l, 6l, 7l, 8l, kl, ql, vl loaders
2l [ option ... ] [ file ... ]
These commands load the named files into executable files for the corresponding architectures;
see 2c(1) for the correspondence between an architecture and the character (1, 2, etc.) that speci­
fies it. The files should be object files or libraries (archives of object files) for the appropriate
architecture. Also, a name like −lext represents the library libext.a in /$objtype/lib,
where objtype is one of 68000, etc. as listed in 2c(1). The libraries must have tables of contents
(see ar(1)).
In practice, −l options are rarely necessary as the header files for the libraries cause their archives
to be included automatically in the load (see 2c(1)). For example, any program that includes
header file libc.h causes the loader to search the C library /$objtype/lib/libc.a. Also,
the loader creates an undefined symbol _main (or _mainp if profiling is enabled) to force load­
ing of the startup linkage from the C library.
The order of search to resolve undefined symbols is to load all files and libraries mentioned explic­
itly on the command line, and then to resolve remaining symbols by searching in topological order
libraries mentioned in header files included by files already loaded. When scanning such libraries,
the algorithm is to scan each library repeatedly until no new undefined symbols are picked up,
then to start on the next library. Thus if library A needs B which needs A again, it may be neces­
sary to mention A explicitly so it will be read a second time.
The loader options are:
(As a bare option.) Suppress the default loading of the startup linkage and libraries
specified by header files.
−o out
Place output in file out. Default is O.out, where O is the first letter of the loader
Insert profiling code into the executable output; no special action is needed during
compilation or assembly.
Insert (embedded) tracing code into the executable output; no special action is needed
during compilation or assembly. The added code calls _tracein at function entries
and _traceout at function exits.
Strip the symbol tables from the output file.
Print the object code in assembly language, with addresses.
Print debugging output that annotates the activities of the load.
(Kl only) Generate instructions rather than calls to emulation routines for multiply and
The entry point for the binary is symbol (default _main; _mainp under −p).
−x [ file ]
Produce an export table in the executable. The optional file restricts the exported
symbols to those listed in the file. See dynld(2).
−u [ file ]
Produce an export table, import table and a dynamic load section in the executable.
The optional file restricts the imported symbols to those listed in the file. See
(5l and vl only) Move strings into the text segment.
Executable header is type n. The meaning of the types is architecture-dependent; typi­
cally type 1 is Plan 9 boot format and type 2 is the regular Plan 9 format, the default.
These are reversed on the MIPS. The Next boot format is 3. Type 4 in vl creates a
MIPS executable for an SGI Unix system.
The text segment starts at address t.
The data segment starts at address d.
The text segment is rounded to a multiple of r (if r is nonzero).
The numbers in the above options can begin with 0x or 0 to change the default base from decimal
to hexadecimal or octal. The defaults for the values depend on the compiler and the header type.
The loaded image has several symbols inserted by the loader: etext is the address of the end of
the text segment; bdata is the address of the beginning of the data segment; edata is the
address of the end of the data segment; and end is the address of the end of the bss segment,
and of the program.
for −llib arguments.
/sys/src/cmd/2l etc.
2c(1), 2a(1), ar(1), nm(1), db(1), prof(1)
Rob Pike, How to Use the Plan 9 C Compiler
The list of loaders given above is only partial, not all architectures are supported on all systems,
some have been retired and some are provided by third parties.
abaco, readweb browse the World-Wide Web
abaco [ −p ] [ −c ncols ] [ −m mtpt ] [ −t charset ] [ url ]
readweb [ url ]
Abaco is a lightweight web browser with the appearance of acme(1) with ncols columns (one by
default). Given a url, it will start by displaying that page. Clicking mouse button 3 on a link opens
it in a new abaco window. −t selects an alternate character set; −m an alternate mount point for
webfs. Normally the standard error of subshells is closed, but −p prevents this.
Readweb imports the outside network, if necessary, starts webfs and webcookies and finally abaco.
default webfs mount point
vnc(1), webcookies(4), webfs(4),
Abaco is a work in progress; many features of giant web browsers are absent.
acid, truss, trump debugger
acid [ −kqw ] [ −l library ] [ −m machine ] [ pid ] [ textfile ]
acid −l truss textfile
acid −l trump [ pid ] [ textfile ]
Acid is a programmable symbolic debugger. It can inspect one or more processes that share an
address space. A program to be debugged may be specified by the process id of a running or
defunct process, or by the name of the programs text file (8.out by default). At the prompt,
acid will store function definitions or print the value of expressions. Options are
Allow the textfile to be modified.
Print variable renamings at startup.
−l library
Load from library at startup; see below.
−m machine
Assume instructions are for the given CPU type (one of alpha, 386, etc., as listed
in 2c(1), or sunsparc or mipsco for the manufacturer-defined instruction nota­
tion for those processors) instead of using the magic number to select the CPU type.
Debug the kernel state for the process, rather than the user state.
/sys/lib/acid/$objtype, user-specified functions from $home/lib/acid, and further
functions from −l files. Definitions in any file may override previously defined functions. If the
function acidinit() is defined, it will be invoked after all libraries have been loaded. See 2c(1) for
information about creating acid functions for examining data structures.
Symbols of the program being debugged become integer variables whose values are addresses.
Contents of addresses are obtained by indirection. Local variables are qualified by function name,
for example main:argv. When program symbols conflict with acid words, distinguishing $
signs are prefixed. Such renamings are reported at startup if the option −q is enabled.
Variable types (integer, float, list, string) and formats are inferred from assignments. Truth values
false/true are attributed to zero/nonzero integers or floats and to empty/nonempty lists or
strings. Lists are sequences of expressions surrounded by {} and separated by commas.
Expressions are much as in C, but yield both a value and a format. Casts to complex types are
allowed. Lists admit the following operators, with subscripts counted from 0.
head list
tail list
append list, element
delete list, subscript
Format codes are the same as in db(1). Formats may be attached to (unary) expressions with \,
e.g. (32*7)\D. There are two indirection operators, * to address a core image, @ to address a
text file. The type and format of the result are determined by the format of the operand, whose
type must be integer.
Statements are
if expr then statement [ else statement ]
while expr do statement
loop expr, expr do statement
defn name(args) { statement }
defn name
builtin name(args)
local name
return expr
whatis [ name ]
The statement defn name clears the definition for name. A defn may override a built-in func­
tion; prefixing a function call with builtin ignores any overriding defn, forcing the use of the
built-in function.
Here is a partial list of functions; see the manual for a complete list.
Print a stack trace for current process.
Print a stack trace with values of local variables.
Print general registers. Registers can also be accessed by name, for example
Print special registers such as program counter and stack pointer.
Print floating-point registers.
Same as spr();gpr().
Expression expr with format given by the character value of expression
Print 10 lines of source around the program address.
Get the source line for the program address into a window of a running
sam(1) and select it.
Print source line nearest to the program address.
List current source directories.
Add a source directory to the list.
filepc(where) Convert a string of the form sourcefile:linenumber to a machine address.
pcfile(address) Convert a machine address to a source file name.
pcline(address) Convert a machine address to a source line number.
List breakpoints set in the current process.
bpset(address) Set a breakpoint in the current process at the given address.
bpdel(address) Delete a breakpoint from the current process.
Continue execution of current process and wait for it to stop.
Execute a single machine instruction in the current process.
Step repeatedly until after a function return.
This replaceable function is called automatically when the given process
stops. It normally prints the program counter and returns to the prompt.
Disassemble 30 machine instructions beginning at the given address.
Print a block of memory interpreted according to a string of format codes.
Like mem(), repeated for n consecutive blocks.
print(expr,...) Print the values of the expressions.
Start a new process with arguments given as a string and halt at the first
Like newproc(), but take arguments (except argv[0]) from string variable
Like new(), but run the process in a separate window.
Start a stopped process.
Kill the given process.
Make the given process current.
Escape to the shell, rc(1), to execute the command string.
There are a number of acid libraries that provide higher-level debugging facilities. Two notable
examples are truss and trump, which use acid to trace system calls (truss) and memory allocation
(trump). Both require starting acid on the program, either by attaching to a running process or by
executing new() on a binary (perhaps after setting progargs), stopping the process, and then
running truss() or trump() to execute the program under the scaffolding. The output will be
a trace of the system calls (truss) or memory allocation and free calls (trump) executed by the pro­
gram. When finished tracing, stop the process and execute untruss() or untrump()
followed by cont() to resume execution.
Start to debug /bin/ls; set some breakpoints; run up to the first one:
% acid /bin/ls
/bin/ls: mips plan 9 executable
acid: new()
70094: system call _main
ADD $−0x14,R29
70094: breakpoint
main+0x4 MOVW R31,0x0(R29)
acid: pid
acid: argv0 = **main:argv\s
acid: whatis argv0
integer variable format s
acid: *argv0
acid: bpset(ls)
acid: cont()
70094: breakpoint ls
ADD $−0x16c8,R29
Display elements of a linked list of structures:
complex Str { ’D’ 0 val; ’X’ 4 next; };
complex Str s;
s = *headstr;
while s != 0 do{
print(s.val, "\n");
s =;
Note the use of the . operator instead of −>.
Display an array of bytes declared in C as char array[].
This example gives array string format, then prints the string beginning at the address (in acid
notation) *array.
Trace the system calls executed by ls(1):
% acid −l truss /bin/ls
/bin/ls:386 plan 9 executable
acid: progargs = "−l lib/profile"
acid: new()
acid: truss()
open("#c/pid", 0)
return value: 3
pread(3, 0x7fffeeac, 20, −1)
return value: 12
data: "
166 "
stat("lib/profile", 0x0000f8cc, 113)
return value: 65
open("/env/timezone", 0)
return value: 3
pread(3, 0x7fffd7c4, 1680, −1)
return value: 1518
data: "EST −18000 EDT −14400
104896800 ..."
return value: 0
pwrite(1, "−−rw−rw−r−− M 9 rob rob 2519 Mar 22 10:29 lib/profile
", 54, −1)
−−rw−rw−r−− M 9 rob rob 2519 Mar 22 10:29 lib/profile
return value: 54
166: breakpoint
INTB $0x40
acid: cont()
2a(1), 2c(1), 2l(1), mk(1), db(1)
Phil Winterbottom, Acid Manual.
At termination, kill commands are proposed for processes that are still active.
There is no way to redirect the standard input and standard output of a new process.
Source line selection near the beginning of a file may pick an adjacent file.
With the extant stepping commands, one cannot step through instructions outside the text seg­
ment and it is hard to debug across process forks.
acme, win, awd interactive text windows
acme [ −ab ] [ −c ncol ] [ −f varfont ] [ −F fixfont ] [ −l loadfile | file ... ]
win [ command ]
awd [ label ]
Acme manages windows of text that may be edited interactively or by external programs. The
interactive interface uses the keyboard and mouse; external programs use a set of files served by
acme; these are discussed in acme(4).
Any named files are read into acme windows before acme accepts input. With the −l option, the
state of the entire system is loaded from loadfile, which should have been created by a Dump com­
mand (q.v.), and subsequent file names are ignored. Plain files display as text; directories display
as columnated lists of the names of their components, as in ls −p directory|mc except that
the names of subdirectories have a slash appended.
The −f (−F) option sets the main font, usually variable-pitch (alternate, usually fixed-pitch); the
(.../lucm/unicode.9.font). Tab intervals are set to the width of 4 (or the value of
$tabstop) numeral zeros in the appropriate font.
Acme windows are in two parts: a one-line tag above a multi-line body. The body typically con­
tains an image of a file, as in sam(1), or the output of a program, as in an rio(1) window. The tag
contains a number of blank-separated words, followed by a vertical bar character, followed by any­
thing. The first word is the name of the window, typically the name of the associated file or direc­
tory, and the other words are commands available in that window. Any text may be added after
the bar; examples are strings to search for or commands to execute in that window. Changes to
the text left of the bar will be ignored, unless the result is to change the name of the window.
If a window holds a directory, the name (first word of the tag) will end with a slash.
Each window has a scroll bar to the left of the body. The scroll bar behaves much as in sam(1) or
rio(1) except that scrolling occurs when the button is pressed, rather than released, and continues
as long as the mouse button is held down in the scroll bar. For example, to scroll slowly through a
file, hold button 3 down near the top of the scroll bar. Moving the mouse down the scroll bar
speeds up the rate of scrolling.
Acme windows are arranged in columns. By default, it creates two columns when starting; this can
be overridden with the −c option. Placement is automatic but may be adjusted using the layout
box in the upper left corner of each window and column. Pressing and holding any mouse button
in the box drags the associated window or column. For windows, just clicking in the layout box
grows the window in place: button 1 grows it a little, button 2 grows it as much as it can, still leav­
ing all other tags in that column visible, and button 3 takes over the column completely, temporar­
ily hiding other windows in the column. (They will return en masse if any of them needs attention.)
The layout box in a window is normally white; when it is black in the center, it records that the file
is dirty: acme believes it is modified from its original contents.
Tags exist at the top of each column and across the whole display. Acme pre-loads them with use­
ful commands. Also, the tag across the top maintains a list of executing long-running commands.
The behavior of typed text is similar to that in rio(1) except that the characters are delivered to the
tag or body under the mouse; there is no click to type. (The experimental option −b causes typ­
ing to go to the most recently clicked-at or made window.) The usual backspacing conventions
apply. As in sam(1) but not rio, the ESC key selects the text typed since the last mouse action, a
feature particularly useful when executing commands. A side effect is that typing ESC with text
already selected is identical to a Cut command (q.v.).
Most text, including the names of windows, may be edited uniformly. The only exception is that
the command names to the left of the bar in a tag are maintained automatically; changes to them
are repaired by acme.
When a window is in autoindent mode (see the Indent command below) and a newline character
is typed, acme copies leading white space on the current line to the new line. The option −a
causes each window to start in autoindent mode.
Directory context
Each windows tag names a directory: explicitly if the window holds a directory; implicitly if it holds
a regular file (e.g. the directory /adm if the window holds /adm/users). This directory provides
a context for interpreting file names in that window. For example, the string users in a window
labeled /adm/ or /adm/keys will be interpreted as the file name /adm/users. The directory
is defined purely textually, so it can be a non-existent directory or a real directory associated with
a non-existent file (e.g. /adm/not−a−file). File names beginning with a slash are assumed
to be absolute file names.
Windows whose names begin with − or + conventionally hold diagnostics and other data not
directly associated with files. A window labeled +Errors receives all diagnostics produced by
acme itself. Diagnostics from commands run by acme appear in a window named
directory/+Errors where directory is identified by the context of the command. These error
windows are created when needed.
Mouse button 1
Mouse button 1 selects text just as in sam(1) or rio(1), including the usual double-clicking con­
Mouse button 2
By an action similar to selecting text with button 1, button 2 indicates text to execute as a com­
mand. If the indicated text has multiple white-space-separated words, the first is the command
name and the second and subsequent are its arguments. If button 2 is clickedindicates a null
stringacme expands the indicated text to find a command to run: if the click is within button-1selected text, acme takes that selection as the command; otherwise it takes the largest string of
valid file name characters containing the click. Valid file name characters are alphanumerics and _
. − + /. This behavior is similar to double-clicking with button 1 but, because a null command is
meaningless, only a single click is required.
Some commands, all by convention starting with a capital letter, are built−ins that are executed
directly by acme:
Delete most recently selected text and place in snarf buffer.
Delete window. If window is dirty, instead print a warning; a second Del will succeed.
Delete column and all its windows, after checking that windows are not dirty.
Delete window without checking for dirtiness.
Dump Write the state of acme to the file name, if specified, or $home/acme.dump by default.
Edit Treat the argument as a text editing command in the style of sam(1). The full Sam lan­
guage is implemented except for the commands k, n, q, and !. The = command is slightly
different: it includes the file name and gives only the line address unless the command is
explicitly =#. The current window for the command is the body of the window in which
the Edit command is executed. Usually the Edit command would be typed in a tag;
longer commands may be prepared in a scratch window and executed, with Edit itself in
the current window, using the 2-1 chord described below.
Exit Exit acme after checking that windows are not dirty.
Font With no arguments, change the font of the associated window from fixed-spaced to
proportional-spaced or vice versa. Given a file name argument, change the font of the win­
dow to that stored in the named file. If the file name argument is prefixed by var (fix),
also set the default proportional-spaced (fixed-spaced) font for future use to that font.
Other existing windows are unaffected.
Load file into window, replacing previous contents (after checking for dirtiness as in Del).
With no argument, use the existing file name of the window. Given an argument, use that
file but do not change the windows file name.
Print window ID number (q.v.).
Incl When opening include files (those enclosed in <>) with button 3, acme searches in direc­
tories /$objtype/include and /sys/include. Incl adds its arguments to a sup­
plementary list of include directories, analogous to the −I option to the compilers. This
list is per-window and is inherited when windows are created by actions in that window, so
Incl is most usefully applied to a directory containing relevant source. With no arguments,
Incl prints the supplementary list. This command is largely superseded by plumbing (see
Set the autoindent mode according to the argument: on and off set the mode for the cur­
rent window; ON and OFF set the mode for all existing and future windows.
Kill Send a kill note to acme-initiated commands named as arguments.
Load Restore the state of acme from a file (default $home/acme.dump) created by the Dump
When prefixed to a command run the command in the same file name space and environ­
ment variable group as acme. The environment of the command is restricted but is suffi­
cient to run bind(1), 9fs (see srv(4)), import(4), etc., and to set environment variables such
as $objtype.
Look Search in body for occurrence of literal text indicated by the argument or, if none is given,
by the selected text in the body.
Make new window. With arguments, load the named files into windows.
Make new column.
Replace most recently selected text with contents of snarf buffer.
Write window to the named file. With no argument, write to the file named in the tag of the
Write all dirty windows whose names indicate existing regular files.
Redo Complement of Undo.
Send Append selected text or snarf buffer to end of body; used mainly with win.
Place selected text in snarf buffer.
Sort Arrange the windows in the column from top to bottom in lexicographical order based on
their names.
Set the width of tab stops for this window to the value of the argument, in units of widths
of the zero character. With no arguments, it prints the current value.
Undo Undo last textual change or set of changes.
Create a copy of the window containing most recently selected text.
If a regular shell command is preceded by a <, |, or > character, the selected text in the
body of the window is affected by the I/O from the command. The < character causes the
selection to be replaced by the standard output of the command; > causes the selection to
be sent as standard input to the command; and | does both at once, piping the selection
through the command and replacing it with the output.
A common place to store text for commands is in the tag; in fact acme maintains a set of com­
mands appropriate to the state of the window to the left of the bar in the tag.
If the text indicated with button 2 is not a recognized built-in, it is executed as a shell command.
For example, indicating date with button 2 runs date(1). The standard and error outputs of com­
mands are sent to the error window associated with the directory from which the command was
run, which will be created if necessary. For example, in a window /adm/users executing pwd
will produce the output /adm in a (possibly newly-created) window labeled /adm/+Errors; in a
window containing /sys/src/cmd/sam/sam.c executing mk will run mk(1) in
/sys/src/cmd/sam/+Errors. The environment of such commands contains the variable $%
with value set to the filename of the window in which the command is run, and $winid set to the
windows id number (see acme(4)).
Mouse button 3
Pointing at text with button 3 instructs acme to locate or acquire the file, string, etc. described by
the indicated text and its context. This description follows the actions taken when button 3 is
released after sweeping out some text. In the description, text refers to the text of the original
sweep or, if it was null, the result of applying the same expansion rules that apply to button 2
If the text names an existing window, acme moves the mouse cursor to the selected text in the
body of that window. If the text names an existing file with no associated window, acme loads the
file into a new window and moves the mouse there. If the text is a file name contained in angle
brackets, acme loads the indicated include file from the directory appropriate to the suffix of the
file name of the window holding the text. (The Incl command adds directories to the standard
If the text begins with a colon, it is taken to be an address, in the style of sam(1), within the body
of the window containing the text. The address is evaluated, the resulting text highlighted, and
the mouse moved to it. Thus, in acme, one must type :/regexp or :127 not just /regexp or
127. (There is an easier way to locate literal text; see below.)
If the text is a file name followed by a colon and an address, acme loads the file and evaluates the
address. For example, clicking button 3 anywhere in the text file.c:27 will open file.c,
select line 27, and put the mouse at the beginning of the line. The rules about Error files, directo­
ries, and so on all combine to make this an efficient way to investigate errors from compilers, etc.
If the text is not an address or file, it is taken to be literal text, which is then searched for in the
body of the window in which button 3 was clicked. If a match is found, it is selected and the
mouse is moved there. Thus, to search for occurrences of a word in a file, just click button 3 on
the word. Because of the rule of using the selection as the button 3 action, subsequent clicks will
find subsequent occurrences without moving the mouse.
In all these actions, the mouse motion is not done if the text is a null string within a non-null
selected string in the tag, so that (for example) complex regular expressions may be selected and
applied repeatedly to the body by just clicking button 3 over them.
Chords of mouse buttons
Several operations are bound to multiple-button actions. After selecting text, with button 1 still
down, pressing button 2 executes Cut and button 3 executes Paste. After clicking one button,
the other undoes the first; thus (while holding down button 1) 2 followed by 3 is a Snarf that
leaves the file undirtied; 3 followed by 2 is a no-op. These actions also apply to text selected by
double-clicking because the double-click expansion is made when the second click starts, not
when it ends.
Commands may be given extra arguments by a mouse chord with buttons 2 and 1. While holding
down button 2 on text to be executed as a command, clicking button 1 appends the text last
pointed to by button 1 as a distinct final argument. For example, to search for literal text one
may execute Look text with button 2 or instead point at text with button 1 in any window,
release button 1, then execute Look, clicking button 1 while 2 is held down.
When an external command (e.g. echo(1)) is executed this way, the extra argument is passed as
expected and an environment variable $acmeaddr is created that holds, in the form interpreted
by button 3, the fully-qualified address of the extra argument.
Support programs
Win creates a new acme window and runs a command (default /bin/rc) in it, turning the window
into something analogous to an rio(1) window. Executing text in a win window with button 2 is
similar to using Send.
Awd loads the tag line of its window with the directory in which its running, suffixed −label
(default rc); it is intended to be executed by a cd function for use in win windows. An example
definition is
fn cd { builtin cd $1 && awd $sysname }
Applications and guide files
In the directory /acme live several subdirectories, each corresponding to a program or set of
related programs that employ acme’s user interface. Each subdirectory includes source, binaries,
and a readme file for further information. It also includes a guide, a text file holding sample
commands to invoke the programs. The idea is to find an example in the guide that best matches
the job at hand, edit it to suit, and execute it.
Whenever a command is executed by acme, the default search path includes the directory of the
window containing the command and its subdirectory $cputype. The program directories in
/acme contain appropriately labeled subdirectories of binaries, so commands named in the guide
files will be found automatically when run. Also, acme binds the directories /acme/bin and
/acme/bin/$cputype to the beginning of /bin when it starts; this is where acme-specific
programs such as win and awd reside.
default file for Dump and Load; also where state is written if acme dies
or is killed unexpectedly, e.g. by deleting its window.
template files for applications
informal documentation for applications
source for applications
MIPS-specific binaries for applications
Rob Pike, Acme: A User Interface for Programmers.
With the −l option or Load command, the recreation of windows under control of external pro­
grams such as win is just to rerun the command; information may be lost.
ansitize translate Plan 9 C to ANSI C
ansitize [ −c conf ] [ −I dir ]... [ −p preload ]... [ file ]
Ansitize translates programs written in the Plan 9 C dialect into standard ANSI C programs, pre­
serving comments and formatting.
The options are:
−c conf
Read configuration information from the file conf. The format of the configuration file is
discussed below.
−I dir Add dir to the list of directories searched for #include files. /386/include and
/sys/include are added to the list after processing the −I options.
−p preload
Before processing file, process the file preload, but do not print its translation. This option
is useful mainly for translating header files. See the examples below.
Ansitize translates many constructs from Plan 9 C, described below. It does not translate types or
other features present in the Plan 9 C environment when those features can be provided by appro­
priate program context. For example, ansitize removes long character constants and strings but
still assumes that Rune is a defined type.
Ansitize translates the following constructs.
anonymous structures or unions
Plan 9 C allows anonymous structures and unions. Ansitize gives these explicit names and trans­
lates references to reflect the new names. If a struct (or union) name is declared anony­
mously, ansitize uses _name in the new declaration. Otherwise, unions are named u, u2, etc.,
and structures are named _1, _2, etc. For example, by default ansitize translates the first struc­
ture definition into the second:
struct A {
union {
int x;
int y;
struct B;
struct A {
union {
int x;
int y;
} u;
struct B _B;
struct A {
union {
int x;
int y;
} au;
struct B b;
These default names can be overridden by a configuration line rename old new, where old is a
single name or is, which restricts the renaming to the elements of struct (or union)
tag. For example, using a configuration:
rename A.u au
rename _B b
(or rename A._b b)
would produce the third structure definition above.
anonymous structure promotions
Plan 9 C allows pointers to structures with anonymous elements to be passed to functions expect­
ing pointers to the anonymous elements. For example, given the structure definition above, if a
struct A *a is passed to a function expecting a struct B*, the C compiler instead passes a
pointer to the B inside the A. Ansitize does the same transformation, in this case rewriting f(a)
to f(&a−>b). The same conversion applies to simple assignment of struct A* to struct
anonymous function parameters
Plan 9 C does not require unused function parameters to be named in the function definition.
Ansitize names these parameters _1, _2, etc. For example, ansitize rewrites
void main(int, char**) { }
void main(int _1, char** _2) { }
structure displays
Plan 9 C allows casted initializer lists as structure values, as in (Point){1,2}. Ansitize can
rewrite these into function calls, as in pt(1,2), but only does so if directed by a configuration
line reconstruct struct−name function−name, as in reconstruct Point pt.
Unicode identifiers
Ansitize rewrites identifiers containing Unicode characters into ASCII equivalents, replacing Greek
letters with their names and other Unicode characters with _xxxx, where xxxx is the hexadecimal
value of the character.
long character constants
Ansitize rewrites long character constants like L’\n’, L’a’, or L’ÿ’ into equivalent expressions
like ’\n’, ’a’, or (Rune)0x00FF.
long string constants
Ansitize replaces Rune string constants like L"abc" with references to statically declared arrays
with names derived from the string data. It recognizes the special case where a Rune string is
being used to initialize a Rune array and replaces the string in that case with an array. For exam­
ple, ansitize rewrites the first program into the second:
Rune L_abc[] = {’a’,’b’,’c’,0};
Rune *x = L_abc;
Rune y[] = {’d’,’e’,’f’,0};
Rune *x = L"abc";
Rune y[] = L"def";
#pragma lines
Ansitize places #pragma lines inside /* */ comments. #pragma varargck lines are handled
separately and are placed inside #ifdef VARARGCK / #endif pairs. (At least one compiler
under development for Unix recognizes these #pragmas.)
integer/pointer casts
Some overeager Unix compilers complain about casts from integer to pointer, even when the
pointer is as wide as or wider than the integer. Ansitize inserts an extra (uintptr) cast to
silence these warnings: p=(void*)i becomes p=(void*)(uintptr)i.
<ctype.h> casts
The macros defined in Plan 9s <ctype.h> cast their arguments to uchar so that either signed
or unsigned character arguments can be passed to them. Unixs <ctype.h> requires the use of
unsigned character arguments. Ansitize adds casts as necessary to the arguments of isalpha,
isdigit, toupper, etc.
A configuration file for translating the regexp(2) library:
Resub.u s
Resub.u1 e
Reinst.u u1
Reinst.u1 u2
Translate the source files:
cd /sys/src/libregexp
for(i in *.c)
ansitize −c conf $i >$i.ansi
Translate the header file, reading <u.h> and <libc.h> first for context:
cd /sys/include
ansitize −p /386/include/u.h −p libc.h regexp.h >regexp.h.ansi
2c(1), fortune(1)
Rob Pike, How to use the Plan 9 C Compiler
Ansitize stops short of full checking of the input program. Test that they compile using 2c(1)
before running ansitize.
Ansitize ignores #ifdef and #define, limiting the kinds of macros that can be used. In partic­
ular, macros that introduce new control flow constructs will confuse the parser. (The parser con­
tains extra grammar productions to accommodate the arg(2) macros and va_arg.)
ap fetch Associated Press news articles
ap [ article−name ]
ap fetches Associated Press news articles from Without any arguments
it provides a two column list of article keys and descriptions. When invoked with an article key it
fetches that article.
ar archive and library maintainer
ar key [ posname ] afile [ file ... ]
Ar maintains groups of files combined into a single archive file, afile. The main use of ar is to cre­
ate and update library files for the loaders 2l(1), etc. It can be used, though, for any similar pur­
Key is one character from the set drqtpmx, optionally concatenated with one or more of
vuaibclo. The files are constituents of the archive afile. The meanings of the key characters
Delete files from the archive file.
Replace files in the archive file, or add them if missing. Optional modifiers are
Replace only files with modified dates later than that of the archive.
Place new files after posname in the archive rather than at the end.
b or i Place new files before posname in the archive.
Quick. Append files to the end of the archive without checking for duplicates. Avoids qua­
dratic behavior in for (i in *.v) ar r lib.a $i.
List a table of contents of the archive. If names are given, only those files are listed.
Print the named files in the archive.
Move the named files to the end or elsewhere, specified as with r.
Preserve the access and modification times of files extracted with the x command.
Extract the named files. If no names are given, all files in the archive are extracted. In nei­
ther case does x alter the archive file.
Verbose. Give a file-by-file description of the making of a new archive file from the old
archive and the constituent files. With p, precede each file with a name. With t, give a
long listing of all information about the files, somewhat like a listing by ls(1), showing
mode uid/gid size date name
Local. Normally ar places its temporary files in the directory /tmp. This option causes
them to be placed in the local directory.
When a d, r, or m key is specified and all members of the archive are valid object files for the same
architecture, ar inserts a table of contents, required by the loaders, at the front of the library. The
table of contents is rebuilt whenever the archive is modified, except when the q key is specified or
when the table of contents is explicitly moved or deleted.
ar cr lib.a *.v
Replace the contents of library lib.a with the object files in the current directory.
2l(1), ar(6)
If the same file is mentioned twice in an argument list, it may be put in the archive twice.
This command predates Plan 9 and makes some invalid assumptions, for instance that user ids
are numeric.
ascii, unicode interpret ASCII, Unicode characters
ascii [ −8cnt ] [ −dox | −b n ] [ text ]
unicode hexmin−hexmax
unicode [ −t ] hex [ ... ]
unicode [ −n ] characters
look hex /lib/unicode
Ascii prints the ASCII values corresponding to characters and vice versa; under the −8 option, the
ISO Latin-1 extensions (codes 0200-0377) are included. The values are interpreted in a settable
numeric base; −o specifies octal, −d decimal, −x hexadecimal (the default), and −bn base n.
With no arguments, ascii prints a table of the character set in the specified base. Characters of
text are converted to their ASCII values, one per line. If, however, the first text argument is a valid
number in the specified base, conversion goes the opposite way. Control characters are printed as
two- or three-character mnemonics. Other options are:
Force numeric output.
Force character output.
Convert from numbers to running text; do not interpret control characters or insert new­
Unicode is similar; it converts between UTF and character values from the Unicode Standard (see
utf(6)). If given a range of hexadecimal numbers, unicode prints a table of the specified Unicode
characters their values and UTF representations. Otherwise it translates from UTF to numeric
value or vice versa, depending on the appearance of the supplied text; the −n option forces
numeric output to avoid ambiguity with numeric characters. If converting to UTF , the characters
are printed one per line unless the −t flag is set, in which case the output is a single string con­
taining only the specified characters. Unlike ascii, unicode treats no characters specially.
The output of ascii and unicode may be unhelpful if the characters printed are not available in the
current font.
The file /lib/unicode contains a table of characters and descriptions, sorted in hexadecimal
order, suitable for look(1) on the lower case hex values of characters.
ascii −d
Print the ASCII table base 10.
unicode p
Print the hex value of p.
unicode 2200−22f1
Print a table of miscellaneous mathematical symbols.
look 039 /lib/unicode
See the start of the Greek alphabets encoding in the Unicode Standard.
table of characters and descriptions.
look(1), tcs(1), utf(6), font(6)
awk pattern-directed scanning and processing language
awk [ −F fs ] [ −d ] [ −mf n ] [ −mr n ] [ −safe ] [ −v var=value ] [ −f progfile | prog ] [ file ... ]
Awk scans each input file for lines that match any of a set of patterns specified literally in prog or
in one or more files specified as −f progfile. With each pattern there can be an associated action
that will be performed when a line of a file matches the pattern. Each line is matched against the
pattern portion of every pattern-action statement; the associated action is performed for each
matched pattern. The file name − means the standard input. Any file of the form var=value is
treated as an assignment, not a file name, and is executed at the time it would have been opened
if it were a file name. The option −v followed by var=value is an assignment to be done before
the program is executed; any number of −v options may be present. −F fs option defines the
input field separator to be the regular expression fs.
An input line is normally made up of fields separated by white space, or by regular expression FS.
The fields are denoted $1, $2, ..., while $0 refers to the entire line. If FS is null, the input line is
split into one field per character.
To compensate for inadequate implementation of storage management, the −mr option can be
used to set the maximum size of the input record, and the −mf option to set the maximum num­
ber of fields.
The −safe option causes awk to run in safe mode, in which it is not allowed to run shell com­
mands or open files and the environment is not made available in the ENVIRON variable.
A pattern-action statement has the form
pattern { action }
A missing { action } means print the line; a missing pattern always matches. Pattern-action state­
ments are separated by newlines or semicolons.
An action is a sequence of statements. A statement can be one of the following:
if( expression ) statement [ else statement ]
while( expression ) statement
for( expression ; expression ; expression ) statement
for( var in array ) statement
do statement while( expression )
{ [ statement ... ] }
# commonly var = expression
print [ expression−list ] [ > expression ]
printf format [ , expression−list ] [ > expression ]
return [ expression ]
# skip remaining patterns on this input line
# skip rest of this file, open next, start at top
delete array[ expression ]
# delete an array element
delete array
# delete all elements of array
exit [ expression ]
# exit immediately; status is expression
Statements are terminated by semicolons, newlines or right braces. An empty expression−list
stands for $0. String constants are quoted " ", with the usual C escapes recognized within.
Expressions take on string or numeric values as appropriate, and are built using the operators + * / % ^ (exponentiation), and concatenation (indicated by white space). The operators ! ++
+= = *= /= %= ^= > >= < <= == != ?: are also available in expressions. Vari­
ables may be scalars, array elements (denoted x[i]) or fields. Variables are initialized to the null
string. Array subscripts may be any string, not necessarily numeric; this allows for a form of asso­
ciative memory. Multiple subscripts such as [i,j,k] are permitted; the constituents are con­
catenated, separated by the value of SUBSEP.
The print statement prints its arguments on the standard output (or on a file if >file or >>file is
present or on a pipe if |cmd is present), separated by the current output field separator, and ter­
minated by the output record separator. file and cmd may be literal names or parenthesized
expressions; identical string values in different statements denote the same open file. The
printf statement formats its expression list according to the format (see fprintf(2)) . The builtin function close(expr) closes the file or pipe expr. The built-in function fflush(expr)
flushes any buffered output for the file or pipe expr. If expr is omitted or is a null string, all open
files are flushed.
The mathematical functions exp, log, sqrt, sin, cos, and atan2 are built in. Other built-in
If its argument is a string, the strings length is returned. If its argument is an array,
the number of subscripts in the array is returned. If no argument, the length of $0 is
random number on (0,1)
sets seed for rand and returns the previous seed.
truncates to an integer value
converts its numerical argument, a character number, to a UTF string
substr(s, m, n)
the n-character substring of s that begins at position m counted from 1.
index(s, t)
the position in s where the string t occurs, or 0 if it does not.
match(s, r)
the position in s where the regular expression r occurs, or 0 if it does not. The vari­
ables RSTART and RLENGTH are set to the position and length of the matched string.
split(s, a, fs)
splits the string s into array elements a[1], a[2], ..., a[n], and returns n. The sep­
aration is done with the regular expression fs or with the field separator FS if fs is not
given. An empty string as field separator splits the string into one array element per
sub(r, t, s)
substitutes t for the first occurrence of the regular expression r in the string s. If s is
not given, $0 is used.
same as sub except that all occurrences of the regular expression are replaced; sub
and gsub return the number of replacements.
sprintf(fmt, expr, ...)
the string resulting from formatting expr ... according to the printf format fmt
executes cmd and returns its exit status
returns a copy of str with all upper-case characters translated to their corresponding
lower-case equivalents.
returns a copy of str with all lower-case characters translated to their corresponding
upper-case equivalents.
The function getline sets $0 to the next input record from the current input file; getline
<file sets $0 to the next record from file. getline x sets variable x instead. Finally, cmd |
getline pipes the output of cmd into getline; each call of getline returns the next line of
output from cmd. In all cases, getline returns 1 for a successful input, 0 for end of file, and 1
for an error.
Patterns are arbitrary Boolean combinations (with ! || &&) of regular expressions and relational
expressions. Regular expressions are as in regexp(6). Isolated regular expressions in a pattern
apply to the entire line. Regular expressions may also occur in relational expressions, using the
operators ~ and !~. /re/ is a constant regular expression; any string (constant or variable) may
be used as a regular expression, except in the position of an isolated regular expression in a pat­
A pattern may consist of two patterns separated by a comma; in this case, the action is performed
for all lines from an occurrence of the first pattern though an occurrence of the second.
A relational expression is one of the following:
expression matchop regular−expression
expression relop expression
expression in array−name
(expr,expr,... ) in array−name
where a relop is any of the six relational operators in C, and a matchop is either ~ (matches) or !~
(does not match). A conditional is an arithmetic expression, a relational expression, or a Boolean
combination of these.
The special patterns BEGIN and END may be used to capture control before the first input line is
read and after the last. BEGIN and END do not combine with other patterns.
Variable names with special meanings:
conversion format used when converting numbers (default %.6g)
regular expression used to separate fields; also settable by option Ffs.
number of fields in the current record
ordinal number of the current record
ordinal number of the current record in the current file
the name of the current input file
input record separator (default newline)
output field separator (default blank)
output record separator (default newline)
output format for numbers (default %.6g)
separates multiple subscripts (default 034)
argument count, assignable
argument array, assignable; non-null members are taken as file names
array of environment variables; subscripts are names.
Functions may be defined (at the position of a pattern-action statement) thus:
function foo(a, b, c) { ...; return x }
Parameters are passed by value if scalar and by reference if array name; functions may be called
recursively. Parameters are local to the function; all other variables are global. Thus local vari­
ables may be created by providing excess parameters in the function definition.
length($0) > 72
Print lines longer than 72 characters.
{ print $2, $1 }
Print first two fields in opposite order.
BEGIN { FS = ",[ \t]*|[ \t]+" }
{ print $2, $1 }
Same, with input fields separated by comma and/or blanks and tabs.
{ s += $1 }
{ print "sum is", s, " average is", s/NR }
Add up first column, print sum and average.
/start/, /stop/
Print all lines between start/stop pairs.
# Simulate echo(1)
for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]
printf "\n"
exit }
sed(1), regexp(6),
A. V. Aho, B. W. Kernighan, P. J. Weinberger, The AWK Programming Language, Addison-Wesley,
1988. ISBN 0-201-07981-X
There are no explicit conversions between numbers and strings. To force an expression to be
treated as a number add 0 to it; to force it to be treated as a string concatenate "" to it.
The scope rules for variables in functions are a botch; the syntax is worse.
UTF is not always dealt with correctly, though awk does make an attempt to do so. The split func­
tion with an empty string as final argument now copes with UTF in the string being split.
basename strip file name affixes
basename [ −d ] string [ suffix ]
Basename deletes any prefix ending in slash (/) and the suffix, if present in string, from string,
and prints the result on the standard output.
The −d option instead prints the directory component, that is, string up to but not including the
final slash. If the string contains no slash, a period and newline are printed.
bc arbitrary-precision arithmetic language
bc [ −cdls ] [ file ... ]
Bc is an interactive processor for a language that resembles C but provides arithmetic on numbers
of arbitrary length with up to 100 digits right of the decimal point. It takes input from any files
given, then reads the standard input.
The −d option enables debugging output. The −l option stands for the name of an arbitrary pre­
cision math library. The −s option suppresses the automatic display of calculation results; all out­
put is via the print command.
The following syntax for bc programs is like that of C; L means letter a-z, E means expression, S
means statement.
comments are enclosed in /* */
newlines end statements
simple variables: L
array elements: L[E]
The words ibase, obase, and scale
Other operands
arbitrarily long numbers with optional sign and decimal point.
number of significant decimal digits
number of digits right of decimal point
function call
+ − * / % ^ (% is remainder; ^ is power)
++ −−
== <= >= != < >
= += −= *= /= %= ^=
{ S ; ... ; S }
print E
if ( E ) S
while ( E ) S
for ( E ; E ; E ) S
null statement
Function definitions
define L ( L , ... , L ){
auto L , ... , L
S ; ... ; S
return E
Functions in
−l math library
s(x) sine
c(x) cosine
e(x) exponential
l(x) log
a(x) arctangent
j(n, x)
Bessel function
All function arguments are passed by value.
The value of an expression at the top level is printed unless the main operator is an assignment or
the −s command line argument is given. Text in quotes, which may include newlines, is always
printed. Either semicolons or newlines may separate statements. Assignment to scale influ­
ences the number of digits to be retained on arithmetic operations in the manner of dc(1). Assign­
ments to ibase or obase set the input and output number radix respectively.
The same letter may be used as an array, a function, and a simple variable simultaneously. All
variables are global to the program. Automatic variables are pushed down during function calls.
In a declaration of an array as a function argument or automatic variable empty square brackets
must follow the array name.
Bc is actually a preprocessor for dc(1), which it invokes automatically, unless the −c (compile only)
option is present. In this case the dc input is sent to the standard output instead.
Define a function to compute an approximate value of the exponential. Use it to print 10 values.
(The exponential function in the library gives better answers.)
scale = 20
define e(x) {
auto a, b, c, i, s
a = 1
b = 1
s = 1
for(i=1; 1; i++) {
a *= x
b *= i
c = a/b
if(c == 0) return s
s += c
for(i=1; i<=10; i++) print e(i)
/sys/lib/bclib mathematical library
dc(1), hoc(1)
No &&, ||, or ! operators.
A for statement must have all three Es.
A quit is interpreted when read, not when executed.
bind, mount, unmount change name space
bind [ option ... ] new old
mount [ option ... ] servename old [ spec ]
unmount [ new ] old
Bind and mount modify the file name space of the current process and other processes in the same
name space group (see fork(2)). For both calls, old is the name of an existing file or directory in
the current name space where the modification is to be made.
For bind, new is the name of another (or possibly the same) existing file or directory in the current
name space. After a successful bind, the file name old is an alias for the object originally named
by new; if the modification doesnt hide it, new will also still refer to its original file. The evalua­
tion of new (see intro(2)) happens at the time of the bind, not when the binding is later used.
The servename argument to mount is the name of a file that, when opened, yields an existing con­
nection to a file server. Almost always, servename will be a file in /srv (see srv(3)). In the discus­
sion below, new refers to the file named by the new argument to bind or the root directory of the
service available in servename after a mount. Either both old and new files must be directories, or
both must not be directories.
Options control aspects of the modification to the name space:
Replace the old file by the new one. Henceforth, an evaluation of old will be translated
to the new file. If they are directories (for mount, this condition is true by definition),
old becomes a union directory consisting of one directory (the new file).
Both files must be directories. Add the new directory to the beginning of the union
directory represented by the old file.
Both files must be directories. Add the new directory to the end of the union directory
represented by the old file.
This can be used in addition to any of the above to permit creation in a union directory.
When a new file is created in a union directory, it is placed in the first element of the
union that has been bound or mounted with the −c flag. If that directory does not have
write permission, the create fails.
(Only in mount.) By default, file contents are always retrieved from the server. With this
option, the kernel may instead use a local cache to satisfy read(5) requests for files
accessible through this mount point. The currency of cached data for a file is verified at
each open(5) of the file from this client machine.
Exit silently if the bind or mount operation fails.
Mount takes two additional options. The first, −k keypattern, constrains the set of factotum(4)
keys used for an authenticated mount. The second, −n, causes mount to skip authentication
The spec argument to mount is passed in the attach(5) message to the server, and selects among
different file trees served by the server.
The srv(3) service registry device, normally bound to /srv, is a convenient rendezvous point for
services that can be mounted. After bootstrap, the file /srv/boot contains the communications
port to the file system from which the system was loaded.
The effects of bind and mount can be undone with the unmount command. If two arguments are
given to unmount, the effect is to undo a bind or mount with the same arguments. If only one
argument is given, everything bound to or mounted upon old is unmounted.
To compile a program with the C library from July 16, 1992:
mount /srv/boot /n/dump dump
bind /n/dump/1992/0716/mips/lib/libc.a /mips/lib/libc.a
bind(2), open(2), srv(3), srv(4)
bitsyload, light, pencal, keyboard, params, prompter bitsy-specific utilities
bitsy/bitsyload k|r [ file ]
bitsy/light [ intensity ]
bitsy/params [ f ]
bitsy/keyboard [ n ]
bitsy/prompter [ n ] file
Bitsyload erases a section of flash memory on the Bitsy (iPAQ 3650 or 3830) and copies new infor­
mation into it, using the format required by the Compaq boot loader. The required first argument
is the destination, either k for /dev/flash/kernel or r for /dev/flash/ramdisk. The
optional second argument is the name of the file to load. The default kernel file is
Light sets the intensity of the display backlight. The values for intensity are:
set intensity to maximum, the default
turn off backlight
sets the intensity to n, where n is a value between 0 and 128. Intensity 0 doesnt turn off
the backlight, it just sets it to the dimmest value.
Pencal calibrates the display with the touch screen on a Bitsy. It loops prompting the user with
crosses whose center that the user must touch with the stylus. After a consistent set of touches, it
writes the calibration both to the kernel and to standard out. It is normally called by the bitsys
Params copies the contents of the file /dev/tmpparams, into the
/dev/flash/params, or if the −f flag it set copies in the opposite direction.
Keyboard creates a virtual on-screen keyboard and, unless the −n option is specified, a scribble
area. A user inputs characters by tapping the keys or by drawing characters in the scribble area
(see scribble(2)). It is usually run as the keyboard command for rio(1) using rios −k option.
Prompter is a small editor used to configure parameters when a Bitsy boots. It displays the file
and starts up a keyboard and scribble pad for input. Clicking with the stylus in the text selects
where input characters will go. Pressing Button 5 (top left side of the Bitsy) or typing the Esc key
on the keyboard causes prompter to write back the updated file and exit; Del causes prompter to
exit without writing the file. The −n flag suppresses the scribble area.
Prompter, params, and calibrate are used in only one place, the Bitsys /rc/bin/cpurc:
# set variables
bitsy/params −f
if(! grep −s ’^calibrate=’ /tmp/tmpparams)
bitsy/pencal >>/tmp/tmpparams
if not {
eval ‘{grep ’^calibrate=’ /tmp/tmpparams}
echo calibrate $calibrate > ’#m/mousectl’
bitsy/prompter /tmp/tmpparams
bundle collect files for distribution
bundle file ...
Bundle writes on its standard output a shell script for rc(1) or a Bourne shell which, when exe­
cuted, will recreate the original files. Its main use is for distributing small numbers of text files by
Although less refined than standard archives from ar(1) or tar(1), a bundle file is selfdocumenting and complete; little preparation is required on the receiving machine.
bundle mkfile *.[ch] | mail kremvax!boris
Send a makefile to Boris together with related .c and .h files. Upon receiving the mail,
Boris may save the file sans postmark, say in gift/horse, then do
cd gift; rc horse; mk
ar(1), tar(1), mail(1)
Bundle will not create directories and is unsatisfactory for non-text files.
Beware of gift horses.
cal print calendar
cal [ month ] [ year ]
Cal prints a calendar. Month is either a number from 1 to 12, a lower case month name, or a lower
case three-letter prefix of a month name. Year can be between 1 and 9999. If either month or
year is omitted, the current month or year is used. If only one argument is given, and it is a num­
ber larger than 12, a calendar for all twelve months of the given year is produced; otherwise a cal­
endar for just one month is printed. The calendar produced is that for England and her colonies.
cal sep 1752
The year is always considered to start in January even though this is historically naive.
Beware that cal 90 refers to the early Christian era, not the 20th century.
calendar print upcoming events
calendar [ −dy ] [ −p days ] [ file ... ]
Calendar reads the named files, default /usr/$user/lib/calendar, and writes to standard
output any lines containing todays or tomorrows date. Examples of recognized date formats are
"4/11", "April 11", "Apr 11", "11 April", and "11 Apr". A special form may be used to represent
weekly and monthly events: "Every Tuesday" "The third Wednesday" All comparisons are case insen­
If the −y flag is given, an attempt is made to match on year too. In this case, dates of the forms
listed above will be accepted if they are followed by the current year (or last two digits thereof) or
not a year digits not followed by white space or non-digits.
If the −p flag is given, its argument is the number of days ahead to match dates. This flag is not
repeatable, and it performs no special processing at the end of the week.
The −d flag enables debugging output.
On Friday and Saturday, events through Monday are printed.
To have your calendar mailed to you every day, use cron(8).
personal calendar
cat, read catenate files
cat [ file ... ]
read [ −m ] [ −n nline ] [ file ... ]
Cat reads each file in sequence and writes it on the standard output. Thus
cat file
prints a file and
cat file1 file2 >file3
concatenates the first two files and places the result on the third.
If no file is given, cat reads from the standard input. Output is buffered in blocks matching the
Read copies to standard output exactly one line from the named file, default standard input. It is
useful in interactive rc(1) scripts.
The −m flag causes it to continue reading and writing multiple lines until end of file; −n causes it
to read no more than nline lines.
Read always executes a single write for each line of input, which can be helpful when preparing
input to programs that expect line-at-a-time data. It never reads any more data from the input
than it prints to the output.
Read exits with status eof on end of file or, in the −n case, if it doesnt read nlines lines.
Beware of cat a b >a and cat a b >b, which destroy input files before reading them.
cb C program beautifier
cb [ −js ] [ −l length ] [ file ... ]
Cb reads syntactically correct C programs from from its input or the given files, and writes them to
its stdout with a more visually pleasing spacing and indentation. Cb understands no C++ syntax
bar newline-terminated comments; and by default all user new-lines are preserved in the output.
The options are:
Join split lines.
Print code in the so-called K&R style used in The C Programming Language .
−l length
Split lines that are longer than length.
Cb does not reformat structure initializers.
Punctuation hidden in macros can cause indentation errors.
chgrp change file group
chgrp [ −ou ] group file ...
The group of each named file is changed to group, which should be a name known to the server
holding the file.
A files group can be changed by the files owner, if the owner is a member of the new group, or
by the leader of both the files current group and the new group.
The −o and −u option are synonyms; they specify that the owner is to be set, rather than the
group. They are ineffectual unless the file server is in the bootstrap state that permits changing
file ownership.
ls(1), chmod(1), stat(2)
chmod change mode
chmod mode file ...
The mode of each named file is changed according to mode, which may be an octal number or a
symbolic change to the existing mode. A mode is an octal number constructed from the OR of the
following modes.
read by owner
write by owner
execute (search in directory) by owner
read, write, execute (search) by group
read, write, execute (search) by others
A symbolic mode has the form:
[who] op permission
The who part is a combination of the letters u (for users permissions), g (group) and o (other).
The letter a stands for ugo. If who is omitted, the default is a.
Op can be + to add permission to the files mode, − to take away permission, and = to assign
permission absolutely (all other bits will be reset).
Permission is any combination of the letters r (read), w (write), x (execute), a (append only), l
(exclusive access), and t (temporary file).
Only the owner of a file or the group leader of its group may change the files mode.
ls(1), stat(2), stat(5)
cleanname clean a path name
cleanname [ −d pwd ] names ...
For each file name argument, cleanname, by lexical processing only, prints the shortest equivalent
string that names the same (possibly hypothetical) file. It eliminates multiple and trailing slashes,
and it lexically interprets . and .. directory components in the name. If the −d option is present,
unrooted names are prefixed with pwd/ before processing.
cmp compare two files
cmp [ −lLs ] file1 file2 [ offset1 [ offset2 ] ]
Cmp compares the two files and prints a message if the contents differ.
The options are:
Print the byte number (decimal) and the differing bytes (hexadecimal) for each difference.
Print the line number of the first differing byte.
Print nothing for differing files, but set the exit status.
If offsets are given, comparison starts at the designated byte position of the corresponding file.
Offsets that begin with 0x are hexadecimal; with 0, octal; with anything else, decimal.
If a file is inaccessible or missing, the exit status is open. If the files are the same, the exit status
is empty (true). If they are the same except that one is longer than the other, the exit status is
EOF. Otherwise cmp reports the position of the first disagreeing byte and the exit status is
col column alignment
col [ −bfx ]
Col overlays lines to expunge reverse line feeds (ESC-7) and half line feeds (ESC-9 and ESC-8) as
produced by nroff for .2C in ms(6) or man(6) and for tbl(1). Col is a pure filter. It normally emits
only full line feeds; option −f (fine) allows half line feeds too. Option −b removes backspaces,
printing just one of each pile of overstruck characters. Col normally converts white space to tabs;
option −x overrides this feature. Other escaped characters and non-printing characters are
tbl file | nroff −ms | col | p
Format some tables for printing on typewriters; use col to remove reverse line feeds, and
paginate the output.
Col cant back up more than 128 lines or handle more than 800 characters per line, and under­
stands VT (013) as reverse line feed.
getmap, colors display color map
colors [ −rx ]
getmap [ colormap ]
Colors presents a grid showing the colors in the current color map. If the display is true color,
colors shows a grid of the RGBV color map (see color(6)).
Clicking mouse button 1 over a color in the grid will display the map index for that color, its red,
green, and blue components, and the 32-bit hexadecimal color value as defined in allocimage(2).
If the −x option is specified, the components will also be listed in hexadecimal.
The −r option instead shows, in the same form, a grey-scale ramp.
A menu on mouse button 3 contains a single entry, to exit the program.
On 8-bit color-mapped displays, getmap loads the displays color map (default rgbv). The
named colormap can be a file in the current directory or in the standard repository /lib/cmap.
It can also be a string of the form gamma or gammaN, where N is a floating point value for the
gamma, defining the contrast for a monochrome map. Similarly, rgamma and rgammaN define a
reverse-video monochrome map. Finally, the names screen or display or vga are taken as
synonyms for the current color map stored in the display hardware.
/lib/cmap directory of color map files
comm select or reject lines common to two sorted files
comm [ −123 ] file1 file2
Comm reads file1 and file2, which are in lexicographical order, and produces a three column out­
put: lines only in file1; lines only in file2; and lines in both files. The file name − means the stan­
dard input.
Flag 1, 2, or 3 suppresses printing of the corresponding column.
comm −12 file1 file2
Print lines common to two sorted files.
sort(1), cmp(1), diff(1), uniq(1)
con, telnet, rx, hayes, xms, xmr remote login, execution, and XMODEM file transfer
con [ −CdnrRsTv ] [ −b baud ] [ −l [ user ] ] [ −S svc ] [ −c cmd ] [net!]machine
telnet [ −dCrn ] [ −s svc ] [net!]machine
rx [ −eTr ] [ −l user ] [net!]machine [ command−word ... ]
hayes [ −pv ] number [ device ]
xms [ −1p ] file
xmr file
Con connects to the computer whose network address is net!machine and logs in if possible. With
no options, the account name used on the remote system is the same as that on the local system.
Standard input and output go to the local machine.
Options are:
sets the baud rate of a dial-up connection to baud.
if the input is a file or pipe, do not hang up the connection when EOF is received, but
instead wait for the remote end to hang up.
with an argument causes user to be used as the account name on the remote system when
performing BSD rlogin authentication. Without an argument this option disables automatic
login and a normal login session ensues.
forces cooked mode, that is, local echo.
runs cmd as if it had been typed as a command from the escape mode.
(verbose mode) causes information about connection attempts to be output to standard
error. This can be useful when trying to debug network connectivity.
causes debugging information to be output to standard error.
suppresses printing of any carriage return followed by a new line. This is useful since car­
riage return is a printable character in Plan 9.
translates newlines to carriage returns and vice versa.
translates incoming carriage returns to newlines.
strips received characters to 7 bits to forestall misinterpretation of ASCII with parity as UTF.
Post a pipe as /srv/svc and connect it to standard input and output. This can be used
with −n to create a standing connection that consolefs(4), for example, can then open. For
telnet, this option is −s.
The control\ character is a local escape. It prompts with >>>. Legitimate responses to the
prompt are
Send a quit [sic] signal to the remote machine.
Send a break.
Return from the escape.
Run the command with the network connection as its standard input and standard output.
Standard error will go to the screen. This is useful for transmitting and receiving files over
the connections using programs such as xms.
Toggle printing of carriage returns.
Telnet is similar to con, but uses the telnet protocol to communicate with the remote machine. It
shares con’s −C, −d, −n, and −r options.
Rx executes one shell command on the remote machine as if logged in there, but with local stan­
dard input and output. A rudimentary shell environment is provided. If the target is a Plan 9
machine, $service there will be rx. Options are:
a zero length message will not be written to the connection when standard input is closed.
runs as user on the remote machine if the remote is a BSD machine.
same as for con
same as for con
Network addresses for both con and rx have the form network!machine. Supported networks are
those listed in /net.
Hayes dials number on a Hayes-compatible modem, device. Under −p, it uses pulse dialing. Upon
connecting, bytes are copied bidirectionally between the connection and standard input and out­
The commands xms and xmr respectively send and receive a single file using the XMODEM proto­
col. They use standard input and standard output for communication and are intended for use
with con. The −1 option to xms causes it to use kilobyte packet size of 1024 bytes. The −p option
causes it to print a progress message every ten kilobytes.
rx kremvax cat file1 >file2
Copy remote file1 to local file2.
rx kremvax cat file1 ’>file2’
Copy remote file1 to remote file2.
eqn paper | rx kremvax troff −ms | rx deepthought lp
Parallel processing: do each stage of a pipeline on a different machine.
for all other commands
cpu(1), ssh(1), telco(4)
Con and telnet are merely obsolescent; the other commands are obsolete and deprecated.
Under rx, a program that should behave specially towards terminals may not: e.g., remote shells
will not prompt. Also under rx, the remote standard error and standard output are combined and
go inseparably to the local standard output. Rx will consume its standard input by copying it to
the remote system, so redirect it from /dev/null if thats not what you want.
cp, fcp, mv copy, move files
cp [ −gux ] file1 file2
cp [ −gux ] file ... directory
fcp [ −gux ] file1 file2
fcp [ −gux ] file ... directory
mv file1 file2
mv file ... directory
In the first form file1 is any name and file2 is any name except an existing directory. In the second
form the commands copy or move one or more files into a directory under their original file
names, as if by a sequence of commands in the first form. Thus cp f1 f2 dir is equivalent to
cp f1 dir/f1; cp f2 dir/f2.
Cp copies the contents of plain file1 to file2. The mode and owner of file2 are preserved if it
already exists; the mode of file1 is used otherwise. The −x option sets the mode and modified
time of file2 from file1; −g sets the group id; and −u sets the group id and user id (which is usu­
ally only possible if the file server is in an administrative mode).
Fcp behaves like cp but transfers multiple blocks in parallel while copying; it is noticeably faster
than cp when the files involved are stored on servers connected over long-distance lines. It is only
appropriate to use fcp with file servers that respect the offset in read(5) and write messages. This
includes the disk-based file systems and ramfs but excludes most device file systems.
Mv moves file1 to file2. If the files are in the same directory, file1 is just renamed; otherwise mv
behaves like cp −x followed by rm file1. Mv will rename directories, but it refuses to move a direc­
tory into another directory.
cat(1), dircp in tar(1), stat(2), read(5)
Cp, fcp, and mv refuse to copy or move files onto themselves.
cpp C language preprocessor
cpp [ option ... ] [ ifile [ ofile ] ]
Cpp interprets ANSI C preprocessor directives and does macro substitution. The input ifile and
output ofile default to standard input and standard output respectively.
The options are:
−Idir Same as in 2c(1): add dir to the search for directives.
Generate no output except a list of include files in a form suitable for specifying dependen­
cies to mk(1). Use twice to list files in angle brackets.
Turn off default include directories. All must be specified with −I, or in the environment
variable include. Without this option, /$objtype/include and /sys/include
are used as the last two searched directories for include directives, where $objtype is
read from the environment.
Print extra debugging information.
Do not insert #line directives into the output.
Understand C++ comments.
Inhibit include search in the sources directory.
Print the list of directories searched when #include is found. Last listed are searched first.
In the absence of the −P option, the processed text output is sprinkled with lines that show the
original input line numbering:
#line linenumber "ifile"
The command reads the environment variable include and adds its (blank-separated) list of direc­
tories to the standard search path for directives. They are looked at before any directories speci­
fied with −I, which are looked at before the default directories.
The input language is as described in the ANSI C standard. The standard Plan 9 C compilers do
not use cpp; they contain their own simple but adequate preprocessor, so cpp is usually superflu­
directory for machine-independent include files
/$objtype/include directory for machine-dependent include files
cpu connection to CPU server
cpu [ −h server ] [ −u user ] [ −a auth−method ] [ −P patternfile ] [ −e encryption−hash−algs ] [
−k keypattern ] [ −c cmd args ... ]
cpu [ −R | −O ]
Cpu starts an rc(1) running on the server machine, or the machine named in the $cpu environ­
ment variable if there is no −h option. Rcs standard input, output, and error files will be
/dev/cons in the name space where the cpu command was invoked. Normally, cpu is run in an
rio(1) window on a terminal, so rc output goes to that window, and input comes from the key­
board when that window is current. Rcs current directory is the working directory of the cpu com­
mand itself.
The name space for the new rc is an analogue of the name space where the cpu command was
invoked: it is the same except for architecture-dependent bindings such as /bin and the use of
fast paths to file servers, if available.
If a −u argument is present, cpu uses the argument as the remote user id.
If a −c argument is present, the remainder of the command line is executed by rc on the server,
and then cpu exits.
If a −P argument is present, the patternfile is passed to exportfs(4) to control how much of the
local name space will be exported to the remote system.
The −a command allows the user to specify the authentication mechanism used when connecting
to the remote system. The two possibilities for auth−method are:
This is the default. Authentication is done using the standard Plan 9 mechanisms, (see
authsrv(6)). No user interaction is required.
Authentication is done using challenge/response and a hand held authenticator or the
netkey program (see passwd(1)). The user must encrypt the challenge and type the
encryption back to cpu. This is used if the local host is in a different protection domain
than the server or if the user wants to log into the server as a different user.
The −e option specifies an encryption and/or hash algorithm to use for the connection. If both
are specified, they must be space separated and comprise a single argument, so they must be
quoted if in a shell command. The default is rc4_256 encryption and sha1 hashing. See ssl(3)
for details on possible algorithms. The argument clear specifies no encryption algorithm and
can be used to talk to older versions of the cpu service.
The −k flag specifies a key pattern to use to restrict the keys selected by the auth_proxy call used
for authentication.
The name space is built by running /usr/$user/lib/profile with the root of the invoking
name space bound to /mnt/term. The service environment variable is set to cpu; the
cputype and objtype environment variables reflect the servers architecture.
The −R flag causes cpu to run the server (remote) side of the protocol. It is run from service files
such as /bin/service/tcp17010. The −O flag is similar but simulates the pre-9P2000 ver­
sion of the cpu protocol.
The name space of the terminal side of the cpu command is mounted, via exportfs(4), on the CPU
side on directory /mnt/term. The files such as /dev/cons are bound to their standard loca­
tions from there.
rc(1), rio(1), exportfs(4)
Binds and mounts done after the terminal lib/profile is run are not reflected in the new name
When using the −a option to log in as another user, be aware that resources in the local name
space will be made available to that user.
crop, iconv frame, crop, and convert image
crop [ −b red green blue ] [ −c red green blue ] [ −i n | −r minx miny maxx maxy | −x dx | −y
dy ] [ −t tx ty ] [ −b red green blue ] [ file ]
iconv [ −u ] [ −c chandesc ] [ file ]
Crop reads an image(6) file (default standard input), crops it, and writes it as a compressed
image(6) file to standard output. There are two ways to specify a crop, by color value or by geom­
etry. They may be combined in a single run of crop, in which case the color value crop will be
done first.
The −c option takes a red-green-blue triplet as described in color(2). (For example, white is 255
255 255.) The corresponding color is used as a value to be cut from the outer edge of the pic­
ture; that is, the image is cropped to remove the maximal outside rectangular strip in which every
pixel has the specified color.
The −i option insets the image rectangle by a constant amount, n, which may be negative to gen­
erate extra space around the image. The −x and −y options are similar, but apply only to the x or
y coordinates of the image.
The −r option specifies an exact rectangle.
The −t option specifies that the images coordinate system should be translated by tx, ty as the
last step of processing.
The −b option specifies a background color to be used to fill around the image if the cropped
image is larger than the original, such as if the −i option is given a negative argument. This can
be used to draw a monochrome frame around the image. The default color is black.
Iconv changes the format of pixels in the image file (default standard input) and writes the result­
ing image to standard output. Pixels in the image are converted according to the channel descrip­
tor chandesc, (see image(6)). For example, to convert a 4-bit-per-pixel grey-scale image to an 8bit-per-pixel color-mapped image, chandesc should be m8. If chandesc is not given, the format is
unchanged. The output image is by default compressed; the −u option turns off the compression.
To crop white edges off the picture and add a ten-pixel pink border,
crop −c 255 255 255 −i −10 −b 255 150 150 imagefile > cropped
image(6), color(2)
Iconv should be able to do Floyd-Steinberg error diffusion or dithering when converting to small
image depths.
date, clock date and time
date [ option ] [ seconds ]
Print the date, in the format
Tue Aug 16 17:03:52 CDT 1977
The options are
Report Greenwich Mean Time (GMT) rather than local time.
Report the date as the number of seconds since the epoch, 00:00:00 GMT, January 1, 1970.
The conversion from Greenwich Mean Time to local time depends on the $timezone environ­
ment variable; see ctime(2).
If the optional argument seconds is present, it is used as the time to convert rather than the real
Clock draws a simple analog clock in its window.
Current timezone name and adjustments.
A directory containing timezone tables.
Default timezone file, copied by init(8) into /env/timezone.
db debugger
db [ option ... ] [ textfile ] [ pid ]
Db is a general purpose debugging program. It may be used to examine files and to provide a
controlled environment for the execution of Plan 9 programs.
A textfile is a file containing the text and initialized data of an executable program. A memfile is
the memory image of an executing process. It is usually accessed via the process id (pid) of the
process in /proc/pid/mem. A memfile contains the text, data, and saved registers and process
state. A map associated with each textfile or memfile supports accesses to instructions and data in
the file; see Addresses.
An argument consisting entirely of digits is assumed to be a process id; otherwise, it is the name
of a textfile. When a textfile is given, the textfile map is associated with it. If only a pid is given,
the textfile map is associated with /proc/pid/text. When a pid is given, the memfile map is
associated with /proc/pid/mem; otherwise it is undefined and accesses to the memfile are not
Commands to db are read from the standard input and responses are to the standard output. The
options are
Use the kernel stack of process pid to debug the executing kernel process. If textfile is not
specified, file /$cputype/9type is used, where type is the second word in $terminal.
Create textfile and memfile if they dont exist; open them for writing as well as reading.
Directory in which to look for relative path names in $< and $<< commands.
Assume instructions are for the given CPU type (any standard architecture name, such as
alpha or 386, plus mipsco and sunsparc, which cause disassembly to the
manufacturers syntax) instead of using the magic number to select the CPU type.
Most db commands have the following form:
[address] [, count] [command]
If address is present then the current position, called dot, is set to address. Initially dot is set to
0. Most commands are repeated count times with dot advancing between repetitions. The default
count is 1. Address and count are expressions. Multiple commands on one line must be separated
by ;.
Expressions are evaluated as long ints.
The value of dot.
The value of dot incremented by the current increment.
The value of dot decremented by the current increment.
The last address typed.
A number, in decimal radix by default. The prefixes 0 and 0o and 0O (zero oh) force inter­
pretation in octal radix; the prefixes 0t and 0T force interpretation in decimal radix; the
prefixes 0x, 0X, and # force interpretation in hexadecimal radix. Thus 020, 0o20, 0t16,
and #10 all represent sixteen.
A single-precision floating point number.
’c ’
The 16-bit value of a character. \ may be used to escape a ’.
The value of name, which is a register name. The register names are those printed by the
$r command.
A symbol is a sequence of upper or lower case letters, underscores or digits, not starting
with a digit. \ may be used to escape other characters. The location of the symbol is cal­
culated from the symbol table in textfile.
The address of the variable name in the specified C routine. Both routine and name are
symbols. If name is omitted the value is the address of the most recently activated stack
frame corresponding to routine; if routine is omitted, the active procedure is assumed.
The address of the instruction corresponding to the source statement at the indicated line
number of the file. If the source line contains no executable statement, the address of the
instruction associated with the nearest executable source line is returned. Files begin at
line 1. If multiple files of the same name are loaded, an expression of this form resolves to
the first file encountered in the symbol table.
The value of the expression exp.
Monadic operators
The contents of the location addressed by exp in memfile.
The contents of the location addressed by exp in textfile.
Integer negation.
Bitwise complement.
When used as an address, exp is an offset into the segment named ublock; see
Dyadic operators are left-associative and are less binding than monadic operators.
e1+e2 Integer addition.
e1−e2 Integer subtraction.
e1*e2 Integer multiplication.
e1%e2 Integer division.
e1&e2 Bitwise conjunction.
e1|e2 Bitwise disjunction.
e1#e2 E1 rounded up to the next multiple of e2.
Most commands have the following syntax:
Locations starting at address in textfile are printed according to the format f.
Locations starting at address in memfile are printed according to the format f.
The value of address itself is printed according to the format f.
A format consists of one or more characters that specify a style of printing. Each format character
may be preceded by a decimal integer that is a repeat count for the format character. If no format
is given then the last format is used.
Most format letters fetch some data, print it, and advance (a local copy of) dot by the number of
bytes fetched. The total number of bytes in a format becomes the currentincrement.
two-byte integer in octal.
four-byte integer in octal.
two-byte integer in signed octal.
four-byte integer in signed octal.
two-byte integer in decimal.
four-byte integer in decimal.
Print eight-byte integer in decimal.
Print eight-byte integer in unsigned decimal.
Print two-byte integer in hexadecimal.
Print four-byte integer in hexadecimal.
Print eight-byte integer in hexadecimal.
Print two-byte integer in unsigned decimal.
Print four-byte integer in unsigned decimal.
Print as a single-precision floating point number.
Print double-precision floating point.
Print the addressed byte in hexadecimal.
Print the addressed byte as an ASCII character.
Print the addressed byte as a character. Printable ASCII characters are represented
normally; others are printed in the form \xnn.
Print the addressed characters, as a UTF string, until a zero byte is reached.
Advance dot by the length of the string, including the zero terminator.
Print a string using the escape convention (see C above).
Print as UTF the addressed two-byte integer (rune).
Print as UTF the addressed two-byte integers as runes until a zero rune is reached.
Advance dot by the length of the string, including the zero terminator.
Print as machine instructions. Dot is incremented by the size of the instruction.
As i above, but print the machine instructions in an alternate form if possible:
sunsparc and mipsco reproduce the manufacturers syntax.
Print the addressed machine instruction in a machine-dependent hexadecimal form.
Print the value of dot in symbolic form. Dot is unaffected.
Print the value of dot in hexadecimal. Dot is unaffected.
Print the function name, source file, and line number corresponding to dot (textfile
only). Dot is unaffected.
Print the addressed value in symbolic form. Dot is advanced by the size of a
machine address.
When preceded by an integer, tabs to the next appropriate tab stop. For example,
8t moves to the next 8-space tab stop. Dot is unaffected.
Print a newline. Dot is unaffected.
Print the enclosed string. Dot is unaffected.
Dot is decremented by the current increment. Nothing is printed.
Dot is incremented by 1. Nothing is printed.
Dot is decremented by 1. Nothing is printed.
Other commands include:
Update dot by the current increment. Repeat the previous command with a count of 1.
[?/]l value mask
Words starting at dot are masked with mask and compared with value until a match is
found. If l is used, the match is for a two-byte integer; L matches four bytes. If no match
is found then dot is unchanged; otherwise dot is set to the matched location. If mask is
omitted then ~0 is used.
[?/]w value ...
Write the two-byte value into the addressed location. If the command is W, write four
[?/]m s b e f [?]
New values for (b, e, f ) in the segment named s are recorded. Valid segment names are
text, data, or ublock. If less than three address expressions are given, the remaining
parameters are left unchanged. If the list is terminated by ? or / then the file (textfile or
memfile respectively) is used for subsequent requests. For example, /m? causes / to refer
to textfile.
Dot is assigned to the variable or register named.
The rest of the line is passed to rc(1) for execution.
Miscellaneous commands. The available modifiers are:
Read commands from the file f. If this command is executed in a file, further com­
mands in the file are not seen. If f is omitted, the current input stream is termi­
nated. If a count is given, and is zero, the command is ignored.
Similar to < except it can be used in a file of commands without causing the file to
be closed. There is a (small) limit to the number of << files that can be open at
Append output to the file f, which is created if it does not exist. If f is omitted, out­
put is returned to the terminal.
Print process id, the condition which caused stopping or termination, the registers
and the instruction addressed by pc. This is the default if modifier is omitted.
Print the general registers and the instruction addressed by pc. Dot is set to pc.
Like $r, but include miscellaneous processor control registers and floating point
Print floating-point register values as single-precision floating point numbers.
Print floating-point register values as double-precision floating point numbers.
Print all breakpoints and their associated counts and commands. B produces the
same results.
Stack backtrace. If address is given, it specifies the address of a pair of 32-bit val­
ues containing the sp and pc of an active process. This allows selecting among
various contexts of a multi-threaded process. If C is used, the names and (long)
values of all parameters, automatic and static variables are printed for each active
function. If count is given, only the first count frames are printed.
Attach to the running process whose pid is contained in address.
The names and values of all external variables are printed.
Set the page width for output to address (default 80).
Exit from db.
Print the address maps.
Simulate kernel memory management.
Set the machine type used for disassembling instructions.
Manage a subprocess. Available modifiers are:
Halt an asynchronously running process to allow breakpointing. Unnecessary for
processes created under db, e.g. by :r.
Set breakpoint at address. The breakpoint is executed count1 times before causing
a stop. Also, if a command c is given it is executed at each breakpoint and if it sets
dot to zero the breakpoint causes a stop.
Delete breakpoint at address.
Run textfile as a subprocess. If address is given the program is entered at that
point; otherwise the standard entry point is used. Count specifies how many break­
points are to be ignored before stopping. Arguments to the subprocess may be
supplied on the same line as the command. An argument starting with < or >
causes the standard input or output to be established for the command.
The subprocess is continued. If s is omitted or nonzero, the subprocess is sent the
note that caused it to stop. If 0 is specified, no note is sent. (If the stop was due to
a breakpoint or single-step, the corresponding note is elided before continuing.)
Breakpoint skipping is the same as for r.
As for c except that the subprocess is single stepped for count machine instruc­
tions. If a note is pending, it is received before the first instruction is executed. If
there is no current subprocess then textfile is run as a subprocess as for r. In this
case no note can be sent; the remainder of the line is treated as arguments to the
Identical to s except the subprocess is single stepped for count lines of C source.
In optimized code, the correspondence between C source and the machine instruc­
tions is approximate at best.
The current subprocess, if any, is released by db and allowed to continue executing
The current subprocess, if any, is terminated.
Display the pending notes for the process. If c is specified, first delete c’th pending
The location in a file or memory image associated with an address is calculated from a map associ­
ated with the file. Each map contains one or more quadruples (t, b, e, f), defining a segment
named t (usually, text, data, or ublock) mapping addresses in the range b through e to the part of
the file beginning at offset f. The memory model of a Plan 9 process assumes that segments are
disjoint. There can be more than one segment of a given type (e.g., a process may have more than
one text segment) but segments may not overlap. An address a is translated to a file address by
finding a segment for which bda<e; the location in the file is then address+fb.
Usually, the text and initialized data of a program are mapped by segments called text and data.
Since a program file does not contain bss, stack or ublock data, these data are not mapped by the
data segment. The text segment is mapped similarly in a normal (i.e., non-kernel) memfile. How­
ever, the segment called data maps memory from the beginning of the programs data space to
the base of the ublock. This region contains the programs static data, the bss, the heap and the
stack. A segment called ublock maps the page containing its registers and process state.
Sometimes it is useful to define a map with a single segment mapping the region from 0 to
0xFFFFFFFF; a map of this type allows the entire file to be examined without address translation.
Registers are saved at a machine-dependent offset in the ublock. It is usually not necessary to
know this offset; the $r, $R, $f, and $F commands calculate it and display the register contents.
The $m command dumps the currently active maps. The ?m and /m commands modify the seg­
ment parameters in the textfile and memfile maps, respectively.
To set a breakpoint at the beginning of write() in extant process 27:
% db 27
To examine the Plan 9 kernel stack for process 27:
% db −k 27
Similar, but using a kernel named test:
% db −k test 27
To set a breakpoint at the entry of function parse when the local variable argc in main is equal
to 1:
parse:b *main.argc−1=X
This prints the value of argc−1 which as a side effect sets dot; when argc is one the breakpoint
will fire. Beware that local variables may be stored in registers; see the BUGS section.
Debug process 127 on remote machine kremvax:
% import kremvax /proc
% db 127
acid(1), nm(1), proc(3)
Exit status is null, unless the last command failed or returned non-null status.
Examining a local variable with returns the contents of the memory allocated for the
variable, but with optimization (suppressed by the −N compiler flag) variables often reside in regis­
ters. Also, on some architectures, the first argument is always passed in a register.
Variables and parameters that have been optimized away do not appear in the symbol table,
returning the error bad local variable when accessed by db.
Because of alignment incompatibilities, Motorola 68000 series machines can not be debugged
remotely from a processor of a different type.
Breakpoints should not be set on instructions scheduled in delay slots. When a program stops on
such a breakpoint, it is usually impossible to continue its execution.
dc desk calculator
dc [ file ]
Dc is an arbitrary precision desk calculator. Ordinarily it operates on decimal integers, but one
may specify an input base, output base, and a number of fractional digits to be maintained. The
overall structure of dc is a stacking (reverse Polish) calculator. If an argument is given, input is
taken from that file until its end, then from the standard input. The following constructions are
The value of the number is pushed on the stack. A number is an unbroken string of the
digits 0−9A−F or 0−9a−f. A hexadecimal number beginning with a lower case letter
must be preceded by a zero to distinguish it from the command associated with the letter.
It may be preceded by an underscore _ to input a negative number. Numbers may contain
decimal points.
− / * % ^
Add +, subtract −, multiply *, divide /, remainder %, or exponentiate ^ the top two values
on the stack. The two entries are popped off the stack; the result is pushed on the stack in
their place. Any fractional part of an exponent is ignored.
Pop the top of the stack and store into a register named x, where x may be any character.
Under operation S register x is treated as a stack and the value is pushed on it.
Push the value in register x onto the stack. The register x is not altered. All registers start
with zero value. Under operation L register x is treated as a stack and its top value is
popped onto the main stack.
Duplicate the top value on the stack.
Print the top value on the stack. The top value remains unchanged. P interprets the top of
the stack as an text string, removes it, and prints it.
Print the values on the stack.
Exit the program. If executing a string, the recursion level is popped by two. Under opera­
tion Q the top value on the stack is popped and the string execution level is popped by that
Treat the top element of the stack as a character string and execute it as a string of dc
Replace the number on the top of the stack with its scale factor.
[ ... ]
Put the bracketed text string on the top of the stack.
Pop and compare the top two elements of the stack. Register x is executed if they obey the
stated relation.
Replace the top element on the stack by its square root. Any existing fractional part of the
argument is taken into account, but otherwise the scale factor is ignored.
Interpret the rest of the line as a shell command.
Clear the stack.
The top value on the stack is popped and used as the number base for further input.
Push the input base on the top of the stack.
The top value on the stack is popped and used as the number base for further output. In
bases larger than 10, each digit prints as a group of decimal digits.
Push the output base on the top of the stack.
Pop the top of the stack, and use that value as a non-negative scale factor: the appropriate
number of places are printed on output, and maintained during multiplication, division,
and exponentiation. The interaction of scale factor, input base, and output base will be
reasonable if all are changed together.
Push the stack level onto the stack.
Replace the number on the top of the stack with its length.
A line of input is taken from the input source (usually the terminal) and executed.
; :
Used by bc for array operations.
The scale factor set by k determines how many digits are kept to the right of the decimal point. If
s is the current scale factor, sa is the scale of the first operand, sb is the scale of the second, and b
is the (integer) second operand, results are truncated to the following scales.
min(sa+sb , max(s,sa,sb))
so that dividend = divisor*quotient + remainder; remainder has sign of dividend
min(sa×|b|, max(s,sa))
Print the first ten values of n!
bc(1), hoc(1)
x is unimplemented, where x is an octal number: an internal error.
Out of headers for too many numbers being kept around.
Nesting depth for too many levels of nested execution.
When the input base exceeds 16, there is no notation for digits greater than F.
Past its time.
dd convert and copy a file
dd [ option value ] ...
Dd copies the specified input file to the specified output with possible conversions. The standard
input and output are used by default. The input and output block size may be specified to take
advantage of raw physical I/O. The options are
−if f
Open file f for input.
−of f
Open file f for output.
−ibs n
Set input block size to n bytes (default 512).
−obs n
Set output block size (default 512).
−bs n
Set both input and output block size, superseding ibs and obs. If no conversion is
specified, preserve the input block size instead of packing short blocks into the output
buffer. This is particularly efficient since no in-core copy need be done.
−cbs n
Set conversion buffer size.
−skip n
Skip n input records before copying.
−iseek n
Seek n records forward on input file before copying.
−files n
Catenate n input files (useful only for magnetic tape or similar input device).
−oseek n
Seek n records from beginning of output file before copying.
−count n
Copy only n input records.
−trunc n
By default, dd truncates the output file when it opens it; −trunc 0 opens it without
−quiet n
By default, dd prints the number of blocks read and written once it is finished.
−quiet 1 silences this summary.
−conv ascii
Convert EBCDIC to ASCII.
Convert ASCII to EBCDIC.
Like ebcdic but with a slightly different character map.
Convert variable length ASCII records to fixed length.
Convert fixed length ASCII records to variable length.
Map alphabetics to lower case.
Map alphabetics to upper case.
Swap every pair of bytes.
Do not stop processing on an error.
Pad every input record to ibs bytes.
Where sizes are specified, a number of bytes is expected. A number may end with k or b to spec­
ify multiplication by 1024 or 512 respectively; a pair of numbers may be separated by x to indicate
a product. Multiple conversions may be specified in the style: −conv ebcdic,ucase.
Cbs is used only if ascii, unblock, ebcdic, ibm, or block conversion is specified. In the
first two cases, n characters are copied into the conversion buffer, any specified character mapping
is done, trailing blanks are trimmed and new-line is added before sending the line to the output.
In the latter three cases, characters are read into the conversion buffer and blanks are added to
make up an output record of size n. If cbs is unspecified or zero, the ascii, ebcdic, and ibm
options convert the character set without changing the block structure of the input file; the
unblock and block options become a simple file copy.
Dd reports the number of full + partial input and output blocks handled.
delkey delete keys from factotum
delkey [ −f ] pattern
Delkey shows the user each key stored in factotum(4) and matching the pattern, prompting for
whether the key should be deleted. At each prompt, typing a response beginning with y deletes
the key, typing a response beginning with q aborts the listing, and any other response skips over
the key.
The −f option disables the prompting; all keys matching the pattern are deleted.
When run on a CPU server, delkey uses the terminals factotum, if present, instead of the servers
First choice for factotum to use
Second choice
deroff, delatex remove formatting requests
deroff [ option ... ] file ...
delatex file
Deroff reads each file in sequence and removes all nroff and troff(1) requests and non-text argu­
ments, backslash constructions, and constructs of preprocessors such as eqn(1), pic(1), and tbl(1).
Remaining text is written on the standard output. Deroff follows files included by .so and .nx
commands; if a file has already been included, a .so for that file is ignored and a .nx terminates
execution. If no input file is given, deroff reads from standard input.
The options are
Output a word list, one word (string of letters, digits, and properly embedded ampersands
and apostrophes, beginning with a letter) per line. Other characters are skipped. Other­
wise, the output follows the original, with the deletions mentioned above.
Like −w, but consider underscores to be alphanumeric rather than punctuation.
Ignore .so and .nx requests.
Remove titles, attachments, etc., as well as ordinary troff constructs, from ms(6) or mm
Same as −mm, but remove lists as well.
Delatex does for tex and latex (see tex(1)) files what deroff −wi does for troff files.
troff(1), tex(1), spell(1)
These filters are not complete interpreters of troff or tex. For example, macro definitions contain­
ing \$ cause chaos in deroff when the popular $$ delimiters for eqn are in effect.
Text inside macros is emitted at place of definition, not place of call.
DIFF (1)
DIFF (1)
diff differential file comparator
diff [ −abcefmnrw ] file1 ... file2
Diff tells what lines must be changed in two files to bring them into agreement. If one file is a
directory, then a file in that directory with basename the same as that of the other file is used. If
both files are directories, similarly named files in the two directories are compared by the method
of diff for text files and cmp(1) otherwise. If more than two file names are given, then each argu­
ment is compared to the last argument as above. The −r option causes diff to process similarly
named subdirectories recursively. When processing more than one file, diff prefixes file differ­
ences with a single line listing the two differing files, in the form of a diff command line. The −m
flag causes this behavior even when processing single files.
The normal output contains lines of these forms:
n1 a n3,n4
n1,n2 d n3
n1,n2 c n3,n4
These lines resemble ed commands to convert file1 into file2. The numbers after the letters pertain
to file2. In fact, by exchanging a for d and reading backward one may ascertain equally how to
convert file2 into file1. As in ed, identical pairs where n1 = n2 or n3 = n4 are abbreviated as a sin­
gle number.
Following each of these lines come all the lines that are affected in the first file flagged by <, then
all the lines that are affected in the second file flagged by >.
The −b option causes trailing blanks (spaces and tabs) to be ignored and other strings of blanks to
compare equal. The −w option causes all white-space to be removed from input lines before
applying the difference algorithm.
The −n option prefixes each range with file: and inserts a space around the a, c, and d verbs.
The −e option produces a script of a, c and d commands for the editor ed, which will recreate file2
from file1. The −f option produces a similar script, not useful with ed, in the opposite order. It
may, however, be useful as input to a stream-oriented post-processor.
The −c option includes three lines of context around each change, merging changes whose con­
texts overlap. In this mode, diff prints − and + instead of < and > because the former are easier
to distinguish when mixed. The −a flag displays the entire file as context.
Except in rare circumstances, diff finds a smallest sufficient set of file differences.
cmp(1), comm(1), ed(1), idiff(1)
Exit status is the empty string for no differences, some for some, and error for trouble.
Editing scripts produced under the −e or −f option are naive about creating lines consisting of a
single ..
When running diff on directories, the notion of what is a text file is open to debate.
doc2txt, doc2ps, wdoc2txt, xls2txt, olefs, mswordstrings, msexceltables extract printable text
from Microsoft documents
doc2txt [ file.doc ]
doc2ps [ file.doc ]
wdoc2txt [ file.doc ]
xls2txt [ file.xls ]
aux/olefs [ −m mtpt ] file.doc
aux/mswordstrings mtpt/WordDocument
aux/msexceltables [ −qaDnt ] [ −d delim ] [ −c column−range ] [ −w worksheet−range ]
Doc2txt is an rc(1) script that uses olefs and mswordstrings to extract the printable text from the
body of a Microsoft Word document and write it on the standard output. Doc2ps is similar, but
emits PostScript corresponding to the document. Wdoc2txt is similar to doc2txt, but uses
plumb(1) to send the output to a new acme(1) window instead. Xls2txt performs a similar function
for Microsoft Excel documents.
Microsoft Office documents are stored in OLE (Object Linking and Embedding) format, which is a
scaled down version of Microsofts FAT file system. Olefs presents the contents of an MS Office
document as a file system on mtpt, which defaults to /mnt/doc. Mswordstrings or
msexceltables may then be used to parse the files inside, extracting a text stream. Msexceltables
may be given options to control the formatting of its output.
Attempt conversion of non-tabular sheets in the workbook (charts).
−d delim Sets the inter-field delimiter to the string delim, by default a single space.
Enables debugging output.
−c range Range is a comma-separated list of column numbers and ranges. Ranges are sepa­
rated by dashes. Limit processing to just those columns named; by default all columns
are output.
Disables field padding to column width.
Disable quoting of textural fields (see quote(2).)
Truncate fields to the column width.
−w range Range is a comma-separated list of worksheet numbers and ranges, this limits the
sheets output using the same syntax as the −c option above. Suppressed chart pages
are always included in the sheet count.
Extract pieces of an MS Excel spreadsheet.
aux/olefs report.xls
msexceltables -q -w 1,7,9-14 -c 3-5 -n -d @ /mnt/doc/Workbook > rpt.txt
unmount /mnt/doc
doc2txt, doc2ps, wdoc2txt, and xls2txt
the others
Microsoft Word 97 Binary File Format, at Microsofts developer (MSDN) home page.
LAOLA Binary Structures, http://user.cs.tu−
OpenOffice.Orgs Excel Documentation,
doctype intuit command line for formatting a document
doctype [ −n ] [ −T dev ] [ file ] ...
Doctype examines a troff(1) input file to deduce the appropriate text formatting command and
prints it on standard output. Doctype recognizes input for troff(1), related preprocessors like
eqn(1), and the ms(6) and mm macro packages.
Option −n invokes nroff instead of troff. The −T option is passed to troff.
eval ‘{doctype chapter.?} | lp
Typeset files named chapter.0, chapter.1, ...
troff(1), eqn(1), tbl(1), pic(1), grap(1), ms(6), man(6)
In true A.I. style, its best guesses are inspired rather than accurate.
du disk usage
du [ −aefhnqstu ] [ −b size ] [ −p SI−prefix ] [ file ... ]
Du gives the number of Kbytes allocated to data blocks of named files and, recursively, of files in
named directories. It assumes storage is quantized in units of 1024 bytes (Kbytes) by default.
Other values can be set by the −b option; size is the number of bytes, optionally suffixed k to
specify multiplication by 1024. If file is missing, the current directory is used. The count for a
directory includes the counts of the contained files and directories.
The −a option prints the number of blocks for every file in a directory. Normally counts are
printed only for contained directories.
The −f option suppresses the printing of warning messages.
The −n option prints the size in bytes and the name of each file; it sets −a.
The −t option prints, in the format of du −n, the modified time of each file rather than the size.
If the options −tu are specified then the accessed time is printed.
The −q option prints, in the format of du −n, the QID path of each file rather than the size.
The −s option causes du to descend the hierarchy as always, but to print only a summary line for
each file.
The −e option causes du to print values (sizes, times or QID paths) in scientific notation via
print(2)s %g.
The −h option causes du to print values (sizes, times or QID paths) in scientific notation, scaled to
less than 1024, and with a suitable SI prefix (e.g., G for binary gigabytes).
The −p option causes du to print values (sizes, times or QID paths) in units of SI−prefix. Case is
ignored when looking up SI−prefix. An empty SI−prefix corresponds to a scale factor of 1 (e.g.,
print sizes in bytes).
Print the size of /tmp in fractional binary gigabytes:
% du −sepg /tmp
.6960154 /tmp
Print the size of /tmp in bytes and in scientific notation:
% du −sep ’’ /tmp
echo print arguments
echo [ −n ] [ arg ... ]
Echo writes its arguments separated by blanks and terminated by a newline on the standard out­
put. Option −n suppresses the newline.
If echo draws an error while writing to standard output, the exit status is write error. Other­
wise the exit status is empty.
ecp fast copy, handling errors
ecp [ bcprvZ ] [ B block−size ] [ e max−errors ] [ i issect ] [ o ossect ] [ s sector−size ]
sectors input output
Ecp copies sectors disk sectors of the specified input file to the specified output file. Ecp copies
multiple sectors (a block) at a time for speed. When ecp encounters an I/O error, it transfers the
current block again, assuming the file is seekable, one sector at a time, prints the sector number(s)
of the error(s), and continues copying.
Options are:
b reblock input on short reads; this was used mainly when reading a pipe on standard input on
4.2+BSD systems.
B sets the block size (16,384 bytes by default) to block−size.
c ask for confirmation on /dev/cons before starting the copy.
e sets a maximum number of consecutive I/O errors to permit at the beginning of the copy
before quitting to max−errors. Lots of consecutive errors may indicate a deeper problem, such
as missing media. By default there is no limit.
i seeks to sector issect (assuming zero-origin) before beginning input.
o seeks to sector ossect (assuming zero-origin) before beginning output.
p print reassuring progress reports; helpful mainly when dealing with cranky hardware.
r copy sector groups in reverse order, assuming the files are seekable; this is most useful when
input and output overlap.
s sets the sector size (512 bytes by default) to sector−size.
v verify the copy by rereading the input and output files after copying all sectors. This is
intended to force the disk to deliver the actual data written on it rather than some cached
copy. The locations of any differences are printed.
Z Swizzle the input: stir the bits around in some fashion. Intended for diagnosing bad disks by
copying a disk to itself a few times with swizzling on (to defeat caching in operating systems
or disk controllers).
fcp in cp(1), dd(1), dup(3)
i, o, r, v and error retries only work on devices capable of seeking.
The set of options reflects decades of experience dealing with troublesome hardware.
If the input file is a tape and the last record on the tape before a file mark is less than blocksize
bytes long, then ecp will read through past the file mark and into the next file.
ed text editor
ed [ − ] [ −o ] [ file ]
Ed is a venerable text editor.
If a file argument is given, ed simulates an e command (see below) on that file: it is read into ed’s
buffer so that it can be edited. The options are
Suppress the printing of character counts by e, r, and w commands and of the confirming
! by ! commands.
(for output piping) Write all output to the standard error file except writing by w com­
mands. If no file is given, make /fd/1 the remembered file; see the e command below.
Ed operates on a buffer, a copy of the file it is editing; changes made in the buffer have no effect
on the file until a w (write) command is given. The copy of the text being edited resides in a tem­
porary file called the buffer.
Commands to ed have a simple and regular structure: zero, one, or two addresses followed by a
single character command, possibly followed by parameters to the command. These addresses
specify one or more lines in the buffer. Missing addresses are supplied by default.
In general, only one command may appear on a line. Certain commands allow the addition of text
to the buffer. While ed is accepting text, it is said to be in input mode. In this mode, no commands
are recognized; all input is merely collected. Input mode is left by typing a period . alone at the
beginning of a line.
Ed supports the regular expression notation described in regexp(6). Regular expressions are used
in addresses to specify lines and in one command (see s below) to specify a portion of a line which
is to be replaced. If it is desired to use one of the regular expression metacharacters as an ordi­
nary character, that character may be preceded by \. This also applies to the character bounding
the regular expression (often /) and to \ itself.
To understand addressing in ed it is necessary to know that at any time there is a current line.
Generally, the current line is the last line affected by a command; however, the exact effect on the
current line is discussed under the description of each command. Addresses are constructed as
The character ., customarily called dot, addresses the current line.
The character $ addresses the last line of the buffer.
A decimal number n addresses the n-th line of the buffer.
’x addresses the line marked with the name x, which must be a lower-case letter. Lines
are marked with the k command.
A regular expression enclosed in slashes ( /) addresses the line found by searching forward
from the current line and stopping at the first line containing a string that matches the reg­
ular expression. If necessary the search wraps around to the beginning of the buffer.
A regular expression enclosed in queries ? addresses the line found by searching backward
from the current line and stopping at the first line containing a string that matches the reg­
ular expression. If necessary the search wraps around to the end of the buffer.
An address followed by a plus sign + or a minus sign − followed by a decimal number
specifies that address plus (resp. minus) the indicated number of lines. The plus sign may
be omitted.
An address followed by + (or −) followed by a regular expression enclosed in slashes speci­
fies the first matching line following (or preceding) that address. The search wraps around
if necessary. The + may be omitted, so 0/x/ addresses the first line in the buffer with an
x. Enclosing the regular expression in ? reverses the search direction.
If an address begins with + or − the addition or subtraction is taken with respect to the cur­
rent line; e.g. −5 is understood to mean .−5.
If an address ends with + or −, then 1 is added (resp. subtracted). As a consequence of
this rule and rule 9, the address − refers to the line before the current line. Moreover, trail­
ing + and − characters have cumulative effect, so −− refers to the current line less 2.
To maintain compatibility with earlier versions of the editor, the character ^ in addresses is
equivalent to −.
Commands may require zero, one, or two addresses. Commands which require no addresses
regard the presence of an address as an error. Commands which accept one or two addresses
assume default addresses when insufficient are given. If more addresses are given than a com­
mand requires, the last one or two (depending on what is accepted) are used.
Addresses are separated from each other typically by a comma ,. They may also be separated by
a semicolon ;. In this case the current line is set to the previous address before the next address
is interpreted. If no address precedes a comma or semicolon, line 1 is assumed; if no address fol­
lows, the last line of the buffer is assumed. The second address of any two-address sequence
must correspond to a line following the line corresponding to the first address.
In the following list of ed commands, the default addresses are shown in parentheses. The paren­
theses are not part of the address, but are used to show that the given addresses are the default.
Dot means the current line.
Read the given text and append it after the addressed line. Dot is left on the last line input,
if there were any, otherwise at the addressed line. Address 0 is legal for this command;
text is placed at the beginning of the buffer.
( .,. ) b[+−][pagesize][pln]
Browse. Print a page, normally 20 lines. The optional + (default) or − specifies whether
the next or previous page is to be printed. The optional pagesize is the number of lines in
a page. The optional p, n, or l causes printing in the specified format, initially p. Page­
size and format are remembered between b commands. Dot is left at the last line dis­
( .,. ) c
Change. Delete the addressed lines, then accept input text to replace these lines. Dot is
left at the last line input; if there were none, it is left at the line preceding the deleted lines.
( .,. ) d
Delete the addressed lines from the buffer. Dot is set to the line following the last line
deleted, or to the last line of the buffer if the deleted lines had no successor.
e filename
Edit. Delete the entire contents of the buffer; then read the named file into the buffer. Dot
is set to the last line of the buffer. The number of characters read is typed. The file name
is remembered for possible use in later e, r, or w commands. If filename is missing, the
remembered name is used.
E filename
Unconditional e; see q below.
f filename
Print the currently remembered file name. If filename is given, the currently remembered
file name is first changed to filename.
( 1,$ ) g/regular expression/command list
( 1,$ ) g/regular expression/
( 1,$ ) g/regular expression
Global. First mark every line which matches the given regularexpression. Then for every
such line, execute the command list with dot initially set to that line. A single command or
the first of multiple commands appears on the same line with the global command. All
lines of a multi-line list except the last line must end with \. The . terminating input
mode for an a, i, c command may be omitted if it would be on the last line of the com­
mand list. The commands g and v are not permitted in the command list. Any character
other than space or newline may be used instead of / to delimit the regular expression.
The second and third forms mean g/regular expression /p.
Insert the given text before the addressed line. Dot is left at the last line input, or, if there
were none, at the line before the addressed line. This command differs from the a com­
mand only in the placement of the text.
( .,.+1 ) j
Join the addressed lines into a single line; intermediate newlines are deleted. Dot is left at
the resulting line.
( . ) kx Mark the addressed line with name x, which must be a lower-case letter. The address form
’x then addresses this line.
( .,. ) l
List. Print the addressed lines in an unambiguous way: a tab is printed as \t, a backspace
as \b, backslashes as \\, and non-printing characters as a backslash, an x, and four hex­
adecimal digits. Long lines are folded, with the second and subsequent sub-lines indented
one tab stop. If the last character in the line is a blank, it is followed by \n. An l may be
appended, like p, to any non-I/O command.
( .,. ) ma
Move. Reposition the addressed lines after the line addressed by a. Dot is left at the last
moved line.
( .,. ) n
Number. Perform p, prefixing each line with its line number and a tab. An n may be
appended, like p, to any non-I/O command.
( .,. ) p
Print the addressed lines. Dot is left at the last line printed. A p appended to any non-I/O
command causes the then current line to be printed after the command is executed.
( .,. ) P
This command is a synonym for p.
Quit the editor. No automatic write of a file is done. A q or e command is considered to
be in error if the buffer has been modified since the last w, q, or e command.
Quit unconditionally.
($) r filename
Read in the given file after the addressed line. If no filename is given, the remembered file
name is used. The file name is remembered if there were no remembered file name
already. If the read is successful, the number of characters read is printed. Dot is left at
the last line read from the file.
( .,. ) sn/regular expression/replacement/
( .,. ) sn/regular expression/replacement/g
( .,. ) sn/regular expression/replacement
Substitute. Search each addressed line for an occurrence of the specified regular expres­
sion. On each line in which n matches are found (n defaults to 1 if missing), the nth
matched string is replaced by the replacement specified. If the global replacement indica­
tor g appears after the command, all subsequent matches on the line are also replaced. It
is an error for the substitution to fail on all addressed lines. Any character other than
space or newline may be used instead of / to delimit the regular expression and the
replacement. Dot is left at the last line substituted. The third form means
sn/regular expression /replacement/p. The second / may be omitted if the replacement
is empty.
An ampersand & appearing in the replacement is replaced by the string matching the regu­
lar expression. The characters \n, where n is a digit, are replaced by the text matched by
the n-th regular subexpression enclosed between ( and ). When nested parenthesized
subexpressions are present, n is determined by counting occurrences of ( starting from
the left.
A literal &, /, \ or newline may be included in a replacement by prefixing it with \.
( .,. ) t a
Transfer. Copy the addressed lines after the line addressed by a. Dot is left at the last line
of the copy.
( .,. ) u
Undo. Restore the preceding contents of the first addressed line (sic), which must be the
last line in which a substitution was made (double sic).
( 1,$ ) v/regular expression/command list
This command is the same as the global command g except that the command list is exe­
cuted with dot initially set to every line except those matching the regular expression.
( 1,$ ) w filename
Write the addressed lines to the given file. If the file does not exist, it is created with mode
666 (readable and writable by everyone). If no filename is given, the remembered file
name, if any, is used. The file name is remembered if there were no remembered file name
already. Dot is unchanged. If the write is successful, the number of characters written is
( 1,$ ) W filename
Perform w, but append to, instead of overwriting, any existing file contents.
($) =
Print the line number of the addressed line. Dot is unchanged.
!shell command
Send the remainder of the line after the ! to rc(1) to be interpreted as a command. Dot is
( .+1) <newline>
An address without a command is taken as a p command. A terminal / may be omitted
from the address. A blank line alone is equivalent to .+1p; it is useful for stepping
through text.
If an interrupt signal (DEL) is sent, ed prints a ? and returns to its command level.
When reading a file, ed discards NUL characters and all characters after the last newline.
ed.hup work is saved here if terminal hangs up
sam(1), sed(1), regexp(6)
?name for inaccessible file; ?TMP for temporary file overflow; ? for errors in commands or other
emacs editor macros
emacs [ options ]
This page intentionally left blank.
sam(1), vi(1)
eqn typeset mathematics
eqn [ option ... ] [ file ... ]
Eqn is a troff(1) preprocessor for typesetting mathematics on a typesetter. Usage is almost always
eqn file ... | troff
If no files are specified, eqn reads from the standard input. Eqn prepares output for the typesetter
named in the −Tdest option (default −Tutf; see troff(1)). When run with other preprocessor fil­
ters, eqn usually comes last.
A line beginning with .EQ marks the start of an equation; the end of an equation is marked by a
line beginning with .EN. Neither of these lines is altered, so they may be defined in macro pack­
ages to get centering, numbering, etc. It is also possible to set two characters as delimiters; text
between delimiters is also eqn input. Delimiters may be set to characters x and y with the option
−dxy or (more commonly) with delim xy between .EQ and .EN. Left and right delimiters may
be identical. (They are customarily taken to be $$). Delimiters are turned off by delim off.
All text that is neither between delimiters nor between .EQ and .EN is passed through
Tokens within eqn are separated by spaces, tabs, newlines, braces, double quotes, tildes or cir­
cumflexes. Braces {} are used for grouping; generally speaking, anywhere a single character like x
could appear, a complicated construction enclosed in braces may be used instead. Tilde ~ repre­
sents a full space in the output, circumflex ^ half as much.
Subscripts and superscripts are produced with the keywords sub and sup. Thus x sub
makes x i , a sub i sup 2 produces a 2i , and e sup {x sup 2 + y sup 2} gives e x + y .
Over makes fractions: a over b yields __ .
Sqrt produces square roots: 1 over sqrt {ax sup 2 +bx+c} results in ______________ .
ax 2 + bx + c
The keywords from and to introduce lower and upper limits on arbitrary things: lim
Σ x i is made
n’ 0
with lim from {n −> inf} sum from 0 to n x sub i.
Left and right brackets, braces, etc., of the right height are made with left and right: left [
y 2  = 1. The
x sup 2 + y sup 2 over alpha right ] ~=~1 produces x 2 + ___
right clause is optional. Legal characters after left and right are braces, brackets, bars, c
and f for ceiling and floor, and "" for nothing at all (useful for a right-side-only bracket).
Vertical piles of things are made with pile, lpile, cpile, and rpile: pile {a above b
above c} produces b. There can be an arbitrary number of elements in a pile. lpile leftc
justifies, pile and cpile center, with different vertical spacing, and rpile right justifies.
Matrices are made with matrix: matrix { lcol { x sub i above y sub 2 } ccol
xi 1
{ 1 above 2 } } produces y 2. In addition, there is rcol for a right-justified column.
Diacritical marks are made with prime, dot, dotdot, hat, tilde, bar, under,
____ vec, dyad,
and under: x sub 0 sup prime = f(t) bar + g(t) under is x ′0 = f (t) + g(t)
____ , and x
vec = y dyad is ’
x =
Sizes and fonts can be changed with prefix operators size n, size ±n, fat, roman, italic,
bold, or font n. Size and fonts can be changed globally in a document by gsize n and gfont
n, or by the command-line arguments −sn and −fn.
Normally subscripts and superscripts are reduced by 3 point sizes from the previous size; this may
be changed by the command-line argument −pn.
Successive display arguments can be lined up. Place mark before the desired lineup point in the
first equation; place lineup at the place that is to line up vertically in subsequent equations.
Shorthands may be defined or existing keywords redefined with define: define thing %
replacement % defines a new token called thing which will be replaced by replacement whenever it
appears thereafter. The % may be any character that does not occur in replacement.
Keywords like sum ( Σ ) , int ( + ) , inf () , and shorthands like >= ( ≥ ) , −> ( → ) , and != (`)
are recognized. Greek letters are spelled out in the desired case, as in alpha or GAMMA. Mathe­
matical words like sin, cos, log are made Roman automatically. Troff(1) four-character
escapes like \(lh ( ) can be used anywhere. Strings enclosed in double quotes " " are passed
through untouched; this permits keywords to be entered as text, and can be used to communicate
with troff when all else fails.
font descriptions for PostScript
troff(1), tbl(1)
J. F. Ossanna and B. W. Kernighan, Troff Users Manual.
B. W. Kernighan and L. L. Cherry, Typesetting MathematicsUsers Guide, Unix Research System
Programmer’s Manual, Tenth Edition, Volume 2.
To embolden digits, parens, etc., it is necessary to quote them, as in bold "12.3".
at, drain, expect, pass dialer scripting tools
dial/at [ −q ] [ −t seconds ] atcommand
dial/expect [ −iq ] [ −t seconds ] goodstring [ badstring... ]
dial/pass [ −q ]
These commands are used to write telephone dialing scripts, mostly for PPP sessions. They all
expect standard input and output to be connected to a communications device, e.g, a serial line to
a modem. They communicate with the user using /dev/cons.
At sends atcommand to the modem prefixed with the string at. It then reads from the modem
expecting an AT response. At will return success if it gets and OK of CONNECT response. Other­
wise it will return the response as an error status. The options are:
set the timeout to seconds. The default is 300.
dont write to /dev/cons what is read from standard in. The default is to copy every­
thing through.
Expect reads standard input looking for one of the strings given as arguments. Reading the first
string causes a successul exit status. Reading any of the others causes an exit status equal to the
string. The command also terminates on a timeout. The options are:
set the timeout to seconds. The default is 300.
ignore case when doing the matches.
dont write to /dev/cons what is read from standard in. The default is to copy every­
thing through.
Pass copies input from /dev/cons to standard output. It terminates on a newline. The only flag
is −q and means the same as it does for expect.
Drain discards any input waiting on standard input. It is used to sync up the stream at the start of
dialing or after an error.
The following rc script dials out through a Hayes compatible modem on /dev/eia1 and lets the
user type in a user name and password before starting ppp.
fn initfn {
echo +++
dial/at zh0
fn dialfn {
dial/at dt^$telno
# set up uart
if( test −e $dev^ctl ){
echo −n b^$baud
echo −n m1
# cts/rts flow control
echo −n q64000 # big buffer
echo −n n1
# nonblocking writes
echo −n r1
# rts on
echo −n d1
echo −n c1
} > $dev^ctl
# dtr on
# handup when we lose dcd
# get the modem’s attention
while( ! initfn )
sleep 1
# dial
while( ! dialfn )
sleep 30
if( ! dial/expect −it 60 ’username:’ ){
echo can’’t connect >[1=2]
exit connect
if( ! dial/expect −it 60 ’password:’ ){
echo can’’t connect >[1=2]
exit connect
if( ! dial/expect −t 60 ’ppp or telnet:’ ){
echo can’’t connect >[1=2]
exit connect
echo ppp
dial/expect −t 5 something
echo connected >[1=2]
# start ppp
ip/ppp $primary −f
} < $dev > $dev
/rc/bin/ipconf/* example dialer scripts for ppp
ppp(8), telco(4)
faces, seemail, vwhois mailbox interface
faces [ −ih ] [ −m maildir ]
vwhois person ...
The faces command monitors incoming mail and displays in its window a representation of the
users mail box using a small image for each message. The image is typically a portrait of the
sender. Which image to display is determined by two directories /usr/$user/lib/face and /lib/face.
Entries in /usr/$user/lib/face take priority over those in /lib/face. See face(6), for how these direc­
tories are organised.
If the user is running plumber(4), faces reacts to plumb messages to the seemail port, typically
from upas/fs, and is thus notified of message additions and deletions.
Right-clicking on a message icon causes that message to be plumbed to showmail. A typical
plumb action will be to display the message, such as by the rule
plumb start window mail −s $0
The acme(1) mail reader listens to the showmail port automatically.
If the user is not running plumber, faces reads the log file and right-clicking has no effect.
If arrows are visible, clicking on them will scroll the display. Middle-clicking on the arrows scrolls
to the end.
Starting faces with the −i flag causes faces to read the messages in /mail/fs/mbox or
the mailboxes specified with the −m flag upon startup.
The −m option directs faces to watch for messages arriving in maildir
/mail/fs/mbox. Multiple −m flags may be used to watch multiple mailboxes.
The −h flag causes a different, venerable behavior in which the window displays the history of
messages received rather than the current state of the mail box. In particular, faces are not
removed from the screen when messages are deleted. Also, in this mode clicking button 1 in the
display will clear the window.
Seemail is an rc(1) script that invokes faces −h.
Vwhois tells faces to display the icons of the named persons, without sending a message.
/mail/fs/mbox mail directory.
mail(1), marshal(1), nedmail(1), plumber(4), face(6), plumb(6)
factor, primes factor a number, generate large primes
factor [ number ]
primes start [ finish ]
Factor prints number and its prime factors, each repeated the proper number of times. The num­
ber must be positive and less than 254 (about 1.8×1016 ).
If no number is given, factor reads a stream of numbers from the standard input and factors them.
It exits on any input not a positive integer. Maximum running time is proportional to √n
Primes prints the prime numbers ranging from start to finish, where start and finish are positive
numbers less than 256. If finish is missing, primes prints without end; if start is missing, it reads
the starting number from the standard input.
fedex, ups, usps track shipments
fedex tracking−number
ups tracking−number
usps tracking−number
Fedex writes available shipment details for the given Federal Express 12-digit tracking−number on
the standard output. Ups is similar, but takes a United Parcel Service 18-digit tracking−number.
Usps takes a US Post Office tracking−number.
Redesigns of the source website can break these programs.
file determine file type
file [ −m ] [ file ... ]
File performs a series of tests on its argument files in an attempt to classify their contents by lan­
guage or purpose. If no arguments are given, the classification is performed on standard input.
If the −m flag is given, file outputs an appropriate MIME Content−Type specification describing
the type and subtype of each file.
The file types it looks for include directory, device file, zero-filled file, empty file, Plan 9 exe­
cutable, PAC audio file, cpio archive, tex dvi file, archive symbol table, archive, rc script, sh
script, PostScript, troff output file for various devices, mail box, GIF, FAX, object code, C and
Alef source, assembler source, compressed files, encrypted file, English text, compressed image,
image, subfont, and font.
If a file has no apparent format, file looks at the character set it uses to classify it according to
ASCII, extended ASCII, Latin ASCII, or UTF holding one or more of the following blocks of the Unicode
Standard: Extended Latin, Greek, Cyrillic, Armenian, Hebrew, Arabic, Devanagari, Bengali, Gur­
mukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Thai, Lao, Tibetan, Georgian, Japanese,
Chinese, or Korean.
If all else fails, file decides its input is binary.
It can make mistakes.
filter, list, deliver, token, vf filtering mail
upas/filter [ −bh ] rcvr mailbox [ regexp file ] ...
upas/list [ −d ] add|check patternfile addressfile ...
upas/deliver recipient fromfile mbox
upas/token key [ tokenfile ]
upas/vf [ −r ] [ −s savefile ]
A user may filter all incoming mail by creating a world readable/executable file
/mail/box/username/pipeto. If the file is a shell script, it can use the commands
described here to implement a filter.
Filter provides simple mail filtering. The first two arguments are the recipients address and mail­
box, that is, the same arguments provided to pipeto. The remaining arguments are all pairs of
a regular expression and a file name. With no flags, the senders address is matched against each
regular expression starting with the first. If the expression matches, then the message is delivered
to the file whose name follows the expression. The file must be world writable and should be
append only. A message that matches none of the expressions is delivered into the users stan­
dard mail box.
By default, filter matches each regular expression against the messages sender. The −h flag
causes filter to match against the entire header, and the −b flag causes filter to match against the
entire message (header and body).
For example, to delete any messages of precedence bulk, place in your pipeto file:
/bin/upas/filter −h $1 $2 ’Precedence: bulk’ /dev/null
Three other commands exist which, combined by an rc(1) script, allow you to build your own filter.
List takes two verbs; check and add. Check directs list to check each address contained in the
addressfiles against a list of patterns in patternfile. Patterns come in four forms:
If any address matches the regular expression, list returns successfully.
If any address exactly matches string, list returns successfully.
!~regular−expression If any address matches the regular expression and no other address
matches a non ! rule, list returns error status "!match".
If any address exactly matches string and no other address matches a non
! rule, list returns error status "!match".
If no addresses match a pattern, list returns "no match".
The pattern file may also contain lines of the form
#include filename
to allow pattern files to include other pattern files. All pattern matches are case insensitive. List
searches the pattern file (and its includes) in order. The first matching pattern determines the
List add directs list to add a pattern to patternfile for each address in the addressfiles that doesht
already match a pattern.
Token, with only one argument, prints to standard output a unique token created from the current
date and key. With two arguments, it checks token against tokens created over the last 10 days
with key. If a match is found, it returns successfully.
Deliver delivers into mail box mbox the message read from standard input. It obeys standard mail
file locking and logging conventions.
/sys/src/cmd/upas/filterkit/pipeto.sample is a sample pipeto using the filter
A sample pipefrom, /sys/src/cmd/upas/filterkit/pipefrom.sample, is provided
which adds all addresses of your outgoing mail to your pattern file. You should copy it into a
directory that normally gets bound by your profile onto /bin.
Vf (virus filter) takes a mail message as standard input and searches for executable MIME attach­
ments, either rewriting them to be non-executable or rejecting the message. The behavior
/sys/lib/mimetype contains the list of known extensions and MIME content types. The fifth
field of each line specifies the safety of a particular file type: y (yes), m (maybe; treated same as
yes), n (no), p (previous), or r (reject). Vf allows attachments with safety y or m to pass through
unaltered. Attachments with safety n both are wrapped in extra MIME headers and have
.suspect appended to their file names, to avoid automatic execution by mail readers. Attach­
ments with safety r (currently, .bat, .com, .exe, and .scr, all Microsoft executable exten­
sions) are taken as cause for the entire message to be rejected. A safety of p (used for the
x−gunzip mime type) causes the previous extension to be tested, so that x.tar.gz is treated
the same as x.tar.
If /mail/lib/validateattachment exists and is executable, vf runs it on all attachments
with safety n (attachments it would normally sanitize). If validateattachments exit status contains
the string discard, vf rejects the entire message. If the status contains the string accept, vf
does not sanitize the attachment. Otherwise, vf sanitizes the attachment as before. The standard
validateattachment uses file(1) to determine the file type. It accepts text and image files and dis­
cards messages containing executables or zip (see gzip(1)) archives of executables.
The −r option causes vf not to sanitize MIME attachments, but instead to reject messages it deter­
mines to be viruses. The −s option causes vf to log all attachments of safety r in the mail box
mail filter
MIME content types
attachment checker
aliasmail(8), faces(1), mail(1), marshal(1), mlmgr(1), nedmail(1), qer(8), rewrite(6), send(8),
smtp(8), upasfs(4)
fmt, htmlfmt simple text formatters
fmt [ option ... ] [ file ... ]
htmlfmt [ −a ] [ −c charset ] [ −u url ] [ file ... ]
Fmt copies the given files (standard input by default) to its standard output, filling and indenting
lines. The options are
−l n
Output line length is n, including indent (default 70).
−w n
A synonym for −l.
−i n
Indent n spaces (default 0).
Do not join short lines: only fold long lines.
Empty lines and initial white space in input lines are preserved. Empty lines are inserted between
input files.
Fmt is idempotent: it leaves already formatted text unchanged.
Htmlfmt performs a similar service, but accepts as input text formatted with HTML tags. It accepts
fmts −l and −w flags and also:
Normally htmlfmt suppresses the contents of form fields and anchors (URLs and image
files); this flag causes it to print them, in square brackets.
−c charset
change the default character set from iso-8859-1 to charset. This is the character set
assumed if there isnt one specified by the html itself in a <meta> directive.
−u url Use url as the base URL for the document when displaying anchors; sets −a.
Htmlfmt makes no attempt to render the two-dimensional geometry of tables; it just treats the
table entries as plain, to-be-formatted text.
fortune sample lines from a file
fortune [ file ]
Fortune prints a one-line aphorism chosen at random. If a file is specified, the saying is taken
from that file; otherwise it is selected from /sys/games/lib/fortunes.
/sys/games/lib/fortunes.index fast lookup table, maintained automatically
freq print histogram of character frequencies
freq [ −cdorx ] [ file ... ]
Freq reads the given files (default standard input) and prints histograms of the character frequen­
cies. By default, freq counts each byte as a character; under the −r option it instead counts UTF
sequences, that is, runes.
Each non-zero entry of the table is printed preceded by the byte value, in decimal, octal, hex, and
Unicode character (if printable). If any options are given, the −d, −x, −o, −c flags specify a sub­
set of value formats: decimal, hex, octal, and character, respectively.
utf(6), wc(1)
4s, 5s, festoon, juggle, life, mahjongg, memo, sokoban, sudoku time wasters
games/festoon [ −pet ] [ sentences [ percent−invented−nouns ] ]
games/juggle [ −d delay ] [ −h hands ] [ start ] pattern
games/life startfile
games/mahjongg [ −c ] [ −f ] [ −b background ] [ −t tileset ] [ −l layout ]
games/memo [ −h ]
games/sokoban [ level ]
There are a few games in /bin/games:
4s, 5s
Try to fill complete rows using 4-square or 5-square tiles. Move tiles left or right
by moving the mouse. Rotate tiles with buttons 1 and 3. Drop tiles for more points
with button 2 or the space bar. Keys a and j move left, s and k rotate left, d and
l rotate right, f and ; move right. z, p and Esc toggle suspend/resume. q, Del
and control−D quit.
Generate an official-looking but utterly nonsensical bureaucratic report as pic |
eqn | tbl | troff −mm input. Options −p, −e and −t add gibberish dia­
grams, equations and tables.
Display the juggling pattern using the optional initial start pattern. The number of
hands involved (default 2) can be specified with −h, and delay can be used to speed
up or slow down the action (default is 20). Try the pattern 333333441333333 or
Play the game of Life, given an initial position. There is a library of interesting ini­
tial positions; the library is consulted if startfile cannot be found.
Remove all tiles from the board. Click on tiles with the same face that are not
blocked by others. A blocked tile is one that is partially or fully covered on top or
has neighbouring tiles to the left and right. The game finishes when either all tiles
are gone or there are no more moves left. The arguments are for changing back­
ground (-b), tile (-t) and layout (-l) images; -c selects a true-color buffer image, for
use with drawterm or in case selecting a tile obscures it completely; -f causes
mahjongg to indicate non-blocked tiles on mouse-over. The N key will generate a
new level, R restarts the current one. Q and Del quit, H gives a hint, either trying to
match the currently selected tile, or if no tile is selected finding out the first avail­
able tile. U and Bksp undo the last move, C tries to solve the level.
Remove all tiles from the board. At first, pictures of various Bell Labs employees,
Lucent Technologies logo, and Glenda will appear. Memorize the sequence, then
click to hide them and begin. Use the mouse to select two tiles. If they are the
same, the tiles will disappear, otherwise the tiles will flip back and you will get a
chance to try again. Button 3 generates a memu allowing you to restart, switch
between easy and hard modes, and exit. The −h option sets the game to hard
mode. Once the game has been completed, a message pops up with how long it
took to win. Use the button 3 menu to choose a mode, or click to play again.
Guide Glenda through a room full of walls, pebbles and holes to put the pebbles in.
Your goal is to arrange all pebbles into holes by pushing them around, but you can
only push a pebble if there is no wall or another pebble blocking the way. Arrow
keys move Glenda up-down-left-right. N and P keys switch between the next and
previous levels, R restarts the current level. Del and Q quit. Button 3 invokes a
menu to restart the current level, load different level sets, and en- and disable ani­
mation of multi-step moves. Button 2 lets you change between levels. Button 1 lets
you do multi-step moves and pushes, by clicking it on the destination where you
want Glenda to go. Glenda will only move if it can reach the destination. For a
multi-step push the pebble must be next to Glenda, the destination must be on the
same row or column, and there must be a free place next to the destination where
the pebble can be pushed to. Otherwise, if possible, Glenda will walk to the desti­
nation without pushing the pebble. Sokoban accepts a level file as its argument.
Sudoku is a puzzle game from Japan. The goal of the game is to fill the numbers 1
to 9 in all squares of the 9x9 board following a few simple rules: no digit should
repeat on the same row and column, and no digit should repeat in the same 3x3
boxes outlined with thicker lines. The board is initially filled with a partial solution
which can be used for inferring digits for the empty squares. The top row of the
board contains the digits 1 through 9, clicking on one of those digits selects that
number for placement on the board, clicking it again will deselect that digit. Click­
ing on an empty square will then affix the square with the selected digit or, if no
digit is selected empty the square.
Button 3 presents a menu with the following options:
autogenerate a new, random board
mark in red any digits not placed according to the rules
present the boards solution
clear the board to its starting (or last loaded) state
save the current board to /tmp/sudoku−save
load the last saved board from /tmp/sudoku−save
print the current board and solution in a format suitable for addition in
the sudoku library to /tmp/sudoku−board
Offline pretty-print the board for off-line solving to /tmp/sudoku−print
quit the game
Button 2 presents a list of sudoku boards of varying degrees of difficulty from
Pressing the Q key quits sudoku.
score files of 4s and 5s
interesting starting positions
image sprites, levels and backgrounds used by mahjongg
tiles for memo
image sprites and levels used by sokoban
images and boards used by sudoku
In 4s and 5s, mouse warping (when the game is resumed, and when a new tile appears) does not
happen when the mouse cursor is outside the game window. Those who prefer to use the key­
board without the mouse cursor blocking the view (or being warped all the time) may consider this
a feature.
grap pic preprocessor for drawing graphs
grap [ file ... ]
Grap is a pic(1) preprocessor for drawing graphs on a typesetter. Graphs are surrounded by the
troff commands .G1 and .G2. Data are scaled and plotted, with tick marks supplied automati­
cally. Commands exist to modify the frame, add labels, override the default ticks, change the plot­
ting style, define coordinate ranges and transformations, and include data from files. In addition,
grap provides the same loops, conditionals, and macro processing that pic does.
frame ht e wid e top dotted ...: Set the frame around the graph to specified ht and wid;
default is 2 by 3 (inches). The line styles (dotted, dashed, invis, solid (default)) of the
sides (top, bot, left, right) of the frame can be set independently.
label side "a label" "as a set of strings" adjust: Place label on specified side;
default side is bottom. adjust is up (or down left right) expr to shift default position;
width expr sets the width explicitly.
ticks side in at optname expr, expr, ...: Put ticks on side at expr, ..., and label with "expr". If
any expr is followed by "...", label tick with "...", and turn off all automatic labels. If "..." contains
%fs, they will be interpreted as printf formatting instructions for the tick value. Ticks point in
or out (default out). Tick iterator: instead of at ..., use from expr to expr by op expr where op
is optionally +−*/ for additive or multiplicative steps. by can be omitted, to give steps of size 1.
If no ticks are requested, they are supplied automatically; suppress this with ticks off. Auto­
matic ticks normally leave a margin of 7% on each side; set this to anything by margin = expr.
grid side linedesc at optname expr, expr, ...: Draw grids perpendicular to side in style linedesc at
expr, .... Iterators and labels work as with ticks.
coord optname x min, max y min, max log x log y: Set range of coords and optional log
scaling on either or both. This overrides computation of data range. Default value of optname is
current coordinate system (each coord defines a new coordinate system).
plot "str" at point; "str" at point: Put str at point. Text position can be qualified with rjust,
ljust, above, below after "...".
line from point to point linedesc: Draw line from here to there. arrow works in place of
next optname at point linedesc: Continue plot of data in optname to point; default is current.
draw optname linedesc ...: Set mode for next: use this style from now on, and plot "..." at each
point (if given).
new optname linedesc ...: Set mode for next, but disconnect from previous.
A list of numbers x y1 y2 y3 ... is treated as plot bullet at x,y1; plot bullet at x,y2;
etc., or as next at x,y1 etc., if draw is specified. Abscissae of 1,2,3,... are provided if there is
only one input number per line.
A point optname expr, expr maps the point to the named coordinate system. A linedesc is one of
dot dash invis solid optionally followed by an expression.
define name {whatever}: Define a macro. There are macros already defined for standard plot­
ting symbols like bullet, circle, star, plus, etc., in /sys/lib/grap.defines, which
is included if it exists.
var = expr: Evaluate an expression. Operators are + − * and /. Functions are log and exp
(both base 10), sin, cos, sqrt; rand returns random number on [0,1); max(e,e),
min(e,e), int(e).
print expr; print "...": As a debugging aid, print expr or string on the standard error.
copy "file name": Include this file right here.
copy thru macro: Pass rest of input (until .G2) through macro, treating each field (non-blank,
or "...") as an argument. macro can be the name of a macro previously defined, or the body of one
in place, like /plot $1 at $2,$3/.
copy thru macro until "string": Stop copy when input is string (left-justified).
pic remainder of line: Copy to output with leading blanks removed.
graph Name pic−position: Start a new frame, place it at specified position, e.g., graph Thing2
with .sw at + (0.1,0). Name must be capitalized to keep pic happy.
.anything at beginning of line: Copied verbatim.
sh %anything %: Pass everything between the %s to the shell; as with macros, % may be any char­
acter and anything may include newlines.
# anything: A comment, which is discarded.
Order is mostly irrelevant; no category is mandatory. Any arguments on the .G1 line are placed
on the generated .PS line for pic.
frame ht 1 top invis right invis
coord x 0, 10 y 1, 3 log y
ticks left in at 1 "bottommost tick", 2,3 "top tick"
ticks bot in from 0 to 10 by 2
label bot "silly graph"
label left "left side label" "here"
grid left dashed at 2.5
copy thru / circle at $1,$2 /
1 1
2 1.5
3 2
4 1.5
10 3
top tick
left side label
bottommost tick
silly graph
definitions of standard plotting characters, e.g., bullet
pic(1), troff(1)
J. L. Bentley and B. W. Kernighan, GRAPA Language for Typesetting Graphs, Unix Research System Programmer’s Manual, Tenth Edition, Volume 2.
graph draw a graph
graph [ option ... ]
Graph with no options takes pairs of numbers from the standard input as abscissas (x-values) and
ordinates (y-values) of a graph. Successive points are connected by straight lines. The graph is
encoded on the standard output for display by plot(1) filters.
If an ordinate is followed by a nonnumeric string, that string is printed as a label beginning on the
point. Labels may be surrounded with quotes " " in which case they may be empty or contain
blanks and numbers; labels never contain newlines.
The following options are recognized, each as a separate argument.
Supply abscissas automatically; no x-values appear in the input. Spacing is given by the
next argument (default 1). A second optional argument is the starting point for automatic
abscissas (default 0, or 1 with a log scale in x, or the lower limit given by −x).
Break (disconnect) the graph after each label in the input.
Character string given by next argument is default label for each point.
Next argument is grid style, 0 no grid, 1 frame with ticks, 2 full grid (default).
Next argument is a legend to title the graph. Grid ranges are automatically printed as part
of the title unless a −s option is present.
Next argument is mode (style) of connecting lines: 0 disconnected, 1 connected. Some
devices give distinguishable line styles for other small integers. Mode 1 (default) begins
with style 1 and rotates styles for successive curves under option −o.
(Overlay.) The ordinates for n superposed curves appear in the input with each abscissa
value. The next argument is n.
Next argument is one or more of the characters bcgkmrwy, choosing pen colors by their
initial letter, as in plot(6). Successive curves will cycle through the colors in the given order.
Save screen; no new page for this graph.
−x l If l is present, x-axis is logarithmic. Next 1 (or 2) arguments are lower (and upper) x lim­
its. Third argument, if present, is grid spacing on x axis. Normally these quantities are
determined automatically.
−y l Similarly for y.
Make automatically determined x and y scales equal.
Next argument is fraction of space for height.
Similarly for width.
Next argument is fraction of space to move right before plotting.
Similarly to move up before plotting.
Transpose horizontal and vertical axes. (Option −a now applies to the vertical axis.)
If a specified lower limit exceeds the upper limit, the axis is reversed.
plot(1), grap(1)
Segments that run out of bounds are dropped, not windowed. Logarithmic axes may not be
reversed. Option −e actually makes automatic limits, rather than automatic scaling, equal.
grep search a file for a pattern
grep [ −bchiLlnsv ] [ −e ] pattern | −f patternfile [ file ... ]
Grep searches the input files (standard input default) for lines that match the pattern, a regular
expression as defined in regexp(6) with the addition of a newline character as an alternative (sub­
stitute for |) with lowest precedence. Normally, each line matching the pattern is selected, and
each selected line is copied to the standard output. The options are
Print only a count of matching lines.
Do not print file name tags (headers) with output lines.
The following argument is taken as a pattern. This option makes it easy to specify patterns
that might confuse argument parsing, such as −n.
Ignore alphabetic case distinctions. The implementation folds into lower case all letters in
the pattern and input before interpretation. Matched lines are printed in their original
(ell) Print the names of files with selected lines; dont print the lines.
Print the names of files with no selected lines; the converse of −l.
Mark each printed line with its line number counted in its file.
Produce no output, but return status.
Reverse: print lines that do not match the pattern.
The pattern argument is the name of a file containing regular expressions one per line.
Dont buffer the output: write each output line as soon as it is discovered.
Output lines are tagged by file name when there is more than one input file. (To force this tag­
ging, include /dev/null as a file name argument.)
Care should be taken when using the shell metacharacters $*[^|()=\ and newline in pattern; it
is safest to enclose the entire expression in single quotes ’ . . . ’. An expression starting with *
will treat the rest of the expression as literal characters.
ed(1), awk(1), sed(1), sam(1), regexp(6)
Exit status is null if any lines are selected, or non-null when no lines are selected or an error
gs Aladdin Ghostscript (PostScript and PDF language interpreter)
gs [ options ] [ files ] ...
Ghostscript is a programming language similar to Adobe Systems PostScript and PDF languages,
which are in turn similar to Forth. Gs reads files in sequence and executes them as Ghostscript
programs. After doing this, it reads further input from the standard input. If the file − is named,
however, it represents the standard input, which is read in order and not after the files on the com­
mand line. Each line is interpreted separately. The quit command, or end-of-file, exits the inter­
The interpreter recognizes several switches described below, which may appear anywhere in the
command line and apply to all files thereafter.
The −h or −? options give help and list the available devices; the default is plan9, which pro­
duces compressed image files suitable for viewing with page(1) (but note that page(1) will invoke
gs automatically; see its manual).
Ghostscript may be built with multiple output devices. Ghostscript normally opens the first one
and directs output to it. To use device xyz as the initial output device, include the switch
in the command line. This switch must precede the first PostScript file and only its first invocation
has any effect. Output devices can also be selected by the word selectdevice in the input lan­
guage, or by setting the environment variable GS_DEVICE. The order of precedence for these
alternatives, highest to lowest, is:
(command line)
Normally, output goes directly to a scratch file. To send the output to a series of files,, etc., use the switch
The %d may be any printf (see fprintf(2)) format specification. Each file will receive one page of
output. If the file name begins with a pipe character, the output will be sent as standard input to
the following pipeline. For example,
Specifying the file − will send the files to standard output; this also requires enabling the −q
Initialization files
When looking for the initialization files (gs_*.ps), the files related to fonts, or the file for the
run operator, Ghostscript first looks for the file (if it doesnt start with a slash) in the current
directory, then in these directories in the following order:
Any directories specified by −I switches in the command line (see below);
Any directories specified by the GS_LIB environment variable;
The directories /sys/lib/ghostscript, /sys/lib/ghostscript/font, and
The GS_LIB or −I parameters may be a single directory or a colon-separated list.
−− filename arg1 ...
Take the next argument as a file name as usual, but take all remaining arguments (even if
they have the syntactic form of switches) and define the name ARGUMENTS in userdict (not
systemdict) as an array of those strings, before running the file. When Ghostscript finishes
executing the file, it exits back to the shell.
Define a name in systemdict with the given definition. The token must be exactly one
token (as defined by the token operator) and must not contain any white space.
Define a name in systemdict with value=null.
Define a name in systemdict with a given string as value. This is different from −d. For
example, −dname=35 is equivalent to the program fragment
/name 35 def
whereas −sname=35 is equivalent to
/name (35) def
Quiet startup: suppress normal startup messages, and also do the equivalent of −dQUIET.
Equivalent to −dDEVICEWIDTH=number1 and −dDEVICEHEIGHT=number2. This is
for the benefit of devices, such as windows, that allow width and height to be specified.
number2. This is for the benefit of devices, such as printers, that support multiple X and Y
resolutions. If only one number is given, it is used for both X and Y resolutions.
Adds the designated list of directories at the head of the search path for library files.
Note that makes systemdict read-only, so the values of names defined with -D/d/S/s
cannot be changed (although, of course, they can be superseded by definitions in userdict or other
Special names
Exit after the last file has been processed. This is equivalent to listing at the end of
the list of files.
Causes individual character outlines to be loaded from the disk the first time they are
encountered. (Normally Ghostscript loads all the character outlines when it loads a font.)
This may allow loading more fonts into RAM, at the expense of slower rendering.
Disables character caching. Only useful for debugging.
Disables the bind operator. Only useful for debugging.
Suppresses the normal initialization of the output device. This may be useful when debug­
Disables the prompt and pause at the end of each page. This may be desirable for applica­
tions where another program (e.g. page(1)) is driving Ghostscript.
Disables the deletefile and renamefile operators, and the ability to open files in
any mode other than read-only. This may be desirable for spoolers or other sensitive envi­
ronments. Files in the /fd directory may still be opened for writing.
Leaves systemdict writable. This is necessary when running special utility programs such
as font2c and pcharstr, which must bypass normal PostScript access protection.
Selects an alternate initial output device, as described above.
Selects an alternate output file (or pipe) for the initial output device, as described above.
Startup-files, utilities, examples, and basic font definitions.
Additional font definitions.
page(1), ps2pdf(1)
The Ghostscript document files in doc and man subdirectories of the source directory.
The treatment of standard input is non-standard.
gview interactive graph viewer
gview [ −mp ] [ −l logfile ] [ files ]
Gview reads polygonal lines or a polygonal line drawing from an ASCII input file (which defaults
to standard input), and views it interactively, with commands to zoom in and out, perform simple
editing operations, and display information about points and polylines. (Multiple input files are
allowed if you want to overlay several line drawings.) The editing commands can change the color
and thickness of the polylines, delete (or undelete) some of them, and optionally rotate and move
them. It is also possible to generate an output file that reflects these changes and is in the same
format as the input.
Since the move and rotate commands are undesirable when just viewing a graph, they are only
enabled if gview is invoked with the −m option.
The −p option plots only the vertices of the polygons.
Clicking on a polyline with button 1 displays the coordinates and a t value that tells how far along
the polyline. (t=0 at the first vertex, t=1 at the first vertex, t=1.5 halfway between the second
and third vertices, etc.) The −l option generates a log file that lists all points selected in this man­
The most important interactive operations are to zoom in by sweeping out a rectangle, or to zoom
out so that everything currently being displayed shrinks to fit in the swept-out rectangle. Other
options on the button 3 menu are unzoom which restores the coordinate system to the default
state where everything fits on the screen, recenter which takes a point and makes it the center of
the window, and square up which makes the horizontal and vertical scale factors equal.
To take a graph of a function where some part is almost linear and see how it deviates from a
straight line, select two points on this part of the graph (i.e., select one with button 1 and then
select the other) and then use the slant command on the button 3 menu. This slants the coordi­
nate system so that the line between the two selected points appears horizontal (but vertical still
means positive y). Then the zoom in command can be used to accentuate deviations from horizon­
tal. There is also an unslant command that undoes all of this and goes back to an unslanted coor­
dinate system.
There is a recolor command on button 3 that lets you select a color and change everything to have
that color, and a similar command on button 2 that only affects the selected polyline. If the input
file uses the Multi(...) feature explained below, either flavor of recolor allows you to type a
digit in lieu of selecting a color.
The thick or thin command on button 2 changes the thickness of the selected polyline and there is
also an undo command for such edits. Finally, button 3 has commands to read a new input file
and display it on top of everything else, restack the drawing order (in case lines of different color
are drawn on top of each other), write everything into an output file, or exit the program.
Each polyline in an input or output file is a space-delimited x y coordinate pair on a line by itself,
and the polyline is a sequence of such vertices followed by a label. The label could be just a blank
line or it could be a string in double quotes, or virtually any text that does not contain spaces and
is on a line by itself. The label at the end of the last polyline is optional. It is not legal to have
two consecutive labels, since that would denote a zero-vertex polyline and each polyline must
have at least one vertex. (One-vertex polylines are useful for scatter plots.) Under the −l option,
a newline causes the selected polylines label to appear in the log file (where it could be seen by
invoking tail −f in another window).
If the label after a polyline contains the word Thick or a color name (Red, Pink, Dkred,
Orange, Yellow, Dkyellow, Green, Dkgreen, Cyan, Blue, Ltblue, Magenta,
Violet, Gray, Black, White), whichever color name comes first will be used to color the
polyline. Alternatively, labels can contain Multi followed by single-letter versions of these
names: (R, P, r, O, Y, y, G, g, C, B, b, M, V, A, K, W, each optionally preceded by T). Then
recolor followed by a nonzero digit n selects the nth alternative for each polyline.
To see a graph of the function y=sin(x)/x generate input with an awk script and pipe it into gview:
awk ’BEGIN{for(x=.1;x<500;x+=.1)print x,sin(x)/x}’ | gview
awk(1), tail(1)
The user interface for the slant command is counter-intuitive. Perhaps it would be better to have a
scheme for sweeping out a parallelogram.
The −p option makes the interactive point selection feature behave strangely, and is unnecessary
since extra blank lines in the input achieve essentially the same effect.
gzip, gunzip, bzip2, bunzip2, compress, uncompress, zip, unzip compress and expand data
gzip [−cvD[1−9]] [file ...]
gunzip [−ctTvD] [file ...]
bzip2 [−cvD[1−9]] [file ...]
bunzip2 [−cvD] [file ...]
compress [ −cv ] [ file ... ]
uncompress [ −cv ] [ file ... ]
zip [−avD[1−9]] [−f zipfile] file [...]
unzip [−cistTvD] [−f zipfile] [file ...]
Gzip encodes files with a hybrid Lempel-Ziv 1977 and Huffman compression algorithm known as
deflate. Most of the time, the resulting file is smaller, and will never be much bigger. Output
files are named by taking the last path element of each file argument and appending .gz; if the
resulting name ends with .tar.gz, it is converted to .tgz instead. Gunzip reverses the pro­
cess. Its output files are named by taking the last path element of each file argument, converting
.tgz to .tar.gz, and stripping any .gz; the resulting name must be different from the original
Bzip2 and bunzip2 are similar in interface to gzip and gunzip, but use a modified Burrows-Wheeler
block sorting compression algorithm. The default suffix for output files is .bz2, with .tar.bz2
becoming .tbz. Bunzip2 recognizes the extension .tbz2 as a synonym for .tbz.
Compress and uncompress are similar in interface to gzip and gunzip, but use the Lempel-ZivWelch compression algorithm. The default suffix for output files is .Z. Compress is one of the
oldest widespread Unix compression programs.
Zip encodes the named files and places the results into the archive zipfile, or the standard output
if no file is given. Unzip extracts files from an archive created by zip. If no files are named as
arguments, all of files in the archive are extracted. A directorys name implies all recursively con­
tained files and subdirectories. Zip is the de facto standard for compression on Microsoft operat­
ing systems.
None of these programs removes the original files. If the process fails, the faulty output files are
The options are:
Automaticialy creates directories as needed, needed for zip files created by broken
implementations which omit directories.
Write to standard output rather than creating an output file.
Convert all archive file names to lower case.
Streaming mode. Looks at the file data adjacent to each compressed file rather than
seeking in the central file directory. This is the mode used by unzip if no zipfile is speci­
fied. If −s is given, −T is ignored.
List matching files in the archive rather than extracting them.
Set the output time to that specified in the archive.
−1 .. −9 Sets the compression level. −1 is tuned for speed, −9 for minimal output size. The best
compromise is −6, the default.
Produce more descriptive output. With −t, adds the uncompressed size in bytes and the
modification time to the output. Without −t, prints the names of files on standard error
as they are compressed or decompressed.
Produce debugging output.
"A Technique for High Performance Data Compression", Terry A. Welch, IEEE Computer, vol. 17,
no. 6 (June 1984), pp. 8-19.
Unzip can only extract files which are uncompressed or compressed with the deflate compres­
sion scheme. Recent zip files fall into this category. Very recent zip files may have tables of con­
tents that unzip cannot read. Such files are still readable by invoking unzip with the −s option.
hget retrieve a web page corresponding to a url
hget [ −dhv ] [ −o ofile ] [ −p body ] [ −x netmntpt ] [ −r header ] url
Hget retrieves the web page specified by the URL url and writes it, absent the −o option, to stan­
dard output. The known URL types are: http and ftp.
If url is of type HTTP and the −p option is specified, then an HTTP POST is performed with body as
the data to be posted.
The −o option is used to keep a local file in sync with a web page. If the web page has been modi­
fied later than the file, it is copied into the file. If the file is up to date but incomplete, hget will
fetch the missing bytes.
Option −h causes HTTP headers to be printed to standard output in addition to the transferred
web page.
Option −r sends an arbitrary HTTP header.
Option −d turns on debugging written to standard error.
Normally, hget uses the IP stack mounted under /net. The −x option can be used to specify the
mount point of a different IP stack to use.
Option −v writes progress lines to standard error once a second. Each line contains two numbers,
the bytes transferred so far and the total length to be transferred.
If the environment variable httpproxy is set, it is used as a URL denoting an HTTP proxy server.
All HTTP accesses use this server to get the page instead of calling the destination server.
history print file names from the dump
history [ −Dabcemnw ] [ −fuv ] [ −d dumpfilesystem ] [ −s yyyymmdd ] files ...
History prints the names, dates, and sizes, and modifier of all versions of the named files, looking
backwards in time, stored in the dump file system. If the file exists in the main tree, the first line
of output will be its current state. For example,
history /adm/users
14 15:29:18
14 15:29:18
11 17:26:24
10 16:40:51
/adm/users 10083 [adm]
/n/dump/2001/0515/adm/users 10083 [adm]
/n/dump/2001/0514/adm/users 10481 [adm]
/n/dump/2001/0511/adm/users 10476 [adm]
When presented with a path of the form /n/fs/path, history will use fsdump as the name of the
dump file system, and will print a history of path.
The −v option enables verbose debugging printout.
The −D option causes diff(1) to be run for each adjacent pair of dump files. The options
−abcemnw are passed through to diff; the little-used diff option −f is replaced by the functional­
ity described below, and the −r option is disallowed.
The −u option causes times to be printed in GMT (UT) rather than local time.
The −d option selects some other dump file system such as /n/bootesdump.
The −f option forces the search to continue even when the file in question does not exist (useful
for files that only exist intermittently).
Finally, the −s option sets the starting (most recent) date for the output.
Check how often a user has been logged in.
history /usr/ches/tmp
hoc interactive floating point language
hoc [ −e expression ] [ file ... ]
Hoc interprets a simple language for floating point arithmetic, at about the level of BASIC, with Clike syntax and functions.
The named files are read and interpreted in order. If no file is given or if file is − hoc interprets the
standard input. The −e option allows input to hoc to be specified on the command line, to be
treated as if it appeared in a file.
Hoc input consists of expressions and statements. Expressions are evaluated and their results
printed. Statements, typically assignments and function or procedure definitions, produce no out­
put unless they explicitly call print.
Variable names have the usual syntax, including _; the name _ by itself contains the value of the
last expression evaluated. The variables E, PI, PHI, GAMMA and DEG are predefined; the last is
59.25..., degrees per radian.
Expressions are formed with these C-like operators, listed by decreasing precedence.
! − ++ −−
* / %
+ −
> >= < <= == !=
= += −= *= /= %=
Built in functions are abs, acos, asin, atan (one argument), cos, cosh, exp, int, log,
log10, sin, sinh, sqrt, tan, and tanh. The function read(x) reads a value into the vari­
able x and returns 0 at EOF; the statement print prints a list of expressions that may include
string constants such as "hello\n".
Control flow statements are if-else, while, and for, with braces for grouping. Newline ends
a statement. Backslash-newline is equivalent to a space.
Functions and procedures are introduced by the words func and proc; return is used to
return with a value from a function.
func gcd(a, b) {
temp = abs(a) % abs(b)
if(temp == 0) return abs(b)
return gcd(b, temp)
for(i=1; i<12; i++) print gcd(i,12)
bc(1), dc(1)
B. W. Kernighan and R. Pike, The Unix Programming Environment, Prentice-Hall, 1984
Error recovery is imperfect within function and procedure definitions.
htmlroff HTML formatting and typesetting
htmlroff [ −iuv ] [ −m name ] [ −r aN ] [ file ... ]
Htmlroff accepts troff(1) input in the named files and formats it as HTML for viewing in a web
If no file argument is given, htmlroff reads the standard input. An argument consisting of a single
minus (−) is taken to be a file name corresponding to the standard input. The options are:
Read standard input after the input files are exhausted.
Process the macro file /sys/lib/tmac/ before the input files.
−raN Set register a (one character name) to N.
Generate UTF output. By default, htmlroff converts Unicode runes into the corresponding
HTML entity sequences (&alpha;, &nbsp;, and so on). Htmlroff invokes tcs(1) for the
Generate debugging output and warnings about suspicious input.
Most troff input files, especially those using the ms(6) macros, can be used unaltered. In general,
the macro file tmac.html should be processed after processing other standard macro files, as in
htmlroff −ms −mhtml.
Htmlroff(6) describes the changes to the input language.
Mhtml(6) describes the new macros.
Format the Plan 9 web page:
cd /usr/web/plan9
htmlroff −mhtml >index.html
Format a paper:
cd /sys/doc
pic | tbl | eqn | htmlroff −ms −mhtml >auth.html
Mapping from troff two-character names like \(*a to Unicode characters like ±.
tcs(1), troff(1), htmlroff(6), mhtml(6)
idiff interactive diff
idiff [ −bw ] file1 file2
Idiff interactively merges file1 and file2 onto standard output. Wherever file1 and file2 differ, idiff
displays the differences in the style of diff −n on standard error and prompts the user to
select a chunk. Valid responses are:
Use the chunk from file1.
Use the chunk from file2.
Use the diff output itself.
q<, q>, q=
Use the given response for all future questions.
!cmd Execute cmd and prompt again.
Idiff invokes diff(1) to compare the files. The −b and −w flags, if passed, are passed to diff.
Kernighan and Pike, The Unix Programming Environment, Prentice-Hall, 1984.
join relational database operator
join [ options ] file1 file2
Join forms, on the standard output, a join of the two relations specified by the lines of file1 and
file2. If one of the file names is −, the standard input is used.
File1 and file2 must be sorted in increasing ASCII collating sequence on the fields on which they are
to be joined, normally the first in each line.
There is one line in the output for each pair of lines in file1 and file2 that have identical join fields.
The output line normally consists of the common field, then the rest of the line from file1, then the
rest of the line from file2.
Input fields are normally separated spaces or tabs; output fields by space. In this case, multiple
separators count as one, and leading separators are discarded.
The following options are recognized, with POSIX syntax.
−a n
In addition to the normal output, produce a line for each unpairable line in file n, where n
is 1 or 2.
−v n
Like −a, omitting output for paired lines.
−e s
Replace empty output fields by string s.
−1 m
−2 m Join on the mth field of file1 or file2.
−jn m
Archaic equivalent for −n m.
Each output line comprises the designated fields. The comma-separated field designators
are either 0, meaning the join field, or have the form n.m, where n is a file number and m
is a field number. Archaic usage allows separate arguments for field designators.
Use character c as the only separator (tab character) on input and output. Every appear­
ance of c in a line is significant.
sort −t: +1 /adm/users | join −t: −1 2 −a 1 −e "" − bdays
Add birthdays to the /adm/users file, leaving unknown birthdays empty. The layout of
ken:Feb 4, 1953.
tr : ’ ’ </adm/users | sort −k 3 3 >temp
join −1 3 −2 3 −o 1.1,2.1 temp temp | awk ’$1 < $2’
Print all pairs of users with identical userids.
sort(1), comm(1), awk(1)
With default field separation, the collating sequence is that of sort −b −ky,y; with −t, the
sequence is that of sort −tx −ky,y.
One of the files must be randomly accessible.
jpg, gif, png, ppm, bmp, v210, yuv, ico, togif, toppm, topng, toico view and convert pictures
jpg [ −39cdefFkJrtv ] [ file ... ]
gif [ −39cdektv ] [ file ... ]
png [ −39cdektv ] [ file ... ]
ppm [ −39cdektv ] [ file ... ]
bmp [ file ]
v210 [ −39cdektv ] [ file ... ]
yuv [ file ]
togif [ −c comment ] [ −l loopcount ] [ −d msec ] [ −t transindex ] [ file ... [ −d msec ] file ... ]
toppm [ −c comment ] [ file ]
topng [ −c comment ] [ [ −g gamma ] [ file ]
ico [ file ]
toico [ file ... ]
These programs read, display, and write image files in public formats. Jpg, gif, png, ppm, bmp,
v210, and yuv read files in the corresponding formats and, by default, display them in the current
window; options cause them instead to convert the images to Plan 9 image format and write them
to standard output. Togif, Toppm, and topng read Plan 9 images files, convert them to GIF, PPM,
or PNG, and write them to standard output.
The default behavior of jpg, gif, and ppm is to display the file, or standard input if no file is
named. Once a file is displayed, typing a character causes the program to display the next image.
Typing a q, DEL, or control-D exits the program. For a more user-friendly interface, use page(1),
which invokes these programs to convert the images to standard format, displays them, and offers
scrolling, panning, and menu-driven navigation among the files.
These programs share many options:
Disable Floyd-Steinberg error diffusion, which is used to improve the appearance of images
on color-mapped displays, typically with 8 bits per pixel. Primarily useful for debugging; if
the display has true RGB color, the image will be displayed in full glory.
Convert and display the image as a black and white (really grey-scale) image.
Convert the image to an RGBV color-mapped image, even if the display has true RGB color.
Suppress display of the image; this is set automatically by any of the following options:
Convert the image to a Plan 9 representation, as defined by image(6), and write it to stan­
dard output.
Like −c, but produce an uncompressed image. This saves processing time, particularly
when the output is being piped to another program such as page(1), since it avoids com­
pression and decompression.
Convert the image, if it is in color, to a true color RGB image.
Like −t, but force the image to RGB even if it is originally grey-scale.
Jpg has two extra options used to process the output of the LML video card:
Merge two adjacent images, which represent the two fields of a video picture, into a single
The input is a motion JPEG file, with multiple images representing frames of the movie.
Sets −f.
The togif and toppm programs go the other way: they convert from Plan 9 images to GIF and PPM,
and have no display capability. Both accept an option −c to set the comment field of the resulting
file. If there is only one input picture, togif converts the image to GIF format. If there are many
files, though, it will assemble them into an animated GIF file. The options control this process:
By default, the animation will loop forever; loopcount specifies how many times to loop. A
value of zero means loop forever and a negative value means to stop after playing the
sequence once.
By default, the images are displayed as fast as they can be rendered. This option specifies
the time, in milliseconds, to pause while displaying the next named file.
Gif translates files that contain a transparency index by attaching an alpha channel to the con­
verted image.
Ico displays a Windows icon (.ico) file. If no file is specified, ico reads from standard input. Icon
files contain sets of icons represented by an image and a mask. Clicking the right button pops up
a menu that lets you write any icons image as a Plan 9 image (widthxheight.image), write any
icons mask as a Plan 9 image (widthxheight.mask), or exit. Selecting one of the write menu items
yields a sight cursor. Move the sight over the icon and right click again to write.
Toico takes a list of Plan 9 image files (or standard input) and creates a single icon file. The masks
in the icon file will be the white space in the image. The icon file is written to standard output.
page(1), image(6).−t81.pdf−gif89a.txt−PNG−20031110
Writing an animated GIF using togif is a clumsy undertaking.
kbmap show a list of available keyboard maps and switch between them.
kbmap [ file... ]
Kbmap shows a single column consisting of the names of keyboard maps for different alphabets
available on the system. With no arguments kbmap will look for files in /sys/lib/kbmap.
Clicking the right mouse button will highlight the entry and force the keyboard mapping defined in
the corresponding file to become current for the system; typing q quits.
Kbmap requires that the file /dev/kbmap served by kbmap(3) exists and is writable.
Not all keyboards map the entire set of characters, so one has to switch back to the default map
before changing to another.
kill, slay, broke print commands to kill processes
kill name ...
slay name ...
broke [ user ]
Kill prints commands that will cause all processes called name and owned by the current user to be
terminated. Use the send command of rio(1), or pipe the output of kill into rc(1) to execute the
Kill suggests sending a kill note to the process; the same message delivered to the processs
ctl file (see proc(3)) is a surer, if heavy handed, kill, but is necessary if the offending process is
ignoring notes. The slay command prints commands to do this.
Broke prints commands that will cause all processes in the Broken state and owned by user (by
default, the current user) to go away. When a process dies because of an error caught by the sys­
tem, it may linger in the Broken state to allow examination with a debugger. Executing the com­
mands printed by broke lets the system reclaim the resources used by the broken processes.
ps(1), stop(1), notify(2), proc(3)
ktrace interpret kernel stack dumps
ktrace [ −i ] kernel pc sp [ link ]
Ktrace translates a hexadecimal kernel stack dump into a sequence of acid(1) commands to show
the points in the call trace. The kernel argument should be the path of the kernel being debugged,
and pc and sp are the PC and SP values given in the stack dump. For MIPS kernels, the contents of
the link register must also be supplied.
A stack trace consists of a ktrace command followed by a series of lines containing fields of the
form location=contents:
ktrace /kernel/path 80105bc1 8048e174
8048e114=80105ac6 8048e120=80140bb4 8048e134=8010031c
8048e16c=80137e45 8048e170=80105bc1 8048e178=80137e62
The trace can be edited to provide the correct kernel path and then pasted into a shell window. If
the −i option is present, ktrace instead prompts for the contents of the memory locations in
which it is interested; this is useful when the stack trace is on a screen rather than in a machine
readable form.
acid(1), rdbfs(4)
When examining a kernel trace resulting from an interrupt on top of other interrupts, only the top­
most call trace is printed.
leak, kmem, umem help find memory leaks
leak [ −abcds ] [ −f binary ] [ −r res ] [ −x width ] pid ...
kmem [ kernel ]
umem pid [ textfile ]
Leak examines the named processes, which should be sharing their data and bss segments, for
memory leaks. It uses a mark and sweep-style algorithm to determine which allocated blocks are
no longer reachable from the set of root pointers. The set of root pointers is created by looking
through the shared bss segment as well as each processs registers.
Unless directed otherwise, leak prints, for each block, a line with seven space-separated fields: the
string block, the address of the block, the size of the block, the first two words of the block, and
the function names represented by the first two words of the block. Usually, the first two words of
the block contain the malloc and realloc tags (see malloc(2)), useful for finding who allocated the
leaked blocks.
If the −s or the −c option is given, leak will instead present a sequence of acid(1) commands that
show each leaky allocation site. With −s a comment appears next to each command to indicate
how many lost blocks were allocated at that point in the program. With −c the comments are
extended to indicate also the total number of bytes lost at that point in the program, and an addi­
tional comment line gives the overall total number of bytes.
If the −a option is given, leak will print information as decribed above, but for all allocated blocks,
not only leaked ones. If the −d option is given, leak will print information as decribed above, but
for all free blocks, i.e. those freed, or those that are not yet in use (fragmentation?). The −a and
−d options can be combined.
If the −b option is given, leak will print a Plan 9 image file graphically summarizing the memory
arenas. In the image, each pixel represents res (default 8) bytes. The color code is:
dark blue
Completely allocated.
bright blue Contains malloc headers.
bright red
Contains malloc headers for leaked memory.
dark red
Contains leaked memory.
Completely free
Padding to fill out the image. The bright pixels representing headers help in counting
the number of blocks. Magnifying the images with lens(1) is often useful.
If given a name rather than a list of process ids, leak echoes back a command-line with process
ids of every process with that name.
The −f option specifies a binary to go on the acid(1) command-line used to inspect the processes,
and is only necessary when inspecting processes started from stripped binaries.
Umem prints a summary of all allocated blocks in the process with id pid. Each line of the sum­
mary gives the count and total size of blocks allocated at an allocation point. The list is sorted by
count in decreasing order. Umem prints summarizes all allocations, not just memory leaks, but it
is faster and requires less memory than leak .
Kmem is like umem but prints a summary for the running kernel.
List lost blocks in 8.out. This depends on the fact that there is only once instance of 8.out running;
if there were more, the output of leak −s 8.out would need editing before sending to the
% leak −s 8.out
leak −s 229 230
% leak −s 8.out | rc
src(0x0000bf1b); // 64
src(0x000016f5); // 7
src(0x0000a988); // 7
View the memory usage graphic for the window system.
% leak −b rio | rc | page
List the top allocation points in the kernel, first by count and then by total size:
% kmem | sed 10q
% kmem | sort −nr +1 | sed 10q
getcallerpc(2), setmalloctag in malloc(2)
Leak and kmem depend on the internal structure of the libc pool memory allocator (see pool(2)).
Since the ANSI/POSIX environment uses a different allocator, leak will not work on APE programs.
Leak is not speedy, and acidleak can consume more memory than the process(es) being examined.
These commands require /sys/src/libc/port/pool.acid to be present and generated
from pool.c.
lens interactive screen magnifier
Lens presents a magnified view in its window of an arbitrary area on the screen. The default mag­
nification is 4 (showing each pixel as a 4×4 pixel block in lenss window). This may be changed by
typing a digit on the keyboard (with 0 standing for 10), or by using the + and − keys to increase or
decrease the magnification by one unit. The lower limit is ×1; the upper ×16.
The interface to indicate what area to magnify is dictated by the mouse multiplexing rules of
rio(1). Start by pressing mouse button 1 in the lens window and dragging, with the button pressed,
to the center of the area to magnify. Lens will update the display as the mouse moves. Releasing
the button freezes the lens display. The magnified view is statica snapshot, not a moviebut
typing a space or . key in the lens window will refresh the display, as will changing the magnifica­
To make counting pixels easier, typing a g toggles whether a checkerboard grid is imposed on the
magnified area.
Button 3 brings up a menu of actions.
There should be an easier way to indicate what to magnify.
lex generator of lexical analysis programs
lex [ −tvn9 ] [ file ... ]
Lex generates programs to be used in simple lexical analysis of text. The input files (standard
input default) contain regular expressions to be searched for and actions written in C to be exe­
cuted when expressions are found.
A C source program, lex.yy.c is generated. This program, when run, copies unrecognized por­
tions of the input to the output, and executes the associated C action for each regular expression
that is recognized.
The options have the following meanings.
Place the result on the standard output instead of in file lex.yy.c.
Print a one-line summary of statistics of the generated analyzer.
Opposite of −v; −n is default.
Adds code to be able to compile through the native C compilers.
This program converts upper case to lower, removes blanks at the end of lines, and replaces multi­
ple blanks by single blanks.
[ ]+$
[ ]+ putchar(’ ’);
yacc(1), sed(1)
M. E. Lesk and E. Schmidt, LEXLexical Analyzer Generator, Unix Research System Programmer’s
Manual, Tenth Edition, Volume 2.
Cannot handle UTF.
The asteroid to kill this dinosaur is still in orbit.
lock run a command under lock
lock [ −w ] lockfile [ command [ argument ... ] ]
Lock runs command (default rc) with arguments while holding lockfile open and (over)writing at
least one byte each minute to keep the exclusive-access lock alive. If lockfile doesnt already have
the exclusive-access bit set in its mode, the exclusive-access bits are set in its mode and
Under −w, lock waits for exclusive access to lockfile instead of just trying once.
Lock sets /env/prompt to contain the name of the lock file.
Build a replica(1) database while preventing collisions with other occurrences.
cd /sys/lib/dist
lock scan.lock replica/scan $dist/sources.replica
intro(5), stat(5)
look find lines in a sorted list
look [ −dfnixtc ] [ string ] [ file ]
Look consults a sorted file and prints all lines that begin with string. It uses binary search.
The following options are recognized. Options dfnt affect comparisons as in sort(1).
Interactive. There is no string argument; instead look takes lines from the standard input
as strings to be looked up.
Exact. Print only lines of the file whose key matches string exactly.
Directory order: only letters, digits, tabs and blanks participate in comparisons.
Fold. Upper case letters compare equal to lower case.
Numeric comparison with initial string of digits, optional minus sign, and optional decimal
−t[c] Character c terminates the sort key in the file. By default, tab terminates the key. If c is
missing the entire line comprises the key.
If no file is specified, /lib/words is assumed, with collating sequence df.
sort(1), grep(1)
The exit status is not found if no match is found, and no dictionary if file or the
default dictionary cannot be opened.
lp printer output
lp [ option ... ] [ file ... ]
Lp is a generalized output printing service. It can be used to queue files for printing, check a
queue, or kill jobs in a queue. The options are:
−d dest Select the destination printer. If dest is ?, list the currently available printers. In the
absence of −d, the destination is taken from the environment variable LPDEST. Desti­
nation stdout is the standard output. Destination safari is /dev/lpt1data line
printer port on a 386 machine, assumed to be connected to a PostScript printer. Desti­
nations hpdeskjet and bjc240l are also /dev/lpt1data but assumed to be con­
nected to an HP Deskjet 670 or Canon BJC-240. Lp can print to any printer supported by
Ghostscript using syntax gs!device where device is a Ghostscript output device. See
gs(1) and the canonbjc240l entry in /sys/lib/lp/devices.
Kill the job(s) given as subsequent arguments, instead of file names, for the given desti­
−p proc The given processor is invoked. The default processor is generic, which tries to do
the right thing for regular text, troff(1) output, or tex(1) output. If no processing is
desired noproc may be specified.
Print the queue for the given destination. For some devices, include printer status.
Stops and restarts the printer daemon. If the printer is wedged, it is often useful to cycle
the power on the printer before running this command.
The remaining options may be used to affect the output at a given device. These options may not
be applicable to all devices.
−c n
−f font
−i n
−x v
−y v
Print n copies.
Set the font (default CW.11).
Suppress printing of header page.
Select paper input tray. n may be a number 0-9, the word man for the manual feed slot,
and/or simplex or duplex to get single or double sided output. Multiple input tray
options may be specified if they are separated by commas.
Set the number of lines per page to n.
Print pages in landscape mode (i.e. turned 90 degrees).
Set magnification to v.
Print n logical pages per physical page.
Print only pages whose page numbers appear in the comma-separated list of numbers
and ranges. A range n−m means pages n through m; a range −n means from the begin­
ning to page n; a range n− means from page n to the end.
Reverse the order of page printing.
Set the horizontal offset of the print image, measured in inches.
Set the vertical offset of the print image, measured in inches.
eqn paper | troff −ms | lp −dsafari
Typeset and print a paper containing equations.
pr −l100 file | lp −l100 −fCW.8
Print a file in a small font at 100 lines per page.
lp −dstdout /dev/windows/3/window >
Convert an image to a postscript file.
P. Glick, A Guide to the Lp Printer Spooler.
Not all options work with all output devices. Any user can kill any job.
ls, lc list contents of directory
ls [ −dlmnpqrstuFQT ] name ...
lc [ −dlmnqrstuFQT ] name ...
For each directory argument, ls lists the contents of the directory; for each file argument, ls
repeats its name and any other information requested. When no argument is given, the current
directory is listed. By default, the output is sorted alphabetically by name.
Lc is the same as ls, but sets the −p option and pipes the output through mc(1).
There are a number of options:
If argument is a directory, list it, not its contents.
List in long format, giving mode (see below), file system type (e.g., for devices, the # code
letter that names it; see intro(3)), the instance or subdevice number, owner, group, size in
bytes, and time of last modification for each file.
List the name of the user who most recently modified the file.
Dont sort the listing.
Print only the final path element of each file name.
List the qid (see stat(2)) of each file; the printed fields are in the order path, version, and
Reverse the order of sort.
Give size in Kbytes for each entry.
Sort by time modified (latest first) instead of by name.
Under −t sort by time of last access; under −l print time of last access.
Add the character / after all directory names and the character * after all executable files.
Print the character t before each file if it has the temporary flag set, and − otherwise.
By default, printed file names are quoted if they contain characters special to rc(1). The −Q
flag disables this behavior.
The mode printed under the −l option contains 11 characters, interpreted as follows: the first
character is
if the entry is a directory;
if the entry is an append-only file;
if the entry is a plain file.
The next letter is l if the file is exclusive access (one writer or reader at a time).
The last 9 characters are interpreted as three sets of three bits each. The first set refers to owner
permissions; the next to permissions to others in the same user-group; and the last to all others.
Within each set the three characters indicate permission respectively to read, to write, or to exe­
cute the file as a program. For a directory, execute permission is interpreted to mean permission
to search the directory for a specified file. The permissions are indicated as follows:
the file is readable;
the file is writable;
the file is executable;
none of the above permissions is granted.
stat(2), mc(1)
mail, mail and mailboxes
mail [ arg ... ]
Mail is a shell script that invokes nedmail(1), the mail reader, when no recipients appear on the
command line and marshal(1), the mail preparer, otherwise. All command line options are passed
through. See the man pages for those two commands for more details.
Incoming mail for a user username is put in the file /mail/box/username/mbox unless either
the file /mail/box/username/forward or /mail/box/username/pipeto exists. The
mailbox must have append-only and exclusive-access mode (see chmod(1)). A user must create
his or her own mailbox using the −c option of nedmail(1). Mailboxes are created writable
(append-only) but not readable by others.
If the file /mail/box/username/forward exists and is readable by everyone, incoming mail
will be forwarded to the addresses contained in the first line of the file. The file may contain multi­
ple addresses. Forwarding loops are caught and resolved by local delivery.
If the file /mail/box/username/pipeto exists and is readable and executable by everyone, it
will be run for each incoming message for the user. The message will be piped to it rather than
appended to his/her mail box. The file is run as user none. Its two arguments are the with argu­
ments of the destination address (e.g., local!gremlin) and the users mail box path (e.g.,
To use mail as an answering machine while you are away, run, which will create
/mail/box/$user/ as a flag for pipeto processing, and truncate
/mail/lib/pipeto.lib will invoke the machinery when it calls spool or
If /mail/box/$user/gone.msg exists, it will be sent (just once) to everyone who sends you
mail that lists your address in a To or Cc header; if not, /mail/lib/gone.msg will be sent.
Upon your return, remove /mail/box/$user/ to stop automatic responses.
mail log file
mail directories
mailbox files
forwarding address(es)
mail filter
mutual exclusion lock for multiple mbox readers
mutual exclusion lock for altering mbox
directories of icons for seemail
helper functions for pipeto files
default vacation message
auto-responder as pipeto script
flag to active gone processing
list of senders answered by
aliasmail(8), faces(1), filter(1), marshal(1), mlmgr(1), nedmail(1), qer(8), rewrite(6), send(8),
smtp(8), upasfs(4)
mailcmd mail the output of a failed command
mailcmd [ −m addr ]... command line
Mailcmd runs the command line using rc(1). If the command exits with an error status, mailcmd
mails the commands output to the named addresses (by default, the current user).
Mailcmd is typically used to run automatic scripts such as those started by cron(8).
man, lookman, sig print or find pages of this manual
man [ −bnpPStw ] [ section ... ] title ...
lookman key ...
sig function ...
Man locates and prints pages of this manual named title in the specified sections. Title is given in
lower case. Each section is a number; pages marked (2S), for example, belong to chapter 2. If no
section is specified, pages in all sections are printed. Any name from the NAME section at the top
of the page will serve as a title.
The options are:
(Default) Print the pages on the standard output using nroff.
Print the pages using nroff and send them to plumber(4) for display in the editor.
Run proof(1) on the specified man pages.
Run page(1) on the specified man pages.
Do not search the manual indices for the names. Only print pages whose file names match
the names.
Run troff(1) and send its output to standard output.
Print the names of the man page source files.
Lookman prints the names of all manual sections that contain all of the key words given on the
command line.
Sig prints the signature (i.e. C definition) of the functions given on the command line.
troff source for manual; this page is /sys/man/1/man
indices searched to find pages corresponding to titles
command to make an index for a given section
index for lookman
page(1), proof(1)
The manual was intended to be typeset; some detail is sacrificed on text terminals.
There is no automatic mechanism to keep the indices up to date.
Except for special cases, man doesnt recognize things that should be run through tbl and/or eqn.
marshal formatting and sending mail
upas/marshal [ −[aA] attachment ] [ −C copyaddr ] [ −nrx# ] [ −R reply−msg ] [ −s subject ]
[ −t mime−type ] [ mailaddr ... ]
Marshal builds a mail message from standard input and passes it, if the body is non-empty, for
transmission or delivery to /mail/box/username/pipefrom if it exists, otherwise to
/bin/upas/send. The message format is both RFC 822 and MIME conformant, so marshal
adds any required headers not already in the message, prefixed by the contents of
/mail/box/username/headers. This allows the addition of personal headers like From:
lines with a full name or a different return address. Command line options direct marshal to add a
subject line and append attachments. The arguments to marshal are the addresses of the recipi­
When running in a rio(1) window, marshal automatically puts the window into hold mode (see
rio(1)); this means that the message can be edited freely, because nothing will be sent to marshal
until the ESC key is hit to exit hold mode.
The options are:
directs marshal to append file as a mime attachment. Unless explicitly specified by
the −t option, the type of the attachment is determined by running the file(1) com­
is like −a but the message disposition is marked as inline directing any mail reader
to display the attachment (if it can) when the mail message is read.
−Ccopyaddr adds a Cc: header with copyaddr and also adds copyaddr as a recipient.
intentionally no standard input
are all passed as command line options to the send that marshal invokes.
−Rreplymsg tells marshal what message this one is in reply to. Replymsg is an upasfs(4) directory
containing the message. Marshal uses any message id in this message in its
/mail/box/username/pipefrom in the replymsg environment variable.
Thus, pipefrom can alter the message to somehow match the reply to the message
it is replying to.
adds a Subject: header line to the message if one does not already exist.
sets the content type for the attachments from all subsequent −a and −A options.
Marshal also expands any user mail aliases contained in /mail/box/username/names. The
format of the alias file is the same as that for system aliases, see aliasmail(8).
Marshal uses the login name as the reply address. This can be overriden using the environment
variable upasname. Its value will become both the envelope and From: mailbox name. For
[email protected] upas/mail [email protected]
aliasmail(8), faces(1), filter(1), mail(1), mlmgr(1), nedmail(1), qer(8), rewrite(6), send(8), smtp(8),
mc multicolumn print
mc [ − ] [ −N ] [ file ... ]
Mc splits the input into as many columns as will fit in N print positions. If run in a rio(1) or
acme(1) window, the default N is the number of blanks that will fit across the window; otherwise
the default N is 80. Under option − each input line ending in a colon : is printed separately.
rio(1), acme(1), acme(4), pr(1), lc in ls(1)
mk, membername maintain (make) related files
mk [ −f mkfile ] ... [ option ... ] [ target ... ]
membername aggregate ...
Mk uses the dependency rules specified in mkfile to control the update (usually by compilation) of
targets (usually files) from the source files upon which they depend. The mkfile (default mkfile)
contains a rule for each target that identifies the files and other targets upon which it depends and
an rc(1) script, a recipe, to update the target. The script is run if the target does not exist or if it
is older than any of the files it depends on. Mkfile may also contain meta−rules that define actions
for updating implicit targets. If no target is specified, the target of the first rule (not meta-rule) in
mkfile is updated.
The environment variable $NPROC determines how many targets may be updated simultaneously;
Plan 9 sets $NPROC automatically to the number of CPUs on the current machine.
Options are:
Assume all targets to be out of date. Thus, everything is updated.
Produce debugging output (p is for parsing, g for graph building, e for execution).
Explain why each target is made.
Force any missing intermediate targets to be made.
Do as much work as possible in the face of errors.
Print, but do not execute, the commands needed to update the targets.
Make the command line arguments sequentially rather than in parallel.
Touch (update the modified date of) file targets, without executing any recipes.
Pretend the modify time for each target is the current time; useful in conjunction with
−n to learn what updates would be triggered by modifying the targets.
The rc(1) script membername extracts member names (see Aggregates below) from its argu­
The mkfile
A mkfile consists of assignments (described under Environment) and rules. A rule contains
targets and a tail. A target is a literal string and is normally a file name. The tail contains zero or
more prerequisites and an optional recipe, which is an rc script. Each line of the recipe must
begin with white space. A rule takes the form
target: prereq1 prereq2
rc recipe using prereq1, prereq2 to build target
When the recipe is executed, the first character on every line is elided.
After the colon on the target line, a rule may specify attributes, described below.
A meta−rule has a target of the form A%B where A and B are (possibly empty) strings. A meta-rule
acts as a rule for any potential target whose name matches A%B with % replaced by an arbitrary
string, called the stem. In interpreting a meta-rule, the stem is substituted for all occurrences of %
in the prerequisite names. In the recipe of a meta-rule, the environment variable $stem contains
the string matched by the %. For example, a meta-rule to compile a C program using 2c(1) might
2c $stem.c
2l −o $stem $stem.2
Meta-rules may contain an ampersand & rather than a percent sign %. A % matches a maximal
length string of any characters; an & matches a maximal length string of any characters except
period or slash.
The text of the mkfile is processed as follows. Lines beginning with < followed by a file name are
replaced by the contents of the named file. Lines beginning with <| followed by a file name are
replaced by the output of the execution of the named file. Blank lines and comments, which run
from unquoted # characters to the following newline, are deleted. The character sequence
backslash-newline is deleted, so long lines in mkfile may be folded. Non-recipe lines are pro­
cessed by substituting for ‘{command} the output of the command when run by rc. References
to variables are replaced by the variables values. Special characters may be quoted using single
quotes ’’ as in rc(1).
Assignments and rules are distinguished by the first unquoted occurrence of : (rule) or = (assign­
A later rule may modify or override an existing rule under the following conditions:
If the targets of the rules exactly match and one rule contains only a prerequisite clause
and no recipe, the clause is added to the prerequisites of the other rule. If either or both
targets are virtual, the recipe is always executed.
If the targets of the rules match exactly and the prerequisites do not match and both rules
contain recipes, mk reports an ambiguous recipe error.
If the target and prerequisites of both rules match exactly, the second rule overrides the
Rules may make use of rc environment variables. A legal reference of the form $OBJ is
expanded as in rc(1). A reference of the form ${name:A%B=C%D}, where A, B, C, D are (possi­
bly empty) strings, has the value formed by expanding $name and substituting C for A and D for B
in each word in $name that matches pattern A%B.
Variables can be set by assignments of the form
Blanks in the value break it into words, as in rc but without the surrounding parentheses. Such
variables are exported to the environment of recipes as they are executed, unless U, the only legal
attribute attr, is present. The initial value of a variable is taken from (in increasing order of prece­
dence) the default values below, mk’s environment, the mkfiles, and any command line assign­
ment as an argument to mk. A variable assignment argument overrides the first (but not any sub­
sequent) assignment to that variable.
The variable MKFLAGS contains all the option arguments (arguments starting with − or containing
=) and MKARGS contains all the targets in the call to mk.
It is recommended that mkfiles start with
to set CC, LD, AS, O, YACC, and MK to values appropriate to the target architecture (see the exam­
ples below).
During execution, mk determines which targets must be updated, and in what order, to build the
names specified on the command line. It then runs the associated recipes.
A target is considered up to date if it has no prerequisites or if all its prerequisites are up to date
and it is newer than all its prerequisites. Once the recipe for a target has executed, the target is
considered up to date.
The date stamp used to determine if a target is up to date is computed differently for different
types of targets. If a target is virtual (the target of a rule with the V attribute), its date stamp is ini­
tially zero; when the target is updated the date stamp is set to the most recent date stamp of its
prerequisites. Otherwise, if a target does not exist as a file, its date stamp is set to the most
recent date stamp of its prerequisites, or zero if it has no prerequisites. Otherwise, the target is
the name of a file and the targets date stamp is always that files modification date. The date
stamp is computed when the target is needed in the execution of a rule; it is not a static value.
Nonexistent targets that have prerequisites and are themselves prerequisites are treated specially.
Such a target t is given the date stamp of its most recent prerequisite and if this causes all the tar­
gets which have t as a prerequisite to be up to date, t is considered up to date. Otherwise, t is
made in the normal fashion. The −i flag overrides this special treatment.
Files may be made in any order that respects the preceding restrictions.
A recipe is executed by supplying the recipe as standard input to the command
/bin/rc −e −I
(the −e is omitted if the E attribute is set). The environment is augmented by the following vari­
all the targets of this rule.
the prerequisites that caused this rule to execute.
the prerequisites that are members of an aggregate that caused this rule to execute.
When the prerequisites of a rule are members of an aggregate, $newprereq con­
tains the name of the aggregate and out of date members, while $newmember con­
tains only the name of the members.
the process slot for this recipe. It satisfies 0d$nproc<$NPROC.
the process id for the mk executing the recipe.
all the prerequisites for this rule.
if this is a meta-rule, $stem is the string that matched % or &. Otherwise, it is
empty. For regular expression meta-rules (see below), the variables stem0, ...,
stem9 are set to the corresponding subexpressions.
the targets for this rule that need to be remade.
These variables are available only during the execution of a recipe, not while evaluating the mkfile.
Unless the rule has the Q attribute, the recipe is printed prior to execution with recognizable envi­
ronment variables expanded. Commands returning nonempty status (see intro(1)) cause mk to
Recipes and backquoted rc commands in places such as assignments execute in a copy of mk’s
environment; changes they make to environment variables are not visible from mk.
Variable substitution in a rule is done when the rule is read; variable substitution in the recipe is
done when the recipe is executed. For example:
foo: $bar
$CC −o foo $bar
will compile b.c into foo, if a.c is newer than foo.
Names of the form a(b) refer to member b of the aggregate a. Currently, the only aggregates sup­
ported are ar(1) archives.
The colon separating the target from the prerequisites may be immediately followed by attributes
and another colon. The attributes are:
If the recipe exits with a non-null status, the target is deleted.
Continue execution if the recipe draws errors.
If there is no recipe, the target has its time updated.
The rule is a meta-rule that cannot be a target of a virtual rule. Only files match the pat­
tern in the target.
The characters after the P until the terminating : are taken as a program name. It will be
invoked as rc −c prog ’arg1’ ’arg2’ and should return a null exit status if and
only if arg1 is up to date with respect to arg2. Date stamps are still propagated in the nor­
mal way.
The recipe is not printed prior to execution.
The rule is a meta-rule using regular expressions. In the rule, % has no special meaning.
The target is interpreted as a regular expression as defined in regexp(6). The prerequisites
may contain references to subexpressions in form \n, as in the substitute command of
The targets are considered to have been updated even if the recipe did not do so.
The targets of this rule are marked as virtual. They are distinct from files of the same
A simple mkfile to compile a program:
prog: a.$O b.$O c.$O
$LD $LDFLAGS −o $target $prereq
%.$O: %.c
$CC $CFLAGS $stem.c
Override flag settings in the mkfile:
% mk target ’CFLAGS=−S −w’
Maintain a library:
libc.a(%.$O):N: %.$O
libc.a(abs.$O) libc.a(access.$O) libc.a(alarm.$O) ...
ar r libc.a $newmember
String expression variables to derive names from a master list:
NAMES=alloc arc bquote builtins expand main match mk var word
Regular expression meta-rules:
([^/]*)/(.*)\.$O:R: \1/\2.c
cd $stem1; $CC $CFLAGS $stem2.c
A correct way to deal with yacc(1) grammars. The file lex.c includes the file rather
than in order to reflect changes in content, not just modification time.
cmp −s || cp gram.y
$YACC −d gram.y
The above example could also use the P attribute for the rule: −s:
rc(1), regexp(6)
A. Hume, Mk: a Successor to Make.
Andrew G. Hume and Bob Flandrena, Maintaining Files on Plan 9 with Mk.
Identical recipes for regular expression meta-rules only have one target.
Seemingly appropriate input like CFLAGS=−DHZ=60 is parsed as an erroneous attribute; correct
it by inserting a space after the first =.
The recipes printed by mk before being passed to rc for execution are sometimes erroneously
expanded for printing. Dont trust whats printed; rely on what rc does.
mkdir make a directory
mkdir [ −p ] [ −m mode ] dirname ...
Mkdir creates the specified directories. It requires write permission in the parent directory.
If the −p flag is given, mkdir creates any necessary parent directories and does not complain if the
target directory already exists.
The −m flag sets the permissions to be used when creating the directory. The default is 0777.
cd in rc(1)
Mkdir returns null exit status if all directories were successfully made. Otherwise it prints a diag­
nostic and returns "error" status.
ml, mlmgr, mlowner unmoderated mailing lists
upas/mlmgr −c listname
upas/mlmgr −ar listname address
upas/ml [ −r replyto−address ] addressfile listname
upas/mlowner addressfile listname
Mlmgr creates and updates unmoderated mailing lists. The −c option creates mail directories for
both listname and listname−owner, each containing a pipeto file. Messages mailed to listname
are sent to all members of the mailing list. Any Reply−to: and Precedence: fields are
removed from the messages and new ones are added directing replies to listname and specifying
bulk precedence. The envelope address for error replies is set to /dev/null.
The mailing list membership is the file /mail/box/listname/address−list. This file is an
add/remove log. Each line represents a single address. Lines beginning with a hash (#) are com­
ments. Lines beginning with an exclamation point (!) are removals. All other lines are additions.
Addition and removal entries can be appended using the −a and −r options to mlmgr. However,
they are normally appended as a consequence of user requests.
To be added or removed from the list, a user may send a message to listname−owner containing
a key word in the header or body. The key words are:
subscribe - add my From: address to the list
remove - remove my From: address from the list
unsubscribe - remove my From: address from the list
Addition and removal events cause notification messages to be sent to the added/removed
address. In the case of addition, the message describes how to be removed.
Ml and mlowner are the programs that receive messages for listname and listname−owner
respectively. Appropriate calls to them are inserted in the pipeto files created by mlmgr.
Mls −r option sets the Reply−to: field in the mail sent out by ml.
lists mailbox directory
owners mailbox directory
log of mailing list deletions and additions
aliasmail(8), faces(1), filter(1), mail(1), marshal(1), nedmail(1), qer(8), rewrite(6), send(8),
smtp(8), upasfs(4)
mp3dec decode audio MPEG files (layers 1, 2 and 3)
mp3dec [ −o outfile ] [ file ... ]
Mp3dec decodes one or more MPEG audio files, writing 16-bit stereo linear PCM sample data to
outfile (default /dev/audio). If no files are named, mp3dec reads standard input.
In the absence of the −o option, mp3dec also opens /dev/volume and sets the sample rate for
playback to match the audio stream. When writing to outfile, mp3dec prints a warning to standard
error if the stream rate is not 44100 Hz.
mp3enc(1), juke(7), playlistfs(7)
Its another GNU behemoth, lightly tamed.
mp3enc create mp3 audio files
games/mp3enc [ −hprv ] [ −b bitrate ] [ −B bitrate ] [ −m mode ] [ −q q ] [ −s sfreq ] [ −V q ] [
long or silly options ]
Mp3enc compresses audio on standard input, normally PCM-encoded, and produces MP3-encoded
audio on standard output. By default, the MP3 file will use constant bit-rate (CBR) encoding, but
that can be changed via −−abr (average bitrate desired, ABR) or −v (variable bitrate, VBR).
set minimum allowed bitrate in Kb/s for VBR, default 32Kb/s. For CBR, set the exact bitrate
in Kb/s, which defaults to 128Kb/s.
set maximum allowed bitrate in Kb/s for VBR, default 256Kb/s.
same as −q 2.
mode may be (s)tereo, (j)oint, (f)orce or (m)ono (default j). force forces mid/side stereo on
all frames.
add CRC error protection (adds an additional 16 bits per frame to the stream). This seems
to break playback.
sets output quality to q (see −V).
input is raw pcm
set sampling frequency of input file (in KHz) to sfreq, default is 44.1.
use variable bitrate (VBR) encoding
set quality setting for VBR to q. Default q is 4; 0 produces highest-quality and largest files,
and 9 produces lowest-quality and smallest files.
Long options
−−abr bitrate
sets average bitrate desired in Kb/s, instead of setting quality, and gener­
ates ABR encoding.
−−resample sfreq set sampling frequency of output file (in KHz) to sfreq, default is input sfreq.
input is an MP3 file
Silly options
−e emp
same as −q 7. Such a deal.
mark as non-original (i.e. do not set the original bit)
mark as copyright
disable sfb=21 cutoff
de-emphasis n/5/c (default n)
allow channels to have different blocktypes
disable Xing VBR informational tag
autoconvert from stereo to mono file for mono encoding
force byte-swapping of input (see dd(1) instead)
dont print progress report, VBR histograms
only use the ATH for masking
disable VBR histogram display
experimental voice mode
Encode a .wav file as highest-quality MP3.
games/mp3enc −q 0 −b 320
Create a fixed 128Kb/s MP3 file from a .wav file.
games/mp3enc −h <foo.wav >foo.mp3
Streaming from stereo 44.1KHz raw PCM data, encoding mono at 16KHz (you may not need dd):
dd −conv swab | games/mp3enc −a −r −m m −−resample 16 −b 24
dd(1), mp3dec(1), audio(3), cdfs(4), audio(7), juke(7), playlistfs(7)
Quality is much better than encoders based on the ISO routines, but still not as good as the FhG
Its a GNU behemoth, lightly rehabilitated. There are zillions of undocumented options.
ms2html, html2ms convert between troffs ms macros and html
ms2html [ −q ] [ −b basename ] [ −d delims ] [ −t title ]
Ms2html converts the ms(6) source on standard input into HTML and prints it to standard output.
If the source contains tbl(1) or eqn input, you must first pipe the text through those preproces­
sors. Postscript images, equations, and tables will be converted to gif files. If the document has a
.TL entry, its contents will be used as the title; otherwise ms2html will look for a ._T macro,
unknown to ms(6), and take its value. Options are:
suppresses warnings about malformed input;
sets the HTML base name to basename;
sets the eqn(1) delimiters to delim;
sets the HTML title to title.
Html2ms reads HTML from standard input and converts it to ms(6) source on standard output.
htmlroff(1), ms(6)
Ms2html doesnt understand a number of troff commands. It does handle macros and defined
Html2ms doesnt understand html tables.
Msgs, mail2fs, M, Mg, mspool, mailplumb, msgs, Arch, Spam, Reply, Send, Post, Delmesg, Save file based mail reader
mail2fs [ −acDnor ] [ −d mdir ] [ mbox ]
msgs [ −aD ] [ −s runes ] [ mdir ] [ monthdir ]
M cmd [ dir ... ]
Mg [ −h ] [ regexp ]
mailplumb [ −dho ] [ mdir ]
Msgs [ −a ] [ mdir [ monthdir ] ]
Arch [ file ... ]
Spam [ file ... ]
Delmesg [ file ... ]
Save file
These programs cooperate to provide mail reading and delivering facilities by using files from a
shared file server. Msgs are stored in a convenient way to read or process them just by browsing
files, using a Plan B mail box format.
Mail box format
In Plan B, msgs for users are parsed and decoded first, and then stored in a file hierarchy where
these and other tools can be used to process them. A mailbox is a directory, usually under
/mail/box/$user/, that contains one directory per month (e.g., 200603/ for msgs pro­
cessed on March 2006). In these diretories there is one directory per message. The convention is
that (message directory) names starting with a. correspond to archived messages not to be usu­
ally shown to the user. Names starting with s. correspond to messages that seem to be spam (not
usually shown either). Names starting with d. correspond to deleted messages not yet removed
from the file system. Any other rune can be used instead of a , s or d as a convenience (the
meaning would be up to the user). But for this optional prefix, messages use a serial message
number as their directory name.
The directory for a message contains at least two files: text and raw. The text file has the
mail headers and body already processed for reading, and raw has the original mail headers with­
out any processing, including the UNIX header line (for debugging and also for obtaining message
ids when replying to msgs). As an option, raw may contain the entire original mail without pro­
cessing and not just the headers. Any attachment in the mail is kept stored in a separate file (pos­
sibly with the file name indicated in the MIME headers) ready to be used, that is, decoded. When
the attachment is a mail, the message is stored in a subdirectory following the same conventions
stated above. For msgs with attachments, the text file contains additional text indicating the rel­
ative path names (from the mails directory) that can be used to open the attachments. This is con­
venient to plumb(1) them while reading.
Because all these files have been already processed for reading, the usual file handling tools can
be used to read, edit, copy, or remove them.
The mailbox used by default is /mail/box/$user/msgs, and corresponds to the inbox.
A Plan B mail box also contains two files: seq and digest. Messages are given sequence num­
bers as added to the mail box. The file seq contains the sequence number for the last message
(or zero) and is DMEXCL to provide locking for multiple programs using the mail box. The file
digest contains digests for msgs added to the mailbox using mail2fs (and not for those added
by hand using file tools). When a message has a digest that was already seen in the past the mes­
sage is silently discarded as a dupplicate.
Programs described below are parsimonious enough in the format of the mail box so that they will
work even if messages are edited by hand, other files are created, or some of them are removed.
Virtual mail folders may be created by storing text files with mail lists that contain a mail descrip­
tion per line starting with the path for each mail. Copying the text shown for some messages in a
mail listing into another text file would save such messages into that file. The program mlist
writes to standard output a clean listing for messages with paths found in the standard input.
A file (a virtual folder) named like a per-month directory with .l or .la appended is considered a
cache of the listing for that directory. But only if the directory has not been modified after the file.
For example, a text file named 200909.l (containing a mail listing in the format shown by msgs
) will be used to list msgs on September 2009, instead of the 200909 directory and its contents.
This file will be ignored for mailbox listings if the directory is modified after the file and the cache
is, therefore, out of date. A file named behaves like before, but is known to contain
only archived msgs. It is, therefore, ignored when listing non-archived msgs. The msgs program
automatically renames .l files to la when the file lists only archived mail.
Reading mail
Mail is converted from a Plan 9 mailbox into a Plan B mailbox using mail2fs. This program may be
run using cron(8) or directly from the pipeto file described in mail(1). It uses upas/fs,
described in upasfs(4), to parse the Plan 9 mail box.
By default /mail/box/$user/mbox is the source (Plan 9) mail box. Messages found on it are
moved into (in Plan B mailbox format). The argument mbox specifies another mail source, to be
used instead of the default. Option −d changes the destination to mdir.
Messages are deleted from the Plan 9 mailbox unless flag −n is given. The Plan B mailbox is cre­
ated if it does not exist only if flag −c is given.
Flag −a makes mail2fs add new messages as archived to the Plan B mailbox. This is useful to add
messages to a mailbox for further reference, not for listing when asking the mail index for the
mailbox. For example, to archive outgoing mail in the default mail box.
Flag −o asks mail2fs to use the date from the mail to determine where to archive it, instead of
using todays. See the examples section.
Flag −r asks mail2fs to store the entire original message in the raw file, and not just message
Flag −D (accepted by mail2fs and other programs) enables debug diagnostics.
The program msgs is a convenience tool for reading mail. It generates a mail index. Flag −a gener­
ates a list for all msgs in the mailbox, archived or not. This may take some time if the mailbox is is
big enough. Flag −s can be used to include in the list msgs starting with any rune in runes, for
example, s for spam. The mailbox is the standard msgs inbox unless a different one is supplied
as an argument. As an option, both the mail box path and the name of a per-month directory can
be indicated, to ask for a list of msgs for just one month. This is useful to generate per-month
mail lists that can be used to quickly browse existing msgs without going through all msgs in the
box. See the Month script supplied as an example.
As an aid for other programs, msgs places a list of the directories for the msgs listed at
/tmp/msgs.$user, which can be useful for retrieve the paths for the msgs the user is working
Programs just described are the basic toolkit to handle msgs. Other programs described here are
a convenience for the user. Users are encouraged to customize them and/or to write their own ver­
M is a script that applies the operation indicated by cmd to one or more msgs. It applies cmd to all
msgs last listed by msgs, (as described by the paths in /tmp/msgs.$user), when no mail direc­
tories are given as arguments. Arguments selecting msgs only need to mention paths to the mail
directories, but may refer to particular files within them, as a convenience, to permit using names
from somewhere else without editing. Cmd may be any of the following:
archive the msgs as read.
archive the msgs as spam.
archive the msgs as unread.
print commands to remove the msgs.
print the text of the msgs.
list the directories for the msgs.
list the attachments for the msgs.
plumb a reply message to the editor.
The single letters a, s, i, d, p, l, m, and r can be used instead of the full cmd name (in the same
order). Note that the letter is the initial for the command, but for deletion.
Mg is not strictly necessary, but is supplied as a convenience script to call grep(1) to locate msgs
containing the expression given as an argument. Flag −h makes it search only in headers. Like the
previous program, Mg only considers msgs listed in /tmp/msgs.$user.
Mailplumb is used to send plumb(1) messages to maintain faces(1) and other programs aware of
msgs in the users Plan B mailbox, or in mdir when supplied. Flag −h makes the program notify
existing msgs as new ones. Flag −o makes mailplumb post events for the Octopus, using ports(4)
instead of plumber(4).
Reading mail in Acme
The program Msgs (see /acme/msgs) is an Acme interface for reading mail. Its arguments are
the same of msgs . Executing Msgs within Acme displays a window with the default (or indicated)
mailbox. It understands both the standard mailbox format (described above) and the virtual folder
format (a text file, see above).
The program listens to plumber events for mail and tries to maintain the mail list up to date.
To read a mail simply click button-3 on the mail file name shown in the mail list. Archiving, mark­
ing a spam, replying, and deleting messages is achieved by executing the scripts Arch, Spam,
Reply and Delmesg respectivelly. Most of them may be used either from a message window or to
process standard input (usually at the mail box directory). Some of them also accept message
paths as arguments. For example, to archive a series of msgs, select them in the mail list and exe­
cute |Arch in that window.
Msgs can be sent using Reply and Post as described later.
Save archives one or more messages, adding them to the named file.
Reading mail in O/live
In general, reading mail in olive(1) is similar to reading mail in Acme. The main difference is that
there is no need for a mail listing command. That is, there is no Msgs program.
Executing !Msgs at /mail/box/$user/msgs produces an initial list of msgs. This list can be
refreshed by executing ,<Msgs for the panel containing the mail list. To read a mail just click
(button-3) on the mail path.
To select msgs according to text shown in the mail index use the Sam command language. For
example, ,x/9fans/+−p produces a mail index for msgs comming from 9fans.
To archive a set of msgs send their index text as standard input to Arch. For example, ,>Arch
archives all msgs listed in the panel. In the same way, Spam flags msgs as spam.
As in Acme, most scripts can be used for a panel showing a single message, for standard input, or
for messages given as argument.
Sending mail
Mspool is a program that takes text files from /mail/box/$user/out reprensenting msgs to
be sent, and sends them. It only operates on files whose names are numbers. To send a mail, the
user creates a file with a randomized name like /mail/box/$user/out/Out.3452, edits it,
and renames the file to just the random number.
The file format is similar to that used by the acme(1) mail composition window. It includes one
text line per header, a blank line, and the body. Attachments are added by lines starting with
Attach: in the header. Inline attachments are added by lines starting with Include: in the
header. Replies to other msgs should contain a Replying: header containing the path to the
mail being replied to (its raw file in a Plan B mailbox).
Messages are sent using marshal(1).
The script Reply is available to send messages from either olive(1) or acme(1). Similar to Arch and
Spam, it replies to the mail shown when executed in a message window (or panel); it replies to the
mail listed in its standard input otherwise. For example, selecting a mail in the index and execut­
ing .>Reply in Olive or >Reply in Acme would reply to it.
When uncertain regarding the mail to reply to, it creates a window to edit and send a new mail.
Mail is delivered by writing the panel created by Reply and then executing either Send or Post.
The former spools the message using mspool , the latter attempts to immediatelly deliver the mes­
Users are expected to customize the scripts supplied to their needs. All of them are to be consid­
ered examples of how to use the mail system.
Move all msgs from the Plan 9 mailbox to the Plan B one, and creates the later if it does not exist.
; mail2fs −c
List msgs:
; msgs omsgs
Ralph Corderoy
Juan Manuel Se
"Raquel Martin
"Fco. J. Balle
Re: [9fans] Hi
Re: reunion
Re: [Diet] reunion
From now on, /tmp/msgs.$user contains a list of mail directories for M to work with. For
example, display them.
; M p
To: [email protected]
From: Ralph Corderoy <[email protected]>
Subject: Re: [9fans] Hi together | a few newbie questions
Sender: 9fans−[email protected]
List their directories and plumb all PDF attachments:
; M l
; plumb ‘{M l}^*.pdf
Reply to the second, mark the first as spam, and archive the others.
; M r 200712/3
; M s 200712/4/text
; M a
Prepare to use the script M (like above) but only for messages from december 2007 that contain
PDF attachments and are kept in the omsgs mailbox:
; ls /mail/box/nemo/omsgs/200712/*/*.pdf >/tmp/msgs.nemo
Use mailplumb to see in faces messages in the Plan B mailbox:
; plumber
; mailplumb
; faces −m /mail/box/$user/msgs
This is a guide for reading mail using olive(1):
# ask for mail index
# archive this mail
# mark this mail as spam
X/text/D # delete all panels showing msgs
, <Msgs
# update mail index
, >Arch
# archive all msgs listed
, x/9fans/+−p # list all 9fans messages shown
The script /sys/src/cmd/mail2fs/Month is an example of a per-month cleanup script.
Usually the directory for the last month is declared as DMTEMP and this permission is cleared
when all spam has been dealt with. The script also creates cached listings for all but the current
Add msgs from the UNIX-format oldmbox to the standard msgs folder, honoring their dates and
inserting them as archived, and produce a listing for them kept at newfolder
; mail2fs −aon oldmbox > /tmp/archived
; mlist </tmp/archived >newfolder
Create a cache for September, 2009, to be used by tools listing msgs.
; cd /mail/box/$user/msgs
; msgs −a msgs 200909 > 200909.l
Standard Plan 9 mail box.
Standard Plan B mail box.
List of msgs being processed by the user.
/sys/src/cmd/upas/mail2fs and /acme/msgs
mtime print file modification time
mtime file ...
Mtime prints the modification time (in seconds since the epoch) and name of each file.
mug - convert an image to a face icon
mug [ file ]
Mug reads a Plan 9 image(6) from file (or standard input if there is no file) and displays a working
version of the icon a gray ramp, and a larger image (the crop box), all derived from file. Selecting
Write from the button-3 menu will write the icon in face(6) format to standard output.
Imagine a 3x3 grid on the crop box. You can move an edge or corner of the box by putting the
mouse in the corresponding section of the grid and dragging. Dragging in the middle box in the
grid translates the crop box. The mouse cursor changes to tell you where you are.
The bar in the gray ramp controls the map from picture gray levels to the output levels. The val­
ues along the bar are mapped to 0 through 255 in the output. You can move the bar vertically by
grabbing the midsection or adjust the width by grabbing an endpoint.
The current icon is shown in the bottom left corner, surrounded by eight small empty boxes. You
can save the settings as they are by dragging the current icon into one of the other boxes. You
can restore the settings by dragging an icon from one of the periphery boxes into the middle.
Convert a JPEG image into a face icon.
jpg −c plus.jpg | mug >plus.1
faces(1), jpg(1), face(6), image(6)
nedmail reading mail
upas/nedmail [ −nr ] [ −f mailfile ] [ −s mailfile ]
upas/nedmail −c dir
Nedmail edits a mailbox. The default mailbox is /mail/box/username/mbox. The −f com­
mand line option specifies an alternate mailbox. Unrooted path names are interpreted relative to
/mail/box/username. If the mailfile argument is omitted, the name defaults to stored.
The options are:
−c dir
−f mailfile
−s mailfile
Create a mailbox. If dir is specified, the new mailbox is created in
/mail/box/username/dir/mbox. Otherwise, the default mailbox is cre­
Reverse: show messages in first-in, first-out order; the default is last-in, firstout.
Make the message numbers the same as the file names in the mail box direc­
tory. This implies the −r option.
Read messages from the specified file (see above) instead of the default mail­
Read a single message file mailfile, as produced by fs, and treat it as an entire
mailbox. This is provided for use in plumbing rules; see faces(1).
Nedmail starts by reading the mail box, printing out the number of messages, and then prompting
for commands from standard input. Commands, as in ed(1), are of the form [range] command
[arguments]. The command is applied to each message in the (optional) range.
The address range can be:
a single message header
a range of contiguous message headers
all messages whose headers match the regular expression.
all messages whose contents match the regular expression.
a particular message
a subpart of a particular message
the next message whose header matches expression
the next message whose contents match expression
the current message
backwards search or movement
The addresses can be:
empty or .
Since messages in MIME are hierarchical structures, in nedmail all the subparts are individually
addressable. For example if message 2 contains 3 attachments, the attachments are numbered
2.1, 2.2, and 2.3.
The commands are:
a args
A args
Reply to all addresses in the To:, From:, and Cc: header lines. Marshal is
used to format the reply and any arguments the user specifies are added to the
command line to marshal before the recipient. The possibility of making a fool
of yourself is very high with this command.
Like a but with the message appended to the reply.
Print the headers for the next ten messages.
Mark message to be deleted upon exiting nedmail.
Append the message to the file /mail/box/username/sendername where
sendername is the account name of the sender.
Print the disposition, size in characters, reception time, sender, and subject of
the message.
Print the MIME structure of the message.
m person ...
M person ...
r args
R args
s mfile
EOT (control-D)
w file
Print a summary of the commands.
Forward the message as a mime attachment to the named persons.
Like m but allow the user to type in text to be included with the forwarded mes­
Print message.An interrupt stops the printing.
Reply to the sender of the message. Marshal is used to format the reply. If and
optional Args are specified, they are added to the command line to marshal
before the recipients address.
Like r but with the original message included as an attachment.
Like r but append the message and the reply to the file
/mail/box/username/sendername where sendername is the account name
of the sender.
Like R but append the message and the reply to the file
/mail/box/username/sendername where sendername is the account name
of the sender.
Append the message to the specified mailbox. If mfile doesnt start with a /, it
is interpreted relative to the directory in which the mailbox resides. If mfile is a
directory then the destination is a file in that directry. If the MIME header speci­
fies a file name, that one is used. Otherwise, one is generated using mktemp(2)
and the string att.XXXXXXXXXXX.
Put undeleted mail back in the mailbox and stop.
Same as q.
Same as s with the mail header line(s) stripped. This can be used to save binary
mail bodies.
Remove mark for deletion.
Exit, without changing the mailbox file.
Synchronize with the mail box. Any deleted messages are purged and any new
messages read. This is equivalent to quiting nedmail and restarting.
Run the command with the message body as standard input.
Run the command with the whole message as standard input.
Escape to the shell to do command.
Print the number of the current message.
Heres an example of a mail session that looks at a summary of the mail messages, saves away an
html file added as an attachment to a message and then deletes the message:
% mail
7 messages
: ,h
H 2129
07/22 12:30 [email protected] "Add Up To 2000 free miles"
07/22 11:43 jmk
07/20 09:05 presotto
07/11 09:23 [email protected] "You don’t call, you don’t write..."
07/06 16:55 presotto
06/01 19:42 jmk
09/02 2000 howard
: 1H
[email protected]
: 1.2w /tmp/northwest.html
!saved in /tmp/northwest.html
1.2: d
1: q
!1 message deleted
Notice that the delete of message 1.2 deleted the entire message and not just the attachment.
mail directories
mailbox files
forwarding address(es)
mail filter
mutual exclusion lock for multiple mbox readers
mutual exclusion lock for altering mbox
mail(1), aliasmail(8), filter(1), marshal(1), mlmgr(1), nedmail(1), upasfs(4), smtp(8), faces(1),
netstat summarize network connections
netstat [ −in ] [ −p proto ] [ netmtpt ]
Netstat prints information about network mounted at netmtpt, default /net. For IP connections,
netstat reports the protocol, connection number, user, connection state, local port, remote port
and remote address.
The options are:
Instead of the usual listing, print one line per network interface. Each line gives the device,
MTU, local address, mask, remote address, packets in, packets out, errors in, and errors
out for this interface.
By default, netstat looks up port numbers and addresses in the network databases to print
symbolic names if possible. This option disables such translation.
Show only connections with the given protocol.
news print news items
news [ −a ] [ −n ] [ item ... ]
When invoked without options, this simple local news service prints files that have appeared in
/lib/news since last reading, most recent first, with each preceded by an appropriate header.
The time of reading is recorded. The options are
Print all items, regardless of currency. The recorded time is not changed.
Report the names of the current items without printing their contents, and without chang­
ing the recorded time.
Other arguments select particular news items.
To post a news item, create a file in /lib/news.
You may arrange to receive news automatically by registering your mail address
/sys/lib/subscribers. A daemon mails recent news to all addresses on the list.
Empty news items, and news items named core or dead.letter are ignored.
modify time is time news was last read
who gets news mailed to them
nm name list (symbol table)
nm [ −aghnsTu ] file ...
Nm prints the name list of each executable or object file in the argument list. If the file is an
archive (see ar(1)), the name list of each file in the archive is printed. If more than one file is given
in the argument list, the name of each file is printed at the beginning of each line.
Each symbol name is preceded by its hexadecimal value (blanks if undefined) and one of the let­
text segment symbol
static text segment symbol
leaf function text segment symbol
static leaf function text segment symbol
data segment symbol
static data segment symbol
bss segment symbol
static bss segment symbol
automatic (local) variable symbol
function parameter symbol
source file name
source file line offset
source file name components
The output is sorted alphabetically.
Options are:
Print all symbols; normally only user-defined text, data, and bss segment symbols are
Print only global (T, L, D, B) symbols.
Do not print file name headers with output lines.
Sort according to the address of the symbols.
Dont sort; print in symbol-table order.
Prefix each line with the symbols type signature.
Print only undefined symbols.
ar(1), 2l(1), db(1), acid(1), a.out(6)
ns display name space
ns [ −r ] [ pid ]
Ns prints a representation of the file name space of the process with the named pid, or by default
itself. The output is in the form of an rc(1) script that could, in principle, recreate the name space.
The output is produced by reading and reformatting the contents of /proc/pid/ns.
By default, ns rewrites the names of network data files to represent the network address that data
file is connected to, for example replacing /net/tcp/82/data with tcp!
The −r flag suppresses this rewriting.
ps(1), proc(3), namespace(4), namespace(6)
The names of files printed by ns will be inaccurate if a file or directory it includes has been
p paginate
p [ −number ] [ file ... ]
P copies its standard input, or the named files if given, to its standard output, stopping at the end
of every 22nd line, and between files, to wait for a newline from the user. The option sets the
number of lines on a page.
While waiting for a newline, p interprets the commands:
Pass the rest of the line to the shell as a command.
page view FAX, image, graphic, PostScript, PDF, and typesetter output files
page [ −abirPRvVw ] [ −p ppi ] [ file... ]
Page is a general purpose document viewer. It can be used to display the individual pages of a
PostScript, PDF, or tex(1) or troff(1) device independent output file. Tex or troff output is simply
converted to PostScript in order to be viewed. It can also be used to view any number of graphics
files (such as a FAX page, a Plan 9 image(6) file, an Inferno bitmap file, or other common format).
Page displays these in sequence. In the absence of named files, page reads one from standard
By default, page runs in the window in which it is started and leaves the window unchanged. The
−R option causes page to grow the window if necessary to display the page being viewed. The −w
option causes page to create a new window for itself. The newly created window will grow as
under the −R option. If being used to display multipage documents, only one file may be specified
on the command line.
The −p option sets the resolution for PostScript and PDF files, in pixels per inch. The default is
100 ppi. The −r option reverses the order in which pages are displayed.
When viewing a document, page will try to guess the true bounding box, usually rounding up from
the files bounding box to 8½×11 or A4 size. The −b option causes it to respect the bounding
box given in the file. As a more general problem, some PostScript files claim to conform to
Adobes Document Structuring Conventions but do not. The −P option enables a slightly slower
and slightly more skeptical version of the PostScript processing code. Unfortunately, there are
PostScript documents that can only be viewed with the −P option, and there are PostScript docu­
ments that can only be viewed without it.
When viewing images with page, it listens to the image plumbing channel (see plumber(4)) for
more images to display. The −i option causes page to not load any graphics files nor to read
from standard input but rather to listen for ones to load from the plumbing channel.
The −v option turns on extra debugging output, and the −V option turns on even more debugging
output. The −a option causes page to call abort(2) rather than exit cleanly on errors, to facilitate
Pressing and holding button 1 permits panning about the page.
Button 2 raises a menu of operations on the current image or the entire set. The image transfor­
mations are non-destructive and are valid only for the currently displayed image. They are lost as
soon as another image is displayed. The button 2 menu operations are:
Orig size
Restores the image to the original. All modifications are lost.
Prompts the user to sweep a rectangle on the image which is expanded proportionally
to the rectangle.
Fit window
Resizes the image so that it fits in the current window.
Rotate 90
Rotates the image 90 degrees clockwise
Upside down
Toggles whether images are displayed upside-down.
Displays the next page.
Displays the previous page.
Displays the current image in a new page window. Useful for selecting important pages
from large documents.
Reverse Reverses the order in which pages are displayed.
Writes the image to file.
Button 3 raises a menu of the pages to be selected for viewing in any order.
Typing a q or control-D exits the program. Typing a u toggles whether images are displayed
upside-down. (This is useful in the common case of mistransmitted upside-down faxes). Typing
a r reverses the order in which pages are displayed. Typing a w will write the currently viewed
page to a new file as a compressed image(6) file. When possible, the filename is of the form
basename.pagenum.bit. Typing a d removes an image from the working set.
To go to a specific page, one can type its number followed by enter. Typing left arrow, backspace,
or minus displays the previous page. Typing right arrow, space, or enter displays the next page.
The up and down arrow pan up and down one half screen height, changing pages when panning
off the top or bottom of the page.
Page calls gs(1) to draw each page of PostScript and PDF files. It also calls a variety of conversion
programs, such as those described in jpg(1), to convert the various raster graphics formats into
Inferno bitmap files. Pages are converted on the fly, as needed.
page /sys/src/cmd/gs/examples/tiger.eps
Display a color PostScript file.
page /usr/inferno/icons/*.bit
Browse the Inferno bitmap library.
man −t page | page −w
Preview this manual in a new window.
gs(1), jpg(1), tex(1), troff(1)
The mouse cursor changes to an arrow and ellipsis when page is reading or writing a file.
Page supports reading of only one document file at a time, and the user interface is clumsy when
viewing very large documents.
When viewing multipage PostScript files that do not contain %%Page comments, the button 3
menu only contains this page and next page: correctly determining page boundaries in
Postscript code is not computable in the general case.
If page has trouble viewing a Postscript file, it might not be exactly conforming: try viewing it with
the −P option.
The interface to the plumber is unsatisfactory. In particular, document references cannot be sent
via plumbing messages.
There are too many keyboard commands.
passwd, netkey change or verify user password
passwd [ username[@domain] ]
Passwd changes the invokers Plan 9 password and/or APOP secret. The Plan 9 password is used
to login to a terminal while the APOP secret is used for a number of external services: POP3, IMAP,
and VPN access. The optional argument specifies the user name and authentication domain to use
if different than the one associated with the machine passwd is run on.
The program first prompts for the old Plan 9 password in the specified domain to establish iden­
tity. It then prompts for changes to the password and the secret. New passwords and secrets
must be typed twice, to forestall mistakes. New passwords must be sufficiently hard to guess.
They may be of any length greater than seven characters.
Netkey prompts for a password to encrypt network challenges. It is a substitute for a SecureNet
These commands may be run only on a terminal, to avoid transmitting clear text passwords over
the network.
readnvram in authsrv(2), encrypt(2), cons(3), auth(8), securenet(8)
Robert Morris and Ken Thompson, UNIX Password Security, AT&T Bell Laboratories Technical
Journal Vol 63 (1984), pp. 1649-1672
Now that cpu connections are always encrypted, the only good reason to require that these com­
mands be run only on terminals is concern that the CPU server might be subverted.
patch simple patch creation and tracking system
patch/create name email files ... [ < description ]
patch/list [ name ... ]
patch/diff name
patch/apply name
patch/undo name
patch/note name [ < note ]
These scripts are a simple patch submission and tracking system used to propose additions or
changes to Plan 9. There is no guarantee that any patch will be accepted, nor that it will be
accepted verbatim. Each patch has a name (lowercase letters, numbers, dash, dot, and underscore
only) and is stored in /n/sources/patch/name.
Patch/create creates a new patch consisting of the changes to the listed files from the distribution,
reading a description of the patch from standard input: please provide an explanation of what the
change is supposed to do, some context, and a rationale for the change. Test data or pointers to
same to verify that the fix works are also welcome. When sending a patch, follow these guidelines:
" Before preparing the patch, run replica/pull and base your patch on current distribution source
" If this is a bug fix, explain the bug clearly. Dont assume the bug is obvious from the fix.
" If this is a new feature, explain it clearly. Dont assume it is obvious from the change.
" Make the new code look as much like the old code as possible: dont make gratuitous changes,
and do follow the style of the old code. See style(6) for the canonical Plan 9 coding style.
" If your patch changes externally-visible behaviour, update the manual page.
The email address, if not −, will be sent notification messages when the patch is applied, rejected,
or commented on. If rejected, the e-mail will contain a note explaining why and probably listing
suggested changes and encouraging you to resubmit.
Patch/list displays information about the named patches, or all currently pending patches if none
are specified.
Patch/diff shows a patch as diffs between the original source files and the patched source files.
Patch/apply applies the patch to the current source tree. It is intended to be run by the Plan 9
developers with pie as their root file system. If the source has changed since the patch was cre­
ated, apply will report the conflict and not change any files. Before changing any files, patch/apply
makes backup copies of the current source trees files. The backups are stored in the patch direc­
Patch/undo will copy the backups saved by patch/apply back into the source tree. It will not
restore a backup if the file being replaced is not byte-identical to the one created by patch/apply.
Propose a change to pwd, which you have modified locally:
% patch/create pwd−errors [email protected] /sys/src/cmd/pwd.c
Fix pwd to print errors to fd 2 rather than 1.
Then the developers at Bell Labs run
patch/diff pwd−errors
to inspect the change (possibly viewing /n/sources/patch/pwd−errors/pwd.c to see the
larger context). To make the change, they run
patch/apply pwd−errors
Otherwise they run
% patch/note pwd−errors
Pwd should definitely print errors to fd 1 because ...
to add a note to the /n/sources/pwd−errors/notes file.
pcc APE C compiler driver
pcc [ option ... ] [ name ... ]
Pcc compiles and loads C programs, using APE (ANSI C/POSIX) include files and libraries. Named
files ending with .c are preprocessed with cpp(1), then compiled with one of the compilers
described in 2c(1), as specified by the environment variable $objtype. The object files are then
loaded using one of the loaders described in 2l(1). The options are:
Accept C++ // comments.
−o out
Place loader output in file out instead of the default 2.out, v.out, etc.
Omit the compilation and loading phases; leave the result of preprocessing
name.c in name.i.
Like −P, but send the result to standard output.
Omit the loading phase.
Insert profiling code into the executable output.
Print compiler warning messages.
Include /$objtype/lib/ape/liblib.a as a library during the linking phase.
Dont complain about functions used without ANSI function prototypes.
Enable void* conversion warnings, as in 2c(1).
Echo the preprocessing, compiling, and loading commands before they are exe­
Define the name to the preprocessor, as if by #define. If no definition is given,
the name is defined as 1.
Undefine the name to the preprocessor, as if by #undef.
#include files whose names do not begin with / are always sought first in the
directory of the file argument, then in directories named in −I options, then in
Dont optimize compiled code.
Print an assembly language version of the object code on standard output.
Instead of compiling, print on standard output acid functions (see acid(1)) for
examining structures declared in the source files.
Like −a except that functions for structures declared in included header files are
Enable vararg type checking as described in 2c(1). This is of limited use without the
appropriate #pragma definitions.
The APE environment contains all of the include files and library routines specified in the ANSI C
standard (X3.159-1989), as well as those specified in the IEEE Portable Operating System Interface
standard (POSIX, 1003.1-1990, ISO 9945-1). In order to access the POSIX routines, source pro­
grams should define the preprocessor constant _POSIX_SOURCE.
directory for machine-independent #include files.
directory for machine-dependent #include files.
ANSI C/POSIX library.
cpp(1), 2c(1), 2a(1), 2l(1), mk(1), nm(1), acid(1), db(1), prof(1)
Howard Trickey, APE The ANSI/POSIX Environment
The locale manipulation functions are minimal. Signal functions and terminal characteristic han­
dlers are only minimally implemented. Link always fails, because Plan 9 doesnt support multiple
links to a file. The functions related to setting effective user and group ids cannot be implemented
because the concept doesnt exist in Plan 9.
pic, tpic troff and tex preprocessors for drawing pictures
pic [ files ]
tpic [ files ]
Pic is a troff(1) preprocessor for drawing figures on a typesetter. Pic code is contained between
.PS and .PE lines:
.PS optional−width optional−height
or in a file mentioned in a .PS line:
.PS <file
If optional−width is present, the picture is made that many inches wide, regardless of any dimen­
sions used internally. The height is scaled in the same proportion unless optional−height is pre­
sent. If .PF is used instead of .PE, the typesetting position after printing is restored to what it
was upon entry.
An element−list is a list of elements:
primitive attribute−list
placename : element
placename : position
var = expr
{ element−list }
[ element−list ]
for var = expr to expr by expr do { anything }
if expr then { anything } else { anything }
copy file, copy thru macro, copy file thru macro
sh { commandline }
print expr
reset optional var−list
Elements are separated by newlines or semicolons; a long element may be continued by ending the
line with a backslash. Comments are introduced by a # and terminated by a newline. Variable
names begin with a lower case letter; place names begin with upper case. Place and variable
names retain their values from one picture to the next.
After each primitive the current position moves in the current direction (up,down, left,right
(default)) by the size of the primitive. The current position and direction are saved upon entry to a
{...} block and restored upon exit. Elements within a block enclosed in [...] are treated as a
unit; the dimensions are determined by the extreme points of the contained objects. Names, vari­
ables, and direction of motion within a block are local to that block.
Troff−command is any line that begins with a period. Such a line is assumed to make sense in the
context where it appears; generally, this means only size and font changes.
The primitive objects are:
box circle ellipse
arrow is a synonym for line −>.
An attribute−list is a sequence of zero or more attributes; each attribute consists of a keyword,
perhaps followed by a value.
h(eigh)t expr
wid(th) expr
rad(ius) expr
diam(eter) expr
up opt−expr
down opt−expr
right opt−expr
left opt−expr
from position
to position
at position
with corner
by expr, expr
dotted opt−expr
dashed opt−expr
chop opt−expr
−> <− <−>
fill opt−expr
Missing attributes and values are filled in from defaults. Not all attributes make sense for all prim­
itives; irrelevant ones are silently ignored. The attribute at causes the geometrical center to be
put at the specified place; with causes the position on the object to be put at the specified place.
For lines, splines and arcs, height and width refer to arrowhead size. A bare expr implies
motion in the current direction.
Text is normally an attribute of some primitive; by default it is placed at the geometrical center of
the object. Stand-alone text is also permitted. A text list is a list of text items:
"..." positioning ...
sprintf("format", expr, ...) positioning ...
center ljust rjust above below
If there are multiple text items for some primitive, they are arranged vertically and centered except
as qualified. Positioning requests apply to each item independently. Text items may contain troff
commands for size and font changes, local motions, etc., but make sure that these are balanced so
that the entering state is restored before exiting.
A position is ultimately an x,y coordinate pair, but it may be specified in other ways.
expr, expr
place ± expr, expr
place ± ( expr, expr )
( position, position )
x from one, y the other
expr [of the way] between position and position
expr < position , position >
( position )
placename optional−corner
corner of placename
nth primitive optional−corner
corner of nth primitive
An optional−corner is one of the eight compass points or the center or the start or end of a primi­
.n .e .w .s .ne .se .nw .sw .c .start .end
top bot left right start end
Each object in a picture has an ordinal number; nth refers to this.
nth last
The built-in variables and their default values are:
boxwid 0.75
boxht 0.5
circlerad 0.25
arcrad 0.25
ellipsewid 0.75
ellipseht 0.5
linewid 0.5
lineht 0.5
movewid 0.5
moveht 0.5
textwid 0
textht 0
arrowwid 0.05
arrowht 0.1
dashwid 0.1
arrowhead 2
scale 1
These may be changed at any time, and the new values remain in force from picture to picture
until changed again or reset by a reset statement. Variables changed within [ and ] revert to
their previous value upon exit from the block. Dimensions are divided by scale during output.
Expressions in pic are evaluated in floating point. All numbers representing dimensions are taken
to be in inches.
expr op expr
− expr
! expr
( expr )
place .x place .y place .ht place .wid place .rad
sin(expr) cos(expr) atan2(expr,expr) log(expr) exp(expr)
sqrt(expr) max(expr,expr) min(expr,expr) int(expr) rand()
+ − * / % < <= > >= == != && ||
The define and undef statements are not part of the grammar.
define name { replacement text }
undef name
Occurrences of $1, $2, etc., in the replacement text will be replaced by the corresponding argu­
ments if name is invoked as
name(arg1, arg2, ...)
Non-existent arguments are replaced by null strings. Replacement text may contain newlines.
The undef statement removes the definition of a macro.
Tpic is a tex(1) preprocessor that accepts pic language. It produces Tex commands that define a
box called \graph, which contains the picture. The box may be output this way:
arrow "input" above; box "process"; arrow "output" above
A: ellipse
circle rad .1 with .w at A.e
circle rad .05 at 0.5 <A.c,>
circle rad .065 at 0.5 <A.c,>
spline from last circle.nw left .25 then left .05 down .05
arc from A.c to rad 0.5
for i = 1 to 10 do { line from A.s+.025*i,.01*i down i/50 }
grap(1), doctype(1), troff(1)
B. W. Kernighan, PICa Graphics Language
Programmer’s Manual, Tenth Edition, Volume 2
pipefile attach filter to file in name space
pipefile [ −d ] [ −r command ] [ −w command ] file
Pipefile uses bind(2) to attach a pair of pipes to file, using them to interpose filter commands
between the true file and the simulated file that subsequently appears in the name space. Option
−r interposes a filter that will affect the data delivered to programs that read from file; −w inter­
poses a filter that will affect the data written by programs to file. At least one command must be
specified; pipefile will insert a cat(1) process in the other direction.
After pipefile has been run, the filters are established for programs that subsequently open the
file; programs already using the file are unaffected.
Pipefile opens the file twice, once for each direction. If the file is a single-use device, such as
/dev/mouse, use the −d flag to specify that the file is to be opened once, in ORDWR mode.
Simulate an old terminal:
% pipefile -w tr a-z A-Z /dev/cons
% rc -i </dev/cons >/dev/cons >[2=1]
% echo hello
Really simulate an old terminal:
% pipefile -r tr A-Z a-z -w tr a-z A-Z /dev/cons
% rc -i </dev/cons >/dev/cons >[2=1]
THU OCT 12 10:13:45 EDT 2000
The I/O model of pipefile is peculiar; it doesnt work well on plain files. It is really intended for use
with continuous devices such as /dev/cons and /dev/mouse. Pipefile should be rewritten to be a
user-level file system.
If the program using the file managed by pipefile exits, the filter will see EOF and exit, and the file
will be unusable until the name space is repaired.
plot graphics filter
plot [ file ... ]
Plot interprets plotting instructions (see plot(6)) from the files or standard input, drawing the
results in a newly created rio(1) window. Plot persists until a newline is typed in the window. Vari­
ous options may be interspersed with the file arguments; they take effect at the given point in pro­
cessing. Options are:
Double buffer: accumulate the plot off-screen and write to the screen all at once
when an erase command is encountered or at end of file.
Erase the screen.
−c col
Set the foreground color (see plot(6) for color names).
−f fill
Set the background color.
−g grade
Set the quality factor for arcs. Higher grades give better quality.
−p col
Set the pen color.
Pause until a newline is typed on standard input.
Close the current plot.
Specify the bounding rectangle of plots window. By default it uses a 512×512 win­
dow in the middle of the screen.
rio(1), plot(6)
plumb send message to plumber
plumb [ −p plumbfile ] [ −a attributes ] [ −s source ] [ −d destination ] [ −t type ] [ −w directory ]
−i | data...
The plumb command formats and sends a plumbing message whose data is, by default, the con­
catenation of the argument strings separated by blanks. The options are:
write the message to plumbfile (default /mnt/plumb/send).
set the attr field of the message (default is empty).
set the src field of the message (default is plumb).
set the dst field of the message (default is empty).
set the type field of the message (default is text).
set the wdir field of the message (default is the current working directory of plumb).
take the data from standard input rather than the argument strings. If an action=
attribute is not otherwise specified, plumb will add an action=showdata attribute to
the message.
default rules file
mount point for plumber(4).
plumb(2), plumber(4), plumb(6)
pq, pqgen, pqsrv query POST database
pq [ −lf ] [ −d debug ] [ −m modules ] [ −o format ] query ...
pqgen [ directory ]
pqsrv [ modules ]
Pq connects to an Implicit Relational Database (IRDB) directory (a read-only, text-based relational
database) and outputs the record(s) that match the query arguments. The directory contacted may
be specified by a modules argument (see dispatch(7)). By default it is the corporate LUCID direc­
tory, which is a superset of the corporate POST directory.
Each query argument results in an independent query of the directory, consisting of a set of input
attributes, obtained from the query argument, and a set of output attributes, obtained from the
output format (see the −o option). The output of all the queries are formatted according to the
output format and concatenated on standard output.
Each query argument is a list of strings of the form attribute=value separated by any num­
ber of separator characters (|). It is an error if there is no corresponding attribute name. The
query argument may be the empty string; in this case, all records that contain the output
attributes are returned. The options are:
−d debug
Print information regarding internal operations. Values for debug range from 1 to 3, with 3
yielding the most detail.
Changes the default output format to a more verbose (full) one.
is similar but omits the htel attribute and consults only POST, not LUCID. This seems to
be necessary to find ex-Alcatel employees.
−m modules
Contact the directory specified by the modules string; the format is described in
dispatch(7). The default value for modules is the empty string.
−o format
Use the output format specified. See below for a full description.
Output Formatting
The format argument specified with the o option is used like a print(2) string for formatting
the output of directory queries. All characters are copied literally, except for attribute substitu­
tions and backslash escapes. Quoting may be necessary to prevent shell interpretation. The syn­
tax for attribute substitutions is this:
% flags minimum . maximum {attribute}
Only % and attribute are required. Curly braces, {}, are required only when the attribute is immedi­
ately followed by an alphanumeric. Flags may be one or more of the following:
Right justify (left justification is the default).
Capitalize the first letter of each word.
Capitalize all letters in the value.
If the value is empty, delete back to the last \< or beginning of output.
If the value is empty, skip to the next \> or end of format string.
Minimum is an integer giving the minimum field width. If the value has fewer than the minimum
number of characters, the field will be padded with blanks. The default minimum is zero.
Maximum is an integer that specifies the maximum number of characters to be output from the
value. If the value has more characters than this number, the value will be truncated. A maximum
of zero (the default) causes all characters to be output. A period is used to separate minimum and
maximum and is only required if maximum is specified.
The following table lists backslash escapes that are recognized by pq(1):
center,tab(;); c l. Escape;Meaning
\b;Backspace \c;Suppress terminating newline \f;Formfeed \n;Newline \ooo;ASCII character
defined by an octal number \r;Carriage return \t;Tab \v;Vertical tab \<;Marker for < flag
\>;Marker for > flag
Pqgen is used to create index files for an existing IRDB ev(7) directory. Once indexed, the speed
of lookups is greatly improved. However, it is then necessary to rerun pqgen after any changes are
made to the ev database. The directory is the location of the ev database. If not an absolute path­
name, it is interpreted relative to /lib/pq.
Pqsrv is the server that handles incoming PQ requests. It is meant to be run by listen(8), typically
for TCP port 411. The optional modules argument is the same as that to pq(1) above.
Find the telephone number of employee with login of liz:
pq −o %telephone ’login=liz’
List addresses of employees in New Jersey and Texas who are full-time:
pq −o ’%20name %25addr %state %zip’ ’status=FT|state=NJ|state=TX’
Consult /sys/src/cmd/pq/example for a more detailed example.
default dispatch file
typical location for pqsrv
Pq prints a diagnostic to the standard error and exits with status no records if there are no
matches. Otherwise, it returns a successful status.
pr print file
pr [ option ... ] [ file ... ]
Pr produces a printed listing of one or more files on its standard output. The output is separated
into pages headed by a date, the name of the file or a specified header, and the page number.
With no file arguments, pr prints its standard input.
Options apply to all following files but may be reset between files:
Produce n-column output.
Begin printing with page n.
Balance columns on last page, in case of multi-column output.
Double space.
Set the tab stops for input text every n spaces.
Take the next argument as a page header (file by default).
Replace sequences of blanks in the output by tabs, using tab stops set every n spaces.
Use form feeds to separate pages.
Take the length of the page to be n lines instead of the default 66.
Print all files simultaneously, each in one column.
Number the lines of each file. The numeric argument m, default 5, sets the width of the
line-number field.
Offset the left margin n character positions.
Pad each file printed to an even number of pages, if necessary. For two-sided printers, this
will ensure each file will start a new page.
Separate columns by the single character c instead of aligning them with white space. A
missing c is taken to be a tab.
Do not print the 5-line header or the 5-line trailer normally supplied for each page.
For multi-column output, take the width of the page to be n characters instead of the
default 72.
cat(1), lp(1)
prof, tprof, kprof display profiling data
prof [ −dr ] [ program ] [ profile ]
tprof pid
kprof kernel kpdata
Prof interprets files produced automatically by programs loaded using the −p option of 2l(1) or
other loader. The symbol table in the named program file (2.out etc., according to $objtype,
by default) is read and correlated with the profile file (prof.out by default). For each symbol,
the percentage of time (in seconds) spent executing between that symbol and the next is printed
(in decreasing order), together with the time spent there and the number of times that routine was
Under option −d, prof prints the dynamic call graph of the target program, annotating the calls
with the time spent in each routine and those it calls, recursively. The output is indented two
spaces for each call, and is formatted as
where symbol is the entry point of the call, time is in milliseconds, and ncall is the number of times
that entry point was called at that point in the call graph. If ncall is one, the /ncall is elided.
Normally recursive calls are compressed to keep the output brief; option −r prints the full call
The size of the buffer in program used to hold the profiling data, by default 2000 entries, may be
controlled by setting the environment variable profsize before running program. If the buffer
fills, subsequent function calls may not be recorded.
The profiling code provided by the linker initializes itself to profile the current pid, producing a file
called If a process forks, only the parent will continue to be profiled. Forked children
can cause themselves to be profile by calling
prof(fn, arg, entries, what)
which causes the function fn(arg) to be profiled. When fn returns is produced for the
current process pid.
The environment variable proftype can be set to one of user, kernel, elapsed, or
sample, to profile time measured spent in user mode, time spent in user+kernel mode, or
elapsed time, using the cycle counter, or the time in user mode using the kernels HZ clock. The
cycle counter is currently only available on modern PCs and on the PowerPC. Default profiling
measures user time, using the cycle counter if it is available.
Tprof is similar to prof, but is intended for profiling multiprocess programs. It uses the
/proc/pid/profile file to collect instruction frequency counts for the text image associated
with the process, for all processes that share that text. It must be run while the program is still
active, since the data is stored with the running program. To enable tprof profiling for a given pro­
echo profile > /proc/pid/ctl
and then, after the program has run for a while, execute
tprof pid
Since the data collected for tprof is based on interrupt-time sampling of the program counter,
tprof has no −d or −r options.
Kprof is similar to prof, but presents the data accumulated by the kernel profiling device, kprof(3).
The symbol table file, that of the operating system kernel, and the data file, typically
/dev/kpdata, must be provided. Kprof has no options and cannot present dynamic data.
2l(1), exec(2), kprof(3)
proof troff output interpreter
proof [ −mmag ] [ −/nview ] [ −F dir ] [ −d ] [ file ]
Proof reads troff(1) intermediate language from file or standard input and simulates the resulting
pages on the screen.
After a page of text is displayed, proof pauses for a command from the keyboard. The typed com­
mands are:
newline Go on to next page of text.
Go back to the previous page.
Print page n. An out-of-bounds page number means the end nearer to that number; a
missing number means the current page; a signed number means an offset to the current
Same as pn.
Clear the screen, then wait for another command.
Change the magnification at which the output is printed. Normally it is printed with mag­
nification .9; mag=.5 shrinks it to half size; mag=2 doubles the size.
Move everything val screen pixels to the right (left, if val is negative).
Move everything val screen pixels down (up, if val is negative).
Split the window into nview pieces. The current page goes into the rightmost, bottom­
most piece, and previous pages are shown in the other pieces.
−F dir
Use dir for fonts instead of /lib/font/bit.
Toggle the debug flag.
These commands are also available, under slightly different form, from a menu on button 3. The
pan menu item allows arbitrary positioning of the page: after selecting pan, press the mouse but­
ton again and hold it down while moving the page to the desired location. The page will be redis­
played in its entirety when the button is released. Mouse button 1 also pans, without the need for
selecting from a menu.
The m, x, y, F, /, and d commands are also available as command line options.
how to convert troff output fonts and character names into screen
fonts and character numbers
lp(1), gs(1), page(1)
J. F. Ossanna and B. W. Kernighan, Troff Users Manual
ps, psu process status
ps [ −apr ]
psu [ −apr ] [ user ]
Ps prints information about processes. Psu prints only information about processes started by
user (default $user).
For each process reported, the user, process id, user time, system time, size, state, and command
name are printed. State is one of the following:
Process has exited and is about to have its resources reclaimed.
on the queue of processes ready to be run.
about to be run.
waiting on a queue for a resource.
waiting for I/O or some other kernel event to wake it up.
dead of unnatural causes; lingering so that it can be examined.
waiting for another process to stop.
servicing a page fault.
waiting for something to do (kernel processes only).
being created.
paging out some other process.
performing the named system call.
no resource
waiting for more of a critical resource.
The −r flag causes ps to print, before the user time, the elapsed real time for the process.
The −p flag causes ps to print, after the system time, the baseline and current priorities of each
The −a flag causes ps to print the arguments for the process. Newlines in arguments will be trans­
lated to spaces for display.
acid(1), db(1), kill(1), ns(1), proc(3)
PS2PDF (1)
PS2PDF (1)
ps2pdf, pdf2ps convert between PostScript and PDF
ps2pdf [ gs−options ] [ input−file [ output−file ] ]
pdf2ps [ gs−options ] [ input−file [ output−file ] ]
Ps2pdf and pdf2ps convert from PostScript to PDF and back by invoking gs(1). If output−file is not
specified, they write to standard output. If neither input−file nor output−file is not specified, they
read from standard input and write to standard output.
The gs−options are passed to Ghostscript unaltered. The most useful option to ps2pdf is
−dCompatibilityLevel=level, which sets the version of PDF to be written. The default is
1.2; 1.3 and 1.4 are also possible. Similarly, the most useful option to pdf2ps is
−dLanguageLevel=level, which sets the version of PostScript to be written. The default is 2; 1
and 3 are also possible.
Ps2pdf produces output competitive with Adobe Distiller in most cases, and it accepts all the
embedded PDF-generation hints that Adobe Distiller does.
Pdf2ps produces a PostScript file containing one large bitmap per page. For a more direct and
smaller translation, use Adobe Acrobats −toPostScript command-line option.
’−dCompatibilityLevel=1.4’ should cure it.
pump copy asynchronously via a large circular buffer
pump [ −b iando ] [ −d sleepms ] [ −f ofile ] [ −i ireadsize ] [ −k KB−buf ] [ −o owritesize ] [ −s
start−KB ] [ file ... ]
Pump copies files (or standard input if none) to standard output by using two processes, one read­
ing and one writing, sharing a large circular buffer, thus permitting the reading process to get
ahead of the writing process if the output device is slow (e.g., an optical disc). This in turn can
keep the output device busy. The pipeline dd | dd can approximate this, but pipe buffering is
limited to 64K bytes, which is fairly modest.
Options are:
sets the size of read and write operations to iando bytes. The default size is 8 kilobytes.
causes the output process to sleep for sleepms milliseconds initially, giving the reading pro­
cess time to accumulate data in the buffer.
writes ofile rather than standard output
sets the size of read operations to ireadsize bytes.
allocates a circular buffer of KB−buf kilobytes rather than the default 5000 kilobytes.
sets the size of write operations to owritesize bytes.
prevents output until start−KB kilobytes have been read.
Append a venti(8) arena to a DVD or BD quickly.
venti/rdarena arena0 arena.3 |
pump −b 65536 −k 51200 >/mnt/cd/wd/arena.3
cp(1), dd(1), ecp(1), cdfs(4)
Pump processes spin while waiting for the circular buffer to fill or drain.
pwd, pbd working directory
Pwd prints the path name of the working (current) directory. Pwd is guaranteed to return the same
path that was used to enter the directory. If, however, the name space has changed, or directory
names have been changed, this path name may no longer be valid. (See fd2path(2) for a descrip­
tion of pwds mechanism.)
Pbd prints the base name of the working (current) directory. It prints no final newline and is
intended for applications such as constructing shell prompts.
cd in rc(1), bind(1), intro(2), getwd(2), fd2path(2)
ratrace trace process system calls
ratrace [ pid ] | [ −c command ]
Ratrace shows the system calls executed by a process, either the one with pid or a fresh invocation
of command.
Trace output is determined by the kernel, not ratrace. Certain fixed rules apply. The first four
fields of the output are pid, text name, system call name, and the PC of the user program. Data is
always printed as pointer/"string", where the string is the first 32 bytes of the data, with . replac­
ing non-printing ASCII characters (printing characters are those between ASCII space (SP) and
delete (DEL), exclusive). Return values follow an =, and include the integer return value, the errstr
(with "" if there is no errstr), and the start and stop times for the system call in nanoseconds. The
times are exclusive of the overhead for tracing.
acid(1), db(1), proc(3)
The printing of the data is too limited in length; printing . instead of something more sensible is
rc, cd, eval, exec, exit, flag, rfork, shift, wait, whatis, ., ~ command language
rc [ −srdiIlxepvV ] [ −c command ] [ −m initial ] [ file [ arg ... ]]
Rc is the Plan 9 shell. It executes command lines read from a terminal or a file or, with the −c
flag, from rc’s argument list.
Command Lines
A command line is a sequence of commands, separated by ampersands or semicolons (& or ;), ter­
minated by a newline. The commands are executed in sequence from left to right. Rc does not
wait for a command followed by & to finish executing before starting the following command.
Whenever a command followed by & is executed, its process id is assigned to the rc variable
$apid. Whenever a command not followed by & exits or is terminated, the rc variable $status
gets the processs wait message (see wait(2)); it will be the null string if the command was suc­
A long command line may be continued on subsequent lines by typing a backslash (\) followed by
a newline. This sequence is treated as though it were a blank. Backslash is not otherwise a special
A number-sign (#) and any following characters up to (but not including) the next newline are
ignored, except in quotation marks.
Simple Commands
A simple command is a sequence of arguments interspersed with I/O redirections. If the first
argument is the name of an rc function or of one of rc’s built-in commands, it is executed by rc.
Otherwise if the name starts with a slash (/), it must be the path name of the program to be exe­
cuted. Names containing no initial slash are searched for in a list of directory names stored in
$path. The first executable file of the given name found in a directory in $path is the program
to be executed. To be executable, the user must have execute permission (see stat(2)) and the file
must be either an executable binary for the current machines CPU type, or a shell script. Shell
scripts begin with a line containing the full path name of a shell (usually /bin/rc), prefixed by
The first word of a simple command cannot be a keyword unless it is quoted or otherwise dis­
guised. The keywords are
for in while if not switch fn ~ ! @
Arguments and Variables
A number of constructions may be used where rc’s syntax requires an argument to appear. In
many cases a constructions value will be a list of arguments rather than a single string.
The simplest kind of argument is the unquoted word: a sequence of one or more characters none
of which is a blank, tab, newline, or any of the following:
# ; & | ^ $ = ‘ ’ { } ( ) < >
An unquoted word that contains any of the characters * ? [ is a pattern for matching against file
names. The character * matches any sequence of characters, ? matches any single character, and
[class] matches any character in the class. If the first character of class is ~, the class is comple­
mented. The class may also contain pairs of characters separated by −, standing for all characters
lexically between the two. The character / must appear explicitly in a pattern, as must the first
character of the path name components . and ... A pattern is replaced by a list of arguments,
one for each path name matched, except that a pattern matching no names is not replaced by the
empty list, but rather stands for itself. Pattern matching is done after all other operations. Thus,
x=/tmp echo $x^/*.c
matches /tmp/*.c, rather than matching /*.c and then prefixing /tmp.
A quoted word is a sequence of characters surrounded by single quotes (’). A single quote is rep­
resented in a quoted word by a pair of quotes (’’).
Each of the following is an argument.
The value of a sequence of arguments enclosed in parentheses is a list comprising the
members of each element of the sequence. Argument lists have no recursive structure,
although their syntax may suggest it. The following are entirely equivalent:
echo hi there everybody
((echo) (hi there) everybody)
The argument after the $ is the name of a variable whose value is substituted. Multiple lev­
els of indirection are possible, but of questionable utility. Variable values are lists of
strings. If argument is a number n, the value is the nth element of $*, unless $* doesnt
have n elements, in which case the value is empty. If argument is followed by a parenthe­
sized list of subscripts, the value substituted is a list composed of the requested elements
(origin 1). The parenthesis must follow the variable name with no spaces. Subscripts can
also take the form m−n or m− to indicate a sequence of elements. Assignments to vari­
ables are described below.
The value is the number of elements in the named variable. A variable never assigned a
value has zero elements.
The value is a single string containing the components of the named variable separated by
spaces. A variable with zero elements yields the empty string.
rc executes the command and reads its standard output, splitting it into a list of argu­
ments, using characters in $ifs as separators. If $ifs is not otherwise set, its value is
’ \t\n’.
The command is executed asynchronously with its standard output or standard input con­
nected to a pipe. The value of the argument is the name of a file referring to the other end
of the pipe. This allows the construction of non-linear pipelines. For example, the follow­
ing runs two commands old and new and uses cmp to compare their outputs
cmp <{old} <{new}
The ^ operator concatenates its two operands. If the two operands have the same number
of components, they are concatenated pairwise. If not, then one operand must have one
component, and the other must be non-empty, and concatenation is distributive.
Free Carets
In most circumstances, rc will insert the ^ operator automatically between words that are not sepa­
rated by white space. Whenever one of $ ’ ‘ follows a quoted or unquoted word or an unquoted
word follows a quoted word with no intervening blanks or tabs, a ^ is inserted between the two. If
an unquoted word immediately follows a $ and contains a character other than an alphanumeric,
underscore, or *, a ^ is inserted before the first such character. Thus
cc −$flags $stem.c
is equivalent to
cc −^$flags $stem^.c
I/O Redirections
The sequence >file redirects the standard output file (file descriptor 1, normally the terminal) to
the named file; >>file appends standard output to the file. The standard input file (file descriptor
0, also normally the terminal) may be redirected from a file by the sequence <file, or from an
inline here document by the sequence <<eof−marker. The contents of a here document are lines
of text taken from the command input stream up to a line containing nothing but the eof−marker,
which may be either a quoted or unquoted word. If eof−marker is unquoted, variable names of the
form $word have their values substituted from rc’s environment. If $word is followed by a caret
(^), the caret is deleted. If eof−marker is quoted, no substitution occurs. The standard input file
may also be redirected from a file by the sequence <>file, which opens file exactly once, for read­
ing and writing.
Redirections may be applied to a file-descriptor other than standard input or output by qualifying
the redirection operator with a number in square brackets. For example, the diagnostic output
(file descriptor 2) may be redirected by writing cc junk.c >[2]junk.
A file descriptor may be redirected to an already open descriptor by writing >[fd0=fd1],
<>[fd0=fd1], or <[fd0=fd1]. Fd1 is a previously opened file descriptor and fd0 becomes a
new copy (in the sense of dup(2)) of it. A file descriptor may be closed by writing >[fd0=] or
Redirections are executed from left to right. Therefore, cc junk.c >/dev/null >[2=1]
and cc junk.c >[2=1] >/dev/null have different effects: the first puts standard output
in /dev/null and then puts diagnostic output in the same place, where the second directs diag­
nostic output to the terminal and sends standard output to /dev/null.
newconn <>/net/tcp/clone >[1=0] opens /net/tcp/clone exactly once for reading
and writing and puts it on standard input and output. lpd <>[3]/net/tcp/42/data opens
/net/tcp/42/data exactly once for reading and writing and puts it on file descriptor 3.
Compound Commands
A pair of commands separated by a pipe operator (|) is a command. The standard output of the
left command is sent through a pipe to the standard input of the right command. The pipe opera­
tor may be decorated to use different file descriptors. |[fd] connects the output end of the pipe
to file descriptor fd rather than 1. |[fd0=fd1] connects output to fd1 of the left command and
input to fd0 of the right command.
A pair of commands separated by && or || is a command. In either case, the left command is
executed and its exit status examined. If the operator is && the right command is executed if the
left commands status is null. || causes the right command to be executed if the left commands
status is non-null.
The exit status of a command may be inverted (non-null is changed to null, null is changed to
non-null) by preceding it with a !.
The | operator has highest precedence, and is left-associative (i.e. binds tighter to the left than
the right). ! has intermediate precedence, and && and || have the lowest precedence.
The unary @ operator, with precedence equal to !, causes its operand to be executed in a subshell.
Each of the following is a command.
if ( list ) command
A list is a sequence of commands, separated by &, ;, or newline. It is executed and if its
exit status is null, the command is executed.
if not command
The immediately preceding command must have been if(list) command. If its condition
was non-zero, the command is executed.
for(name in arguments) command
for(name) command
The command is executed once for each argument with that argument assigned to name. If
the argument list is omitted, $* is used.
while(list) command
The list is executed repeatedly until its exit status is non-null. Each time it returns null sta­
tus, the command is executed. An empty list is taken to give null status.
The list is searched for simple commands beginning with the word case. (The search is
only at the top level of the list. That is, cases in nested constructs are not found.)
Argument is matched against each word following case using the pattern-matching algo­
rithm described above, except that / and the first characters of . and .. need not be
matched explicitly. When a match is found, commands in the list are executed up to the
next following case command (at the top level) or the closing brace.
Braces serve to alter the grouping of commands implied by operator priorities. The body is
a sequence of commands separated by &, ;, or newline.
fn name{list}
fn name
The first form defines a function with the given name. Subsequently, whenever a command
whose first argument is name is encountered, the current value of the remainder of the
commands argument list will be assigned to $*, after saving its current value, and rc will
execute the list. The second form removes names function definition.
fn note{list}
fn note
A function with a special name will be called when rc receives a corresponding note; see
notify(2). The valid note names (and corresponding notes) are sighup (hangup),
sigint (interrupt), sigalrm (alarm), and sigfpe (floating point trap). By
default rc exits on receiving any signal, except when run interactively, in which case inter­
rupts and quits normally cause rc to stop whatever its doing and start reading a new com­
mand. The second form causes rc to handle a signal in the default manner. Rc recognizes
an artificial note, sigexit, which occurs when rc is about to finish executing.
name=argument command
Any command may be preceded by a sequence of assignments interspersed with redirec­
tions. The assignments remain in effect until the end of the command, unless the com­
mand is empty (i.e. the assignments stand alone), in which case they are effective until
rescinded by later assignments.
Built−in Commands
These commands are executed internally by rc, usually because their execution changes or
depends on rcs internal state.
. file ...
Execute commands from file. $* is set for the duration to the remainder of the argument
list following file. File is searched for using $path.
builtin command ...
Execute command as usual except that any function named command is ignored in favor of
the built-in meaning.
cd [dir]
Change the current directory to dir. The default argument is $home. dir is searched for in
each of the directories mentioned in $cdpath.
eval [arg ...]
The arguments are concatenated separated by spaces into a single string, read as input to
rc, and executed.
exec [command ...]
This instance of rc replaces itself with the given (non-built-in) command.
flag f [+−]
Either set (+), clear (−), or test (neither + nor −) the flag f, where f is a single character, one
of the command line flags (see Invocation, below).
exit [status]
Exit with the given exit status. If none is given, the current value of $status is used.
rfork [nNeEsfFm]
Become a new process group using rfork(flags) where flags is composed of the bitwise
OR of the rfork flags specified by the option letters (see fork(2)). If no flags are given,
they default to ens. The flags and their meanings are: n is RFNAMEG; N is RFCNAMEG; e
is RFENVG; E is RFCENVG; s is RFNOTEG; f is RFFDG; F is RFCFDG; and m is
shift [n]
Delete the first n (default 1) elements of $*.
wait [pid]
Wait for the process with the given pid to exit. If no pid is given, all outstanding processes
are waited for.
whatis name ...
Print the value of each name in a form suitable for input to rc. The output is an assignment
to any variable, the definition of any function, a call to builtin for any built-in com­
mand, or the completed pathname of any executable file.
~ subject pattern ...
The subject is matched against each pattern in sequence. If it matches any pattern,
$status is set to zero. Otherwise, $status is set to one. Patterns are the same as for
file name matching, except that / and the first character of . and .. need not be matched
explicitly. The patterns are not subjected to file name matching before the ~ command is
executed, so they need not be enclosed in quotation marks.
The environment is a list of strings made available to executing binaries by the env device (see
env(3)). Rc creates an environment entry for each variable whose value is non-empty, and for each
function. The string for a variable entry has the variables name followed by = and its value. If the
value has more than one component, these are separated by ctrl-a (’\001’) characters. The
string for a function is just the rc input that defines the function. The name of a function in the
environment is the function name preceded by fn#.
When rc starts executing it reads variable and function definitions from its environment.
Special Variables
The following variables are set or used by rc.
Set to rcs argument list during initialization. Whenever a . command or a function
is executed, the current value is saved and $* receives the new argument list. The
saved value is restored on completion of the . or function.
Whenever a process is started asynchronously with &, $apid is set to its process id.
The default directory for cd.
The input field separators used in backquote substitutions. If $ifs is not set in rcs
environment, it is initialized to blank, tab and newline.
The search path used to find commands and input files for the . command. If not
set in the environment, it is initialized by path=(. /bin). Its use is discouraged;
instead use bind(1) to build a /bin containing whats needed.
Set during initialization to rcs process id.
$prompt When rc is run interactively, the first component of $prompt is printed before read­
ing each command. The second component is printed whenever a newline is typed
and more lines are required to complete the command. If not set in the environment,
it is initialized by prompt=(’% ’ ’ ’).
$status Set to the wait message of the last-executed program. (unless started with &). !
and ~ also change $status. Its value is used to control execution in &&, ||, if
and while commands. When rc exits at end-of-file of its input or on executing an
exit command with no argument, $status is its exit status.
If rc is started with no arguments it reads commands from standard input. Otherwise its first
non-flag argument is the name of a file from which to read commands (but see −c below). Subse­
quent arguments become the initial value of $*. Rc accepts the following command-line flags.
−c string
Commands are read from string.
Print out exit status after any command where the status is non-null.
Exit if $status is non-null after executing a simple command.
If −i is present, or rc is given no arguments and its standard input is a terminal, it
runs interactively. Commands are prompted for using $prompt.
Makes sure rc is not run interactively.
If −l is given or the first character of argument zero is −, rc reads commands from
$home/lib/profile, if it exists, before reading its normal input.
Read commands to initialize rc from initial instead of from /rc/lib/rcmain.
A no-op.
A no-op.
Echo input on file descriptor 2 as it is read.
Print each simple command before executing it.
Print debugging information (internal form of commands as they are executed).
Tom Duff, Rc The Plan 9 Shell.
There should be a way to match patterns against whole lists rather than just single strings.
Using ~ to check the value of $status changes $status.
Functions containing here documents dont work.
Free carets dont get inserted next to keywords.
changes, pull, push, scan client-server replica management
replica/pull [ −nv ] [ −c name ]... [ −s name ]... name [ path ]
replica/push [ −nv ] name [ path ]
replica/changes name [ path ]
replica/scan name [ path ]
These shell scripts provide a simple log-based client-server replica management. The server
keeps a log of changes made to its file system, and clients synchronize by reading the log and
applying these changes locally.
These scripts are a polished interface to the low-level tools described in replica(8). See replica(8)
for details on the inner workings of replica management. These tools were written primarily as the
fourth edition Plan 9 distribution mechanism, but they have wider applicability. For example, they
could be used to synchronize ones home directory between a laptop and a central file server.
Replicas are described by configuration files. The name in all the replica commands is a configura­
tion file. Paths that do not begin with /, ./, or ../ are assumed to be relative to
$home/lib/replica. Configuration files are described below.
Replica/scan is the only one of these programs that does not need to be run on the client. It scans
the server file system for changes and appends entries for those changes into the server log. Typi­
cally it is run on a machine with a fast network connection to the server file system.
Replica/pull copies changes from the server to the client, while replica/push copies changes from
the client to the server. (Both run on the client.) If a list of paths is given, only changes to those
paths or their children are copied. The −v flag causes pull or push to print a summary of what it is
doing. Each status line is of the form
verb path serverpath mode uid gid mtime length
Verb describes the event: addition of a file (a), deletion of a file (d), a change to a files contents
(c), or a change to a files metadata (m). Path is the file path on the client; serverpath is the file
path on the server. Mode, uid, gid, and mtime are the files metadata as in the Dir structure (see
stat(5)). For deletion events, the metadata is that of the deleted file. For other events, the meta­
data is that after the event. The −n flag causes pull or push to print the summary but not actually
carry out the actions.
Push and pull are careful to notice simultaneous changes to a file or its metadata on both client
and server. Such simultaneous changes are called conflicts. Here, simultaneous does not mean at
the same instant but merely that both changes were carried out without knowledge of the other.
For example, if a client and server both make changes to a file without an intervening push or pull,
the next push or pull will report an update/update conflict. If a conflict is detected, both files are
left the same. The −c flag to pull specifies that conflicts for paths beginning with name should be
resolved using the clients copy, while −s specifies the servers copy. The −c and −s options may
be repeated.
Replica/changes prints a list of local changes made on the client that have not yet been pushed to
the server. It is like push with the −n flag, except that it does not check for conflicts and thus
does not require the server to be available.
The replica configuration file is an rc(1) script that must define the following functions and vari­
A function that mounts the server; run on both client and server.
A function that rescans the server for changes. Typically this command dials a CPU server
known to be close to the file server and runs replica/scan on that well-connected machine.
The path to the root of the replicated file system on the server, as it will be in the name
space after running servermount.
The path to the servers change log, after running servermount.
The path to the proto file describing the servers files, after running servermount. Only
used by scan.
The path to the servers file database, after running servermount. Only used by scan.
A function to mount the client file system; run only on the client.
The path to the root of the replicated file system on the client, after running
The path to the clients copy of the server log file. The client log is maintained by pull.
The path to the proto file describing the clients files. Only used by changes. Often just a
copy of $serverproto.
The path to the clients file database, after running clientmount.
A (potentially empty) list of paths to exclude from synchronization. A typical use of this is
to exclude the client database and log files. These paths are relative to the root of the
replicated file system.
As an example, the Plan 9 distribution replica configuration looks like:
fn servermount { 9fs sources; bind /n/sources/plan9 /n/dist }
fn serverupdate { status=’’ }
fn clientmount { 9fs kfs }
(Since the Plan 9 developers run scan manually to update the log, the clients need not do anything
to rescan the file system. Thus serverupdate simply returns successfully.)
The fourth edition Plan 9 distribution uses these tools to synchronize installations with the central
server at Bell Labs. The replica configuration files and metadata are kept in /dist/replica.
To update your system, make sure you are connected to the internet and run
replica/pull /dist/replica/network
If conflicts are reported (say you have made local changes to /rc/bin/cpurc and
/rc/bin/termrc, but only want to keep the cpurc changes), use
replica/pull −c rc/bin/cpurc −s rc/bin/termrc /dist/replica/network
to instruct pull to ignore the servers change to cpurc.
The script /usr/glenda/bin/rc/pull runs pull with the −v flag and with
/dist/replica/network inserted at the right point on the command line. Logged in as
glenda, one can repeat the above example with:
pull −c rc/bin/cpurc −s rc/bin/termrc
To see a list of changes made to the local file system since installation, run
replica/changes /dist/replica/network
(Although the script is called network, since changes is a local-only operation, the network need
not be configured.)
resample resample a picture
resample [ −x size ] [ −y size ] [ file ]
Resample resamples its input image (default standard input) to a new size. The image is deci­
mated or interpolated using a Kaiser window.
The size of the resampled image can be specified with the −x and −y options. An unadorned
value sets the number of pixels of that dimension; a suffixed percent sign specifies a percentage.
If only one of −x or −y is given, the other dimension is scaled to preserve the aspect ratio of the
original image. Thus, −x50% will reduce the image to half its original dimension in both x and y.
The input should be a Plan 9 image as described in image(6), and the output will be a compressed
24-bit r8g8b8 image. To uncompress the image or change the pixel format, use iconv (see
crop(1), image(6)
Faster algorithms exist, but this implementation produces correct pictures.
rio, label, window, wloc window system
rio [ −i ’cmd’ ] [ −k ’kbdcmd’ ] [ −s ] [ −f font ]
label name
window [ −m ] [ −r minx miny maxx maxy ] [ −dx n ] [ −dy n ] [ −minx n ] [ −miny n ] [ −maxx
n ] [ −maxy n ] [ −cd dir ] [ −hide ] [ −scroll ] [ −noscroll ] [ cmd arg ... ]
Rio manages asynchronous layers of text, or windows, on a raster display. It also serves a variety
of files for communicating with and controlling windows; these are discussed in section rio(4).
The rio command starts a new instance of the window system. Its −i option names a startup
script, which typically contains several window commands generated by wloc. The −k option
causes rio to run the command kbdcmd at startup and allow it to provide characters as keyboard
input; the keyboard program described in bitsyload(1) is the usual choice.
The −s option initializes windows so that text scrolls; the default is not to scroll. The font argu­
ment names a font used to display text, both in rios menus and as a default for any programs
running in its windows; it also establishes the environment variable $font. If −f is not given, rio
uses the imported value of $font if set; otherwise it imports the default font from the underlying
graphics server, usually the terminals operating system.
The label command changes a windows identifying name.
The window command creates a window. By default, it creates a shell window and sizes and places
it automatically. The geometry arguments control the size (dx, dy) and placement (minx, miny,
maxx, maxy); the units are pixels with the upper left corner of the screen at (0, 0). The hide
option causes the window to be created off-screen. The scroll and noscroll options set the
scroll mode. The cd option sets the working directory. The optional command and arguments
define which program to run in the window.
By default, window uses /dev/wctl (see rio(4)) to create the window and run the command.
Therefore, the window and command will be created by rio and run in a new file name space, just
as if the window had been created using the interactive menu. However, the −m option uses the
file server properties of rio to mount (see bind(1)) the new windows name space within the name
space of the program calling window. This means, for example, that running window in a CPU
window will create another window whose command runs on the terminal, where rio is running;
while window −m will create another window whose command runs on the CPU server.
The wloc command prints the coordinates and label of each window in its instance of rio and is
used to construct arguments for window.
Window control
Each window behaves as a separate terminal with at least one process associated with it. When a
window is created, a new process (usually a shell; see rc(1)) is established and bound to the win­
dow as a new process group. Initially, each window acts as a simple terminal that displays charac­
ter text; the standard input and output of its processes are attached to /dev/cons. Other spe­
cial files, accessible to the processes running in a window, may be used to make the window a
more general display. Some of these are mentioned here; the complete set is discussed in rio(4).
One window is current, and is indicated with a dark border and text; characters typed on the key­
board are available in the /dev/cons file of the process in the current window. Characters writ­
ten on /dev/cons appear asynchronously in the associated window whether or not the window
is current.
Windows are created, deleted and rearranged using the mouse. Clicking (pressing and releasing)
mouse button 1 in a non-current window makes that window current and brings it in front of any
windows that happen to be overlapping it. When the mouse cursor points to the background area
or is in a window that has not claimed the mouse for its own use, pressing mouse button 3
activates a menu of window operations provided by rio. Releasing button 3 then selects an opera­
tion. At this point, a gunsight or cross cursor indicates that an operation is pending. The button 3
menu operations are:
Create a window. Press button 3 where one corner of the new rectangle should appear
(cross cursor), and move the mouse, while holding down button 3, to the diagonally
opposite corner. Releasing button 3 creates the window, and makes it current. Very
small windows may not be created.
Change the size and location of a window. First click button 3 in the window to be
changed (gunsight cursor). Then sweep out a window as for the New operation. The
window is made current.
Move a window to another location. After pressing and holding button 3 over the win­
dow to be moved (gunsight cursor), indicate the new position by dragging the rectan­
gle to the new location. The window is made current. Windows may be moved par­
tially off-screen.
Delete a window. Click in the window to be deleted (gunsight cursor). Deleting a win­
dow causes a hangup note to be sent to all processes in the windows process group
(see notify(2)).
Hide a window. Click in the window to be hidden (gunsight cursor); it will be moved
off-screen. Each hidden window is given a menu entry in the button 3 menu according
to the value of the file /dev/label, which rio maintains (see rio(4)).
Restore a hidden window.
Windows may also be arranged by dragging their borders. Pressing button 1 or 2 over a windows
border allows one to move the corresponding edge or corner, while button 3 moves the whole win­
Text windows
Characters typed on the keyboard or written to /dev/cons collect in the window to form a long,
continuous document.
There is always some selected text, a contiguous string marked on the screen by reversing its
color. If the selected text is a null string, it is indicated by a hairline cursor between two charac­
ters. The selected text may be edited by mousing and typing. Text is selected by pointing and
clicking button 1 to make a null-string selection, or by pointing, then sweeping with button 1
pressed. Text may also be selected by double-clicking: just inside a matched delimiter-pair with
one of {[(<«‘’" on the left and }])>»‘’" on the right, it selects all text within the pair; at the
beginning or end of a line, it selects the line; within or at the edge of an alphanumeric word, it
selects the word.
Characters typed on the keyboard replace the selected text; if this text is not empty, it is placed in
a snarf buffer common to all windows but distinct from that of sam(1).
Programs access the text in the window at a single point maintained automatically by rio. The
output point is the location in the text where the next character written by a program to
/dev/cons will appear; afterwards, the output point is the null string beyond the new character.
The output point is also the location in the text of the next character that will be read (directly
from the text in the window, not from an intervening buffer) by a program from /dev/cons.
When such a read will occur is, however, under control of rio and the user.
In general there is text in the window after the output point, usually placed there by typing but
occasionally by the editing operations described below. A pending read of /dev/cons will block
until the text after the output point contains a newline, whereupon the read may acquire the text,
up to and including the newline. After the read, as described above, the output point will be at the
beginning of the next line of text. In normal circumstances, therefore, typed text is delivered to
programs a line at a time. Changes made by typing or editing before the text is read will not be
seen by the program reading it. If the program in the window does not read the terminal, for
example if it is a long-running computation, there may accumulate multiple lines of text after the
output point; changes made to all this text will be seen when the text is eventually read. This
means, for example, that one may edit out newlines in unread text to forestall the associated text
being read when the program finishes computing. This behavior is very different from most sys­
Even when there are newlines in the output text, rio will not honor reads if the window is in hold
mode, which is indicated by a white cursor and blue text and border. The ESC character toggles
hold mode. Some programs, such as mail(1), automatically turn on hold mode to simplify the edit­
ing of multi-line text; type ESC when done to allow mail to read the text.
An EOT character (control-D) behaves exactly like newline except that it is not delivered to a pro­
gram when read. Thus on an empty line an EOT serves to deliver an end-of-file indication: the
read will return zero characters. Like newlines, unread EOTs may be successfully edited out of the
text. The BS character (control-H) erases the character before the selected text. The ETB character
(control-W) erases any nonalphanumeric characters, then the alphanumeric word just before the
selected text. Alphanumeric here means non-blanks and non-punctuation. The NAK character
(control-U) erases the text after the output point, and not yet read by a program, but not more
than one line. All these characters are typed on the keyboard and hence replace the selected text;
for example, typing a BS with a word selected places the word in the snarf buffer, removes it from
the screen, and erases the character before the word.
An ACK character (control-F) or Insert character triggers file name completion for the preceding
string (see complete(2)).
Typing a left or right arrow moves the cursor one character in that direction. Typing an SOH char­
acter (control-A) moves the cursor to the beginning of the current line; an ENQ character (controlE) moves to the end.
Text may be moved vertically within the window. A scroll bar on the left of the window shows in
its clear portion what fragment of the total output text is visible on the screen, and in its gray part
what is above or below view; it measures characters, not lines. Mousing inside the scroll bar
moves text: clicking button 1 with the mouse pointing inside the scroll bar brings the line at the
top of the window to the cursors vertical location; button 3 takes the line at the cursor to the top
of the window; button 2, treating the scroll bar as a ruler, jumps to the indicated portion of the
stored text. Holding a button pressed in the scroll bar will cause the text to scroll continuously
until the button is released. Also, a page down or down-arrow scrolls forward half a window, and
page up or up-arrow scrolls back. Typing the home key scrolls to the top of the window; typing
the end key scrolls to the bottom.
The DEL character sends an interrupt note to all processes in the windows process group.
Unlike the other characters, the DEL, VIEW, and up- and down-arrow keys do not affect the
selected text. The left (right) arrow key moves the selection to one character before (after) the cur­
rent selection.
Normally, written output to a window blocks when the text reaches the end of the screen; a button
2 menu item toggles scrolling.
Other editing operations are selected from a menu on button 2. The cut operation deletes the
selected text from the screen and puts it in the snarf buffer; snarf copies the selected text to the
buffer without deleting it; paste replaces the selected text with the contents of the buffer; and
send copies the snarf buffer to just after the output point, adding a final newline if missing.
Paste will sometimes and send will always place text after the output point; the text so placed
will behave exactly as described above. Therefore when pasting text containing newlines after the
output point, it may be prudent to turn on hold mode first.
The plumb menu item sends the contents of the selection (not the snarf buffer) to the plumber(4).
If the selection is empty, it sends the white-space-delimited text containing the selection (typing
cursor). A typical use of this feature is to tell the editor to find the source of an error by plumbing
the file and line information in a compilers diagnostic.
Raw text windows
Opening or manipulating certain files served by rio suppresses some of the services supplied to
ordinary text windows. While the file /dev/mouse is open, any mouse operations are the
responsibility of another program running in the window. Thus, rio refrains from maintaining the
scroll bar, supplying text editing or menus, interpreting the VIEW key as a request to scroll, and
also turns scrolling on.
The file /dev/consctl controls interpretation of keyboard input. In particular, a raw mode may
be set: in a raw-input window, no typed keyboard characters are special, they are not echoed to
the screen, and all are passed to a program immediately upon reading, instead of being gathered
into lines.
Graphics windows
A program that holds /dev/mouse and /dev/consctl open after putting the console in raw
mode has complete control of the window: it interprets all mouse events, gets all keyboard charac­
ters, and determines what appears on the screen.
font directories
Files served by rio (also unioned in /dev in a windows name
space, before the terminals real /dev files)
Server end of rio.
Named pipe for wctl messages.
rio(4), rc(1), cpu(1), sam(1), mail(1), proof(1), graphics(2), frame(2), window(2), notify(2),
cons(3), draw(3), mouse(3), keyboard (6)
The standard input of window is redirected to the newly created window, so there is no way to pipe
the output of a program to the standard input of the new window. In some cases, plumb(1) can be
used to work around this limitation.
rm remove files
rm [ −fr ] file ...
Rm removes files or directories. A directory is removed only if it is empty. Removal of a file
requires write permission in its directory, but neither read nor write permission on the file itself.
The options are
Dont report files that cant be removed.
Recursively delete the entire contents of a directory and the directory itself.
rwd, conswdir maintain remote working directory
rwd path
conswdir [ prog ]
Rwd and conswdir conspire to keep rio(4) and acme(4) informed about the current directory on
remote systems during login sessions. Rio and acme include this information in plumb messages
sent to plumber(4). If the remote systems name space is mounted in the plumbers name space,
the end result is that file paths printed during the session are plumbable.
Rwd informs rio and acme of directory changes. The name of the remote machine is taken from
the environment variable $remotesys. Rwd writes the full path to /dev/wdir; writes the last
element of the path, suffixed by @remotesys, to /dev/label; and when run inside a win (see
acme(1)) window, changes the window title to path/−remotesys using /dev/acme/ctl.
Conswdir copies standard input to standard output, looking for in-band messages about directory
changes. The messages are of the form:
where \033 and \007 are ASCII escape and bell characters. Such messages are removed from
the stream and not printed to standard output; for each such message conswdir runs prog (default
/bin/rwd) with path as its only argument.
Add this plumbing rule (see plumb(6)) in order to run commands in the plumbers name space:
# have plumber run command
kind is text
data matches ’Local (.*)’
plumb to none
plumb start rc −c $1
Mount a Unix system in your name space and the plumbers:
% 9fs unix
% plumb ’Local 9fs unix’
(If youre using acme, execute Local 9fs unix with the middle button to mount the Unix sys­
tem in acmes name space.)
Connect to the Unix system, processing in-band directory change messages:
% ssh unix | aux/conswdir
Add this shell function to your .profile on the Unix system to generate directory change mes­
sages every time a cd command is executed:
H=‘hostname | sed ’s/\..*//’‘
_cd () {
\cd $* &&
case $− in
echo /n/$H$_dir | awk ’{printf("\033];%s\007", $1);}’
alias cd=_cd
The examples described so far only help for relative path names. Add this plumbing rule to handle
rooted names like /usr/include/stdio.h:
# remote rooted path names
type is text
wdir matches ’/n/unix(/.*)?’
data matches ’/([.a−zA−Z¡− 0−9_/\−]*[a−zA−Z¡− 0−9_/\−])(’$addr’)?’
arg isfile /n/unix/$1
data set $file
attr add addr=$3
plumb to edit
plumb client window $editor
plumber(4), plumb(6), srv(4)
This mechanism is clunky, but Unix and SSH make it hard to build a better one.
The escape sequence was chosen because it changes the title on xterm windows.
sam, B,, samterm screen editor with structural regular expressions
sam [ option ... ] [ files ]
sam −r machine
B [ −nnnn ] file ...
Sam is a multi-file editor. It modifies a local copy of an external file. The copy is here called a
file. The files are listed in a menu available through mouse button 3 or the n command. Each file
has an associated name, usually the name of the external file from which it was read, and a modi­
fied bit that indicates whether the editors file agrees with the external file. The external file is
not read into the editors file until it first becomes the current filethat to which editing com­
mands applywhereupon its menu entry is printed. The options are
−r machine
−s path
−t path
Autoindent. In this mode, when a newline character is typed in the terminal inter­
face, samterm copies leading white space on the current line to the new line.
Do not download the terminal part of sam. Editing will be done with the com­
mand language only, as in ed(1).
Run the host part remotely on the specified machine, the terminal part locally.
Start the host part from the specified file on the remote host. Only meaningful
with the −r option.
Start the terminal part from the specified file. Useful for debugging.
Regular expressions
Regular expressions are as in regexp(6) with the addition of \n to represent newlines. A regular
expression may never contain a literal newline character. The empty regular expression stands for
the last complete expression encountered. A regular expression in sam matches the longest left­
most substring formally matched by the expression. Searching in the reverse direction is equiva­
lent to searching backwards with the catenation operations reversed in the expression.
An address identifies a substring in a file. In the following, character n means the null string
after the n-th character in the file, with 1 the first character in the file. Line n means the n-th
match, starting at the beginning of the file, of the regular expression .*\n?. All files always have
a current substring, called dot, that is the default address.
Simple Addresses
The empty string after character n; #0 is the beginning of the file.
Line n; 0 is the beginning of the file.
The substring that matches the regular expression, found by looking toward the end (/) or
beginning (?) of the file, and if necessary continuing the search from the other end to the
starting point of the search. The matched substring may straddle the starting point. When
entering a pattern containing a literal question mark for a backward search, the question
mark should be specified as a member of a class.
The string before the first full line. This is not necessarily the null string; see + and −
The null string at the end of the file.
The mark in the file (see the k command below).
Preceding a simple address (default .), refers to the address evaluated in the unique file
whose menu line matches the regular expression.
Compound Addresses
In the following, a1 and a2 are addresses.
The address a2 evaluated starting at the end of a1.
The address a2 evaluated looking in the reverse direction starting at the beginning of
The substring from the beginning of a1 to the end of a2. If a1 is missing, 0 is substi­
tuted. If a2 is missing, $ is substituted.
Like a1,a2, but with a2 evaluated at the end of, and dot set to, a1.
The operators + and − are high precedence, while , and ; are low precedence.
In both + and − forms, if a2 is a line or character address with a missing number, the number
defaults to 1. If a1 is missing, . is substituted. If both a1 and a2 are present and distinguishable,
+ may be elided. a2 may be a regular expression; if it is delimited by ?s, the effect of the + or −
is reversed.
It is an error for a compound address to represent a malformed substring. Some useful idioms:
a1+− (a1−+) selects the line containing the end (beginning) of a1. 0/regexp/ locates the first
match of the expression in the file. (The form 0;// sets dot unnecessarily.) ./regexp/// finds
the second following occurrence of the expression, and .,/regexp/ extends dot.
In the following, text demarcated by slashes represents text delimited by any printable character
except alphanumerics. Any number of trailing delimiters may be elided, with multiple elisions then
representing null strings, but the first delimiter must always be present. In any delimited text,
newline may not appear literally; \n may be typed for newline; and \/ quotes the delimiter, here
/. Backslash is otherwise interpreted literally, except in s commands.
Most commands may be prefixed by an address to indicate their range of operation. Those that
may not are marked with a * below. If a command takes an address and none is supplied, dot is
used. The sole exception is the w command, which defaults to 0,$. In the description, range is
used to represent whatever address is supplied. Many commands set the value of dot as a side
effect. If so, it is always set to the result of the change: the empty string for a deletion, the new
text for an insertion, etc. (but see the s and e commands).
Text commands
lines of text
Insert the text into the file after the range. Set dot.
Same as a, but c replaces the text, while i inserts before the range.
Delete the text in the range. Set dot.
Substitute text for the first match to the regular expression in the range. Set dot to the
modified range. In text the character & stands for the string that matched the expression.
Backslash behaves as usual unless followed by a digit: \d stands for the string that
matched the subexpression begun by the d-th left parenthesis. If s is followed immedi­
ately by a number n, as in s2/x/y/, the n-th match in the range is substituted. If the
command is followed by a g, as in s/x/y/g, all matches in the range are substituted.
m a1
t a1
Move (m) or copy (t) the range to after a1. Set dot.
Display commands
Print the text in the range. Set dot.
Print the line address and character address of the range.
Print just the character address of the range.
File commands
* b file−list
Set the current file to the first file named in the list that sam also has in its menu. The list
may be expressed <Plan 9 command in which case the file names are taken as words (in
the shell sense) generated by the Plan 9 command.
* B file−list
Same as b, except that file names not in the menu are entered there, and all file names in
the list are examined.
Print a menu of files. The format is:
’ or blank indicating the file is modified or clean,
− or +
indicating the file is unread or has been read (in the terminal, * means more
than one window is open),
. or blank indicating the current file,
a blank,
and the file name.
* D file−list
Delete the named files from the menu. If no files are named, the current file is deleted. It
is an error to D a modified file, but a subsequent D will delete such a file.
I/O Commands
* e filename
Replace the file by the contents of the named external file. Set dot to the beginning of the
r filename
Replace the text in the range by the contents of the named external file. Set dot.
w filename
Write the range (default 0,$) to the named external file.
* f filename
Set the file name and print the resulting menu entry.
If the file name is absent from any of these, the current file name is used. e always sets the file
name; r and w do so if the file has no name.
< Plan 9−command
Replace the range by the standard output of the Plan 9 command.
> Plan 9−command
Send the range to the standard input of the Plan 9 command.
| Plan 9−command
Send the range to the standard input, and replace it by the standard output, of the Plan 9
* ! Plan 9−command
Run the Plan 9 command.
* cd directory
Change working directory. If no directory is specified, $home is used.
In any of <, >, | or !, if the Plan 9 command is omitted the last Plan 9 command (of any type) is
substituted. If sam is downloaded (using the mouse and raster display, i.e. not using option −d),
! sets standard input to /dev/null, and otherwise unassigned output (stdout for ! and >,
stderr for all) is placed in /tmp/sam.err and the first few lines are printed.
Loops and Conditionals
x/regexp/ command
For each match of the regular expression in the range, run the command with dot set to the
match. Set dot to the last match. If the regular expression and its slashes are omitted,
/.*\n/ is assumed. Null string matches potentially occur before every character of the
range and at the end of the range.
y/regexp/ command
Like x, but run the command for each substring that lies before, between, or after the
matches that would be generated by x. There is no default regular expression. Null sub­
strings potentially occur before every character in the range.
* X/regexp/ command
For each file whose menu entry matches the regular expression, make that the current file
and run the command. If the expression is omitted, the command is run in every file.
* Y/regexp/ command
Same as X, but for files that do not match the regular expression, and the expression is
g/regexp/ command
v/regexp/ command
If the range contains (g) or does not contain (v) a match for the expression, set dot to the
range and run the command.
These may be nested arbitrarily deeply, but only one instance of either X or Y may appear in a
single command. An empty command in an x or y defaults to p; an empty command in X or Y
defaults to f. g and v do not have defaults.
Set the current files mark to the range. Does not set dot.
Quit. It is an error to quit with modified files, but a second q will succeed.
Undo the last n (default 1) top-level commands that changed the contents or name of
the current file, and any other file whose most recent change was simultaneous with
the current files change. Successive us move further back in time. The only com­
mands for which u is ineffective are cd, u, q, w and D. If n is negative, u redoes,
undoing the undo, going forwards in time again.
If the range is explicit, set dot to the range. If sam is downloaded, the resulting dot
is selected on the screen; otherwise it is printed. If no address is specified (the com­
mand is a newline) dot is extended in either direction to line boundaries and printed.
If dot is thereby unchanged, it is set to .+1 and printed.
Grouping and multiple changes
Commands may be grouped by enclosing them in braces {}. Commands within the braces must
appear on separate lines (no backslashes are required between commands). Semantically, an
opening brace is like a command: it takes an (optional) address and sets dot for each subcommand. Commands within the braces are executed sequentially, but changes made by one
command are not visible to other commands (see the next paragraph). Braces may be nested arbi­
When a command makes a number of changes to a file, as in x/re/c/text/, the addresses of
all changes to the file are computed in the original file. If the changes are in sequence, they are
applied to the file. Successive insertions at the same address are catenated into a single insertion
composed of the several insertions in the order applied.
The terminal
What follows refers to behavior of sam when downloaded, that is, when operating as a display edi­
tor on a raster display. This is the default behavior; invoking sam with the −d (no download)
option provides access to the command language only.
Each file may have zero or more windows open. Each window is equivalent and is updated simulta­
neously with changes in other windows on the same file. Each window has an independent value
of dot, indicated by a highlighted substring on the display. Dot may be in a region not within the
window. There is usually a current window, marked with a dark border, to which typed text and
editing commands apply. Text may be typed and edited as in rio(1); also the escape key (ESC)
selects (sets dot to) text typed since the last mouse button hit.
The button 3 menu controls window operations. The top of the menu provides the following oper­
ators, each of which uses one or more rio-like cursors to prompt for selection of a window or
sweeping of a rectangle. Sweeping a null rectangle gets a large window, disjoint from the com­
mand window or the whole screen, depending on where the null rectangle is.
Create a new, empty file.
Create a copy of an existing window.
As in rio.
Delete the window. In the last window of a file, close is equivalent to a D for the file.
Equivalent to a w for the file.
Below these operators is a list of available files, starting with ~~sam~~, the command window.
Selecting a file from the list makes the most recently used window on that file current, unless it is
already current, in which case selections cycle through the open windows. If no windows are open
on the file, the user is prompted to open one. Files other than ~~sam~~ are marked with one of
the characters −+* according as zero, one, or more windows are open on the file. A further mark
. appears on the file in the current window and a single quote, ’, on a file modified since last
The command window, created automatically when sam starts, is an ordinary window except that
text typed to it is interpreted as commands for the editor rather than passive text, and text printed
by editor commands appears in it. The behavior is like rio, with an output point that separates
commands being typed from previous output. Commands typed in the command window apply to
the current open filethe file in the most recently current window.
Manipulating text
Button 1 changes selection, much like rio. Pointing to a non-current window with button 1 makes
it current; within the current window, button 1 selects text, thus setting dot. Double-clicking
selects text to the boundaries of words, lines, quoted strings or bracketed strings, depending on
the text at the click.
Button 2 provides a menu of editing commands:
Delete dot and save the deleted text in the snarf buffer.
Replace the text in dot by the contents of the snarf buffer.
Save the text in dot in the snarf buffer.
Send the text in the selection as a plumb message. If the selection is empty, the
white-space-delimited block of text is sent as a plumb message with a click
attribute defining where the selection lies (see plumb(6)).
Search forward for the next occurrence of the literal text in dot. If dot is the null
string, the text in the snarf buffer is used. The snarf buffer is unaffected.
Exchange snarf buffers with rio.
Search forward for the next match of the last regular expression typed in a command.
(Not in command window.)
Send the text in dot, or the snarf buffer if dot is the null string, as if it were typed to
the command window. Saves the sent text in the snarf buffer. (Command window
External communication
Sam listens to the edit plumb port. If plumbing is not active, on invocation sam creates a named
pipe /srv/sam.user which acts as an additional source of commands. Characters written to the
named pipe are treated as if they had been typed in the command window.
B is a shell-level command that causes an instance of sam running on the same terminal to load
the named files. B uses either plumbing or the named pipe, whichever service is available. If
plumbing is not enabled, the option allows a line number to be specified for the initial position to
display in the last named file (plumbing provides a more general mechanism for this ability).
Abnormal termination
If sam terminates other than by a q command (by hangup, deleting its window, etc.), modified files
are saved in an executable file, $home/ This program, when executed, asks whether
to write each file back to a external file. The answer y causes writing; anything else skips the file.
the program called to unpack $home/
source for sam itself
source for the separate terminal part
ed(1), sed(1), grep(1), rio(1), regexp(6).
Rob Pike, The text editor sam.
aescbc, ipso, secstore secstore commands
auth/secstore [ −cinv ] [ −(g|G) getfile ] [ −p putfile ] [ −r rmfile ] [ −s server ] [ −u user
auth/aescbc -e [ -in ] <cleartext >ciphertext
auth/aescbc -d [ -in ] <ciphertext >cleartext
ipso [ −a −e −l −f −s ] [ file ... ]
Secstore authenticates to a secure-store server using a password and optionally a hardware token,
then saves or retrieves a file. This is intended to be a credentials store (public/private keypairs,
passwords, and other secrets) for a factotum.
Option −c prompts for a password change.
Option −g retrieves a file to the local directory; option −G writes it to standard output instead.
Specifying getfile of . will send to standard output a list of remote files with dates, lengths and
SHA1 hashes.
Option −i says that the password should be read from standard input instead of from
Option −n says that the password should be read from NVRAM (see authsrv(2)) instead of from
Option −p stores a file on the secstore.
Option −r removes a file from the secstore.
The server is tcp!$auth!secstore, or the server specified by option −s.
Option −u access the secure-store files belonging to user.
Option −v produces more verbose output, in particular providing a few bits of feedback to help
the user detect mistyping.
For example, to add a secret to the file read by factotum(4) at startup, open a new window, type
% ramfs −p; cd /tmp
% auth/secstore −g factotum
secstore password:
% echo ’key proto=apop user=ehg !password=hi’ >> factotum
% auth/secstore −p factotum
secstore password:
% read −m factotum > /mnt/factotum/ctl
and delete the window. The first line creates an ephemeral memory-resident workspace, invisible
to others and automatically removed when the window is deleted. The next three commands fetch
the persistent copy of the secrets, append a new secret, and save the updated file back to secstore.
The final command loads the new secret into the running factotum.
The ipso command packages this sequence into a convenient script to simplify editing of files
stored on a secure store. It copies the named files into a local ramfs(4) and invokes acme(1) on
them. When the editor exits, ipso prompts the user to confirm copying modifed or newly created
files back to secstore. If no file is mentioned, ipso grabs all the users files from secstore for edit­
By default, ipso will edit the secstore files and, if one of them is named factotum, flush current
keys from factotum and load the new ones from the file. If the −e, −f, or −l options are given,
ipso will just perform only the requested operations, i.e., edit, flush, and/or load.
The −s option of ipso invokes sam(1) as the editor insted of acme; the −a option provides a simi­
lar service for files encrypted by aescbc (q.v.). With the −a option, the full rooted pathname of the
file must be specified and all files must be encrypted with the same key. Also with −a, newly cre­
ated files are ignored.
Aescbc encrypts (under −e) and decrypts (under −d) using AES (Rijndael) in cipher block chaining
(CBC) mode. Options i and n are as per secstore, except that i reads from file descriptor 3.
factotum(4), secstore(8)
There is deliberately no backup of files on the secstore, so −r (or a disk crash) is irrevocable. You
are advised to store important secrets in a second location.
When using ipso, secrets will appear as plain text in the editor window, so use the command in pri­
sed stream editor
sed [ −n ] [ −g ] [ −e script ] [ −f sfile ] [ file ... ]
Sed copies the named files (standard input default) to the standard output, edited according to a
script of commands. The −f option causes the script to be taken from file sfile; these options
accumulate. If there is just one −e option and no −fs, the option −e may be omitted. The −n
option suppresses the default output; −g causes all substitutions to be global, as if suffixed g.
A script consists of editing commands, one per line, of the following form:
[address [, address] ] function [argument ...] [;]
In normal operation sed cyclically copies a line of input into a pattern space (unless there is some­
thing left after a D command), applies in sequence all commands whose addresses select that pat­
tern space, and at the end of the script copies the pattern space to the standard output (except
under −n) and deletes the pattern space.
An address is either a decimal number that counts input lines cumulatively across files, a $ that
addresses the last line of input, or a context address, /regular−expression /, in the style of
regexp(6), with the added convention that \n matches a newline embedded in the pattern space.
A command line with no addresses selects every pattern space.
A command line with one address selects each pattern space that matches the address.
A command line with two addresses selects the inclusive range from the first pattern space that
matches the first address through the next pattern space that matches the second. (If the second
address is a number less than or equal to the line number first selected, only one line is selected.)
Thereafter the process is repeated, looking again for the first address.
Editing commands can be applied to non-selected pattern spaces by use of the negation function
! (below).
An argument denoted text consists of one or more lines, all but the last of which end with \ to
hide the newline. Backslashes in text are treated like backslashes in the replacement string of an s
command, and may be used to protect initial blanks and tabs against the stripping that is done on
every script line.
An argument denoted rfile or wfile must terminate the command line and must be preceded by
exactly one blank. Each wfile is created before processing begins. There can be at most 120 dis­
tinct wfile arguments.
b label
Append. Place text on the output before reading the next input line.
Branch to the : command bearing the label. If label is empty, branch to the end of
the script.
Change. Delete the pattern space. With 0 or 1 address or at the end of a 2address range, place text on the output. Start the next cycle.
Delete the pattern space. Start the next cycle.
Delete the initial segment of the pattern space through the first newline. Start the
next cycle.
Replace the contents of the pattern space by the contents of the hold space.
Append the contents of the hold space to the pattern space.
Replace the contents of the hold space by the contents of the pattern space.
Append the contents of the pattern space to the hold space.
Insert. Place text on the standard output.
Copy the pattern space to the standard output. Replace the pattern space with the
next line of input.
Append the next line of input to the pattern space with an embedded newline.
(The current line number changes.)
Print. Copy the pattern space to the standard output.
Copy the initial segment of the pattern space through the first newline to the stan­
dard output.
Quit. Branch to the end of the script. Do not start a new cycle.
r rfile
Read the contents of rfile. Place them on the output before reading the next input
Substitute the replacement string for instances of the regular−expression in the
pattern space. Any character may be used instead of /. For a fuller description
see regexp(6). Flags is zero or more of
Global. Substitute for all non-overlapping instances of the regular
expression rather than just the first one.
Print the pattern space if a replacement was made.
w wfile
Write. Append the pattern space to wfile if a replacement was made.
t label
Test. Branch to the : command bearing the label if any substitutions have been
made since the most recent reading of an input line or execution of a t. If label is
empty, branch to the end of the script.
Write. Append the pattern space to wfile.
Exchange the contents of the pattern and hold spaces.
Transform. Replace all occurrences of characters in string1 with the corresponding
character in string2. The lengths of string1 and string2 must be equal.
Dont. Apply the function (or group, if function is {) only to lines not selected by
the address(es).
Comment. Ignore the rest of the line.
: label
This command does nothing; it bears a label for b and t commands to branch to.
Place the current line number on the standard output as a line.
Execute the following commands through a matching } only when the pattern
space is selected.
An empty command is ignored.
sed 10q file
Print the first 10 lines of the file.
sed ’/^$/d’
Delete empty lines from standard input.
sed ’s/UNIX/& system/g’
Replace every instance of UNIX by UNIX system.
sed ’s/ *$//
drop trailing blanks
drop empty lines
s/ */\
replace blanks by newlines
/^$/d’ chapter*
Print the files chapter1, chapter2, etc. one word to a line.
nroff −ms manuscript | sed ’
if last line of file is empty, print it
if current line is empty, append next line
if two lines are empty, delete the first
Delete all but one of each group of empty lines from a formatted manuscript.
ed(1), grep(1), awk(1), lex(1), sam(1), regexp(6)
L. E. McMahon, SED A Non-interactive Text Editor, Unix Research System Programmers Man­
ual, Volume 2.
If input is from a pipe, buffering may consume characters beyond a line on which a q command is
seq print sequences of numbers
seq [ −w ] [ −fformat ] [ first [ incr ] ] last
Seq prints a sequence of numbers, one per line, from first (default 1) to as near last as possible, in
increments of incr (default 1). The loop is:
for(val = min; val <= max; val += incr) print val;
The numbers are interpreted as floating point.
Normally integer values are printed as decimal integers. The options are
Use the print(2)-style format print for printing each (floating point) number. The
default is %g.
Equalize the widths of all numbers by padding with leading zeros as necessary. Not
effective with option −f, nor with numbers in exponential notation.
seq 0 .05 .1
Print 0 0.05 0.1 (on separate lines).
seq −w 0 .05 .1
Print 0.00 0.05 0.10.
Option −w always surveys every value in advance. Thus seq −w 1000000000 is a painful way
to get an infinite sequence.
size print size of executable files
size [ file ... ]
Size prints the size of the segments for each of the argument executable files (default v.out).
The format is
textsizet + datasized + bsssizeb = total
where the numbers are in bytes.
sleep suspend execution for an interval
sleep time
Sleep suspends execution for time seconds. Time may be floating-point.
Execute a command 100 seconds hence.
{sleep 100; command}&
Repeat a command every 30 seconds.
while (){
sleep 30
soelim preprocess so inclusion commands in troff input
soelim [ files ... ]
Soelim reads the specified files or the standard input and performs the textual inclusion implied by
troff(1) directives of the form
.so some_file
when they appear at the beginning of input lines. This is useful when using programs such as
tbl(1) that do not normally do this, allowing placement of individual tables or other text objects in
separate files to be run as a part of a large document.
Note that inclusion can be suppressed by using ’ instead of . at the start of the line as in:
’so /usr/share/lib/tmac/tmac.s
The shell script was written by Sape Mullender.
sort sort and/or merge files
sort [ −cmuMbdfinrwtx ] [ +pos1 [ −pos2 ] ... ] ... [ −k pos1 [ ,pos2 ] ] ...
[ −o output ] [ −T dir ... ] [ option ... ] [ file ... ]
Sort sorts lines of all the files together and writes the result on the standard output. If no input
files are named, the standard input is sorted.
The default sort key is an entire line. Default ordering is lexicographic by runes. The ordering is
affected globally by the following options, one or more of which may appear.
Compare as months. The first three non-white space characters of the field are folded to
upper case and compared so that JAN precedes FEB, etc. Invalid fields compare low to
Ignore leading white space (spaces and tabs) in field comparisons.
Phone directory order: only letters, accented letters, digits and white space are significant
in comparisons.
Fold lower case letters onto upper case. Accented characters are folded to their nonaccented upper case form.
Ignore characters outside the ASCII range 040-0176 in non-numeric comparisons.
Like −i, but ignore only tabs and spaces.
An initial numeric string, consisting of optional white space, optional plus or minus sign,
and zero or more digits with optional decimal point, is sorted by arithmetic value.
Numbers, like −n but with optional e-style exponents, are sorted by value.
Reverse the sense of comparisons.
Tab character separating fields is x.
The notation +pos1 −pos2 restricts a sort key to a field beginning at pos1 and ending just before
pos2. Pos1 and pos2 each have the form m.n, optionally followed by one or more of the flags
Mbdfginr, where m tells a number of fields to skip from the beginning of the line and n tells a
number of characters to skip further. If any flags are present they override all the global ordering
options for this key. A missing .n means .0; a missing −pos2 means the end of the line. Under
the −tx option, fields are strings separated by x; otherwise fields are non-empty strings sepa­
rated by white space. White space before a field is part of the field, except under option −b. A b
flag may be attached independently to pos1 and pos2.
The notation −k pos1[,pos2] is how POSIX sort defines fields: pos1 and pos2 have the same format
but different meanings. The value of m is origin 1 instead of origin 0 and a missing .n in pos2 is
the end of the field.
When there are multiple sort keys, later keys are compared only after all earlier keys compare
equal. Lines that otherwise compare equal are ordered with all bytes significant.
These option arguments are also understood:
Check that the single input file is sorted according to the ordering rules; give no out­
put unless the file is out of sort.
Merge; assume the input files are already sorted.
Suppress all but one in each set of equal lines. Ignored bytes and bytes outside keys
do not participate in this comparison.
The next argument is the name of an output file to use instead of the standard out­
put. This file may be the same as one of the inputs.
Put temporary files in dir rather than in /tmp.
sort −u +0f +0 list
Print in alphabetical order all the unique spellings in a list of words where capitalized words
differ from uncapitalized.
sort −t: +1 /adm/users
Print the users file sorted by user name (the second colon-separated field).
sort −umM dates
Print the first instance of each month in an already sorted file. Options −um with just one
input file make the choice of a unique representative from a set of equal lines predictable.
grep −n ’^’ input | sort −t: +1f +0n | sed ’s/[0−9]*://’
A stable sort: input lines that compare equal will come out in their original order.
uniq(1), look(1)
Sort comments and exits with non-null status for various trouble conditions and for disorder dis­
covered under option −c.
An external null character can be confused with an internally generated end-of-field character.
The result can make a sub-field not sort less than a longer field.
Some of the options, e.g. −i and −M, are hopelessly provincial.
spell, sprog find spelling errors
spell [ options ] ... [ file ] ...
aux/sprog [ options ] [ −f file ]
Spell looks up words from the named files (standard input default) in a spelling list and places pos­
sible misspellingswords not sanctioned thereon the standard output.
Spell ignores constructs of troff(1) and its standard preprocessors. It understands these options:
Check British spelling.
Print all words not literally in the spelling list, with derivations.
Print on standard error, marked with =, every stem as it is looked up in the spelling list,
along with its affix classes.
As a matter of policy, spell does not admit multiple spellings of the same word. Variants that fol­
low general rules are preferred over those that dont, even when the unruly spelling is more com­
mon. Thus, in American usage, modelled, sizeable, and judgment are rejected in favor of
modeled, sizable, and judgement. Agglutinated variants are shunned: crewmember and
backyard cede to crew member and back yard (noun) or back-yard (adjective).
American spelling list
British spelling list
The actual spelling checker. It expects one word per line on standard
input, and takes the same arguments as spell.
the script
source for sprog
The heuristics of deroff(1) used to excise formatting information are imperfect.
The spelling lists coverage is uneven; in particular biology, medicine, and chemistry, and perforce
proper names, not to mention languages other than English, are covered very lightly.
spin - verification tool for models of concurrent systems
spin −a [ −m ] [ −Pcpp ] file
spin [ −bglmprsv ] [ −nN ] [ −Pcpp ] file
spin −c [ −t ] [ −Pcpp ] file
spin −d [ −Pcpp ] file
spin −f ltl
spin −F file
spin −i [ −bglmprsv ] [ −nN ] [ −Pcpp ] file
spin −M [ −t ] [ −Pcpp ] file
spin −t[N] [ −bglmprsv ] [ −jN ] [ −Pcpp ] file
spin −V
Spin is a tool for analyzing the logical consistency of asynchronous systems, specifically dis­
tributed software amd communication protocols. A verification model of the system is first speci­
fied in a guarded command language called Promela. This specification language, described in the
reference, allows for the modeling of dynamic creation of asynchronous processes, nondeterminis­
tic case selection, loops, gotos, local and global variables. It also allows for a concise specification
of logical correctness requirements, including, but not restricted to requirements expressed in lin­
ear temporal logic.
Given a Promela model stored in file, spin can perform interactive, guided, or random simulations
of the systems execution. It can also generate a C program that performs an exhaustive or
approximate verification of the correctness requirements for the system.
Generate a verifier (model checker) for the specification. The output is written into a set of
C files, named pan.[cbhmt], that can be compiled (pcc pan.c) to produce an exe­
cutable verifier. The online spin manuals (see below) contain the details on compilation
and use of the verifiers.
Produce an ASCII approximation of a message sequence chart for a random or guided
(when combined with −t) simulation run. See also option −M.
Produce symbol table information for the model specified in file. For each Promela object
this information includes the type, name and number of elements (if declared as an array),
the initial value (if a data object) or size (if a message channel), the scope (global or local),
and whether the object is declared as a variable or as a parameter. For message channels,
the data types of the message fields are listed. For structure variables, the third field
defines the name of the structure declaration that contains the variable.
−f ltl Translate the LTL formula ltl into a never claim.
This option reads a formula in LTL syntax from the second argument and translates it into
Promela syntax (a never claim, which is Promelas equivalent of a Büchi Automaton). The
LTL operators are written: [] (always), <> (eventually), and U (strong until). There is no X
(next) operator, to secure compatibility with the partial order reduction rules that are
applied during the verification process. If the formula contains spaces, it should be quoted
to form a single argument to the spin command.
−F file
Translate the LTL formula stored in file into a never claim.
This behaves identically to option −f but will read the formula from the file instead of from
the command line. The file should contain the formula as the first line. Any text that fol­
lows this first line is ignored, so it can be used to store comments or annotation on the for­
mula. (On some systems the quoting conventions of the shell complicate the use of option
−f. Option −F is meant to solve those problems.)
Perform an interactive simulation, prompting the user at every execution step that requires
a nondeterministic choice to be made. The simulation proceeds without user intervention
when execution is deterministic.
Produce a message sequence chart in Postscript form for a random simulation or a guided
simulation (when combined with −t), for the model in file, and write the result into
See also option −c.
Changes the semantics of send events. Ordinarily, a send action will be (blocked) if the tar­
get message buffer is full. With this option a message sent to a full buffer is lost.
Set the seed for a random simulation to the integer value N. There is no space between the
−n and the integer N.
Perform a guided simulation, following the error trail that was produces by an earlier verifi­
cation run, see the online manuals for the details on verification.
Prints the spin version number and exits.
With only a filename as an argument and no options, spin performs a random simulation of the
model specified in the file (standard input is the default if the filename is omitted). If option −i is
added, the simulation is interactive, or if option −t is added, the simulation is guided.
The simulation normally does not generate output, except what is generated explicitly by the user
within the model with printf statements, and some details about the final state that is reached after
the simulation completes. The group of options −bglmprsv sets the desired level of information
that the user wants about a random, guided, or interactive simulation run. Every line of output
normally contains a reference to the source line in the specification that generated it.
Suppress the execution of printf statements within the model.
Show at each time step the current value of global variables.
In combination with option −p, show the current value of local variables of the process.
Show at each simulation step which process changed state, and what source statement was
Show all message-receive events, giving the name and number of the receiving process and
the corresponding the source line number. For each message parameter, show the mes­
sage type and the message channel number and name.
Show all message-send events.
Verbose mode, add some more detail, and generate more hints and warnings about the
WhatsNew.pdf, Exercises.pdf
G.J. Holzmann, Design and Validation of Computer Protocols, Prentice Hall, 1991.
, Design and validation of protocols: a tutorial, Computer Networks and ISDN Systems, Vol. 25,
No. 9, 1993, pp. 981-1017.
, The model checker Spin, IEEE Trans. on SE, Vol, 23, No. 5, May 1997.
split split a file into pieces
split [ option ... ] [ file ]
Split reads file (standard input by default) and writes it in pieces of 1000 lines per output file. The
names of the output files are xaa, xab, and so on to xzz. The options are
−n n
Split into n-line pieces.
−l n
Synonym for −n n, a nod to Unixs syntax.
−e expression
File divisions occur at each line that matches a regular expression; see regexp(6). Multiple
−e options may appear. If a subexpression of expression is contained in parentheses
(...), the output file name is the portion of the line which matches the subexpression.
−f stem
Use stem instead of x in output file names.
−s suffix
Append suffix to names identified under −e.
Exclude the matched input line from the output file.
Ignore case in option −e; force output file names (excluding the suffix) to lower case.
sed(1), awk(1), grep(1), regexp(6)
src find source code for executable
src [ −n ] [ −s symbol ] file ...
Src examines the named files to find the corresponding source code, which is then sent to the edi­
tor using B (see sam(1)). If file is an rc(1) script, the source is the file itself. If file is an exe­
cutable, the source is defined to be the single file containing the definition of main and src will
point the editor at the line that begins the definition. Src uses db(1) to extract the symbol table
information that identifies the source.
Src looks for each file in the current directory, in /bin, and in the subdirectories of /bin, in that
The −n flag causes src to print the file name but not send it to the editor. The −s flag identifies
a symbol other than main to locate.
Find the source to the main routine in /bin/ed:
src ed
Find the source for strcmp:
src −s strcmp rc
db(1), plumb(1), sam(1).
ssh, sshnet, scp, sshserve secure login and file copy from/to Unix or Plan 9
ssh [ −CfiImPpRrw ] [ −A authlist ] [ −c cipherlist ] [ −[lu] user ] [[email protected]]host [ cmd [ args ...
sshnet [ −A authlist ] [ −c cipherlist ] [ −m mtpt ] [ −s service ] [[email protected]]host
scp [host:]file [host:]file
scp [host:]file ... [host:]dir
aux/sshserve [ −p ] address
Ssh allows authenticated login over an encrypted channel to hosts that support the ssh protocol
(see the RFCs listed below for encryption and authentication details).
Ssh takes the host name of the machine to connect to as its mandatory argument. It may be speci­
fied as a domain name or an IP address. Normally, login is attempted using the user name from
Command-line options are:
force input to be read in cooked mode: line at a time with local echo.
enable agent forwarding. With this flag, ssh uses SSHs agent forwarding protocol to allow
programs running on the remote server to interact with factotum(4) to perform RSA authen­
force interactive mode. In interactive mode, ssh prompts for passwords and confirmations
of new host keys when necessary. (In non-interactive mode, password requests are
rejected and unrecognized host keys are cause for disconnecting.) By default, ssh runs in
interactive mode only when its input file descriptor is /dev/cons.
force non-interactive mode.
disable the control-\ menu, described below.
force pseudoterminal request. The ssh protocol, grounded in Unix tradition, differentiates
between connections that request controlling pseudoterminals and those that do not. By
default, ssh requests a pseudoterminal only when no command is given.
force no pseudoterminal request.
strip carriage returns.
put the allocated pseudoterminal, if any, in raw mode.
notify the remote side whenever the window changes size.
−[lu] user
specify user name. This option is deprecated in favor of the [email protected] syntax.
−A authlist
specify an ordered space-separated list of authentication protocols to try. The full set of
authentication protocols is rsa (RSA using factotum(4) to moderate key usage),
password (use a password gathered from factotum), and tis (challenge-response). The
default list is all three in that order.
−c cipherlist
specify an ordered space-separated list of allowed ciphers to use when encrypting the
channel. The full set of ciphers is des (standard DES), 3des (a somewhat doubtful varia­
tion on triple DES), blowfish (Bruce Schneiers Blowfish), rc4 (RC4), and none (no
encryption). The default cipher list is blowfish rc4 3des.
The control\ character is a local escape, as in con(1). It prompts with >>>. Legitimate responses
to the prompt are
Return from the escape.
!cmd Run the command with the network connection as its standard input and standard output.
Standard error will go to the screen.
Toggle printing of carriage returns.
If no command is specified, a login session is started on the remote host. Otherwise, the com­
mand is executed with its arguments.
Ssh establishes a connection with an ssh daemon on the remote host. The daemon sends to ssh
its RSA public host key and session key. Using these, ssh sends a session key which, presumably,
only the daemon can decipher. After this, both sides start encrypting their data with this session
When the daemons host key has been received, ssh looks it up in $home/lib/keyring and in
/sys/lib/ssh/keyring. If the key is found there, and it matches the received key, ssh is
satisfied. If not, ssh reports this and offers to add the key to $home/lib/keyring.
Over the encrypted channel, ssh attempts to convince the daemon to accept the call using the
listed authentication protocols (see the −A option above).
The preferred way to authenticate is a netkey-style challenge/response or via a SecurID token. Ssh
users on other systems than Plan 9 should enable TIS_Authentication.
When the connection is authenticated, the given command line, (by default, a login shell) is exe­
cuted on the remote host.
The SSH protocol allows clients to make outgoing TCP calls via the server. Sshnet establishes an
SSH connection and, rather than execute a remote command, presents the remote servers TCP
stack as a network stack (see the discussion of TCP in ip(3)) mounted at mtpt (default /net),
optionally posting a 9P service descriptor for the new file system as /srv/service. The −A and
−c arguments are as in ssh.
Scp uses ssh to copy files from one host to another. A remote file is identified by a host name, a
colon and a file name (no spaces). Scp can copy files from remote hosts and to remote hosts.
Sshserve is the server that services ssh calls from remote hosts. The −A and −c options set valid
authentication methods and ciphers as in ssh, except that there is no rsa authentication method.
Unlike in ssh, the list is not ordered: the server presents a set and the client makes the choice.
The default sets are tis and blowfish rc4 3des. By default, users start with the namespace
defined in /lib/namespace. Users in group noworld in /adm/users start with the names­
pace defined in /lib/namespace.noworld. Sshserve does not provide the TCP forwarding
functionality used by sshnet, because many Unix clients present this capability in an insecure man­
Sshserve requires that factotum(4) hold the host key, identified by having attributes proto=rsa
service=sshserve. To generate a host key:
auth/rsagen −t ’service=sshserve’ >/mnt/factotum/ctl
To extract the public part of the host key in the form used by SSH key rings:
grep ’service=sshserve’ /mnt/factotum/ctl | auth/rsa2ssh
System key ring file containing public keys for remote ssh clients and servers.
Personal key ring file containing public keys for remote ssh clients and servers.
factotum(4), authsrv(6), rsa(8)
Only version 1 of the SSH protocol is implemented.
stop, start print commands to stop and start processes
stop name
start name
Stop prints commands that will cause all processes called name and owned by the current user to
be stopped. The processes can then be debugged when they are in a consistent state.
Start prints commands that will cause all stopped processes called name and owned by the current
user to be started again.
Use the send command of rio(1), or pipe into rc(1) to execute the commands.
ps(1), kill(1), proc(3)
strings extract printable strings
strings [ −m min ] [ file ... ]
Strings finds and prints strings containing min (default 6) or more consecutive printable UTFencoded characters in a (typically) binary file, default standard input. Printable characters are
taken to be ASCII characters from blank through tilde (hexadecimal 20 through 7E), inclusive, and
all other characters from value 00A0 to FFFF. Strings reports the decimal offset within the file at
which the string starts and the text of the string. If the string is longer than 70 runes the line is
terminated by three dots and the printing is resumed on the next line with the offset of the contin­
uation line.
strip remove symbols from binary files
strip file ...
strip −o ofile file
Strip removes symbol table segments from executable files, rewriting the files in place. Stripping a
file requires write permission of the file and the directory it is in.
If the −o flag is given, the single input file file is stripped and the result written to ofile. File is
sum, md5sum, sha1sum sum and count blocks in a file
sum [ −5r ] [ file ... ]
md5sum [ file ... ]
sha1sum [ −2 bits ] [ file ... ]
By default, sum calculates and prints a 32-bit hexadecimal checksum, a byte count, and the name
of each file. The checksum is also a function of the input length. If no files are given, the standard
input is summed. Other summing algorithms are available. The options are
Sum with the algorithm of System Vs sum −r and print the length (in 1K blocks) of the
Sum with System Vs default algorithm and print the length (in 512-byte blocks) of the input.
Sum is typically used to look for bad spots, to validate a file communicated over some transmis­
sion line or as a quick way to determine if two files on different machines might be the same.
Md5sum computes the 32 hex digit RSA Data Security, Inc. MD5 Message-Digest Algorithm
described in RFC1321.
Sha1sum computes the 40 hex digit National Institute of Standards and Technology (NIST) SHA1
secure hash algorithm described in FIPS PUB 180-1, by default. Given the 2 option, it instead com­
putes the bits-bit NIST SHA2 secure hash algorithm described in FIPS PUB 180-2 and prints the
hash in hex. Currently supported values of bits are 224, 256, 384, and 512.
cmp(1), wc(1), sechash(2)
syscall test a system call
syscall [ −osx ] entry [ arg ... ]
Syscall invokes the system call entry with the given arguments. (Some functions, such as write
and read(2), although not strictly system calls, are valid entries.) It prints the return value and the
error string, if there was an error. An argument is either an integer constant as in C (its value is
passed), a string (its address is passed), or the literal buf (a pointer to a 1MB buffer is passed).
If −o is given, the contents of the 1MB buffer are printed as a zero-terminated string after the sys­
tem call is done. The −x and −s options are similar, but −x formats the data as hexadecimal
bytes, while −s interprets the data as a stat(5) message and formats it similar to the style of ls
−lqm (see ls(1)), with extra detail about the modify and access times.
Write a string to standard output:
syscall write 1 hello 5
Print information about the file connected to standard input:
syscall −s fstat 0 buf 1024
Section 2 of this manual.
If entry is not known to syscall, the exit status is unknown. If the system call succeeds, the exit
status is null; otherwise the exit status is the string that errstr(2) returns.
tagrd plumb a Mifare Ultralight tag
tagrd [ −D ] /dev/cci*/rpc
Tagrd runs continuously, polling a usb(4) ccid-based Touchatag reader and plumbs a message for
any tag with its content and its UID. It plumbs another message when the tag disappears. For an
example of how to use this, see /sys/src/cmd/scard/plumbing.
When the program successfully communicates with the reader, its led should turn orange.
This program is part of an ongoing programming of the ISO smartcard standards, part of the
library can be seen at /sys/src/cmd/scard.
tail deliver the last part of a file
tail [ +−number[lbc][rf] ] [ file ]
tail [ −fr ] [ −n nlines ] [ −c nbytes ] [ file ]
Tail copies the named file to the standard output beginning at a designated place. If no file is
named, the standard input is copied.
Copying begins at position +number measured from the beginning, or −number from the end of
the input. Number is counted in lines, 1K blocks or bytes, according to the appended flag l, b, or
c. Default is −10l (ten ell).
The further flag r causes tail to print lines from the end of the file in reverse order; f (follow)
causes tail, after printing to the end, to keep watch and print further data as it appears.
The second syntax is that promulgated by POSIX, where the numbers rather than the options are
tail file
Print the last 10 lines of a file.
tail +0f file
Print a file, and continue to watch data accumulate as it grows.
sed 10q file
Print the first 10 lines of a file.
Tails relative to the end of the file are treasured up in a buffer, and thus are limited in length.
According to custom, option +number counts lines from 1, and counts blocks and bytes from 0.
Tail is ignorant of UTF.
tar, dircp archiver
tar key [ file ... ]
dircp fromdir todir
Tar saves and restores file trees. It is most often used to transport a tree of files from one system
to another. The key is a string that contains at most one function letter plus optional modifiers.
Other arguments to the command are names of files or directories to be dumped or restored. A
directory name implies all the contained files and subdirectories (recursively).
The function is one of the following letters:
Create a new archive with the given files as contents.
The named files are appended to the archive.
List all occurrences of each file in the archive, or of all files if there are no file arguments.
Extract the named files from the archive. If a file is a directory, the directory is extracted
recursively. Modes are restored if possible. If no file argument is given, extract the entire
archive. If the archive contains multiple entries for a file, the latest one wins.
The modifiers are:
Use the next argument as the name of the archive instead of the default standard input (for
keys x and t) or standard output (for keys c and r).
Use the next (numeric) argument as the group id for files in the output archive.
Ignore errors encountered when reading. Errors writing either produce a corrupt archive or
indicate deeper file system problems.
(keep) Modifies the behavior of x not to extract files which already exist.
Do not set the modification time on extracted files. This is the default behavior; the flag
exists only for compatibility with other tars.
Create archive in POSIX ustar format, which raises the maximum pathname length from 100
to 256 bytes. Ustar archives are recognised automatically by tar when reading archives.
This is the default behavior; the flag exists only for backwards compatibility with older ver­
sions of tar.
Do not generate the POSIX ustar format.
When extracting, respect leading slash on file names. By default, files are always extracted
relative to the current directory.
When extracting, attempt to resynchronise after not finding a tape header block where
Modifies the behavior of x to set the modified time, mode and, for POSIX archives and
filesystem permitting, the user and group of each file to that specified in the archive.
Use the next (numeric) argument as the user id for files in the output archive. This is only
useful when moving files to a non-Plan 9 system.
(verbose) Print the name of each file as it is processed. With t, give more details about the
archive entries.
Operate on compressed tar archives. The type of compression is inferred from the file
name extension: gzip(1) for .tar.gz and .tgz; bzip2 (see gzip(1)) for,
.tbz, .tar.bz2, and .tbz2; compress for .tar.Z and .tz. If no extension
matches, gzip is used. The z flag is unnecessary (but allowed) when using the t and x
verbs on archives with recognized extensions.
Tar can be used to copy hierarchies thus:
@{cd fromdir && tar c .} | @{cd todir && tar xT}
Dircp does this.
ar(1), bundle(1), tapefs(4), mkfs(8)
There is no way to ask for any but the last occurrence of a file.
File path names are limited to 100 characters (256 when using ustar format).
The tar format allows specification of links and symbolic links, concepts foreign to Plan 9: they are
The r key (append) cannot be used on compressed archives.
Tar, thus dircp, doesnt record Plan-9-specific metadata such as append-only and exclusive-open
permission bits, so they arent copied.
tbl format tables for nroff or troff
tbl [ file ... ]
Tbl is a preprocessor for formatting tables for nroff or troff(1). The input files are copied to the
standard output, except for segments of the form
options ;
format .
format .
which describe tables and are replaced by troff requests to lay out the tables. If no arguments are
given, tbl reads the standard input.
The (optional) options line is terminated by a semicolon and contains one or more of
center the table; default is left-adjust
make table as wide as current line length
enclose the table in a box or double box
enclose every item in a box
use x to separate input items; default is tab
set rules in n-point type
recognize x and y as eqn(1) delimiters
Each line, except the last, of the obligatory format describes one row of the table. The last line
describes all rows until the next .T&, where the format changes, or the end of the table at .TE. A
format is specified by key letters, one per column, either upper or lower case:
Left justify: the default for columns without format keys.
Right justify.
Numeric: align at decimal point (inferred for integers) or at \&.
Span: extend previous column across this one.
Alphabetic: left-aligned within column, widest item centered, indented relative to L
Vertical span: continue item from previous row into this row.
Draw a horizontal rule in this column.
Draw a double horizontal rule in this column.
Key letters may be followed by modifiers, also either case:
Draw vertical rule between columns.
Draw a double vertical rule between columns.
Gap between column is n ens wide. Default is 3.
Use specified font. B and I mean FB and FI.
Begin vertically-spanned item at top row of range; default is vertical centering
(with ^).
Use point size n.
Use n-point vertical spacing in text block; signed n means relative change.
Column width as a troff width specification. Parens are optional if n is a simple
Equalize the widths of all columns marked E.
Each line of data becomes one row of the table; tabs separate items. Lines beginning with . are
troff requests. Certain special data items are recognized:
Draw a horizontal rule in this column.
Draw a double horizontal rule in this column. A data line consisting of a single _ or
= draws the rule across the whole table.
Draw a rule only as wide as the contents of the column.
Repeat character x across the column.
Span the previous item in this column down into this row.
The item is a text block to be separately formatted by troff and placed in the table.
The block continues to the next line beginning with T}. The remainder of the data
line follows at that point.
When it is used in a pipeline with eqn, the tbl command should be first, to minimize the volume of
data passed through pipes.
Let <tab> represent a tab (which should be typed as a genuine tab).
c s s
c c s
c c c
Household Population
l n n.
Household Population
Number Size
Bernards Twp.
Bernards Twp.<tab>3087<tab>3.74
troff(1), eqn(1), doctype(1)
M. E. Lesk and L. L. Cherry, TBLa Program to Format Tables, Unix Research System
Programmer’s Manual, Tenth Edition, Volume 2.
tcs translate character sets
tcs [ −slcv ] [ −f ics ] [ −t ocs ] [ file ... ]
Tcs interprets the named file(s) (standard input default) as a stream of characters from the ics char­
acter set or format, converts them to runes, and then converts them into a stream of characters
from the ocs character set or format on the standard output. The default value for ics and ocs is
utf, the UTF encoding described in utf(6). The −l option lists the character sets known to tcs.
Processing continues in the face of conversion errors (the −s option prevents reporting of these
errors). The −c option forces the output to contain only correctly converted characters; otherwise,
Runeerror (0xFFFD) characters will be substituted for UTF encoding errors and unknown charac­
The −v option generates various diagnostic and summary information on standard error, or makes
the −l output more verbose.
Tcs recognizes an ever changing list of character sets. In particular, it supports a variety of Rus­
sian and Japanese encodings. Some of the supported encodings are
The Plan 9 UTF encoding, known by ISO as UTF-8
The deprecated original UTF encoding from ISO 10646
7-bit ASCII
Latin-1 (Central European)
Latin-2 (Czech .. Slovak)
Latin-3 (Dutch .. Turkish)
Latin-4 (Scandinavian)
Part 5 (Cyrillic)
Part 6 (Arabic)
Part 7 (Greek)
Part 8 (Hebrew)
Latin-5 (Finnish .. Portuguese)
Unicode as encoded by HTML
KOI-8 (GOST 19769-74)
ISO 2022-JP
EUC-JX: JIS 0208
Microsoft, or Shift-JIS
(from only) guesses between ISO 2022-JP, EUC or Shift-Jis
Chinese national standard (GB2312-80)
Big 5 (HKU version)
Unicode Standard 1.0
Thai character set plus ASCII (TIS 620-1986)
IBM PC: CP 437
Atari-ST character set
tcs −f 8859−1
Convert 8859-1 (Latin-1) characters into UTF format.
tcs −s −f jis
Convert characters encoded in one of several shift JIS encodings into UTF format. Unknown
Kanji will be converted into 0xFFFD characters.
tcs −t html
Convert UTF into character set-independent HTML.
tcs −lv
Print an up to date list of the supported character sets.
ascii(1), rune(2), utf(6).
tee pipe fitting
tee [ −i ] [ −a ] files
Tee transcribes the standard input to the standard output and makes copies in the files. The
options are
Ignore interrupts.
Append the output to the files rather than rewriting them.
tel, iwhois look in phone book
tel key ...
iwhois name[@domain]
Tel looks up key in a private telephone book, $home/lib/tel, and in the public telephone
book, /lib/tel. It uses grep (with the −i option to ignore case differences), so the key may be
any part of a name or number. Customarily, the telephone book contains names, userids, home
numbers, and office numbers of users. It also contains a directory of area codes and miscella­
neous people of general interest.
Iwhois looks up names in the Internet NICs personnel database. Name should be a surname
optionally followed by a comma and given name. A different server can be chosen by appending
to the name an @ followed by the servers domain name.
Telephone area codes database.
Public telephone number database.
Personal telephone number database.
test set status according to condition
test expr
Test evaluates the expression expr. If the value is true the exit status is null; otherwise the exit sta­
tus is non-null. If there are no arguments the exit status is non-null.
The following primitives are used to construct expr.
True if the file exists (is accessible) and is readable.
True if the file exists and is writable.
True if the file exists and has execute permission.
True if the file exists.
True if the file exists and is a plain file.
True if the file exists and is a directory.
True if the file exists and has a size greater than zero.
True if the open file whose file descriptor number is fildes (1 by default) is the same
file as /dev/cons.
−A file
True if the file exists and is append-only.
−L file
True if the file exists and is exclusive-use.
True if the file exists and is temporary.
s1 = s2
True if the strings s1 and s2 are identical.
s1 != s2
True if the strings s1 and s2 are not identical.
True if s1 is not the null string. (Deprecated.)
−n s1
True if the length of string s1 is non-zero.
−z s1
True if the length of string s1 is zero.
n1 −eq n2 True if the integers n1 and n2 are arithmetically equal. Any of the comparisons
−ne, −gt, −ge, −lt, or −le may be used in place of −eq. The (nonstandard)
construct −l string, meaning the length of string, may be used in place of an inte­
a −nt b
True if file a is newer than (modified after) file b.
a −ot b
True if file a is older than (modified before) file b.
f −older t True if file f is older than (modified before) time t. If t is a integer followed by the
letters y(years), M(months), d(days), h(hours), m(minutes), or s(seconds), it repre­
sents current time minus the specified time. If there is no letter, it represents sec­
onds since epoch. You can also concatenate mixed units. For example, 3d12h
means three days and twelve hours ago.
These primaries may be combined with the following operators:
( expr )
unary negation operator
binary or operator
binary and operator; higher precedence than −o
parentheses for grouping.
The primitives −b, −u, −g, and −s return false; they are recognized for compatibility with POSIX.
Notice that all the operators and flags are separate arguments to test. Notice also that parentheses
and equal signs are meaningful to rc and must be enclosed in quotes.
Test is a dubious way to check for specific character strings: it uses a process to do what an rc(1)
match or switch statement can do. The first example is not only inefficient but wrong, because
test understands the purported string "−c" as an option.
if (test $1 ’=’ "−c") echo OK # wrong!
A better way is
if (~ $1 −c) echo OK
Test whether abc is in the current directory.
test −f abc −o −d abc
Wont complain about extraneous arguments since there may be arguments left unprocessed by
short-circuit evaluation of −a or −o.
thesaurus search online thesaurus
thesaurus word
thesaurus searches the online thesaurus at
time time a command
time command [ arg ... ]
The command is executed with the given arguments; after it is complete, time reports on standard
error the programs elapsed user time, system time, and real time, in seconds, followed by the
command line.
touch set modification date of a file
touch [ −c ] [ −t time ] file ...
Touch attempts to set the modification time of the files to time (by default, the current time). If a
file does not exist, it will be created unless option −c is present.
ls(1), stat(2), chmod(1)
Touch will not touch directories.
tr translate characters
tr [ −cds ] [ string1 [ string2 ] ]
Tr copies the standard input to the standard output with substitution or deletion of selected char­
acters (runes). Input characters found in string1 are mapped into the corresponding characters of
string2. When string2 is short it is padded to the length of string1 by duplicating its last character.
Any combination of the options −cds may be used:
Complement string1: replace it with a lexicographically ordered list of all other characters.
Delete from input all characters in string1.
Squeeze repeated output characters that occur in string2 to single characters.
In either string a noninitial sequence −x, where x is any character (possibly quoted), stands for a
range of characters: a possibly empty sequence of codes running from the successor of the previ­
ous code up through the code for x. The character \ followed by 1, 2 or 3 octal digits stands for
the character whose 16-bit value is given by those digits. The character sequence \x followed by
1, 2, 3, or 4 hexadecimal digits stands for the character whose 16-bit value is given by those dig­
its. A \ followed by any other character stands for that character.
Replace all upper-case ASCII letters by lower-case.
tr A−Z a−z <mixed >lower
Create a list of all the words in file1 one per line in file2, where a word is taken to be a maxi­
mal string of alphabetics. String2 is given as a quoted newline.
tr −cs A−Za−z ’
’ <file1 >file2
trace show (real-time) process behavior
trace [ −d file ] [ −v ] [ −w ] [ pid ... ]
Trace displays the behavior of processes running on the machine. In its window it shows a time
line for each traced process. Running processes appear as colored blocks, with arrows marking
important events in real-time processes (see proc(3)). Black up arrows mark process releases,
black down arrows mark process deadlines, green down arrows mark times when a process yielded
the processor before its deadline, red down arrows mark times when the process overran its allot­
ted time.
Trace reads /proc/trace to retrieve trace events from the kernel scheduler. Trace events are
binary data structures generated by the kernel scheduler. It is assumed that the reader of
/proc/trace and the kernel providing it have the same byte order.
The options are:
specify an alternate trace event file
print events as they are read from the trace event file
run in a new window rather than using the current one
Trace recognizes these keystroke commands while it is running:
zoom in by a factor of two
zoom out by a factor of two
pause or resume
trace event file
trace event data structures
troff, nroff, dpost text formatting and typesetting
troff [ option ... ] [ file ... ]
dpost [ −f ] [ file ... ]
nroff [ option ... ] [ file ... ]
Troff formats text in the named files for printing on a typesetter, emitting a textual intermediate
format called typesetter-independent troff output, understood by programs such as proof(1) and
lp(1), but also by a troff post-processor named dpost, which emits corresponding Postscript.
Under −f, dpost also emits Postscript font definitions as needed. Nroff does the same as troff,
but produces output suitable for typewriter-like devices, usually without further post-processing,
but see col(1).
If no file argument is present, the standard input is read. An argument consisting of a single
minus (−) is taken to be a file name corresponding to the standard input. The options are:
Print pages in the comma-separated list of numbers and ranges. A range N−M means N
through M; initial −M means up to M; final N− means from N to the end.
Number first generated page N.
−mname Process the macro file /sys/lib/tmac/ before the input files.
Set register a (one character name) to N.
Read standard input after the input files are exhausted.
Invoke the simultaneous input-output mode of the rd request.
Produce output suitable for typewriter-like devices.
Typesetter devices (not −N) only
Send a printable textual approximation of the results to the standard output.
Prepare output for typesetter dest:
(The default.) PostScript printers with preprocessing to handle Unicode
characters encoded in UTF
Regular PostScript printers
Mergenthaler Linotron 202
Take font information from directory dir.
Typewriter (−N) output only
Halt prior to every N pages (default N=1) to allow paper loading or changing.
−Tname Prepare output for specified terminal. Known names include utf for the normal Plan 9
UTF encoding of the Unicode Standard character set (default), 37 for the Teletype model
37, lp (line-printer) for any terminal without half-line capability, 450 for the DASI-450
(Diablo Hyterm), and think (HP ThinkJet).
Produce equally-spaced words in adjusted lines, using full terminal resolution.
Use output tabs during horizontal spacing to speed output and reduce output character
count. Tab settings are assumed to be every 8 nominal character widths.
temporary file
standard macro files
terminal driving tables for nroff
font width tables for troff
lp(1), proof(1), page(1), eqn(1), tbl(1), pic(1), grap(1), doctype(1), ms(6), image(6), tex(1),
deroff(1), col(1)
J. F. Ossanna and B. W. Kernighan, Troff Users Manual
B. W. Kernighan, A Typesetter-Independent TROFF, CSTR #97
B. W. Kernighan, A TROFF Tutorial, Unix Research System Programmer’s Manual, Tenth Edition,
Volume 2.
troff2html convert troff output into HTML
troff2html [ −t title ] [ file ... ]
Troff2html reads the troff(1) output in the named files, default standard input, and converts them
into HTML.
Troff2html does a tolerable job with straight troff output, but it is helped by annotations,
described below. Its main use is for man2html (see httpd(8)), which converts man(1) pages into
HTML and depends on a specially annotated set of man(6) macros, invoked by troff
Troff output lines beginning
x X html ...
which are introduced by placing \X’html ...’ in the input, cause the rest of the line to be inter­
polated into the HTML produced. Several such lines are recognized specially by troff2html. The
most important are the pair
x X html manref start cp 1
x X html manref end cp 1
which are used to create HTML hyperlinks around text of the form cp(1) pointing to
Troff2html is new and experimental; in time, it may improve and subsume ms2html(1). On the one
hand, because it uses the input, ms2html can handle pic(1), eqn(1), etc., which troff2html does
not handle at all; on the other hand, ms2html understands only ms(6) documents and is easily
confused by complex troff constructions. Troff2html has the reverse properties: it does not
handle the preprocessors but its output is reliable and (modulo helper annotations) is independent
of macro package.
troff(1), ms2html(1), man2html in httpd(8).
Troff and HTML have different models, and they dont mesh well in all cases. Troffs indented
paragraphs are not well served in HTML, and the output of troff2html shows this.
tweak edit image files, subfont files, face files, etc.
tweak [ file ... ]
Tweak edits existing files holding various forms of images. To create original images, start from
an existing image, subfont, etc.
Tweak reads its argument files and displays the resulting images in a vertical column. If the image
is too wide to fit across the display, it is folded much like a long line of text in an rio window.
Under each image is displayed one or two lines of text presenting its parameters. The first line
shows the images depth, the number of bits per pixel; r, the rectangle covered by the image;
and the name of the file from which it was read. If the file is a subfont, a second line presents a
hexadecimal 16-bit offset to be applied to character values from the subfont (typically as
stored in a font file; see font(6)); and the subfonts n, height, and ascent as defined in
By means described below, magnified views of portions of the images may be displayed. The text
associated with such a view includes mag, the magnification. If the view is of a single character
from a subfont, the second line of text shows the characters value (including the subfonts offset)
in hexadecimal and as a character in tweak’s default font; the characters x, top, bottom, left,
and width as defined in cachechars(2); and iwidth, the physical width of the image in the
subfonts image.
There are two methods to obtain a magnified view of a character from a subfont. The first is to
click mouse button 1 over the image of the character in the subfont. The second is to select the
char entry on the button 3 menu, point the resulting gunsight cursor at the desired subfont and
click button 3, and then type at the text prompt at the bottom of the screen the character value,
either as a multi-digit hexadecimal number or as a single rune representing the character.
To magnify a portion of other types of image files, click button 1 over the unmagnified file. The
cursor will switch to a cross. Still with button 1, sweep a rectangle, as in rio, that encloses the
portion of the image to be magnified. (If the file is 16×16 or smaller, tweak will just magnify the
entire file; no sweeping is necessary.)
Pressing buttons 1 and 2 within magnified images changes pixel values. By default, button 1 sets
the pixel to all zeros and button 2 sets the pixel to all ones.
Across the top of the screen is a textual display of global parameters. These values, as well as
many of the textual values associated with the images, may be edited by clicking button 1 on the
displayed value and typing a new value. The values along the top of the screen are:
Default magnification.
The value used to modify pixels within magnified images. The value must be in hexadeci­
mal, optionally preceded by a tilde for bitwise negation.
but2 The pixel value written when the corresponding button is pressed over a pixel.
Whether the pixel values are inverted when a copy operation is performed.
Under button 3 is a menu holding a variety of functions. Many of these functions prompt for the
image upon which to act by switching to a gunsight cursor; click button 3 over the selection, or
click a different button to cancel the action.
open Read and display a file. The name of the file is typed to the prompt on the bottom line.
read Reread a file.
Write a file.
copy Use the copy function, default S, to transfer a rectangle of pixels from one image to
another. The program prompts with a cross cursor; sweep out a rectangle in one image or
just click button 3 to select the whole image. The program will leave that rectangle in place
and attach another one to the cursor. Move that rectangle to the desired place in any
image and click button 3, or another button to cancel the action.
char As described above, open a magnified view of a character image in a subfont.
Report the coordinate and value of individual pixels indicated by pressing button 3. This is
a mode of operation canceled by pressing button 1 or 2.
Close the specified image. If the image is the unmagnified file, also close any magnified
views of that file.
exit Quit tweak. The program will complain once about modified but unwritten files.
cachechars(2), image(6), font(6)
For a program written to adjust width tables in fonts, tweak has been pushed unreasonably far.
uniq report repeated lines in a file
uniq [ −udc [ +−num ] ] [ file ]
Uniq copies the input file, or the standard input, to the standard output, comparing adjacent lines.
In the normal case, the second and succeeding copies of repeated lines are removed. Repeated
lines must be adjacent in order to be found.
Print unique lines.
Print (one copy of) duplicated lines.
Prefix a repetition count and a tab to each output line. Implies −u and −d.
−num The first num fields together with any blanks before each are ignored. A field is defined as
a string of non-space, non-tab characters separated by tabs and spaces from its neigh­
+num The first num characters are ignored. Fields are skipped before characters.
Field selection and comparison should be compatible with sort(1).
units conversion program
units [ −v ] [ file ]
Units converts quantities expressed in various standard scales to their equivalents in other scales.
It works interactively in this fashion:
you have: inch
you want: cm
* 2.54
/ 0.393701
A quantity is specified as a multiplicative combination of units and floating point numbers. Opera­
tors have the following precedence:
+ −
( ... )
add and subtract
multiply and divide
Most familiar units, abbreviations, and metric prefixes are recognized, together with a generous
leavening of exotica and a few constants of nature including:
ratio of circumference to diameter
speed of light
charge on an electron
acceleration of gravity
same as g
Avogadros number
pressure head per unit height of water
astronomical unit
The pound is a unit of mass. Compound names are run together, e.g. lightyear. British
units that differ from their US counterparts are prefixed thus: brgallon. Currency is denoted
belgiumfranc, britainpound, etc.
The complete list of units can be found in /lib/units. A file argument to units specifies a file
to be used instead of /lib/units. The −v flag causes units to print its entire database.
you have: 15 pounds force/in²
you want: atm
* 1.02069
/ .97973
Since units does only multiplicative scale changes, it can convert Kelvin to Rankine but not Centi­
grade to Fahrenheit.
Currency conversions are only as accurate as the last time someone updated the database.
uptime show how long the system has been running
Uptime shows how long the system has been running. It uses the following format:
sysname up 33 days, 17:56:42
The time given accounts for the timezone.
uuencode, uudecode encode/decode a file as printable ASCII
uuencode [ input ]
uudecode [ input ]
Uuencode and uudecode are filters used to transmit files over transmission media that do not sup­
port other than simple ASCII data.
Uuencode converts a file to a purely ASCII-based representation.
Uudecode reads a file produced by uuencode, ignoring any leading and trailing lines that are not
part of the encoding, and emits the original file on standard output, also writing its name to stan­
dard error.
Encode a dis file limbo.dis so that it can be included in a mail message:
uuencode limbo.dis >tmp
place tmp in mail message and send to recipient
Decode the mail message (msg say):
uudecode <msg >limbo.dis
The encoded file is expanded by at least a third.
This encoding is a relic of the days before MIME encoding.
vac, unvac create, extract a vac archive on Venti
vac [ −mqsv ] [ −b blocksize ] [ −d oldvacfile ] [ −e exclude ] [ −f vacfile ] [ −i name ] [ −h host ]
file ...
unvac [ −Tctv ] [ −h host ] vacfile [ file ... ]
Vac creates an archival copy of Plan 9 file trees on Venti. It can be used to build a simple backup
system. One of the unusual properties of Venti is that duplicate blocks are detected and coalesced.
When vac is used on a file tree that shares data with an existing archive, the consumption of stor­
age will be approximately equal to an incremental backup. This reduction in storage consumption
occurs transparently to the user.
As an optimization, the −d and −q options, described below, can be used to explicitly create an
archive relative to an existing archive. These options do not change the resulting archive gener­
ated by vac, but simply reduce the number of write operations to Venti.
The output of vac is the hexadecimal representation of the SHA1 fingerprint of the root of the
archive, in this format:
The options to vac are:
−b blocksize Specifies the block size that data will be broken into. The units for the size can be
specified by appending k to indicate kilobytes. The default is 8k. The size must be
in the range of 512 bytes to 52k.
−d oldvacfile Reduce the number of blocks written to Venti by comparing the files to be stored
with the contents of an existing vac file tree whose score is stored in oldvacfile.
−e exclude
Do not include the file or directory specified by exclude. This option may be
repeated multiple times.
−f vacfile
The results of vac are placed in vacfile, or the standard output if no file is given.
−i name
Include standard input as one of the input files, storing it in the archive with the
specified name.
−h host
The network address of the Venti server. The default is taken from the environment
variable venti. If this variable does not exist, then the default is the metaname
$venti, which can be configured via ndb(6).
Expand and merge any vac archives that are found while reading the input files.
This option is useful for building an archive from a collection of existing archives.
Each archive is inserted into the new archive as if it had been unpacked in the direc­
tory in which it was found. Multiple archives can be unpacked in a single directory
and the contents will be merged. To be detected, the archives must end in .vac.
Note, an archive is inserted by simply copying the root fingerprint and does not
require the archive to be unpacked.
Increase the performance of the −d option by detecting unchanged files based on a
match of the files name and other meta data, rather than examining the contents of
the files.
Print out various statistics on standard error.
Produce more verbose output on standard error, including the name of the files
added to the archive and the vac archives that are expanded and merged.
Unvac lists or extracts files stored in the vac archive vacfile, which can be either a vac archive
string in the format given above or the name of a file containing one. If file arguments are given,
only those files or directories will be extracted. The options are:
Set the modification time on extracted files to the time listed in the archive.
Write extracted files to standard output instead of creating a file.
as per vac.
Print a list of the files to standard output rather than extracting them.
If extracting files, print the name of each file and directory to standard error. If listing files,
print metadata in addition to the names.
vacfs(4), venti(8)
read, write, copy simple Venti clients
venti/read [ −h host ] [ −t type ] score
venti/write [ −z ] [ −h host ] [ −t type ]
venti/copy [ −fir ] [ −t type ] srchost dsthost score [ type ]
Venti is a SHA1-addressed block storage server. See venti(6) for a full introduction.
Read reads a block with the given score and numeric type from the server host and prints the block
to standard output. If the −h option is omitted, read consults the environment variable $venti
for the name of the Venti server. If the −t option is omitted, read will try each type, one at a time,
until it finds one that works. It prints the corresponding read −t command to standard error to
indicate the type of the block.
Write writes at most 56 kilobytes of data from standard input to the server host and prints the
resulting score to standard output. If the −t option is omitted, write uses type 0, denoting a data
block. If the −z option is given, write zero truncates the block before writing it to the server.
Copy expects score to be the score of a VtRoot block. It copies the entire tree of blocks reach­
able from the root block from the server srchost to the server dsthost.
The −f option causes copy to run in fast mode, assuming that if a block already exists on the
destination Venti server, all its children also exist and need not be checked.
The −i and −r options control copys reaction to errors reading from srchost. Copy always prints
information to standard error about each read error. By default, copy exits after printing the first
error. If the −i option is given, read errors are ignored. This is dangerous behavior because it
breaks the assumption made by fast mode. If the −r option is given, copy replaces pointers to
unreadable blocks with pointers to the zero block. It writes the new root score to standard output.
vac(1), venti(2), vacfs(4), venti(6), venti(8), venti−backup(8), venti−fmt(8)
There should be programs to read and write venti files and directories.
5i, ki, vi, qi instruction simulators
[ textfile
[ textfile
[ textfile
[ textfile
Vi simulates the execution of a MIPS binary in a Plan 9 environment. It has two main uses: as a
debugger and as a statistics gatherer. Programs running under vi execute about two hundred
times slower than normalbut faster than single stepping under db. 5i, ki, and qi are similar to vi
but interpret ARM, SPARC, and PowerPC binaries. The following discussion refers to vi but applies
to the others as well.
Vi will simulate the execution of a named textfile. It will also make a copy of an existing process
with process id pid and simulate its continuation.
As a debugger vi offers more complete information than db(1). Tracing can be performed at the
level of instructions, system calls, or function calls. Vi allows breakpoints to be triggered when
specified addresses in memory are accessed. A report of instruction counts, load delay fills and
distribution is produced for each run. Vi simulates the CPUs caches and MMU to assist the opti­
mization of compilers and programs.
The command interface mirrors the interface to db; see db(1) for a detailed description. Data for­
mats and addressing are compatible with db except for disassembly: vi offers only MIPS (db
−mmipsco) mnemonics for machine instructions. Ki offers both Plan 9 and Sun SPARC formats.
Several extra commands allow extended tracing and printing of statistics:
The t command controls tracing. Zero cancels all tracing options.
Enable instruction tracing
Enable call tracing
Enable system call tracing
The i command prints statistics accumulated by all code run in this session.
Print instruction counts and frequency.
Print cycle profile.
(Vi only) Print TLB and cache statistics.
Print memory reference, working set and size statistics.
Vi allows breakpoints to be set on any memory location. These breakpoints monitor when
a location is accessed, read, written, or equals a certain value. For equality the compared
value is the count (see db(1)) supplied to the command.
/sys/src/cmd/vi etc.
nm(1), db(1)
The code generated by the compilers is well supported, but some unusual instructions are unim­
plemented. Some Plan 9 system calls such as rfork cause simulated traps. The floating point
simulation makes assumptions about the interpreting machines floating point support. The float­
ing point conversions performed by vi may cause a loss of precision.
vncs, vncv remote frame buffer server and viewer for Virtual Network Computing (VNC)
vncs [ −v ] [ −c cert ] [ −d :display ] [ −g widthxheight ] [ −p pixfmt ] [ −x net ] [ cmd [ args ] ]
vncs −k :display [ −x net ]
vncv [ −cstv ] [ −e encodings ] [ −k keypattern ] host[:n]
VNC is a lightweight protocol for accessing graphical applications remotely. The protocol allows
one or more clients to connect to a server. While connected, clients display the frame buffer pre­
sented by the server and can send mouse events, keyboard events, and exchange snarf buffers.
The server persists across viewer sessions, so that the virtual application can be accessed from
various locations as its owner moves around.
VNC displays have names of the form host:n, where host is the machines network name and n is
a small integer identifier; display n is served on TCP port 5900+n.
Vncs starts a new virtual frame buffer in memory, simulating a Plan 9 terminal running cmd args,
by default an interactive shell. As viewers connect, each is authenticated using a (rather breakable)
challenge-response protocol using the users Inferno/POP password.
The options are:
−c cert
start TLS on each viewer connection using the certificate in the file cert. The corre­
sponding private key must be loaded into the servers factotum(4). When serving TLS
connections, the base port is 35729 rather than 5900.
−d :n
run on display n ; without this option, the server searches for an unused display.
−g widthxheight
set the virtual frame buffer to be widthxheight (default 1024x768) pixels.
−p pixfmt set the virtual frame buffers internal pixel format to pixfmt (default r5g6b5).
print verbose output to standard error.
−x net
announce on an alternate network interface. Because of the weak authentication pro­
tocol and default lack of encryption, this option must be accompanied by −c.
The command vncs −k :n kills the VNC server running on display n.
Vncv provides access to remote display host:n. It resizes its window to be the smaller of the
remote frame buffer size and the local screen.
The options are:
when connecting to 8-bit displays, request r4g4b4 pixels rather than r3g3b2 pixels.
This takes up more bandwidth but usually gives significantly better matching to the Plan 9
color map.
−e encodings
set the ordered list of allowed frame buffer update encodings. The default (and full) set is
copyrect corre hextile rre raw. The encodings should be given as a single
space-separated argument (quoted when using the shell).
−k keypattern
add keypattern to the pattern used to select a key from factotum(4).
share the display with extant viewers; by default extant viewers are closed when a new
viewer connects.
start TLS on the connection.
print verbose output to standard error.
The VNC protocol represents keyboard input as key up/down events. Plan 9 does not expose the
state of the Ctl and Shift keys except as it can be inferred from receipt of control or shifted charac­
ters. It does not expose the state of the Alt key at all, since the Alt key is used to compose
Unicode characters (see keyboard (6)). Vncv correctly handles the sending of control and shifted
characters. To support systems that use key sequences like Alt-X (or worse, Alt-mouse-click), typ­
ing the Plan 9 compose sequences Alt Z A (for Alt), Alt Z C (for Ctrl), and Alt Z S (for Shift)
will send a key down message for the given key. A corresponding key up message will be
sent after the next key is pressed, or when the sequence is retyped, whichever happens first.
If the remote frame buffer is larger than the local screen, only the upper left corner can be
Vncv does no verification of the TLS certificate presented by the server.
Vncv supports only version 3.3 of the RFB protocol.
vt emulate a VT-100 or VT-220 terminal
vt [ −2abcx ] [ −f font ] [ −l log ]
Vt replaces a rio window with a fresh instance of the shell, rc(1), running within an emulation of a
DEC VT-100 terminal. To exit vt, exit the rc it starts.
x change vt to emulate a VT-220, ANSI, or XTerm terminal respectively.
b changes the color scheme to white text on a black background, but potentially with colors
from escape sequences.
c changes the color scheme to monochrome (no colors).
f sets the font.
l names a log file for the session.
The right button has a menu with the following entries to provide the sort of character processing
expected by non-Plan 9 systems:
Resize the vt window to hold 24 rows of 80 columns.
Print a newline (linefeed) character after receiving a carriage return from the host.
Do not print a newline after carriage return.
Print a carriage return after receiving a newline from the host.
Do not print a carriage return after newline.
Enter raw (no echo, no interpretation) character mode for input.
Leave raw mode.
Exit vt.
The middle button has a menu with the following entries:
Move the display back one screenful.
Move the display forward one screenful. (These are a poor substitute for a scroll
Display the last screenful; the same as going forward to the end.
Clear the screen. Previous contents can be recovered using backup.
Send the contents of the rio snarf buffer, just as send in the rio menu.
Make new lines visible as they appear at the bottom.
When the page fills, pause and wait for a character to be typed before proceeding.
The down arrow key advances a page without sending the character to the host.
This program is used only for communicating with foreign systems, so it is not as rich an emula­
tion as its equivalent in other environments.
Use care in setting raw and newline modes when connecting to Unix systems via con(1) or ssh(1).
It may also be necessary to set the emulator into raw mode.
wc word count
wc [ −lwrbc ] [ file ... ]
Wc counts lines, words, runes, syntactically-invalid UTF codes and bytes in the named files, or in
the standard input if no file is named. A word is a maximal string of characters delimited by
spaces, tabs or newlines. The count of runes includes invalid codes.
If the optional argument is present, just the specified counts (lines, words, runes, broken UTF
codes or bytes) are selected by the letters l, w, r, b, or c. Otherwise, lines, words and bytes
(−lwc) are reported.
The Unicode Standard has many blank characters scattered through it, but wc looks for only ASCII
space, tab and newline.
Wc should have options to count suboptimal UTF codes and bytes that cannot occur in any UTF
weather print weather report
weather [ air ] [ st ]
Weather prints the local conditions and seven-day forecast most recently reported at the US airport
with the three-letter location identifier air. Given a two-letter US state abbreviation st instead,
weather prints a table of air location identifiers known for st.
The arguments are mutually exclusive and case-insensitive. If neither is given, air defaults to loca­
tion identifier ewr, designating the Newark, NJ, airport near Bell Labs, Murray Hill.
who, whois who is using the machine
whois person
Who prints the name of everyone with a non-Exiting process on the current machine.
Whois looks in /adm/whois and /adm/users to find out more information about person.
winwatch monitor rio windows
winwatch [ −e exclude ] [ −f font ]
Winwatch displays the labels of all current rio(4) windows, refreshing the display every five sec­
onds. Right clicking a windows label unhides, raises and gives focus to that window. Typing q or
DEL quits winwatch.
If the −e flag is given, windows matching the regular expression exclude are not shown.
Excluding winwatch, stats and faces from being showed.
% winwatch −e ’^(winwatch|stats|faces)’
rio(1), rio(4), regexp(6).
xd hex, octal, decimal, or ASCII dump
xd [ option ... ] [ −format ... ] [ file ... ]
Xd concatenates and dumps the files (standard input by default) in one or more formats. Groups
of 16 bytes are printed in each of the named formats, one format per line. Each line of output is
prefixed by its address (byte offset) in the input file. The first line of output for each group is
zero-padded; subsequent are blank-padded.
Formats other than −c are specified by pairs of characters telling size and style, 4x by default.
The sizes are
big-endian units.
big-endian units.
big-endian units.
The styles are
Other options are
Format as 1x but print ASCII representations or C escape sequences where possible.
Print file addresses in the given style (and size 4).
(Unbuffered) Flush the output buffer after each 16-byte sequence.
Reverse (swab) the order of bytes in each group of 4 before printing.
Print repeating groups of identical 16-byte sequences as the first group followed by an
The various output formats dont line up properly in the output of xd.
yacc yet another compiler-compiler
yacc [ option ... ] grammar
Yacc converts a context-free grammar and translation code into a set of tables for an LR(1) parser
and translator. The grammar may be ambiguous; specified precedence rules are used to break
The output file,, must be compiled by the C compiler to produce a program yyparse.
This program must be loaded with a lexical analyzer function, yylex(void) (often generated by
lex(1)), with a main(int argc, char *argv[]) program, and with an error handling rou­
tine, yyerror(char*).
The options are
−o output
Direct output to the specified file instead of
Create file y.debug, containing diagnostic messages. To incorporate them in the
parser, compile it with preprocessor symbol yydebug defined. The amount of
diagnostic output from the parser is regulated by value n. The value 0 reports errors;
1 reports reductions; higher values (up to 4) include more information about state
Create file y.output, containing a description of the parsing tables and of con­
flicts arising from ambiguities in the grammar.
Create file, containing #define statements that associate yacc-assigned
token codes with user-declared token names. Include it in source files other than to give access to the token codes.
−s stem
Change the prefix y of the file names,, y.debug, and
y.output to stem.
Write a parser that uses Stdio instead of the print routines in libc.
The specification of yacc itself is essentially the same as the UNIX version described in the refer­
ences mentioned below. Besides the −D option, the main relevant differences are:
The interface to the C environment is by default through <libc.h> rather than
<stdio.h>; the −S option reverses this.
The parser accepts UTF input text (see utf(6)), which has a couple of effects. First, the
return value of yylex() no longer fits in a short; second, the starting value for nonterminals is now 0xE000 rather than 257.
The generated parser can be recursive: actions can call yyparse, for example to implement
a sort of #include statement in an interpreter.
Finally, some undocumented inner workings of the parser have been changed, which may
affect programs that know too much about its structure.
temporary file
temporary file
parser prototype
parser prototype using stdio
S. C. Johnson and R. Sethi, Yacc: A parser generator, Unix Research System Programmer’s Manual, Tenth Edition, Volume 2
B. W. Kernighan and Rob Pike, The UNIX Programming Environment, Prentice Hall, 1984
The parser may not have full information when it writes to y.debug so that the names of the
tokens returned by yylex may be missing.
yesterday, diffy print file names from the dump
yesterday [ −abcCdDs ] [ −n daysago ] [ date ] files ...
diffy [ −abcefmnrw ] files ...
Yesterday prints the names of the files from the most recent dump. Since dumps are done early in
the morning, yesterdays files are really in todays dump. For example, if today is March 17, 1992,
yesterday /adm/users
In fact, the implementation is to select the most recent dump in the current year, so the dump
selected may not be from today.
When presented with a path of the form /n/fs/path, yesterday will look for dump files of the
form /n/fsdump/yyyy/hhmm/path.
By default, yesterday prints the names of the dump files corresponding to the named files. The
first set of options changes this behavior.
Run acme(1)s adiff to compare the dump files with the named files.
Bind the dump files over the named files.
Copy the dump files over the named files.
Copy the dump files over the named files only when they differ.
Run diff to compare the dump files with the named files.
Run diff −n to compare the dump files with the named files.
The date option selects other days dumps, with a format of 1, 2, 4, 6, or 8 digits of the form d,
dd, mmdd, yymmdd, or yyyymmdd .
The −n option selects the dump daysago prior to the current day.
The −s option selects the most recent snapshot instead of the most recent archived dump. Snap­
shots may occur more frequently than dumps.
Yesterday does not guarantee that the string it prints represents an existing file.
Diffy runs diff(1) with the given options to compare yesterdays version of each of the named files
with todays.
Back up to yesterdays MIPS binary of vc:
yesterday −c /mips/bin/vc
Temporarily back up to March 1s MIPS C library to see if a program runs correctly when loaded
with it:
yesterday −b −0301 /mips/lib/libc.a
rm v.out
Find what has changed in the C library since March 1:
yesterday −d −0301 /sys/src/libc/port/*.c
Find what has changed in the source tree today:
diffy −r /sys/src
history(1), bind(1), diff(1), fs(4).
Its hard to use this command without singing.
intro introduction to library functions
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <bio.h>
#include <draw.h>
#include <fcall.h>
#include <frame.h>
#include <mach.h>
#include <ndb.h>
#include <regexp.h>
#include <stdio.h>
#include <thread.h>
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 /$objtype/lib/libx.a, where x is the base of the
include file name, stripped of a leading lib if present. For example, <draw.h> defines the con­
tents of library /$objtype/lib/libdraw.a, which may be abbreviated when named to the
loader as −ldraw. In practice, each include file contains a #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.
The library to which a function belongs is defined by the header file that defines its interface. The
C library, libc, contains most of the basic subroutines such as strlen. Declarations for all of these
functions are in <libc.h>, which must be preceded by (needs) an include of <u.h>. The
graphics library, draw, is defined by <draw.h>, which needs <libc.h> and <u.h>. The Buf­
fered I/O library, libbio, is defined by <bio.h>, which needs <libc.h> and <u.h>. The ANSI
C Standard I/O library, libstdio, is defined by <stdio.h>, which needs <u.h>. There are a few
other, less commonly used libraries defined on individual pages of this section.
The include file <u.h>, a prerequisite of several other include files, declares the architecturedependent and -independent types, including: uchar, ushort, uint, and ulong, the unsigned inte­
ger types; schar, the signed char type; vlong and uvlong, the signed and unsigned very long inte­
gral types; Rune, the Unicode character type; u8int, u16int, u32int, and u64int, the unsigned inte­
gral types with specific widths; uintptr, the unsigned integral type with the same width as a
pointer; jmp_buf, the type of the argument to setjmp and longjmp, plus macros that define the lay­
out of jmp_buf (see setjmp(2)); definitions of the bits in the floating-point control register as used
by getfcr(2); and the macros va_arg and friends for accessing arguments of variadic functions
(identical to the macros defined in <stdarg.h> in ANSI C).
Name space
Files are collected into a hierarchical organization called a file tree starting in a directory called the
root. File names, also called paths, consist of a number of /-separated path elements with the
slashes corresponding to directories. A path element must contain only printable characters (those
outside the control spaces of ASCII and Latin-1). A path element cannot contain a slash.
When a process presents a file name to Plan 9, it is evaluated by the following algorithm. Start
with a directory that depends on the first character of the path: / means the root of the main hier­
archy, # means the separate root of a kernel devices file tree (see Section 3), and anything else
means the processs 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 name space of a process.
A program can use bind or mount (see bind(2)) to say that whenever a specified file is reached dur­
ing evaluation, evaluation instead continues from a second specified file. Also, the same system
calls create union directories, which are concatenations of ordinary directories that are searched
sequentially until the desired element is found. Using bind and mount to do name space adjust­
ment affects only the current process group (see below). Certain conventions about the layout of
the name space should be preserved; see namespace(4).
File I/O
Files are opened for input or output by open or create (see open(2)). These calls return an integer
called a file descriptor which identifies the file to subsequent I/O calls, notably read(2) and 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 dup(2). File descriptors are indices into a kernel resident file
descriptor table. Each process has an associated file descriptor table. In some cases (see rfork in
fork(2)) a file descriptor table may be shared by several processes.
By convention, file descriptor 0 is the standard input, 1 is the standard output, and 2 is the stan­
dard 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 bro­
ken processes to file descriptor 2.
Files are normally read or written in sequential order. The I/O position in the file is called the file
offset and may be set arbitrarily using the seek(2) system call.
Directories may be opened and read much like regular files. They contain an integral number of
records, called directory entries. Each entry is a machine-independent representation of the infor­
mation 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 stat(2) or fstat;
wstat and fwstat write back entries, thus changing the properties of a file. An entry may be trans­
lated into a more convenient, addressable form called a Dir structure; dirstat, dirfstat, dirwstat,
and dirfwstat execute the appropriate translations (see stat(2)).
New files are made with create (see open(2)) and deleted with remove(2). Directories may not
directly be written; create, remove, wstat, and fwstat alter them.
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 / or #), the system makes the stored
name absolute by prefixing the string associated with the current directory. Similar lexical adjust­
ments are made for path names containing . (dot) or .. (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
errorthe name is not maintained after the file is opened, so removals and renamings can con­
found itthis simple method usually permits the system to return, via the fd2path(2) system call
and related calls such as 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 ns(1) or /dev/ns (see proc(3)).
Pipe(2) creates a connected pair of file descriptors, useful for bidirectional local communication.
Process execution and control
A new process is created when an existing one calls rfork with the RFPROC bit set, usually just by
calling 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; exec(2) will bring in a different one.
Each process has a unique integer process id; a set of open files, indexed by file descriptor; and a
current working directory (changed by chdir(2)).
Each process has a set of attributes memory, open files, name space, etc. that may be shared
or unique. Flags to rfork control the sharing of these attributes.
The memory of a process is divided into segments. Every program has at least a text (instruction)
and stack segment. Most also have an initialized data segment and a segment of zero-filled data
called bss. Processes may segattach(2) other segments for special purposes.
A process terminates by calling exits(2). A parent process may call wait(2) to wait for some child to
terminate. A string of status information may be passed from exits to wait. A process can go to
sleep for a specified time by calling sleep(2).
There is a notification mechanism for telling a process about events such as address faults, float­
ing point faults, and messages from other processes. A process uses notify(2) to register the func­
tion to be called (the notification handler) when such events occur.
By calling rfork with the 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 pro­
cess). Where possible according to the ANSI C standard, the main C library works properly in mul­
tiprocess programs; malloc, print, and the other routines use locks (see lock(2)) to synchronize
access to their data structures. The graphics library defined in <draw.h> is also multi-process
capable; details are in graphics(2). In general, though, multiprocess programs should use some
form of synchronization to protect shared data.
The thread library, defined in <thread.h>, provides support for multiprocess programs. It
includes a data structure called a Channel that can be used to send messages between pro­
cesses, and coroutine-like threads, which enable multiple threads of control within a single pro­
cess. 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
Most programs using the thread library comprise multiple processes communicating over chan­
nels, 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 shouldnt 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 ioproc(2) or mouse(2).
nm(1), 2l(1), 2c(1)
Math functions in libc return special values when the function is undefined for the given arguments
or when the value is not representable (see nan(2)).
Some of the functions in libc are system calls and many others employ system calls in their imple­
mentation. All system calls return integers, with 1 indicating that an error occurred; errstr(2)
recovers a string describing the error. Some user-level library functions also use the errstr mecha­
nism to report errors. Functions that may affect the value of the error string are said to set
errstr; it is understood that the error string is altered only if an error occurs.
Srv, dirread9p, emalloc9p, erealloc9p, estrdup9p, listensrv, postfd, postmountsrv, readbuf, read­
str, respond, responderror, threadlistensrv, threadpostmountsrv, srv 9P file service
typedef struct Srv {
Tree* tree;
(*attach)(Req *r);
(*auth)(Req *r);
(*open)(Req *r);
(*create)(Req *r);
(*read)(Req *r);
(*write)(Req *r);
(*remove)(Req *r);
(*flush)(Req *r);
(*stat)(Req *r);
(*wstat)(Req *r);
(*walk)(Req *r);
char* (*walk1)(Fid *fid, char *name, Qid *qid);
char* (*clone)(Fid *oldfid, Fid *newfid);
} Srv;
(*destroyfid)(Fid *fid);
(*destroyreq)(Req *r);
(*end)(Srv *s);
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)
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)
void* emalloc9p(ulong n)
void* erealloc9p(void *v, ulong n)
char* estrdup9p(char *s)
extern int chatty9p;
The function srv serves a 9P session by reading requests from s−>infd, dispatching them to the
function pointers kept in Srv, and writing the responses to s−>outfd. (Typically, postmountsrv
or threadpostmountsrv initializes the infd and outfd structure members. See the description
Req and Fid structures are allocated one-to-one with uncompleted requests and active fids, and
are described in 9pfid(2).
The behavior of srv depends on whether there is a file tree (see 9pfile(2)) associated with the
server, that is, whether the tree element is nonzero. The differences are made explicit in the dis­
cussion of the service loop below. The aux element is the clients, to do with as it pleases.
Srv does not return until the 9P conversation is finished. Since it is usually run in a separate pro­
cess so that the caller can exit, the service loop has little chance to return gracefully on out of
memory errors. It calls emalloc9p, erealloc9p, and estrdup9p to obtain its memory. The default
implementations of these functions act as malloc, realloc, and strdup but abort the program if
they run out of memory. If alternate behavior is desired, clients can link against alternate imple­
mentations of these functions.
Postmountsrv and threadpostmountsrv are wrappers that create a separate process in which to run
srv. They do the following:
If s−>nopipe is zero (the common case), initialize s−>infd and s−>outfd to be one end of
a freshly allocated pipe, with s−>srvfd initialized as the other end.
If name is non-nil, call postfd(s−>srvfd, name) to post s−>srvfd as /srv/name.
Fork a child process via rfork (see fork(2)) or procrfork (see thread(2)), using the RFFDG,
RFNAMEG, and RFMEM flags. The child process calls close(s−>srvfd) and then srv(s); it
will exit once srv returns.
If mtpt is non-nil, call amount(s−>srvfd, mtpt, flag, ""); otherwise, close s−>srvfd.
The parent returns to the caller.
If any error occurs during this process, the entire process is terminated by calling sysfatal (see
Listensrv and threadlistensrv create a separate process to announce as addr. The process listens
for incoming connections, creating a new process to serve each. Using these functions results in
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
Service functions
The functions in a Srv structure named after 9P transactions are called to satisfy requests as they
arrive. If a function is provided, it must arrange for respond to be called when the request is satis­
fied. The only parameter of each service function is a Req* parameter (say r). The incoming
request parameters are stored in r−>ifcall; r−>fid and r−>newfid are pointers to Fid structures
corresponding to the numeric fids in r−>ifcall; similarly, r−>oldreq is the Req structure corre­
sponding to r−>ifcall.oldtag. The outgoing response data should be stored in r−>ofcall. The
one exception to this rule is that stat should fill in r−>d rather than r−>ofcall.stat: the library will
convert the structure into the machine-independent wire representation. Similarly, wstat may con­
sult r−>d rather than decoding r−>ifcall.stat itself. When a request has been handled, respond
should be called with 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 call­
ing respond, as long as it has arranged for respond to be called at some point in the future by
another proc sharing its address space, but see the discussion of flush below. Once respond has
been called, the Req* as well as any pointers it once contained must be considered freed and not
Responderror calls respond with the system error string (see errstr(2)).
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 con­
sulting the service functions.
The service loop provided by srv (and indirectly by postmountsrv and threadpostmountsrv) is
single-threaded. If it is expected that some requests might block, arranging for alternate pro­
cesses to handle them is suggested.
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, srv will call endsrv
and then abort.
If authentication is desired, the auth function should record that r−>afid is the new
authentication fid and set r−>afid−>qid and ofcall.qid. Auth may be nil, in which case it
will be treated as having responded with the error argv0: authentication not required,
where argv0 is the program name variable as set by ARGBEGIN (see arg(2)).
Attach The attach function should check the authentication state of afid if desired, and set
r−>fid−>qid and ofcall.qid to the qid of the file system root. 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 authenti­
cation will be done.
If file trees are in use, walk is handled internally, and srv−>walk is never called.
If file trees are not in use, walk should consult r−>ifcall.wname and r−>ifcall.nwname,
filling in ofcall.qid and ofcall.nqid, and also copying any necessary aux state from r−>fid
to r−>newfid when the two are different. As long as walk sets ofcall.nqid appropriately, it
can respond with a nil error string even when 9P demands an error (e.g., in the case of a
short walk); the library detects error conditions and handles them appropriately.
Because implementing the full walk message is intricate and prone to error, the helper rou­
tine walkandclone will handle the request given pointers to two functions walk1 and
(optionally) clone . Clone, if non-nil, is called to signal the creation of newfid from oldfid.
Typically a clone routine will copy or increment a reference count in oldfids aux element.
Walk1 should walk fid to name, initializing fid−>qid to the new paths qid. Both should
return nil on success or an error message on error. Walkandclone will call respond after
handling the request.
Walk1, Clone
If the client provides functions srv−>walk1 and (optionally) srv−>clone, the 9P service
loop will call walkandclone with these functions to handle the request. Unlike the walk1
above, srv−>walk1 must fill in both fid−>qid and *qid with the new qid on a successful
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.
If not using file trees or the user has the appropriate permissions, open is called with
r−>ofcall.qid already initialized to the one stored in the Fid structure (that is, the one
returned in the previous walk). If the qid changes, both should be updated.
Create The create function must fill in both r−>fid−>qid and r−>ofcall.qid on success. When
using file trees, create should allocate a new File with createfile; note that createfile may
return nil (because, say, the file already exists). If the create function is nil, srv behaves as
though it were a function that always responded with the error create prohibited.
Remove should mark the file as removed, whether by calling removefile when using file
trees, or by updating an internal data structure. In general it is not a good idea to clean up
the aux information associated with the corresponding File at this time, to avoid memory
errors if other fids have references to that file. Instead, it is suggested that remove simply
mark the file as removed (so that further operations on it know to fail) and wait until the file
trees destroy function is called to reclaim the aux pointer. If not using file trees, it is pru­
dent to take the analogous measures. If remove is not provided, all remove requests will
draw remove prohibited errors.
The read function must be provided; it fills r−> with at most r−>ifcall.count
bytes of data from offset r−>ifcall.offset of the file. It also sets r−>ofcall.count to the
number of bytes being returned. If using file trees, srv will handle reads of directories
internally, only calling read for requests on files. Readstr and readbuf are useful for
satisfying read requests on a string or buffer. Consulting the request in r−>ifcall, they fill
r−> and set r−>ofcall.count; they do not call respond. Similarly, dirread9p
can be used to handle directory reads in servers not using file trees. The passed gen func­
tion will be called as necessary to fill dir with information for the nth entry in the directory.
The string pointers placed in dir should be fresh copies made with estrdup9p; they will be
freed by dirread9p after each successful call to gen. Gen should return zero if it success­
fully filled dir, minus one on end of directory.
The write function is similar but need not be provided. If it is not, all writes will draw
write prohibited errors. Otherwise, write should attempt to write the r−>ifcall.count
bytes of r−> to offset r−>ifcall.offset of the file, setting r−>ofcall.count to
the number of bytes actually written. Most programs consider it an error to write less than
the requested amount.
Stat should fill r−>d with the stat information for r−>fid. If using file trees, r−>d will
have been initialized with the stat info from the tree, and stat itself may be nil.
Wstat The wstat consults r−>d in changing the metadata for r−>fid as described in stat(5). When
using file trees, srv will take care to check that the request satisfies the permissions out­
lined in stat(5). Otherwise wstat should take care to enforce permissions where appropri­
Servers that always call respond before returning from the service functions need not pro­
vide a flush implementation: flush is only necessary in programs that arrange for respond
to be called asynchronously. Flush should cause the request r−>oldreq to be cancelled or
hurried along. If oldreq is cancelled, this should be signalled by calling respond on oldreq
with error string interrupted. Flush must respond to r with a nil error string. Flush
may respond to r before forcing a response to r−>oldreq. In this case, the library will
delay sending the Rflush message until the response to r−>oldreq has been sent.
Destroyfid, destroyreq, and end are auxiliary functions, not called in direct response to 9P
When a Fids reference count drops to zero (i.e., it has been clunked and there are no out­
standing requests referring to it), destroyfid is called to allow the program to dispose of the
fid−>aux pointer.
Similarly, when a Reqs reference count drops to zero (i.e., it has been handled via respond
and other outstanding pointers to it have been closed), destroyreq is called to allow the
program to dispose of the r−>aux pointer.
Once the 9P service loop has finished (end of file been reached on the service pipe or a bad
message has been read), 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 ter­
minate the serial conversation once the file system had been unmounted. After calling end,
the service loop (which runs in a separate process from its caller) terminates using _exits
(see exits(2)).
If the chatty9p flag is at least one, a transcript of the 9P session is printed on standard error. If
the chatty9p flag is greater than one, additional unspecified debugging output is generated. By
convention, servers written using this library accept the −D option to increment chatty9p.
Archfs(4), cdfs(4), nntpfs(4), snap(4), and /sys/src/lib9p/ramfs.c are good examples of
simple single-threaded file servers. Webfs(4) and sshnet (see ssh(1)) are good examples of multi­
threaded file servers.
In general, the File interface is appropriate for maintaining arbitrary file trees (as in ramfs). The
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 cdfs and nntpfs) or is maintained elsewhere.
9pfid(2), 9pfile(2), srv(3), intro(5)
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.
Cmdbuf, parsecmd, respondcmderror, lookupcmd control message parsing
typedef struct Cmdbuf
} Cmdbuf;
typedef struct Cmdtab
*parsecmd(char *p, int n)
*lookupcmd(Cmdbuf *cb, Cmdtab *tab, int ntab)
respondcmderror(Req *r, Cmdbuf *cb, char *fmt, ...)
These data structures and functions provide parsing of textual control messages.
Parsecmd treats the n bytes at p (which need not be NUL-terminated) as a UTF string and splits it
using tokenize (see getfields(2)). It returns a Cmdbuf structure holding pointers to each field in
the message. It is the callers responsibility to free this structure when it is no longer needed.
Lookupcmd walks through the array ctab, which has ntab entries, looking for the first Cmdtab
that matches the parsed command. (If the parsed command is empty, lookupcmd returns nil
immediately.) A Cmdtab matches the command if cmd is equal to cb−>f[0] or if cmd is *.
Once a matching Cmdtab has been found, if narg is not zero, then the parsed command must
have exactly narg fields (including the command string itself). If the command has the wrong
number of arguments, lookupcmd returns nil. Otherwise, it returns a pointer to the Cmdtab
entry. If lookupcmd does not find a matching command at all, it returns nil. Whenever lookupcmd
returns nil, it sets the system error string.
Respondcmderror resoponds to request r with an error of the form fmt: cmd, where fmt is the
formatted string and cmd is a reconstruction of the parsed command. Fmt is often simply %r .
This interface is not used in any distributed 9P servers. It was lifted from the Plan 9 kernel.
Almost any kernel driver (/sys/src/9/*/dev*.c) is a good example.
Fid, Fidpool, allocfidpool, freefidpool, allocfid, closefid, lookupfid, removefid, Req, Reqpool,
allocreqpool, freereqpool, allocreq, closereq, lookupreq, removereq 9P fid, request tracking
typedef struct Fid
ulong fid;
char omode; /* −1 if not open */
char *uid;
File *file;
void *aux;
} Fid;
typedef struct Req
ulong tag;
Fcall ifcall;
Fcall ofcall;
void *aux;
} Req;
allocfidpool(void (*destroy)(Fid*))
freefidpool(Fidpool *p)
allocfid(Fidpool *p, ulong fid)
lookupfid(Fidpool *p, ulong fid)
removefid(Fidpool *p, ulong fid);
closefid(Fid *f)
allocreqpool(void (*destroy)(Req*))
freereqpool(Reqpool *p)
allocreq(Reqpool *p, ulong tag)
lookupreq(Reqpool *p, ulong tag)
removereq(Reqpool *p, ulong tag);
closereq(Req *f)
These routines provide management of Fid and Req structures from Fidpools and Reqpools.
They are primarily used by the 9P server loop described in 9p(2).
Fid structures are intended to represent active fids in a 9P connection, as Chan structures do in
the Plan 9 kernel. The fid element is the integer fid used in the 9P connection. Omode is the
mode under which the fid was opened, or −1 if this fid has not been opened yet. Note that in
addition to the values OREAD, OWRITE, and ORDWR, omode can contain the various flags permis­
sible in an open call. To ignore the flags, use omode&OMASK. Omode should not be changed by
the client. The fid derives from a successful authentication by uid. Qid contains the qid
returned in the last successful walk or create transaction involving the fid. In a file tree-based
server, the Fids file element points at a File structure (see 9pfile(2)) corresponding to the
fid. The aux member is intended for use by the client to hold information specific to a particular
Fid. With the exception of aux, these elements should be treated as read-only by the client.
Allocfidpool creates a new Fidpool. Freefidpool destroys such a pool. Allocfid returns a new
Fid whose fid number is fid. There must not already be an extant Fid with that number in the
pool. Once a Fid has been allocated, it can be looked up by fid number using lookupfid. Fids
are reference counted: both allocfid and lookupfid increment the reference count on the Fid struc­
ture before returning. When a reference to a Fid is no longer needed, closefid should be called to
note the destruction of the reference. When the last reference to a Fid is removed, if destroy
(supplied when creating the fid pool) is not zero, it is called with the Fid as a parameter. It
should perform whatever cleanup is necessary regarding the aux element. Removefid is equiva­
lent to lookupfid but also removes the Fid from the pool. Note that due to lingering references,
the return of removefid may not mean that destroy has been called.
Allocreqpool, freereqpool, allocreq, lookupreq, closereq, and removereq are analogous but operate
on Reqpools and Req structures.
9p(2), 9pfile(2)
Tree, alloctree, freetree, File, createfile, closefile, removefile, walkfile, opendirfile, readdirfile,
closedirfile, hasperm in-memory file hierarchy
typedef struct File
} File;
typedef struct Tree
File *root;
} Tree;
alloctree(char *uid, char *gid, ulong mode,
void (*destroy)(File*))
freetree(Tree *tree)
createfile(File *dir, char *name, char *uid,
ulong mode, void *aux)
removefile(File *file)
closefile(File *file)
walkfile(File *dir, char *path)
Readdir* opendirfile(File *dir)
readdirfile(Readdir *rdir, uchar *buf, long n)
closedirfile(Readdir *rdir)
hasperm(File *file, char *uid, int p)
Files and Trees provide an in-memory file hierarchy intended for use in 9P file servers.
Alloctree creates a new tree of files, and freetree destroys it. The root of the tree (also the root
element in the structure) will have mode mode and be owned by user uid and group gid. Destroy is
used when freeing File structures and is described later.
Files (including directories) other than the root are created using createfile, which attempts to
create a file named name in the directory dir. If created, the file will have owner uid and have a
group inherited from the directory. Mode and the permissions of dir are used to calculate the per­
mission bits for the file as described in open(5). It is permissible for name to be a slash-separated
path rather than a single element.
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. Removefile returns zero on
success, 1 on error. It is correct to consider removefile to be closefile with the side effect of
removing the file when possible.
Walkfile evaluates path relative to the directory dir, returning the resulting file, or zero if the
named file or any intermediate element does not exist.
The File structures aux pointer may be used by the client for per-File storage. Files are
reference-counted: if not zero, destroy (specified in the call to alloctree) will be called for each file
when its last reference is removed or when the tree is freed. Destroy should take care of any nec­
essary cleanup related to aux. When creating new file references by copying pointers, call incref
(see lock(2)) to update the reference count. To note the removal of a reference to a file, call
closefile. Createfile and walkfile return new references. Removefile, closefile, and walkfile (but not
createfile) consume the passed reference.
Directories may be read, yielding a directory entry structure (see stat(5)) for each file in the direc­
tory. In order to allow concurrent reading of directories, clients must obtain a Readdir structure
by calling opendirfile on a directory. Subsequent calls to readdirfile will each yield an integral
number of machine-independent stat buffers, until end of directory. When finished, call
closedirfile to free the Readdir.
Hasperm does simplistic permission checking; it assumes only one-user groups named by uid and
returns non-zero if uid has permission p (a bitwise-or of AREAD, AWRITE and AEXEC) according
to file−>mode. 9P servers written using File trees will do standard permission checks automati­
cally; hasperm may be called explicitly to do additional checks. A 9P server may link against a dif­
ferent hasperm implementation to provide more complex groups.
The following code correctly handles references when elementwise walking a path and creating a
f = tree−>root;
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);
return nf;
The reference counting is cumbersome.
abort generate a fault
#include <u.h>
#include <libc.h>
void abort(void)
Abort causes an access fault, causing the current process to enter the Broken state. The process
can then be inspected by a debugger.
abs, labs integer absolute values
#include <u.h>
#include <libc.h>
abs(int a)
long labs(long a)
Abs returns the absolute value of integer a, and labs does the same for a long.
floor(2) for fabs
Abs and labs return the most negative integer or long when the true result is unrepresentable.
access determine accessibility of file
#include <u.h>
#include <libc.h>
int access(char *name, int mode)
Access evaluates the given file name for accessibility. If mode&4 is nonzero, read permission is
expected; if mode&2, write permission; if mode&1, execute permission. If mode==0, 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.
Only access for open is checked. A file may look executable, but exec(2) will fail unless it is in
proper format.
The include file defines AEXIST=0, AEXEC=1, AWRITE=2, and AREAD=4.
Sets errstr.
Since file permissions are checked by the server and group information is not known to the client,
access must open the file to check permissions. (It calls stat(2) to check simple existence.)
addpt, subpt, mulpt, divpt, rectaddpt, rectsubpt, insetrect, canonrect, eqpt, eqrect, ptinrect, rectin­
rect, rectXrect, rectclip, combinerect, Dx, Dy, Pt, Rect, Rpt arithmetic on points and rectangles
#include <u.h>
#include <libc.h>
#include <draw.h>
addpt(Point p, Point q)
subpt(Point p, Point q)
mulpt(Point p, int a)
divpt(Point p, int a)
Rectangle rectaddpt(Rectangle r, Point p)
Rectangle rectsubpt(Rectangle r, Point p)
Rectangle insetrect(Rectangle r, int n)
Rectangle canonrect(Rectangle r)
eqpt(Point p, Point q)
eqrect(Rectangle r, Rectangle s)
ptinrect(Point p, Rectangle r)
rectinrect(Rectangle r, Rectangle s)
rectXrect(Rectangle r, Rectangle s)
rectclip(Rectangle *rp, Rectangle b)
combinerect(Rectangle *rp, Rectangle b)
Dx(Rectangle r)
Dy(Rectangle r)
Pt(int x, int y)
Rectangle Rect(int x0, int y0, int x1, int y1)
Rectangle Rpt(Point p, Point q)
The functions Pt, Rect and Rpt construct geometrical data types from their components.
Addpt returns the Point sum of its arguments: Pt(p.x+q.x, p.y+q.y). Subpt returns the
Point difference of its arguments: Pt(p.x−q.x, p.y−q.y). Mulpt returns the Point
Pt(p.x*a, p.y*a). Divpt returns the Point Pt(p.x/a, p.y/a).
Rectaddpt returns the Rectangle Rect(add(r.min, p), add(r.max, p)); rectsubpt returns
the Rectangle Rpt(sub(r.min, p), sub(r.max, p)).
Insetrect returns the Rectangle Rect(r.min.x+n, r.min.y+n, r.max.x−n, r.max.y−n).
Canonrect returns a rectangle with the same extent as r, canonicalized so that min.x d max.x,
and min.y d max.y.
Eqpt compares its argument Points and returns 0 if unequal, 1 if equal. Eqrect does the same for
its argument Rectangles.
Ptinrect returns 1 if p is a point within r, and 0 otherwise.
Rectinrect returns 1 if all the pixels in r are also in s, and 0 otherwise.
RectXrect returns 1 if r and s share any point, and 0 otherwise.
Rectclip clips in place the Rectangle pointed to by rp so that it is completely contained within b.
The return value is 1 if any part of *rp is within b. Otherwise, the return value is 0 and *rp is
Combinerect overwrites *rp with the smallest rectangle sufficient to cover all the pixels of *rp
and b.
The functions Dx and Dy give the width (”x) and height (”y) of a Rectangle. They are implemented
as macros.
setupAESstate, aesCBCencrypt, aesCBCdecrypt, aesCTRencrypt, aesCTRdecrypt, setupAESXCBC­
state, aesXCBCmac - advanced encryption standard (rijndael)
void aes_encrypt(ulong rk[], int Nr, uchar pt[16], uchar ct[16]);
void aes_decrypt(ulong rk[], int Nr, uchar ct[16], uchar pt[16]);
void setupAESstate(AESstate
void aesCBCencrypt(uchar *p, int len, AESstate *s)
void aesCBCdecrypt(uchar *p, int len, AESstate *s)
void aesCTRencrypt(uchar *p, int len, AESstate *s)
void aesCTRdecrypt(uchar *p, int len, AESstate *s)
void setupAESXCBCstate(AESstate *s)
void aesXCBCmac(uchar *p, int len, AESstate *s)
AES (a.k.a. Rijndael) has replaced DES as the preferred block cipher. Aes_encrypt and aes_decrypt
are the block ciphers, corresponding to des(2)s block_cipher. SetupAESstate, aesCBCencrypt, and
aesCBCdecrypt implement cipher-block-chaining encryption. AesCTRencrypt and aesCTRdecrypt
implement counter mode, per RFC 3686; they are identical operations. setupAESXCBCstate and
aesXCBCmac implement AES XCBC message authentication, per RFC 3566. All ciphering is per­
formed in place. Keybytes should be 16, 24, or 32. The initialization vector ivec of AESbsize bytes
should be random enough to be unlikely to be reused but does not need to be cryptographically
strongly unpredictable.
aescbc in secstore(1), mp(2), blowfish(2), des(2), dsa(2), elgamal(2), rc4(2), rsa(2), sechash(2),
prime(2), rand(2)−197.pdf
The functions aes_encrypt, aes_decrypt, aesCTRencrypt, aesCTRdecrypt, setupAESXCBCstate, and
aesXCBCmac have not yet been verified by running test vectors through them.
allocimage, allocimagemix, freeimage, nameimage, namedimage, setalpha, loadimage, cloadim­
age, unloadimage, readimage, writeimage, bytesperline, wordsperline allocating, freeing, read­
ing, writing images
#include <u.h>
#include <libc.h>
#include <draw.h>
Image *allocimage(Display *d, Rectangle r,
ulong chan, int repl, int col)
Image *allocimagemix(Display *d, ulong one, ulong three)
freeimage(Image *i)
nameimage(Image *i, char *name, int in)
Image *namedimage(Display *d, char *name)
ulong setalpha(ulong color, uchar alpha)
loadimage(Image *i, Rectangle r, uchar *data, int ndata)
cloadimage(Image *i, Rectangle r, uchar *data, int ndata)
unloadimage(Image *i, Rectangle r, uchar *data, int ndata)
Image *readimage(Display *d, int fd, int dolock)
writeimage(int fd, Image *i, int dolock)
bytesperline(Rectangle r, int d)
wordsperline(Rectangle r, int d)
= 0xFFFFFF00,
= DNotacolor,
A new Image on Display d is allocated with allocimage; it will have the rectangle, pixel
channel format, and replication flag given by its arguments. Convenient pixel channels like
GREY1, GREY2, CMAP8, RGB16, RGB24, and RGBA32 are predefined. All the new images pix­
els will have initial value col. If col is DNofill, no initialization is done. Representative useful
values of color are predefined: DBlack, DWhite, DRed, and so on. Colors are specified by 32bit 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 id field will have been set to the identifying number used
by /dev/draw (see draw(3)), and the cache field will be zero. If repl is true, the clip rectangle is
set to a very large region; if false, it is set to r. The depth field will be set to the number of bits per
pixel specified by the channel descriptor (see image(6)). Allocimage returns 0 if the server has run
out of image memory.
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 one and the other three with three. (This
simulates a wider range of tones than can be represented by a single pixel value on a colormapped 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.
Freeimage frees the resources used by its argument image.
Nameimage publishes in the server the image i under the given name. If in is non-zero, the image
is published; otherwise i must be already named name and it is withdrawn from publication.
Namedimage returns a reference to the image published under the given name on Display d.
These routines permit unrelated applications sharing a display to share an image; for example they
provide the mechanism behind getwindow (see graphics(2)).
The RGB values in a color are premultiplied by the alpha value; for example, a 50% red is
0x7F00007F not 0xFF00007F. The function setalpha performs the alpha computation on a
given color, ignoring its initial alpha value, multiplying the components by the supplied alpha.
For example, to make a 50% red color value, one could execute setalpha(DRed, 0x7F).
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 image(6)).
Unloadimage reads a rectangle of pixels from image i into data, whose length is specified by
ndata. It is an error if ndata is too small to accommodate the pixels.
Loadimage replaces the specified rectangle in image i with the ndata bytes of data.
The pixels are presented one horizontal line at a time, starting with the top-left pixel of 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 data, regardless of the rectangle being extracted. Bytes are filled from most to least signifi­
cant bit order, as the x coordinate increases, aligned so x=0 would appear as the leftmost pixel of
its byte. Thus, for depth 1, the pixel at x offset 165 within the rectangle will be in a data byte at
bit-position 0x04 regardless of the overall rectangle: 165 mod 8 equals 5, and 0x80 >> 5
equals 0x04.
Cloadimage does the same as loadimage, but for ndata bytes of compressed image data (see
image(6)). On each call to cloadimage, the data must be at the beginning of a compressed data
block, in particular, it should start with the y coordinate and data length for the block.
Loadimage , cloadimage, and unloadimage return the number of bytes copied.
Readimage creates an image from data contained in an external file (see image(6) for the file for­
mat); fd is a file descriptor obtained by opening such a file for reading. The returned image is allo­
cated using allocimage. The dolock flag specifies whether the Display should be synchronized
for multithreaded access; single-threaded programs can leave it zero.
Writeimage writes image i onto file descriptor fd, which should be open for writing. The format is
as described for readimage.
Readimage and writeimage do not close fd.
Bytesperline and wordsperline return the number of bytes or words occupied in memory by one
scan line of rectangle r in an image with d bits per pixel.
To allocate a single-pixel replicated image that may be used to paint a region red,
red = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DRed);
graphics(2), draw(2), draw(3), image(6)
These functions return pointer 0 or integer 1 on failure, usually due to insufficient memory.
May set errstr.
Depth must be a divisor or multiple of 8.
ARGBEGIN, ARGEND, ARGC, ARGF, EARGF process option letters from argv
#include <u.h>
#include <libc.h>
char *ARGF();
char *EARGF(code);
Rune ARGC();
extern char *argv0;
These macros assume the names argc and argv are in scope; see exec(2). ARGBEGIN and 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
−−, before an argument −, or before an argument that doesnt begin with −.
The function macro ARGC returns the current option character, as an integer.
The function macro ARGF returns the current option argument: a pointer to the rest of the option
string if not empty, or the next argument in argv if any, or 0. ARGF must be called just once for
each option argument. The macro EARGF is like ARGF but instead of returning zero runs code and,
if that returns, calls abort(2). A typical value for code is usage(), as in EARGF(usage()).
After ARGBEGIN, argv0 is a copy of argv[0] (conventionally the name of the program).
After ARGEND, argv points at a zero-terminated list of the remaining argc arguments.
This C program can take option b and option f, which requires an argument.
#include <u.h>
#include <libc.h>
main(int argc, char *argv[])
char *f;
print("%s", argv[0]);
case ’b’:
print(" −b");
case ’f’:
print(" −f(%s)", (f=ARGF())? f: "no arg");
print(" badflag(’%c’)", ARGC());
print(" %d args:", argc);
print(" ’%s’", *argv++);
Here is the output from running the command prog −bffile1 −r −f file2 arg1
prog −b −f(file1) badflag(’r’) −f(file2) 2 args: ’arg1’ ’arg2’
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
#include <draw.h>
#include <geometry.h>
Point3 add3(Point3 a, Point3 b)
Point3 sub3(Point3 a, Point3 b)
Point3 neg3(Point3 a)
Point3 div3(Point3 a, double b)
Point3 mul3(Point3 a, double b)
int eqpt3(Point3 p, Point3 q)
int closept3(Point3 p, Point3 q, double eps)
double dot3(Point3 p, Point3 q)
Point3 cross3(Point3 p, Point3 q)
double len3(Point3 p)
double dist3(Point3 p, Point3 q)
Point3 unit3(Point3 p)
Point3 midpt3(Point3 p, Point3 q)
Point3 lerp3(Point3 p, Point3 q, double alpha)
Point3 reflect3(Point3 p, Point3 p0, Point3 p1)
Point3 nearseg3(Point3 p0, Point3 p1, Point3 testp)
double pldist3(Point3 p, Point3 p0, Point3 p1)
double vdiv3(Point3 a, Point3 b)
Point3 vrem3(Point3 a, Point3 b)
Point3 pn2f3(Point3 p, Point3 n)
Point3 ppp2f3(Point3 p0, Point3 p1, Point3 p2)
Point3 fff2p3(Point3 f0, Point3 f1, Point3 f2)
Point3 pdiv4(Point3 a)
Point3 add4(Point3 a, Point3 b)
Point3 sub4(Point3 a, Point3 b)
These routines do arithmetic on points and planes in affine or projective 3-space. Type Point3
typedef struct Point3 Point3;
struct Point3{
double x, y, z, w;
Routines whose names end in 3 operate on vectors or ordinary points in affine 3-space, repre­
sented by their Euclidean (x,y,z) coordinates. (They assume w=1 in their arguments, and set
w=1 in their results.)
Add the coordinates of two points.
Subtract coordinates of two points.
Negate the coordinates of a point.
Multiply coordinates by a scalar.
Divide coordinates by a scalar.
Test two points for exact equality.
Is the distance between two points smaller than eps?
Dot product.
Cross product.
Distance to the origin.
Distance between two points.
A unit vector parallel to p.
The midpoint of line segment pq.
Linear interpolation between p and q.
The reflection of point p in the segment joining p0 and p1.
The closest point to testp on segment p0 p1.
The distance from p to segment p0 p1.
Vector divide the length of the component of a parallel to b, in units of the
length of b.
Vector remainder the component of a perpendicular to b. Ignoring roundoff, we
have eqpt3(add3(mul3(b, vdiv3(a, b)), vrem3(a, b)), a).
The following routines convert amongst various representations of points and planes. Planes are
represented identically to points, by duality; a point p is on a plane q whenever
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 p.w=1, we cant make the same assumption for planes. The names of these routines are
extra-cryptic. They contain an f (for face) to indicate a plane, p for a point and n for a normal
vector. The number 2 abbreviates the word to. The number 3 reminds us, as before, that were
dealing with affine points. Thus pn2f3 takes a point and a normal vector and returns the corre­
sponding plane.
Compute the plane passing through p with normal n.
Compute the plane passing through three points.
Compute the intersection point of three planes.
The names of the following routines end in 4 because they operate on points in projective 4space, represented by their homogeneous coordinates.
pdiv4 Perspective division. Divide p.w into ps coordinates, converting to affine coordinates. If
p.w is zero, the result is the same as the argument.
Add the coordinates of two points.
Subtract the coordinates of two points.
assert check program invariants
#include <u.h>
#include <libc.h>
#define assert(cond) if(cond);else _assert("cond")
void _assert(char* cond)
Assert is a preprocessor macro that (via _assert) prints a message and calls abort when cond is
atof, atoi, atol, atoll, charstod, strtod, strtol, strtoll, strtoul, strtoull convert text to numbers
#include <u.h>
#include <libc.h>
double atof(char *nptr)
atoi(char *nptr)
atol(char *nptr)
atoll(char *nptr)
double charstod(int (*f)(void *), void *a)
double strtod(char *nptr, char **rptr)
strtol(char *nptr, char **rptr, int base)
strtoll(char *nptr, char **rptr, int base)
strtoul(char *nptr, char **rptr, int base)
uvlong strtoull(char *nptr, char **rptr, int base)
Atof, atoi, atol, and atoll convert a string pointed to by nptr to floating, integer, long integer, and
long long integer (vlong) representation respectively. The first unrecognized character ends the
string. Leading C escapes are understood, as in strtol with base zero (described below).
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 e or E followed by an optionally signed
Atoi and atol recognize an optional string of tabs and spaces, then an optional sign, then a string
of decimal digits.
Strtod, strtol, strtoll, strtoul, and strtoull behave similarly to atof and atol and, if rptr is not zero,
set *rptr to point to the input character immediately after the string converted.
Strtol, strtoll, strtoul, and strtoull interpret the digit string in the specified 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 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 0, hexadecimal if they begin with 0x or 0X, other­
wise decimal.
Charstod interprets floating point numbers in the manner of atof, but gets successive characters
by calling (*f)(a). The last call to 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 charstod.
Zero is returned if the beginning of the input string is not interpretable as a number; even in this
case, rptr will be updated.
Atoi, atol, and atoll accept octal and hexadecimal numbers in the style of C, contrary to the ANSI
ainc, adec, cas, casv, casp, loadlink, storecond, _tas atomic RMW operations
#include <u.h>
#include <libc.h>
long ainc(long *addr);
long adec(long *addr);
int cas(int *addr, int ov, int nv);
int casv(u64int *addr, u64int ov, u64int nv);
int casp(void **addr, void *ov, void *nv);
int _tas(ulong *addr);
ulong loadlink(ulong*);
int storecond(ulong*, ulong);
Ainc atomically increments the value pointed to by addr and returns the new value.
Adec atomically decrements the value pointed to by addr and returns the new value.
Cas, casv and casp implement Compare−and−Swap on, respectively, int, vlong and void* values.
The availability of these functions depends on the CPU architecture: Pentium III and later, as well as
AMD64 have 64-bit CAS instructions. Other architectures dont. ARM-5 processors and earlier do
not have CAS (nor have they Load−Linked or Store−Conditional). These instructions are, however,
emulated by the Plan 9 kernel. All other architectures have 32-bit CAS.
_tas implements Test−and−Set, which is available on all architectures and used for the implemen­
tation of kernel locks (see lock(2) and thread(2)).
Loadlink and storecond access the load−linked and store−conditional instructions present on MIPS
(LL/SC), ARM (Strex/Ldrex), PowerPC (LWAR/STWCCC), Alpha (MOVLL, MOVLC). These are not pre­
sent on Pentium or AMD64. On the architectures that have load−linked and store−conditional,
these are used to implement compare−and−swap.
lock(2), semacquire(2), thread(2)
The CAS functions, _tas, and storecond return 0 for failure and 1 for success.
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
#include <u.h>
#include <libc.h>
#include <auth.h>
newns(char *user, char *nsfile);
addns(char *user, char *nsfile);
amount(int fd, char *old, int flag, char *aname);
login(char *user, char *password, char *namespace);
noworld(char *user);
AuthInfo* auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...);
AuthInfo* fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey,
char *params);
auth_allocrpc(int afd);
auth_freerpc(AuthRpc *rpc);
auth_rpc(AuthRpc *rpc, char *verb, void *a, int n);
auth_getkey(char *proto, char *dom);
(*amount_getkey)(char*, char*);
auth_freeAI(AuthInfo *ai);
auth_chuid(AuthInfo *ai, char *ns);
Chalstate* auth_challenge(char *fmt, ...);
AuthInfo* auth_response(Chalstate*);
auth_respond(void *chal, uint nchal, char *user, uint
nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...);
AuthInfo* auth_userpasswd(char*user, char*password);
AuthInfo* auth_getinfo(int fd);
This library, in concert with factotum(4), is used to authenticate users. It provides the primary
interface to factotum.
Newns builds a name space for user. It opens the file nsfile (/lib/namespace is used if nsfile is
null), copies the old environment, erases the current name space, sets the environment variables
user and home, and interprets the commands in nsfile. The format of nsfile is described in
Addns also interprets and executes the commands in nsfile. Unlike newns it applies the command
to the current name space rather than starting from scratch.
Amount is like mount but performs any authentication required. It should be used instead of
mount whenever the file server being mounted requires authentication. See bind(2) for a definition
of the arguments to mount and amount.
Login changes the user id of the process user and recreates the namespace using the file
namespace (default /lib/namespace). It uses auth_userpasswd and auth_chuid.
Noworld returns 1 if the user is in the group noworld in /adm/users. Otherwise, it returns 0.
Noworld is used by telnetd and ftpd to provide sandboxed access for some users.
The following routines use the AuthInfo structure returned after a successful authentication by
typedef struct
char *cuid;
char *suid;
char *cap;
uchar *secret;
} AuthInfo;
caller id */
server id */
capability */
length of secret */
secret */
The fields cuid and suid point to the authenticated ids of the client and server. Cap is a capa­
bility returned only to the server. It can be passed to the cap(3) device to change the user id of the
process. Secret is an 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.
Auth_proxy proxies an authentication conversation between a remote server reading and writing fd
and a factotum file. The factotum file used is /mnt/factotum/rpc. An sprint (see
print(2)) of fmt and the variable arg list yields a key template (see factotum(4)) specifying the key
to use. The template must specify at least the protocol ( proto=xxx) and the role (either
role=client or role=server). Auth_proxy either returns an allocated AuthInfo struc­
ture, or sets the error string and returns nil.
Fauth_proxy can be used instead of auth_proxy if a single connection to factotum will be used for
multiple authentications. This is necessary, for example, for newns which must open the factotum
file before wiping out the namespace. Fauth_proxy takes as an argument a pointer to an
AuthRPC structure which contains an fd for an open connection to factotum in addition to stor­
age and state information for the protocol. An AuthRPC structure is obtained by calling
auth_allocrpc with the fd of an open factotum connection. It is freed using auth_freerpc. Individ­
ual commands can be sent to factotum(4) by invoking auth_rpc.
Both auth_proxy and fauth_proxy take a pointer to a routine, getkey, to invoke should factotum
not posess a key for the authentication. If getkey is nil, the authentication fails. Getkey is called
with a key template for the desired key. We have provided a generic routine, auth_getkey, which
queries the user for the key information and passes it to factotum. This is the default for the glo­
bal variable, amount_getkey, which holds a pointer to the key prompting routine used by amount.
Auth_chuid uses the cuid and cap fields of an AuthInfo structure to change the user id of the
current process and uses ns, default /lib/namespace, to build it a new name space.
Auth_challenge and auth_response perform challenge/response protocols with factotum. State
between the challenge and response phase are kept in the Chalstate structure:
struct Chalstate
char *user;
char chal[MAXCHLEN];
void *resp;
/* for implementation only */
AuthRpc *rpc;
char userbuf[MAXNAMELEN];
Auth_challenge requires a key template generated by an sprint of fmt and the variable argu­
ments. It must contain the protocol (proto=xxx) and depending on the protocol, the user name
(user=xxx). P9cr and vnc expect the user specified as an attribute in the key template and
apop, cram, and chap expect it in the user field of the arg to auth_response. For all protocols,
the response is returned to auth_response in the resp field of the Chalstate. Chalstate.nresp
must be the length of the response.
Supply to auth_respond a challenge string and the fmt and args specifying a key, and it will use
factotum to return the proper user and response.
Auth_userpasswd verifies a simple user/password
user/password pair from factotum if permitted:
typedef struct UserPasswd {
char *user;
char *passwd;
} UserPasswd;
Auth_getinfo reads an AuthInfo message from fd and converts it into a structure. It is only used
by the other routines in this library when communicating with factotum.
Auth_freeAI is used to free an AuthInfo structure returned by one of these routines. Similary
auth_freechal frees a challenge/response state.
factotum(4), authsrv(2), bind(2)
These routines set errstr.
authdial, passtokey, nvcsum, readnvram, convT2M, convM2T, convTR2M, convM2TR, convA2M,
convM2A, convPR2M, convM2PR, _asgetticket, _asrdresp routines for communicating with
authentication servers
#include <u.h>
#include <libc.h>
#include <authsrv.h>
authdial(char *netroot, char *ad);
passtokey(char key[DESKEYLEN], char *password)
uchar nvcsum(void *mem, int len)
readnvram(Nvrsafe *nv, int flag);
convT2M(Ticket *t, char *msg, char *key)
convM2T(char *msg, Ticket *t, char *key)
convA2M(Authenticator *a, char *msg, char *key)
convM2A(char *msg, Authenticator *a, char *key)
convTR2M(Ticketreq *tr, char *msg)
convM2TR(char *msg, Ticketreq *tr)
convPR2M(Passwordreq *pr, char *msg, char *key)
convM2PR(char *msg, Passwordreq *pr, char *key)
_asgetticket(int fd, char *trbuf, char *tbuf);
_asrdresp(int fd, char *buf, int len);
Authdial dials an authentication server over the network rooted at net, default /net. The authen­
tication domain, ad, specifies which server to call. If ad is non-nil, the connection server cs (see
ndb(8)) is queried for an entry which contains authdom=ad or dom=ad, the former having prece­
dence, and which also contains an auth attribute. If it finds neither, it tries in DNS
as the authentication server. The string dialed is then netroot!server!ticket where server is the
value of the auth attribute. If no entry is found, the error string is set to no authentication
server found and -1 is returned. If authdom is nil, the string netroot!$auth!ticket is used to
make the call.
Passtokey converts password into a DES key and stores the result in key. It returns 0 if password
could not be converted, and 1 otherwise.
Readnvram reads authentication information into the structure:
struct Nvrsafe
machkey[DESKEYLEN];/* was file server’s authid’s des key */
authkey[DESKEYLEN];/* authid’s des key from password */
* file server config string of device holding full configuration;
* secstore key on non−file−servers.
authid[ANAMELEN];/* auth userid, e.g., bootes */
authdom[DOMLEN]; /* auth domain, e.g., cs.bell− */
On Sparc, MIPS, and SGI machines this information is in non-volatile ram, accessible in the file
#r/nvram. On x86s and Alphas readnvram successively opens the following areas stopping with
the first to succeed:
the partition named by the $nvram environment variable (commonly set via plan9.ini(8))
the partition #S/sdC0/nvram
a file called plan9.nvr in the partition #S/sdC0/9fat
the partition #S/sd00/nvram
a file called plan9.nvr in the partition #S/sd00/9fat
a file called plan9.nvr on a DOS floppy in drive 0
a file called plan9.nvr on a DOS floppy in drive 1
The nvcsums of the fields machkey, authid, and authdom must match their respective check­
sum or that field is zeroed. If flag is NVwrite or at least one checksum fails and flag is
NVwriteonerr, readnvram will prompt for new values on #c/cons and then write them back
to the storage area. If flag is NVwritemem, readnvram will write the values in *nv back to the
storage area.
ConvT2M, convA2M, convTR2M, and convPR2M convert tickets, authenticators, ticket requests, and
password change request structures into transmittable messages. ConvM2T, convM2A, convM2TR,
and convM2PR are used to convert them back. Key is used for encrypting the message before
transmission and decrypting after reception.
The routine _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.
The routine _asgetticket sends a ticket request message and then uses _asgetresp to recieve an
passwd(1), cons(3), dial(2), authsrv(6),
These routines set errstr. Integer-valued functions return -1 on error.
mkavltree, insertavl, lookupavl, deleteavl, avlwalk, avlnext, avlprev, endwalk - AVL tree routines
#include <u.h>
#include <libc.h>
#include <avl.h>
typedef struct Avl Avl;
struct Avl
/* parent */
/* children */
/* balance bits */
*avlnext(Avlwalk *walk);
*avlprev(Avlwalk *walk);
*avlwalk(Avltree *tree);
deleteavl(Avltree *tree, Avl *key, Avl **oldp);
endwalk(Avlwalk *walk);
insertavl(Avltree *tree, Avl *new, Avl **oldp);
*lookupavl(Avltree *tree, Avl *key);
*searchavl(Avltree *tree, Avl *key, int neighbor);
*mkavltree(int(*cmp)(Avl*, Avl*));
An AVL tree is a self-balancing binary search tree. These routines allow creation and maintenance
of in-memory AVL trees.
An empty AVL tree is created by calling mkavltree with a comparison function as argument. This
function should take two pointers to Avl objects and return -1, 0 or 1 as the first is respectively
less than, equal to, or greater than, the second. Insertavl adds a new tree node into tree. If oldp is
non-nil upon return, it points to storage for an old node with the same key that may now be freed.
Lookupavl returns the tree node that matches key by trees comparison function, or nil if none.
Searchavl returns the tree node that matches key by trees comparison function, if it exists. If it
does not, and neighbor is positive, it returns the nearest node whose key is greater or nil if there
is none and, if neighbor is negative, it returns the nearest node whose key is less or nil if there is
none. It is an error to set neighbor to values other than 1, 0, or +1.
Deleteavl removes the node matching key from tree; oldp is handled as per insertavl.
Avlwalk returns a pointer to a newly-allocated Avlwalk object. Endwalk frees such an object.
Avlnext and avlprev walk the tree associated with walk, returning the next (respectively, previous)
tree node in the comparison order defined by the comparison function associated with the tree
associated with walk.
Intended usage seems to be to make an anonymous Avl the first member of the applications
tree-node structure, then pass these routines tree-node pointers instead of Avl*s.
typedef struct Node {
} Node;
Avltree *tree;
Avl *res;
Node *np;
res = lookupavl(tree, np);
G. M. Adelson-Velsky, E. M. Landis, An algorithm for the organization of information, Soviet
Mathematics, Vol. 3, pp. 12561263.
Functions returning pointers return nil on error.
binalloc, bingrow, binfree grouped memory allocation
#include <u.h>
#include <libc.h>
#include <bin.h>
typedef struct BinBin;
*binalloc(Bin **bp, ulong size, int clr);
*bingrow(Bin **bp, void *op, ulong osize,
ulong size, int clr);
binfree(Bin **bp);
These routines provide simple grouped memory allocation and deallocation. Items allocated with
binalloc are added to the Bin pointed to by bp. All items in a bin may be freed with one call to
binfree; there is no way to free a single item.
Binalloc returns a pointer to a new block of at least size bytes. The block is suitably aligned for
storage of any type of object. No two active pointers from binalloc will have the same value. The
call binalloc(0) returns a valid pointer rather than null. If clr is non-zero, the allocated mem­
ory is set to 0; otherwise, the contents are undefined.
Bingrow is used to extend the size of a block of memory returned by binalloc. Bp must point to the
same bin group used to allocate the original block, and osize must be the last size used to allocate
or grow the block. A pointer to a block of at least size bytes is returned, with the same contents in
the first osize locations. If clr is non-zero, the remaining bytes are set to 0, and are undefined
otherwise. If op is nil, it and osize are ignored, and the result is the same as calling binalloc.
Binalloc and bingrow allocate large chunks of memory using malloc(2) and return pieces of these
chunks. The chunks are freed upon a call to binfree.
binalloc and bingrow return 0 if there is no available memory.
bind, mount, unmount change name space
#include <u.h>
#include <libc.h>
int bind(char *name, char *old, int flag)
int mount(int fd, int afd, char *old, int flag, char *aname)
int unmount(char *name, char *old)
Bind and mount modify the file name space of the current process and other processes in its name
space group (see fork(2)). For both calls, old is the name of an existing file or directory in the cur­
rent name space where the modification is to be made. The name old is evaluated as described in
intro(2), except that no translation of the final path element is done.
For bind, name is the name of another (or possibly the same) existing file or directory in the cur­
rent name space. After a successful bind call, the file name old is an alias for the object originally
named by name; if the modification doesnt hide it, name will also still refer to its original file.
The evaluation of new happens at the time of the bind, not when the binding is later used.
The fd argument to mount is a file descriptor of an open network connection or pipe to a file
server, while afd is a authentication file descriptor as created by fauth(2) and subsequently authen­
ticated. If authentication is not required, afd should be -1. The old file must be a directory. After
a successful mount the file tree served (see below) by fd will be visible with its root directory hav­
ing name old.
The flag controls details of the modification made to the name space. In the following, new refers
to the file as defined by name or the root directory served by fd. Either both old and new files must
be directories, or both must not be directories. Flag can be one of:
Replace the old file by the new one. Henceforth, an evaluation of old will be trans­
lated to the new file. If they are directories (for mount, this condition is true by defi­
nition), old becomes a union directory consisting of one directory (the new file).
Both the old and new files must be directories. Add the constituent files of the new
directory to the union directory at old so its contents appear first in the union. After
an MBEFORE bind or mount, the new directory will be searched first when evaluating
file names in the union directory.
Like MBEFORE but the new directory goes at the end of the union.
The flags are defined in <libc.h>. In addition, there is an MCREATE flag that can be ORd with
any of the above. When a create system call (see 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
MCREATE set. The file is created in that directory; if that attempt fails, the create fails.
Finally, the MCACHE flag, valid for 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 read(5) requests for files accessible through this
mount point. The currency of cached data for a file is verified at each open(5) of the file from this
client machine.
With mount, the file descriptor fd must be open for reading and writing and prepared to respond
to 9P messages (see Section 5). After the mount, the file tree starting at old is served by a kernel
mnt(3) device. That device will turn operations in the tree into messages on fd. Aname selects
among different file trees on the server; the null string chooses the default tree.
The file descriptor fd is automatically closed by a successful mount call.
The effects of bind and mount can be undone by unmount. If name is zero, everything bound to or
mounted upon old is unbound or unmounted. If name is not zero, it is evaluated as described
above for bind, and the effect of binding or mounting that particular result on old is undone.
bind(1), intro(2), fcall(2), auth(2) (particularly amount), intro(5), mnt(3), srv(3)
The return value is a positive integer (a unique sequence number) for success, -1 for failure.
These routines set errstr.
Mount will not return until it has successfully attached to the file server, so the process doing a
mount cannot be the one serving.
Bopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetrune, Bgetd, Bungetc, Bungetrune, Bread, Bseek,
Boffset, Bfildes, Blinelen, Bputc, Bputrune, Bprint, Bvprint, Bwrite, Bflush, Bterm, Bbuffered buf­
fered input/output
#include <u.h>
#include <libc.h>
#include <bio.h>
Biobuf* Bopen(char *file, int mode)
Binit(Biobuf *bp, int fd, int mode)
Binits(Biobufhdr *bp, int fd, int mode, uchar *buf, int size)
Bterm(Biobufhdr *bp)
Bprint(Biobufhdr *bp, char *format, ...)
Bvprint(Biobufhdr *bp, char *format, va_list arglist);
void* Brdline(Biobufhdr *bp, int delim)
char* Brdstr(Biobufhdr *bp, int delim, int nulldelim)
Blinelen(Biobufhdr *bp)
vlong Boffset(Biobufhdr *bp)
Bfildes(Biobufhdr *bp)
Bgetc(Biobufhdr *bp)
Bgetrune(Biobufhdr *bp)
Bgetd(Biobufhdr *bp, double *d)
Bungetc(Biobufhdr *bp)
Bungetrune(Biobufhdr *bp)
vlong Bseek(Biobufhdr *bp, vlong n, int type)
Bputc(Biobufhdr *bp, int c)
Bputrune(Biobufhdr *bp, long c)
Bread(Biobufhdr *bp, void *addr, long nbytes)
Bwrite(Biobufhdr *bp, void *addr, long nbytes)
Bflush(Biobufhdr *bp)
Bbuffered(Biobufhdr *bp)
These routines implement fast buffered I/O. I/O on different file descriptors is independent.
Bopen opens file for mode OREAD or creates for mode OWRITE. It calls malloc(2) to allocate a
Binit initializes a standard size buffer, type Biobuf, with the open file descriptor passed in by the
user. Binits initializes a non-standard size buffer, type Biobufhdr, with the open file descriptor,
buffer area, and buffer size passed in by the user. Biobuf and Biobufhdr are related by the declara­
typedef struct Biobuf Biobuf;
struct Biobuf
uchar b[Bungetsize+Bsize];
Arguments of types pointer to Biobuf and pointer to Biobufhdr can be used interchangeably in the
following routines.
Bopen, Binit, or Binits should be called before any of the other routines on that buffer. Bfildes
returns the integer file descriptor of the associated open file.
Bterm flushes the buffer for bp and returns Bflushs return value. If the buffer was allocated by
Bopen, the buffer is freed and the file is closed.
Brdline reads a string from the file associated with bp up to and including the first delim character.
The delimiter character at the end of the line is not altered, thus the returned string probably wont
be NUL-terminated. Brdline returns a pointer to the start of the line or 0 on end-of-file or read
error. Blinelen returns the length (including the delimiter) of the most recent string returned by
Brdstr returns a malloc(2)-allocated buffer containing the next line of input delimited by delim,
terminated by a NUL (0) byte. Unlike Brdline, which returns when its buffer is full even if no delim­
iter has been found, Brdstr will return an arbitrarily long line in a single call. If nulldelim is set, the
terminal delimiter will be overwritten with a NUL. After a successful call to Brdstr, the return value
of Blinelen will be the length of the returned buffer, excluding the NUL.
Bgetc returns the next character from bp, or a negative value at end of file. Bungetc may be called
immediately after Bgetc to allow the same character to be reread.
Bgetrune calls Bgetc to read the bytes of the next 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.
Bungetrune may be called immediately after Bgetrune to allow the same UTF sequence to be reread
as either bytes or a rune. Bungetc and Bungetrune may back up a maximum of five bytes.
Bgetd uses charstod (see atof(2)) and Bgetc to read the formatted floating-point number in the
input stream, skipping initial blanks and tabs. The value is stored in *d.
Bread reads nbytes of data from bp into memory starting at addr. The number of bytes read is
returned on success and a negative value is returned if a read error occurred.
Bseek applies seek(2) to bp. It returns the new file offset. Boffset returns the file offset of the next
character to be processed.
Bputc outputs the low order 8 bits of c on bp. If this causes a write to occur and there is an error,
a negative value is returned. Otherwise, a zero is returned.
Bputrune calls Bputc to output the low order 16 bits of c as a rune in UTF format on the output
Bprint is a buffered interface to print(2). If this causes a write to occur and there is an error, a neg­
ative value (Beof) is returned. Otherwise, Bprint returns the number of bytes written. Bvprint
does the same except it takes as argument a va_list parameter, so it can be called within a
variadic function.
Bwrite outputs nbytes of data starting at addr to bp. If this causes a write to occur and there is an
error, a negative value is returned. Otherwise, the number of bytes written is returned.
Bflush causes any buffered output associated with bp to be written. The return is as for Bputc.
Bflush is called on exit for every buffer still open for writing.
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 writ­
open(2), print(2), exits(2), utf(6),
Bio routines that return integers yield Beof if bp is not the descriptor of an open file. Bopen
returns zero if the file cannot be opened in the given mode. All routines set errstr on error.
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. Blinelen will tell how many characters are available
in these cases. In the case of a true end-of-file, Blinelen will return zero. At the cost of allocating
a buffer, Brdstr sidesteps these issues.
Only the low byte of Brdstrs delim is examined, so delim cannot be an arbitrary rune.
The data returned by Brdline may be overwritten by calls to any other bio routine on the same bp.
setupBFstate, bfCBCencrypt, bfCBCdecrypt, bfECBencrypt, bfECBdecrypt - blowfish encryption
uchar *ivec)
void bfCBCencrypt(uchar *data, int len, BFstate *s)
void bfCBCdecrypt(uchar *data, int len, BFstate *s)
void bfECBencrypt(uchar *data, int len, BFstate *s)
void bfECBdecrypt(uchar *data, int len, BFstate *s)
Blowfish is Bruce Schneiers 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.
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.
mp(2), aes(2), des(2), dsa(2), elgamal(2), rc4(2), rsa(2), sechash(2), prime(2), rand(2)
brk, sbrk change memory allocation
#include <u.h>
#include <libc.h>
brk(void *addr)
void* sbrk(ulong incr)
Brk sets the systems idea of the lowest bss location not used by the program (called the break) to
addr rounded up to the next multiple of 8 bytes. Locations not less than addr and below the stack
pointer may cause a memory violation if accessed.
In the alternate function sbrk, incr more bytes are added to the programs data space and a
pointer to the start of the new area is returned. Rounding occurs as with brk.
When a program begins execution via 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 brk. A call to sbrk with a zero argument returns the lowest address in the dynamic
intro(2), malloc(2), segattach(2), segbrk(2)
These functions set errstr.
The error return from sbrk is (void*)−1.
cachechars, agefont, loadchar, Subfont, Fontchar, Font font utilities
#include <u.h>
#include <libc.h>
#include <draw.h>
cachechars(Font *f, char **s, Rune **r, ushort *c, int max,
int *widp, char **sfname)
loadchar(Font *f, Rune r, Cacheinfo *c, int h,
int noclr, char **sfname)
void agefont(Font *f)
A Font may contain too many characters to hold in memory simultaneously. The graphics library
and draw device (see 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:
initdraw and its associated font variable, openfont, stringwidth, string, and freefont are sufficient
for most purposes. The routines described below are used internally by the graphics library to
maintain the font cache.
A 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
struct Fontchar {
} Fontchar;
struct Subfont {
Fontchar *info;
} Subfont;
left edge of bits */
first non−zero scan−line */
last non−zero scan−line */
offset of baseline */
width of baseline */
number of chars in subfont */
height of image */
top of image to baseline */
n+1 Fontchars */
of font */
The image fills the rectangle (0, 0, w, height), where w is the sum of the horizontal
extents (of non-zero pixels) for all characters. The pixels to be displayed for character c are in the
rectangle (i−>x, i−>top, (i+1)−>x, i−>bottom) where i is &subfont−>info[c].
When a character is displayed at Point p in an image, the character rectangle is placed at
(p.x+i−>left, p.y) and the next character of the string is displayed at (p.x+i−>width,
p.y). The baseline of the characters is ascent rows down from the top of the subfont image.
The info array has n+1 elements, one each for characters 0 to n−1 plus an additional entry so
the size of the last character can be calculated. Thus the width, w, of the Image associated with a
Subfont s is s−>info[s−>n].x.
A Font consists of an overall height and ascent and a collection of subfonts together with the
ranges of runes (see utf(6)) they represent. Fonts are described by the following structures.
struct Cachefont {
/* value of 0th char in subfont */
} Cachefont;
/* value+1 of last char in subfont */
/* posn in subfont of char at min */
/* stored in font */
*subfontname;/* to access subfont */
struct Cacheinfo {
} Cacheinfo;
struct Cachesubf {
Cachefont *cf;
} Cachesubf;
struct Font {
} Font;
left edge of bits */
width of baseline */
offset of baseline */
of char at this slot in cache */
/* for replacement */
/* font info that owns us */
/* attached subfont */
max ht of image;interline space*/
top of image to baseline */
widest so far; used in caching */
number of subfonts */
increasing counter; for LRU */
size of cache */
size of subfont list */
as read from file */
The height and ascent fields of Font are described in graphics(2). Sub contains nsub point­
ers to Cachefonts. A Cachefont connects runes min through max, inclusive, to the subfont
with file name name; it corresponds to a line of the file describing the font.
The characters are taken from the subfont starting at character number offset (usually zero) in
the subfont, permitting selection of parts of subfonts. Thus the image for rune r is found in posi­
tion r−min+offset of the subfont.
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 subf and cache fields are used by the
library to maintain these caches. The width of a font is the maximum of the horizontal extents
of the characters in the cache. String draws a string by loading the cache and emitting a sequence
of cache indices to draw. Cachechars guarantees the images for the characters pointed to by *s or
*r (one of these must be nil in each call) are in the cache of f. It calls loadchar to put missing char­
acters into the cache. Cachechars translates the character string into a set of cache indices which
it loads into the array c, up to a maximum of n indices or the length of the string. Cachechars
returns in c the number of cache indices emitted, updates *s to point to the next character to be
processed, and sets *widp to the total width of the characters processed. 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 *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.
Loadchar loads a character image into the character cache. Then it tells the graphics server to
copy the character into position h in the character cache. If the current font width is smaller than
the horizontal extent of the character being loaded, loadfont clears the cache and resets it to
accept characters with the bigger width, unless noclr is set, in which case it just returns 1. If the
character does not exist in the font at all, loadfont returns 0; if it is unable to load the character
without destroying cached information, it returns 1, updating *sfname as described above. It
returns 1 to indicate success.
The age fields record when subfonts and characters have been used. The font age is increased
every time the font is used (agefont does this). A character or subfont 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.
graphics(2), allocimage(2), draw(2), subfont(2), image(6), font(6)
All of the functions use the graphics error function (see graphics(2)).
chdir change working directory
#include <u.h>
#include <libc.h>
int chdir(char *dirname)
Chdir changes the working directory of the invoking process to dirname. The working directory is
the starting point for evaluating file names that do not begin with / or #, as explained in intro(2).
When Plan 9 boots, the initial process has / for its working directory.
Sets errstr.
cleanname clean a path name
#include <u.h>
#include <libc.h>
cleanname(char *filename)
Cleanname takes a 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 . and .. directory components in the name. The string is overwritten in place.
The shortest string cleanname can return is two bytes: the null-terminated string ".". Therefore
filename must contain room for at least two bytes.
cmap2rgb, cmap2rgba, rgb2cmap colors and color maps
#include <u.h>
#include <libc.h>
#include <draw.h>
rgb2cmap(int red, int green, int blue)
cmap2rgb(int col)
cmap2rgba(int col)
These routines convert between true color red/green/blue triples and the Plan 9 color map. See
color(6) for a description of RGBV, the standard color map.
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.
Cmap2rgb decomposes the color of RGBV index 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.
Cmap2rgba decomposes the color of RGBV index 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 cmap2rgba shifted up 8 bits. This 32-bit representation is the format used by
draw(2) and memdraw(2) library routines that take colors as arguments.
graphics(2), allocimage(2), draw(2), image(6), color(6)
complete file name completion
#include <u.h>
#include <libc.h>
#include <complete.h>
typedef struct CompletionCompletion;
struct Completion{
uchar advance; /* whether forward progress has been made */
uchar complete; /* whether the completion now represents a file or director
char *string;
/* the string to advance, suffixed " " or "/" for file or d
int nmatch;
/* number of files that matched */
int nfile;
/* number of files returned */
char **filename;/* their names */
Completion* complete(char *dir, char *s);
void freecompletion(Completion *c);
The complete function implements file name completion. Given a directory dir and a string s, it
returns an analysis of the file names in that directory that begin with the string s. The fields
nmatch and nfile will be set to the number of files that match the prefix and filename will
be filled in with their names. If the file named is a directory, a slash character will be appended to
If no files match the string, nmatch will be zero, but complete will return the full set of files in the
directory, with nfile set to their number.
The flag advance reports whether the string s can be extended without changing the set of files
that match. If true, string will be set to the extension; that is, the value of string may be
appended to s by the caller to extend the embryonic file name unambiguously.
The flag complete reports whether the extended file name uniquely identifies a file. If true,
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.
The freecompletion function frees a Completion structure and its contents.
In rio(1) and acme(1), file name completion is triggered by a control-F character or an Insert char­
rio(1), acme(1)
The complete function returns a null pointer and sets errstr if the directory is unreadable or there
is some other error.
The behavior of file name completion should be controlled by the plumber.
Control, Controlset, activate, closecontrol, closecontrolset, controlcalled, controlwire, createbox,
createboxbox, createbutton, createcolumn, createentry, createkeyboard, createlabel, createmenu,
createradiobutton, createrow, createscribble, createslider, createstack, createtab, createtext, cre­
atetextbutton, ctlerror, ctlmalloc, ctlrealloc, ctlstrdup, ctlprint, deactivate, freectlfont, freectlimage,
initcontrols, namectlfont, namectlimage, newcontrolset, resizecontrolset interactive graphical
typedef struct Control Control;
typedef struct Controlset Controlset;
struct Control
Rectangle rect;
Rectangle size;
Channel *event;
Channel *data;
area on screen
min/max Dx, Dy
chan(char*) to
chan(char*) to
(not a rect) */
client */
client */
struct Controlset
Controlset*newcontrolset(Image *i, Channel *kc, Channel *mc, Channel *rc)
closecontrolset(Controlset *cs)
namectlfont(Font *font, char *name)
freectlfont(char *name)
namectlimage(Image *image, char *name)
freectlimage(char *name)
Control* createbox(Controlset *cs, char *name)
Control* createboxbox(Controlset *cs, char *name)
Control* createbutton(Controlset *cs, char *name)
Control* createcolumn(Controlset*, char*)
Control* createentry(Controlset *cs, char *name)
Control* createkeyboard(Controlset *cs, char *name)
Control* createlabel(Controlset *cs, char *name)
Control* createmenu(Controlset *cs, char *name)
Control* createradiobutton(Controlset *cs, char *name)
Control* createrow(Controlset*, char*)
Control* createscribble(Controlset *cs, char *name)
Control* createslider(Controlset *cs, char *name)
Control* createstack(Controlset*, char*)
Control* createtab(Controlset*, char *)
Control* createtext(Controlset *cs, char *name)
Control* createtextbutton(Controlset *cs, char *name)
closecontrol(Control *c)
ctlprint(Control*, char*, ...);
ctlerror(char *fmt, ...)
Control* controlcalled(char *name)
controlwire(Control *c, char *cname, Channel *ch)
activate(Control *c)
deactivate(Control *c)
resizecontrolset(Controlset *cs)
ctlmalloc(uint n)
ctlrealloc(void *p, uint n)
ctlstrdup(char *s)
This library provides a set of interactive controls for graphical displays: buttons, sliders, text entry
boxes, and so on. It also provides aggregator Controls: boxes, columns, rows and stacks of
Controls. A stack is a collection of co-located Controls, of which one is normally visible. A
Controlset collects a group of Controls that share mouse and keyboard. Each
Controlset has a separate thread of control that processes keyboard and mouse events as well
as commands to be passed on to the Controls. Since each Controlset uses a thread, pro­
grams using the control library must be linked with the thread library, thread(2).
Controls are manipulated by reading and writing to the control channel, ctl, of their
Controlset. Channels are defined in thread(2). Each Control has two output channels:
Event delivers messages about actions within the control (such as a button press) and data
delivers (if requested by an appropriate write to ctl) control-specific data such as the contents of
a field.
The library provides a simple mechanism for automatic layout: the minimum and maximum sizes
of each simple control can be specified. Boxbox, row, column and stack Controls then
use these sizes to lay out their constituent Controls when called upon to do so. See the descrip­
tion of these grouping Controls for further details.
Message format
All messages are represented as UTF-8 text. Numbers are formatted in decimal, and strings are
transmitted in the quoted form of quote(2).
Messages sent to a Controlset are of the form,
sender: destination verb [argument ... ]
The sender (and the colon following it) may be ommitted. For example, the initial field of a text
entry control called entry could be set by sending the message,
entry value ’Hello, world!’
to its Controlsets ctl file. This message contains the verb value and the single argument
Hello, world!
To make it easy to write messages, the function chanprint (see thread(2)) can be used to print for­
matted text to a Controlsets channel.
The %q and %Q formats are convenient for properly quoting string arguments, as in
chanprint(e−>event, "value %q", "Don’t touch!");
It is wise to use %q always instead of %s when sending messages, and avoid dealing with the quot­
ing explicitly. In the other direction, tokenize (see getfields(2)) parses these messages and
interprets the quotes correctly.
The destination of a message can be a named control, or a set of controls identified by name or
type. The command
’entry slider’ show
(note the quotation) sends the show command to the entry named entry and all controls of type
slider. If there were a control whose name was slider that control would also be shown.
Note that we are still experimenting with destination names. One proposal is that a destination of
the form "name1 name2 ï type1 type2 ï selects all controls of the named types in the control
hierarchies (of columns, rows and stacks) whose names precede the types.
Messages sent by a control on its event channel are of the form
sender: event
The sender is the name of the control sending the message; the event describes the event. Its for­
mat can often be controlled by setting the Controls format string. For example, when the user
types a newline at a text entry Control named entry, the control sends the message
entry: value ’Hello again!’ on its event channel.
Initialization and Control sets
After initdraw (see graphics(2)) is called, the function initcontrols should be called to initialize
the library. It calls quotefmtinstall to install the %q and %Q formats; see quote(2).
Each control is represented by a Control data structure and is associated with a Controlset
that groups a set of controls sharing mouse, keyboard, and display. Most applications will need
only one Controlset; only those with multiple windows or unusual configurations will need
more than one. The function newcontrolset creates a Controlset. Its arguments are the image
(usually a window) on which its controls will appear, typically the screen variable in the draw
library, and three channels: kc, a channel of Runes from the keyboard; mc, a channel of Mouse
structures from the mouse; and rc, a channel of int that indicates when the window has been
resized. Any of the channels may be nil, in which case newcontrolset will call initkeyboard
and/or initmouse (see keyboard (2) and 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 nonnil.
The function closecontrolset frees all the controls in the control set and tears down all the associ­
ated threads. It does not close the mouse and keyboard.
The public elements of a Controlset are the flag clicktotype, and the ctl and data chan­
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.
Commands for controls are sent through the Controlsets ctl channel. One special command
is recognized by the Controlset itself: Sending the string sync to the ctl channel causes tha
string to be echoed to the Controlsets data channel when all commands up to the sync com­
mand have been processed. The string is allocated and must be freed (see malloc(2)). Synchro­
nization is necessary between sending a command, for example, to resize all controls, and using
their rect fields.
The function resizecontrolset must be provided by the user. When the associated window is
resized, the library will call resizecontrolset with the affected Controlset; the function should
reconnect to and redraw the window.
If all windows are organized in a hierachy of boxboxes, columns, rows and stacks, and minimum
and maximum sizes have already been supplied, only the top control needs to be resized (see the
rect command below).
Fonts and images
Fonts and images must be given names so they may be referenced in messages. The functions
namectlfont and namectlimage associate a (unique) name with the specified font or image. The
association is removed by freectlfont and freectlimage. The font or image is not freed by these
functions, however.
The function initcontrols establishes name bindings for all the colors mentioned in <draw.h>,
such as black, white, red, yellow, etc., as well as masks transparent and opaque. It
also sets the name font to refer to the default font variable set up by initdraw.
Each type of control has an associated creation function: createbutton, createentry, etc., whose
arguments are the Controlset to attach it to and a globally unique name for it. A control may
be destroyed by calling closecontrol.
The function controlcalled returns a pointer to the Control with the given name, or nil if no such
control exists.
After a control is created, it must be configured using the control-specific commands documented
below. Commands are sent to the ctl channel of the Controlset. Multiple commands may be
sent in a single message; newline characters separate commands. For an example, see the imple­
mentation of resizecontrolset in the EXAMPLES section. Note that newline is a separator, not a
terminator; the final command does not need a newline.
Messages sent to the ctl channel are delivered to all controls that match the 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.
The recipient of a message ignores the initial sender: field of the message, if present, making it
possible to send messages generated on an event channel directly to another controls ctl
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 mes­
sages but not be useful to edit. But buttons, entry boxes, and other text displays should be active.
To enable a control, call the activate function, which specifies that the Control c should respond
to mouse and keyboard events; deactivate turns it off again.
Controls can be either revealed (default) or hidden. When a control is hidden, it will not receive
mouse or keyboard events and state changes or show commands will be ignored until the control
is once again revealed . Control hiding is particularly useful when different controls are overlayed,
revealing only the top one.
The function controlwire permits rearrangement of the channels associated with a Control. The
channel cname (one of "data" or "event") of Control c is reassigned to the channel ch.
There are several uses for this operation: one may reassign all the event channels to a single
channel, in effect multiplexing all the events onto a single channel; or connect the event channel
of a slider to the ctl channel for delivery to a text display (after setting the format for the sliders
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.
The following sections document the individual controls in alphabetical order. The layout of each
section is a brief description of the controls behavior, followed by the messages it sends on
event, followed by the messages it accepts via the ctl channel. The event messages are trig­
gered only by mouse or keyboard action; messages to the ctl file do not cause events to be gen­
All controls accept the following messages:
rect minx miny maxx maxy
Set the bounding rectangle for the control on the display. The syntax generated by the
%R print format of the draw library is also acceptable for the coordinates.
size [ min”x min”y max”x max”y ]
Set the minimum and maximum size for automatic layout in columns, rows and 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 Controls.
Disable drawing of the control and ignore mouse and keyboard events until the control
is once again revealed. Grouping Controls (column, row, and stack) pass the
request down to their constituent Controls.
This is the opposite of hide: the Control is displayed and mouse and keyboard
operations resume. Grouping Controls (column, row, and stack) pass the request
down to their constituent Controls. The reveal command for stacks takes an
optional argument naming the Control to be revealed; all other Controls will be
Display the Control on its screen if not hidden. Some actions will also cause the
Controls to show themselves automatically (but never when the control is hid­
den). Grouping Controls (column, row, and stack) pass the request down to their
constituent Controls.
Many messages are common between multiple Controls. Such messages are described in detail
here to avoid repetition. In the individual descriptions, only the syntax is presented.
align n
Specify the alignment of (some part of) the Controls display within its rectan­
gle. For textual controls, 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 Controls, the alignment affects
the appearance of the display in a reasonable way. The valid alignments are
upperright, centerleft, center, centerright, lowerleft,
lowercenter, and lowerright.
border n
Inset the Control (or separate constituent Controls in boxbox, column and
row Controls after the next rect command) within its rectangle by n pixels,
default zero.
bordercolor name
Paint the border of the control with the named color, default black.
focus n
The Control now has (if n is non-zero) or does not have ( if n is zero) focus.
Most Controls ignore the message; there are plans to make them react.
format fmt
Set the format of value messages sent on the event channel. By default, the
format is "%q: value %q" for string-valued Controls, "%q: value
%d" for integer-valued Control s such as buttons, and "%q: value
0x%x" for the keyboard and scribble Controls. The %q prints the name of
the Control; the rest the value. Any supplied format string must be typeequivalent to the default for that Control.
image name
light name
mask name
Many controls set a background image or color for display. The image message
sets the image. The mask and light images together specify how the
Control shows it is enabled: the light is printed through the mask when
the state is on or pressed. Otherwise, the image appears unmodified. The
default image is white; mask opaque; light yellow.
font name
textcolor name
These commands set the font and color for displaying text. The defaults are the
default font set up by the draw library, and black.
value v
Set the value of the Control. Textual images accept an arbitrary string; others
an integral value.
A box is a trivial control that does nothing more than pass keyboard, mouse, and focus messages
back on its event channel. Keyboard characters are sent in the format
boxname: key 0xnn
where nn is the hexadecimal value of the character. Mouse messages are sent in the format
boxname: mouse [x y] but msec
where x, y, but, and msec are the various fields of the Mouse structure. The focus message is
boxname: focus n
where n is 0 if the box has lost focus, 1 if it has acquired it.
The box displays within its rectangle an image, under mask, with specified alignment. The control
messages it accepts are:
align a
Controls the placement of the image in the rectangle (unimplemented).
border b
bordercolor name
focus n
image name
rect minx miny maxx maxy
size min”x min”y max”x max”y
A boxbox allows a set of controls (boxes) to be displayed in rows and columns within the rect­
angle of the 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
Controls to be displayed. This aggregator works well for collections of buttons, labels, or
textbuttons that all have a fixed height.
add name ...
adds the named control to the box of controls. The display order is deter­
mined 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 con­
trols but the layout of the result will be quite unpredictable.
border width
bordercolor color
This command is passed on to the member controls.
image color
Background color displayed between member controls.
This command is passed on to the member controls.
separation width
Set the separation between member controls to n pixels.
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 maxi­
mum size are not big enough to fit, they are top-left justified at their maxi­
mum 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 borderwidth.
remove name
Remove the named control from the box.
This command is passed on to the member controls. Show also (re)displays
background and borders.
size min”x min”y max”x max”y
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:
buttonname: value n
where n encodes the mouse buttons used to make the selection.
The button displays an image (which may of course be a simple color) and illuminates in the stan­
dard way when it is on. The control messages it accepts are:
align a
Controls the placement of the image in the rectangle (unimplemented).
border b
bordercolor name
focus n
format fmt
image name
light name
mask name
rect minx miny maxx maxy
size min”x min”y max”x max”y
value n
Set the button to on (if n is non-zero) or off (if n is zero).
A column is a grouping control which lays out its members vertically, from top to bottom. Cur­
rently, columns ignore mouse and keyboard events, but there are plans to allow dragging the bor­
ders (when they have non-zero width) between constituent members.
add name ...
adds the named control to the column of controls. The vertical order is deter­
mined 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.
border width
Set the border between members to the width given.
bordercolor color
image color
Background color displayed between member controls.
separation width
Set the separation between member controls to n pixels.
These three commands are passed on to the member controls. Show also
(re)displays the borders between members.
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. Oth­
erwise, 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 borderwidth.
remove name
Remove the named control from the column.
size [ min”x min”y max”x max”y ]
Without arguments, this command computes the minimum and maximum size
of a column by adding the minimum and maximum heights to set min”y and
max”y, and it finds the largest minimum and maximum widths to set min”y
and max”y. When called with arguments, it simply sets the minimum and maxi­
mum sizes to those given.
The entry control manages a single line of editable text. When the user hits a carriage return any­
where in the text, the control generates the event message,
entryname: value s
with s the complete text of the entry box.
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.
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 draw(2)). The file /lib/font/bit/lucm/passwd.9.font defines
such a font.
The control messages the entry control accepts are:
align a
Controls the placement of the text in the rectangle.
border b
bordercolor name
After receiving this message, the entry will send its value to its data channel as an
unadorned, unquoted string.
focus n
When it receives focus, the entry box displays a typing cursor. When it does not
have focus, the cursor is not displayed.
font name
format fmt
image name
rect minx miny maxx maxy
size min”x min”y max”x max”y
textcolor name
value s
Set the string displayed in the entry box.
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:
keyboardname: value 0xnn
where nn is the hexadecimal Unicode value of the character. Shift, control, and caps lock are han­
dled 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 nonASCII characters.
There are two special keys, Scrib and Menu, which return values 0x10000 and 0x10001.
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.
The control messages the keyboard accepts are:
border b
bordercolor name
focus n
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.
/lib/font/bit/lucidasans/unicode.6.font for the second argument.) If
neither is specified, both will be set to the default global font.
format fmt
image name
light name
mask name
rect minx miny maxx maxy
size minx miny maxx maxy
A label is like a textbutton (q.v.) that does not react, but whose value is the text it displays. The
control messages it accepts are:
align a
Controls the placement of the image in the rectangle.
border b
bordercolor name
focus n
font name
image name
rect minx miny maxx maxy
size minx miny maxx maxy
textcolor name
value s
The value is a string that can be modified only by sending this message to the ctl
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:
menuname: value n
If no selection is made, no message is reported. Because it creates a window, programs using a
menu must have their screen variable (see graphics(2) and window(2)) set up to be refreshed
properly. The easiest way to do this is to call getwindow with refresh argument Refbackup
(see graphics(2)); most programs use Refnone.
The control messages accepted by a menu are:
add text
Add a line of text to the end of the menu.
align a
Controls the left-right placement of the text in its rectangle.
border b
bordercolor name
focus n
font name
format fmt
image name
rect minx miny maxx maxy
size minx miny maxx maxy
Only the origin of the rectangle is significant; menus calculate the appropriate size.
selectcolor name
Set the color in which to highlight selected lines; default yellow.
selecttextcolor name
Set the color in which to draw the text in selected lines; default black.
Display the menu. Not usually needed unless the menu is changed while visible; use
window instead.
window n
With no arguments, toggle the menus visibility; otherwise make it visible (1) or
invisible (0). When the selection is made, the menu will remove its window automat­
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, start­
ing 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:
radiobuttonname: value n
Buttons are added to the radio button using the add message; there is no way to remove them,
although they may be turned off independently using 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 but­
tons. In other words, the geometry is not maintained automatically.
The control messages the radiobutton accepts are:
add name
Add the control with the specified name to the radiobutton.
focus n
format fmt
rect minx miny maxx maxy
size minx miny maxx maxy
value n
A row groups a number of member controls left to right in a rectangle. Rows behave exactly like
columns with the roles of x and y interchanged.
The control messages it accepts are:
add name ...
border width
bordercolor color
image color
rect minx miny maxx maxy
remove name
separation width
size [ min”x min”y max”x max”y ]
The scribble control provides a region in which strokes drawn with mouse button 1 are interpreted
as characters in the manner of scribble(2). In most respects, including the format of its event mes­
sages, it is equivalent to a keyboard control.
The control messages it accepts are:
align a
border b
bordercolor name
focus n
font name
image name
linecolor name
rect minx miny maxx
size minx miny maxx
Controls the placement of the image in the rectangle (unimplemented).
Used to display the indicia.
The color in which to draw the strokes; default black.
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.
The control messages it accepts are:
rect minx miny maxx maxy
remove name
reveal [ n ]
Without argument, reveal is the opposite of hide: it makes its selected con­
trol visible after it was hidden. With an argument, it makes the nth added con­
trol visible, hiding all others.
size [ min”x min”y max”x max”y ]
Without argument, size computes the maximum of the minimum and maximum
sizes of its constituent controls. With arguments, it sets the size to the given val­
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:
slidername: value n
The slider is a good candidate for connecting to another control by setting its format and rewiring
its event channel to the others ctl channel.
The geometry of the slider is defined by three numbers: max is a number representing the range
of the slider; vis is a number representing how much of what is being controlled is visible; and
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, max will be 1000, vis will be 18, and value will be 304. The indicator
is the visual representation of the vis portion of the controlled object.
The control messages the slider accepts are:
absolute n
If 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 n is nonzero, all buttons behave like button 2, setting the absolute value.
border b
bordercolor name
clamp end n
The end is either the word high or low; n sets whether that end is clamped or
not. If it is clamped, that end of the indicator is always at its supremum. A stan­
dard 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.
focus n
format fmt
image name
indicatorcolor name
Set the color in which to draw the indicator; default black.
max n
Set the maximum value of the range covered by the slider.
orient dir
The string dir begins either hor or ver to specify the orientation of the slider.
The default is vertical. The value always increases to the right for horizontal slid­
ers and downwards for vertical sliders.
rect minx miny maxx maxy
size minx miny maxx maxy
value n
vis n
Set the visible area shown by the indicator.
A tab control combines radiobottuns with a stack of windows giving the appearance of tabbed con­
trols. 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.
Control messages are
add button control button control ...
Adds a button to the radiobutton, and an associated control to the stack. But­
tons and controls are numbered in the order of addition. There is no remove
border b
bordercolor color
focus n
format fmt
When a format string is defined, the tab control reports which tab is selected
using the format string (which must print a char* and an int).
image color
Color between member controls.
separation n Spacing between buttons in the radiobutton and between the row of buttons and
the stack below it.
rect n n n n
size n n n n
value n
Value must be an integer indicating which tab to bring to the top.
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:
textname: select n s
states that line n has changed its selection state to s, either zero (unselected) or non-zero
(selected). The non-zero value encodes the mouse buttons that were down when the selection
The control messages the text control accepts are:
accumulate s
accumulate n s
add s
add n s
align a
With one argument, append the string s as a new last line of the control; if n
is specified, add the line before the current line n, making the new line num­
ber n. The lines are zero indexed and n can be no greater than the current
number of lines. Add refreshes the display, but accumulate does not, to
avoid n-squared behavior when assembling a piece of text.
Controls the placement of each line of text left-to-right in its rectangle. Ver­
tically, lines are tightly packed with separation set by the fonts interline
border b
bordercolor name
Delete all text.
delete n
Delete line n.
focus n
font name
image name
rect minx miny maxx maxy
replace n s
Replace line n by the string s.
scroll n
If n is non-zero, the text will automatically scroll so the last line is always vis­
ible when new text is added.
select n m
Set the selection state of line n to m.
selectcolor name
Set the color in which to highlight selected lines; default yellow.
selectmode s
The string s is either single or multi. If single, the default, only one
line may be selected at a time; when a line is selected, other lines are unse­
lected. If multi, the selection state of individual lines can be toggled inde­
size minx miny maxx maxy
textcolor name
topline n
value s
Scroll the text so the top visible line is number n.
Delete all the text in the control and then add the single line s.
A textbutton is a textual variant of a plain button. Each state change triggers an event message:
textbuttonname: value n
where n encodes the mouse buttons used to make the selection.
Like a regular button, the value of a textbutton is an integer; the 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:
align a
Controls the placement of the text in the rectangle.
border b
bordercolor name
focus n
font name
format fmt
image name
light name
mask name
pressedtextcolor name
Set the color in which to display text when the textbutton is pressed.
rect minx miny maxx maxy
size minx miny maxx maxy
text s
Set the text displayed in the button.
textcolor name
value n
Set the button to on (if n is non-zero) or off (if n is zero).
Helper functions
The function ctlerror is called when the library encounters an error. It prints the formatted mes­
sage and exits the program.
The functions ctlmalloc, ctlrealloc, ctlstrdup, and ctlrunestrdup are packagings of the correspond­
ing C library functions. They call ctlerror if they fail to allocate memory, and ctlmalloc zeros the
memory it returns.
Finally, for debugging, if the global variable ctldeletequits is set to a non-zero value, typing a DEL
will cause the program to call
This library is very new and is still missing a number of important features. The details are all sub­
ject to change. Another level of library that handles geometry and has sensible default appear­
ances for the controls would be useful.
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.
This example creates two entry boxes, top and bot, and copies the contents of one to the other
whenever a newline is typed.
Controlset *cs;
int ctldeletequits = 1;
int i;
Rectangle r, r1, r2;
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\ntop show", r1);
chanprint(cs−>ctl, "bot rect %R\nbot show", r2);
threadmain(int argc, char *argv[])
char *s, *args[3];
Channel *c;
Control *top, *bot;
int n;
initdraw(0, 0, "example");
cs = newcontrolset(screen, nil, nil, nil);
cs−>clicktotype = 1;
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");
c = chancreate(sizeof(char*), 0);
controlwire(top, "event", c);
controlwire(bot, "event", c);
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]);
chanprint(cs−>ctl, "top value %q", args[2]);
A richer variant couples a text entry box to a slider. Since the value of a slider is its numerical set­
ting, as a decimal number, all that needs changing is the setup of bot:
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");
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.
Finally, we can avoid processing events altogether by cross-coupling the controls. Replace the rest
of threadmain with this:
chanprint(cs−>ctl, "bot format %q", "%q: top value %q");
chanprint(cs−>ctl, "top format %q", "%q: bot value %q");
controlwire(top, "event", cs−>ctl);
controlwire(bot, "event", cs−>ctl);
draw(2), frame(2), graphics(2), quote(2), thread(2)
The library is strict about matters of formatting, argument count in messages, etc., and calls
ctlerror in situations where it may be fine to ignore the error and continue.
cputime, times, cycles cpu time in this process and children
#include <u.h>
#include <libc.h>
times(long t[4])
double cputime(void)
cycles(vlong *cyclep)
If t is non-null, 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. Cputime returns the sum of
those same times, converted to seconds. Times returns the elapsed real time, in milliseconds, that
the process has been running.
These functions read /dev/cputime, opening that file when they are first called.
Cycles reads the processors timestamp counter of cycles since reset, if any, and stores it via
cyclep. Currently supported architectures are 386, amd64, and power; on all others, cycles will
store zero.
exec(2), cons(3)
Only 386 processors starting with the Pentium have timestamp counters; calling cycles on earlier
processors may execute an illegal instruction.
ctime, localtime, gmtime, asctime, tm2sec, timezone convert date and time
#include <u.h>
#include <libc.h>
char* ctime(long clock)
localtime(long clock)
gmtime(long clock)
char* asctime(Tm *tm)
tm2sec(Tm *tm)
Ctime converts a time clock such as returned by time(2) into ASCII (sic) and returns a pointer to a
30-byte string in the following form. All the fields have constant width.
Wed Aug
5 01:07:47 EST 1973\n\0
Localtime and gmtime return pointers to structures containing the broken-down time. Localtime
corrects for the time zone and possible daylight savings time; gmtime converts directly to GMT.
Asctime converts a broken-down time to ASCII and returns a pointer to a 30-byte string.
struct {
} Tm;
seconds (range 0..59) */
minutes (0..59) */
hours (0..23) */
day of the month (1..31) */
month of the year (0..11) */
year A.D. 1900 */
day of week (0..6, Sunday = 0) */
day of year (0..365) */
time zone name */
time zone delta from GMT */
Tm2sec converts a broken-down time to seconds since the start of the epoch. It ignores wday,
and assumes the local time zone if zone is not GMT.
When local time is first requested, the program consults the timezone environment variable to
determine the time zone and converts accordingly. (This variable is set at system boot time by
init(8).) The 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:
EST −18000 EDT −14400
9943200 25664400 41392800 57718800 ...
Greenwich Mean Time is represented by
date(1), time(2), init(8)
The return values point to static data whose content is overwritten by each call.
Daylight Savings Time is normal in the Southern hemisphere.
These routines are not equipped to handle non-ASCII text, and are provincial anyway.
isalpha, isupper, islower, isdigit, isxdigit, isalnum, isspace, ispunct, isprint, isgraph, iscntrl, isascii,
toascii, _toupper, _tolower, toupper, tolower ASCII character classification
#include <u.h>
#include <libc.h>
#include <ctype.h>
These macros classify ASCII-coded integer values by table lookup. Each is a predicate returning
nonzero for true, zero for false. Isascii is defined on all integer values; the rest are defined only
where isascii is true and on the single non-ASCII value EOF; see fopen(2).
isalpha c is a letter, az or AZ
isupper c is an upper case letter, AZ
c is a lower case letter, az
c is a digit, 09
isxdigit c is a hexadecimal digit, 09 or af or AF
isalnum c is an alphanumeric character, az or AZ or 09
isspace c is a space, horizontal tab, newline, vertical tab, formfeed, or carriage return (0x20, 0x9,
0xA, 0xB, 0xC, 0xD)
ispunct c is a punctuation character (one of !"#$%&’()*+,−./:;<=>[email protected][\]^_‘{|}~)
c is a printing character, 0x20 (space) through 0x7E (tilde)
isgraph c is a visible printing character, 0x21 (exclamation) through 0x7E (tilde)
c is a delete character, 0x7F, or ordinary control character, 0x0 through 0x1F
c is an ASCII character, 0x0 through 0x7F
Toascii is not a classification macro; it converts its argument to ASCII range by anding with 0x7F.
If c is an upper case letter, tolower returns the lower case version of the character; otherwise it
returns the original character. Toupper is similar, returning the upper case version of a character
or the original character. Tolower and toupper are functions; _tolower and _toupper are corre­
sponding macros which should only be used when it is known that the argument is upper case or
lower case, respectively.
for the macros.
for the tables.
These macros are ASCII-centric.
cisctrace, risctrace, ciscframe, riscframe, localaddr, symoff, fpformat, beieee80ftos, beieeesftos,
beieeedftos, leieee80ftos, leieeesftos, leieeedftos, ieeesftos, ieeedftos machine-independent
debugger functions
int cisctrace(Map *map, ulong pc, ulong sp, ulong link,
Tracer trace)
int risctrace(Map *map, ulong pc, ulong sp, ulong link,
Tracer trace)
ulong ciscframe(Map *map, ulong addr, ulong pc, ulong sp,
ulong link)
ulong riscframe(Map *map, ulong addr, ulong pc, ulong sp,
ulong link)
int localaddr(Map *map, char *fn, char *var, long *ret,
Rgetter rget)
int symoff(char *buf, int n, long addr, int type)
int fpformat(Map *map, Reglist *rp, char *buf, int n, int code)
int beieee80ftos(char *buf, int n, void *fp)
int beieeesftos(char *buf, int n, void *fp)
int beieeedftos(char *buf, int n, void *fp)
int leieee80ftos(char *buf, int n, void *fp)
int leieeesftos(char *buf, int n, void *fp)
int leieeedftos(char *buf, int n, void *fp)
int ieeesftos(char *buf, int n, ulong f)
int ieeedftos(char *buf, int n, ulong high, ulong low)
extern Machdata *machdata;
These functions provide machine-independent implementations of common debugger functions.
Many of the functions assume that global variables mach and machdata point to the Mach and
Machdata data structures describing the target architecture. The former contains machine param­
eters and a description of the register set; it is usually set by invoking crackhdr (see mach(2)) to
interpret the header of an executable. The Machdata structure is primarily a jump table specifying
functions appropriate for processing an executable image for a given architecture. Each applica­
tion is responsible for setting machdata to the address of the Machdata structure for the target
architecture. Many of the functions described here are not called directly; instead, they are invoked
indirectly through the Machdata jump table.
These functions must retrieve data and register contents from an executing image. The Map (see
mach(2)) data structure supports the consistent retrieval of data, but no uniform access mecha­
nism 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 Rgetter, is of the
ulong rget(Map *map, char *name);
It returns the contents of a register when given the address of a Map associated with an executing
image and the name of the register.
Cisctrace and risctrace unwind the stack for up to 40 levels or until the frame for main is found.
They return the count of the number of levels unwound. These functions process stacks conform­
ing to the generic compiler model for RISC and CISC architectures, respectively. Map is the address
of a Map data structure associated with the image of an executing process. Sp, pc and 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 multithreaded process. 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:
void tracer(Map *map, ulong pc, ulong fp, Symbol *s);
where Map is the Map pointer passed to cisctrace or risctrace and pc and fp are the program
counter and frame pointer. S is the address of a Symbol structure, as defined in symbol(2), con­
taining the symbol table information for the function owning the frame (i.e., the function that
caused the frame to be instantiated).
Ciscframe and riscframe calculate the frame pointer associated with a function. They are suitable
for programs conforming to the CISC and RISC stack models. Map is the address of a Map associ­
ated with the memory image of an executing process. Addr is the entry point of the desired func­
tion. Pc, sp and link are the program counter, stack pointer and link register of an execution con­
text. 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.
Localaddr fills the location pointed to by ret with the address of a local variable. Map is the
address of a Map associated with an executing memory image. Fn and var are pointers to the
names of the function and variable of interest. Rget is the address of a register retrieval function.
If both fn and var are non-zero, the frame for function fn is calculated and the address of the
automatic or argument named var in that frame is returned. If var is zero, the address of the
frame for function fn is returned. In all cases, the frame for the function named fn must be instan­
tiated 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 cur­
rent value of the program counter and stack pointer. If a valid address is found, localaddr returns
1. A negative return indicates an error in resolving the address.
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. Buf is the address of a buffer
of n characters to receive the formatted string. Addr is the address to be converted. Type is the
type code of the search space: CTEXT, CDATA, or CANY. Symoff returns the length of the format­
ted string contained in buf.
Fpformat converts the contents of a floating point register to a string. Map is the address of a
Map associated with an executing process. Rp is the address of a Reglist data structure describing
the desired register. Buf is the address of a buffer of n characters to hold the resulting string.
Code must be either F or f, selecting double or single precision, respectively. If code is 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 code f, the specified register is for­
matted as a single precision float. Fpformat returns 1 if the number is successfully converted or
1 in the case of an error.
Beieee80ftos, beieeesftos and beieeedftos convert big-endian 80-bit extended, 32-bit single preci­
sion, and 64-bit double precision floating point values to a string. Leieee80ftos, leieeesftos, and
leieeedftos are the little-endian counterparts. Buf is the address of a buffer of n characters to
receive the formatted string. Fp is the address of the floating point value to be converted. These
functions return the length of the resulting string.
Ieeesftos converts the 32-bit single precision floating point value f, to a string in buf, a buffer of n
bytes. It returns the length of the resulting string.
Ieeedftos converts a 64-bit double precision floating point value to a character string. Buf is the
address of a buffer of n characters to hold the resulting string. High and low contain the most and
least significant 32 bits of the floating point value, respectively. Ieeedftos returns the number of
characters in the resulting string.
mach(2), symbol(2), errstr(2)
Set errstr.
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
void des_key_setup(uchar key[8], ulong schedule[32])
void block_cipher(ulong *schedule, uchar *data, int decrypting)
void setupDESstate(DESstate *s, uchar key[8], uchar *ivec)
void desCBCencrypt(uchar *p, int len, DESstate *s)
void desCBCdecrypt(uchar *p, int len, DESstate *s)
void desECBencrypt(uchar *p, int len, DESstate *s)
void desECBdecrypt(uchar *p, int len, DESstate *s)
void triple_block_cipher(ulong expanded_key[3][32], uchar text[8],
int ende)
void setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec)
void des3CBCencrypt(uchar *p, int len, DES3state *s)
void des3CBCdecrypt(uchar *p, int len, DES3state *s)
void des3ECBencrypt(uchar *p, int len, DES3state *s)
void des3ECBdecrypt(uchar *p, int len, DES3state *s)
void key_setup(uchar[7], ulong[32])
void des56to64(uchar *k56, uchar *k64)
void des64to56(uchar *k64, uchar *k56)
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.
The basic DES function, 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 des_key_setup .
Since it is a bit awkward, 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 DESstate structure that
contains the key schedule and any chained state. SetupDESstate sets up the DESstate structure
using the key and an 8-byte initialization vector.
Electronic code book, using desECBencrypt and 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.
Cipher block chaining mode, using desCBCencrypt and desCBCdecrypt, is more secure. Every
block encrypted depends on the initialization vector and all blocks encrypted before it.
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.
There are equivalent triple-DES (DES3-EDE) functions for each of the DES functions.
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, weve abandoned this format. There are two functions, des56to64 and des64to56, to
convert back and forth between the two formats. Also a key schedule can be set up from the 7byte format using key_setup.
mp(2), aes(2), blowfish(2), dsa(2), elgamal(2), rc4(2), rsa(2), sechash(2), prime(2), rand(2)
Breaking DES, Electronic Frontier Foundation, OReilly, 1998
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 aes(2) instead, or at least triple DES.
dial, hangup, announce, listen, accept, reject, netmkaddr, setnetmtpt, getnetconninfo, freenetcon­
ninfo make and break network connections
#include <u.h>
#include <libc.h>
dial(char *addr, char *local, char *dir, int *cfdp)
hangup(int ctl)
announce(char *addr, char *dir)
listen(char *dir, char *newdir)
accept(int ctl, char *dir)
reject(int ctl, char *dir, char *cause)
char* netmkaddr(char *addr, char *defnet, char *defservice)
setnetmtpt(char *to, int tolen, char *from)
getnetconninfo(char *conndir, int fd)
void freenetconninfo(NetConnInfo*)
For these routines, addr is a network address of the form network!netaddr!service,
network!netaddr, or simply netaddr. Network is any directory listed in /net or the special token,
net. Net is a free variable that stands for any network in common between the source and the
host netaddr. Netaddr can be a host name, a domain name, a network address, or a meta-name of
the form $attribute, which is replaced by value from the value-attribute pair attribute=value most
closely associated with the source host in the network data base (see ndb(6)).
If a connection attempt is successful and dir is non-zero, the path name of a line directory that
has files for accessing the connection is copied into dir. The path name is guaranteed to be less
than 40 bytes long. One line directory exists for each possible connection. The data file in the
line directory should be used to communicate with the destination. The ctl file in the line direc­
tory can be used to send commands to the line. See ip(3) for messages that can be written to the
ctl file. The last close of the data or ctl file will close the connection.
Dial makes a call to destination addr on a multiplexed network. If the network in addr is net, dial
will try in succession all networks in common between source and destination until a call succeeds.
It returns a file descriptor open for reading and writing the data file in the line directory. The
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 local is non-zero, the local address
will be set to local. If cfdp is non-zero, *cfdp is set to a file descriptor open for reading and writ­
ing the control file.
Hangup is a means of forcing a connection to hang up without closing the ctl and data files.
Announce and listen are the complements of dial. Announce establishes a network name to which
calls can be made. Like dial, announce returns an open ctl file. The netaddr used in announce
may be a local address or an asterisk, to indicate all local addresses, e.g. tcp!*!echo. The
listen routine takes as its first argument the dir of a previous announce. When a call is received,
listen returns an open ctl file for the line the call was received on. It sets newdir to the path
name of the new line directory. Accept accepts a call received by listen, while reject refuses the
call because of cause. Accept returns a file descriptor for the data file opened ORDWR.
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.
Getnetconninfo returns a structure containing information about a network connection. The struc­
ture is:
typedef struct NetConnInfo NetConnInfo;
struct NetConnInfo
connection directory */
network root */
binding spec */
local system */
local service */
remote system */
remote service */
local address */
remote address */
The information is obtained from the connection directory, conndir. If conndir is nil, the directory
is obtained by performing fd2path(2) on fd. Getnetconninfo returns either a completely specified
structure, or nil if either the structure cant be allocated or the network directory cant be deter­
mined. The structure is freed using freenetconninfo.
Setnetmtpt copies the name of the network mount point into the buffer to, whose length is 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 dns, cs (see ndb(8)), and ipconfig(8)) should now
call setnetmtpt. If from is nil, the mount point is set to the default, /net. If 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 from appended to the string /net. The last form is obsolete and is should be
avoided. It exists only to aid in conversion.
Make a call and return an open file descriptor to use for communications:
int callkremvax(void)
return dial("kremvax", 0, 0, 0);
Call the local authentication server:
int dialauth(char *service)
return dial(netmkaddr("$auth", 0, service), 0, 0, 0);
Announce as kremvax on TCP/IP and loop forever receiving calls and echoing back to the caller
anything sent:
int dfd, acfd, lcfd;
char adir[40], ldir[40];
int n;
char buf[256];
acfd = announce("tcp!*!7", adir);
if(acfd < 0)
return −1;
/* listen for a call */
lcfd = listen(adir, ldir);
if(lcfd < 0)
return −1;
/* fork a process to echo */
case −1:
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);
/sys/src/libc/9sys, /sys/src/libc/port
auth(2), ip(3), ndb(8)
Dial, announce, and listen return 1 if they fail. Hangup returns nonzero if it fails.
dirread, dirreadall read directory
#include <u.h>
#include <libc.h>
long dirread(int fd, Dir **buf)
long dirreadall(int fd, Dir **buf)
The data returned by a read(2) on a directory is a set of complete directory entries in a machineindependent format, exactly equivalent to the result of a stat(2) on each file or subdirectory in the
directory. Dirread decodes the directory entries into a machine-dependent form. It reads from fd
and unpacks the data into an array of Dir structures whose address is returned in *buf (see
stat(2) for the layout of a Dir). The array is allocated with malloc(2) each time dirread is called.
Dirreadall is like dirread, but reads in the entire directory; by contrast, dirread steps through a
directory one read(2) at a time.
Directory entries have variable length. A successful read of a directory always returns an integral
number of complete directory entries; dirread always returns complete Dir structures. See
read(5) for more information.
The constant STATMAX is the maximum size that a directory entry can occupy. The constant
DIRMAX is an upper limit on the size necessary to hold a Dir structure and all the associated
Dirread and dirreadall return the number of Dir structures filled in buf. The file offset is
advanced by the number of bytes actually read.
intro(2), open(2), read(2)
Dirread and Dirreadall return zero for end of file and a negative value for error. In either case,
*buf is set to nil so the pointer can always be freed with impunity.
These functions set errstr.
opendisk, Disk generic disk device interface
#include <u.h>
#include <libc.h>
#include <disk.h>
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;
Disk* opendisk(char *file, int rdonly, int noctl)
These routines provide a simple way to gather and use information about floppy(3) and sd(3) disks
and disk partitions, as well as plain files.
Opendisk opens file for reading and stores the file descriptor in the fd field of the Disk structure.
If rdonly is not set, opendisk also opens file for writing and stores that file descriptor in wfd. The
two file descriptors are kept separate to help prevent accidents.
If noctl is not set, opendisk looks for a ctl file in the same directory as the disk file; if it finds one,
it declares the disk to be an sd device, setting the type field in the Disk structure to Tsd. If the
passed file is named fdndisk, it looks for a file fdnctl, and if it finds that, declares the disk
to be a floppy disk, of type Tfloppy. If either control file is found, it is opened for reading and
writing, and the resulting file descriptor is saved as ctlfd. Otherwise the returned disk has type
Opendisk then stats the file and stores its length in size. If the disk is an sd partition, opendisk
reads the sector size from the control file and stores it in secsize; otherwise the sector size is
assumed to be 512, as is the case for floppy disks. Opendisk then stores the disk size measured
in sectors in secs.
If the disk is an sd partition, opendisk parses the control file to find the partitions offset within its
disk; otherwise it sets offset to zero. If the disk is an ATA disk, opendisk reads the disk geome­
try (number of cylinders, heads, and sectors) from the geometry line in the sd control file; other­
wise it sets these to zero as well. Name is initialized with the base name of the disk partition, and
is useful for forming messages to the sd control file. Prefix is set to the passed filename with­
out the name suffix.
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. Opendisk
employs a number of heuristics to discover this supposed geometry and store it in the c, h, and s
fields. Disk offsets in partition tables and in FAT descriptors are stored in a form dependent upon
these numbers, so opendisk works hard to report numbers that agree with those used by other
operating systems; the numbers bear little or no resemblance to reality.
floppy(3), sd(3)
Image, draw, gendraw, drawreplxy, drawrepl, replclipr, line, poly, fillpoly, bezier, bezspline, fill­
bezier, fillbezspline, ellipse, fillellipse, arc, fillarc, icossin, icossin2, border, string, stringn, rune­
string, runestringn, stringbg, stringnbg, runestringbg, runestringnbg, _string, ARROW, drawsetde­
bug graphics functions
#include <u.h>
#include <libc.h>
#include <draw.h>
struct Image
} Image;
display holding data */
id of system−held Image */
rectangle in data area, local coords */
clipping region */
pixel channel format descriptor */
number of bits per pixel */
flag: data replicates to tile clipr */
0 if not a window */
next in list of windows */
typedef enum
/* Porter−Duff compositing operators */
= 0,
SinD = 8,
DinS = 4,
= 2,
= 1,
= SinD|SoutD,
= SinD|SoutD|DoutS,
= SinD|DoutS,
= SoutD|DoutS,
= DinS|DoutS,
= DinS|DoutS|SoutD,
= DinS|SoutD,
= DoutS|SoutD, /* == SxorD */
Ncomp = 12,
} Drawop;
draw(Image *dst, Rectangle r, Image *src,
Image *mask, Point p)
void drawop(Image *dst, Rectangle r, Image *src,
Image *mask, Point p, Drawop op)
void gendraw(Image *dst, Rectangle r, Image *src, Point sp,
Image *mask, Point mp)
void gendrawop(Image *dst, Rectangle r, Image *src, Point sp,
Image *mask, Point mp, Drawop op)
drawreplxy(int min, int max, int x)
Point drawrepl(Rectangle r, Point p)
void replclipr(Image *i, int repl, Rectangle clipr)
void line(Image *dst, Point p0, Point p1, int end0, int end1,
int radius, Image *src, Point sp)
void lineop(Image *dst, Point p0, Point p1, int end0, int end1,
int radius, Image *src, Point sp, Drawop op)
poly(Image *dst, Point *p, int np, int end0, int end1,
int radius, Image *src, Point sp)
polyop(Image *dst, Point *p, int np, int end0, int end1,
int radius, Image *src, Point sp, Drawop op)
fillpoly(Image *dst, Point *p, int np, int wind,
Image *src, Point sp)
fillpolyop(Image *dst, Point *p, int np, int wind,
Image *src, Point sp, Drawop op)
bezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
int end0, int end1, int radius, Image *src, Point sp)
bezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
int end0, int end1, int radius, Image *src, Point sp,
Drawop op)
bezspline(Image *dst, Point *pt, int npt, int end0, int end1,
int radius, Image *src, Point sp)
bezsplineop(Image *dst, Point *pt, int npt, int end0, int end1,
int radius, Image *src, Point sp, Drawop op)
bezsplinepts(Point *pt, int npt, Point **pp)
fillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
int w, Image *src, Point sp)
fillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
int w, Image *src, Point sp, Drawop op)
fillbezspline(Image *dst, Point *pt, int npt, int w,
Image *src, Point sp)
fillbezsplineop(Image *dst, Point *pt, int npt, int w,
Image *src, Point sp, Drawop op)
ellipse(Image *dst, Point c, int a, int b, int thick,
Image *src, Point sp)
ellipseop(Image *dst, Point c, int a, int b, int thick,
Image *src, Point sp, Drawop op)
fillellipse(Image *dst, Point c, int a, int b,
Image *src, Point sp)
fillellipseop(Image *dst, Point c, int a, int b,
Image *src, Point sp, Drawop op)
arc(Image *dst, Point c, int a, int b, int thick,
Image *src, Point sp, int alpha, int phi)
arcop(Image *dst, Point c, int a, int b, int thick,
Image *src, Point sp, int alpha, int phi, Drawop op)
fillarc(Image *dst, Point c, int a, int b, Image *src,
Point sp, int alpha, int phi)
fillarcop(Image *dst, Point c, int a, int b, Image *src,
Point sp, int alpha, int phi, Drawop op)
icossin(int deg, int *cosp, int *sinp)
icossin2(int x, int y, int *cosp, int *sinp)
border(Image *dst, Rectangle r, int i, Image *color, Point sp)
string(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s)
stringop(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, Drawop op)
stringn(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, int len)
stringnop(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, int len, Drawop op)
runestring(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r)
runestringop(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, Drawop op)
runestringn(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, int len)
Point runestringnop(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, int len, Drawop op)
Point stringbg(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, Image *bg, Point bgp)
Point stringbgop(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, Image *bg, Point bgp, Drawop op)
Point stringnbg(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, int len, Image *bg, Point bgp)
Point stringnbgop(Image *dst, Point p, Image *src, Point sp,
Font *f, char *s, int len, Image *bg, Point bgp, Drawop op)
Point runestringbg(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, Image *bg, Point bgp)
Point runestringbgop(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, Image *bg, Point bgp, Drawop op)
Point runestringnbg(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, int len, Image *bg, Point bgp)
Point runestringnbgop(Image *dst, Point p, Image *src, Point sp,
Font *f, Rune *r, int len, Image *bg, Point bgp, Drawop op)
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)
void drawsetdebug(int on)
/* line ends
Endsquare =
Endarrow = 2,
#define ARROW(a, b, c) (Endarrow|((a)<<5)|((b)<<14)|((c)<<23))
The 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 repre­
sented as an Image; no special operators are needed to draw on a window.
The coordinates of the rectangle in the plane for which the Image has defined pixel val­
ues. It should not be modified after the image is created.
The clipping rectangle: operations that read or write the image will not access pixels out­
side clipr. Frequently, clipr is the same as r, but it may differ; see in particular
the discussion of repl. The clipping region may be modified dynamically using
replclipr (q.v.).
The pixel channel format descriptor, as described in image(6). The value should not be
modified after the image is created.
The number of bits per pixel in the picture; it is identically chantodepth(chan) (see
graphics(2)) and is provided as a convenience. The value should not be modified after
the image is created.
A boolean value specifying whether the image is tiled to cover the plane when used as a
source for a drawing operation. If repl is zero, operations are restricted to the inter­
section of r and clipr. If repl is set, r defines the tile to be replicated and clipr
defines the portion of the plane covered by the tiling, in other words, r is replicated to
cover clipr; in such cases r and clipr are independent.
For example, a replicated image with r set to ((0, 0), (1, 1)) and clipr set to
((0, 0), (100, 100)), with the single pixel of r set to blue, behaves identically to an image
with r and 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 dynami­
cally using replclipr (q.v.).
Most of the drawing functions come in two forms: a basic form, and an extended form that takes
an extra Drawop to specify a Porter-Duff compositing operator to use. The basic forms assume
the operator is SoverD, which suffices for the vast majority of applications. The extended forms
are named by adding an -op suffix to the basic form. Only the basic forms are listed below.
draw(dst, r, src, mask, p)
Draw is the standard drawing function. Only those pixels within the intersection of dst−>r
and dst−>clipr will be affected; draw ignores dst−>repl. The operation proceeds as
follows (this is a description of the behavior, not the implementation):
If repl is set in src or mask, replicate their contents to fill their clip rectangles.
Translate src and mask so p is aligned with r.min.
Set r to the intersection of r and dst−>r.
Intersect r with src−>clipr. If src−>repl is false, also intersect r with src−>r.
Intersect r with mask−>clipr. If mask−>repl is false, also intersect r with
For each location in r, combine the dst pixel with the src pixel using the alpha value
corresponding to the mask pixel. If the mask has an explicit alpha channel, the
alpha value corresponding to the mask pixel is simply that pixels 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 composit­
ing algebra, draw replaces the dst pixels with (src in mask) over dst. (In the
extended form, over is replaced by op).
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.
gendraw(dst, r, src, p0, mask, p1)
Similar to draw except that gendraw aligns the source and mask differently: src is aligned
so p0 corresponds to r.min and mask is aligned so p1 corresponds to r.min. For most
purposes with simple masks and source images, draw is sufficient, but gendraw is the
general operator and the one all other drawing primitives are built upon.
Clips x to be in the half-open interval [min, max) by adding or subtracting a multiple of
Clips the point p to be within the rectangle r by translating the point horizontally by an
integer multiple of rectangle width and vertically by the height.
Because the image data is stored on the server, local modifications to the Image data
structure itself will have no effect. Repclipr modifies the local Image data structures
repl and clipr fields, and notifies the server of their modification.
line(dst, p0, p1, end0, end1, thick, src, sp)
Line draws in dst a line of width 1+2*thick pixels joining points p0 and p1. The line is
drawn using pixels from the src image aligned so sp in the source corresponds to p0 in the
destination. The line touches both p0 and p1, and end0 and end1 specify how the ends of
the line are drawn. Endsquare terminates the line perpendicularly to the direction of the
line; a thick line with Endsquare on both ends will be a rectangle. Enddisc terminates
the line by drawing a disc of diameter 1+2*thick centered on the end point. Endarrow
terminates the line with an arrowhead whose tip touches the endpoint.
The macro ARROW permits explicit control of the shape of the arrow. If all three parame­
ters are zero, it produces the default arrowhead, otherwise, a sets the distance along line
from end of the regular line to tip, b sets the distance along line from the barb to the tip,
and c sets the distance perpendicular to the line from edge of line to the tip of the barb, all
in pixels.
Line and the other geometrical operators are equivalent to calls to gendraw using a mask
produced by the geometric procedure.
poly(dst, p, np, end0, end1, thick, src, sp)
Poly draws a general polygon; it is conceptually equivalent to a series of calls to line joining
adjacent points in the array of Points p, which has np elements. The ends of the poly­
gon are specified as in line; interior lines are terminated with Enddisc to make smooth
joins. The source is aligned so sp corresponds to p[0].
fillpoly(dst, p, np, wind, src, sp)
Fillpoly is like poly but fills in the resulting polygon rather than outlining it. The source is
aligned so sp corresponds to p[0]. The winding rule parameter wind resolves ambiguities
about what to fill if the polygon is self-intersecting. If wind is ~0, a pixel is inside the poly­
gon if the polygons winding number about the point is non-zero. If wind is 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
bezier(dst, a, b, c, d, end0, end1, thick, src, sp)
Bezier draws the cubic Bezier curve defined by Points a, b, c, and d. The end styles are
determined by end0 and end1; the thickness of the curve is 1+2*thick. The source is
aligned so sp in src corresponds to a in dst.
bezspline(dst, p, end0, end1, thick, src, sp)
Bezspline takes the same arguments as poly but draws a quadratic B-spline (despite its
name) rather than a polygon. If the first and last points in p are equal, the spline has peri­
odic end conditions.
bezsplinepts(pt, npt, pp)
Bezsplinepts returns in pp a list of points making up the open polygon that bezspline would
draw. The caller is responsible for freeing *pp.
fillbezier(dst, a, b, c, d, wind, src, sp)
Fillbezier is to bezier as fillpoly is to poly.
fillbezspline(dst, p, wind, src, sp)
Fillbezspline is like fillpoly but fills the quadratic B-spline rather than the polygon outlined
by p. The spline is closed with a line if necessary.
ellipse(dst, c, a, b, thick, src, sp)
Ellipse draws in dst an ellipse centered on c with horizontal and vertical semiaxes a and b.
The source is aligned so sp in src corresponds to c in dst. The ellipse is drawn with thick­
ness 1+2*thick.
fillellipse(dst, c, a, b, src, sp)
Fillellipse is like ellipse but fills the ellipse rather than outlining it.
arc(dst, c, a, b, thick, src, sp, alpha, phi)
Arc is like ellipse, but draws only that portion of the ellipse starting at angle alpha and
extending through an angle of phi. The angles are measured in degrees counterclockwise
from the positive x axis.
fillarc(dst, c, a, b, src, sp, alpha, phi)
Fillarc is like arc, but fills the sector with the source color.
icossin(deg, cosp, sinp)
Icossin stores in *cosp and *sinp scaled integers representing the cosine and sine of the
angle deg, measured in integer degrees. The values are scaled so cos(0) is 1024.
icossin2(x, y, cosp, sinp)
Icossin2 is analogous to icossin, with the angle represented not in degrees but implicitly by
the point (x,y). It is to icossin what atan2 is to atan (see sin(2)).
border(dst, r, i, color, sp)
Border draws an outline of rectangle r in the specified color. The outline has width i; if pos­
itive, the border goes inside the rectangle; negative, outside. The source is aligned so sp
corresponds to r.min.
string(dst, p, src, sp, font, s)
String draws in dst characters specified by the string s and font; it is equivalent to a series
of calls to gendraw using source src and masks determined by the character shapes. The
text is positioned with the left of the first character at p.x and the top of the line of text at
p.y. The source is positioned so sp in src corresponds to p in dst. String returns a
Point that is the position of the next character that would be drawn if the string were
For characters with undefined or zero-width images in the font, the character at font posi­
tion 0 (NUL) is drawn.
The other string routines are variants of this basic form, and have names that encode their
variant behavior. Routines whose names contain rune accept a string of Runes rather than
UTF-encoded bytes. Routines ending in n accept an argument, n, that defines the number
of characters to draw rather than accepting a NUL-terminated string. Routines containing
bg draw the background behind the characters in the specified color (bg) and alignment
(bgp); normally the text is drawn leaving the background intact.
The routine _string captures all this behavior into a single operator. Whether it draws a UTF
string or Rune string depends on whether s or r is null (the string length is always deter­
mined by len). If bg is non-null, it is used as a background color. The 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.
Turns on or off debugging output (usually to a serial line) according to whether on is nonzero.
graphics(2), stringsize(2), color(6), utf(6), addpt(2)
T. Porter, T. Duff. Compositing Digital Images, Computer Graphics (Proc. SIGGRAPH), 18:3, pp.
253-259, 1984.
These routines call the graphics error function on fatal errors.
Anti-aliased characters can be drawn by defining a font with multiple bits per pixel, but there are
no anti-aliasing geometric primitives.
dsagen, dsasign, dsaverify, dsapuballoc, dsapubfree, dsaprivalloc, dsaprivfree, dsasigalloc, dsasig­
free, dsaprivtopub - digital signature algorithm
dsagen(DSApub *opub)
dsasign(DSApriv *k, mpint *m)
dsaverify(DSApub *k, DSAsig *sig, mpint *m)
DSA is the NIST approved digital signature algorithm. The owner of a key publishes the public part
of the key:
struct DSApub
*p; // modulus
*q; // group order, q divides p−1
// group generator
// alpha**secret mod p
This part can be used for verifying signatures (with dsaverify) created by the owner. The owner
signs (with dsasign) using his private key:
struct DSApriv
*secret; // (decryption key)
Keys are generated using dsagen. If dsagens argument opub is nil, a key is created using a new
p and q generated by DSAprimes (see prime(2)). Otherwise, p and q are copied from the old key.
Dsaprivtopub returns a newly allocated copy of the public key corresponding to the private key.
The routines dsapuballoc, dsapubfree, dsaprivalloc, and dsaprivfree are provided to manage key
Dsasign signs message m using a private key k yielding a
struct DSAsig
*r, *s;
Dsaverify returns 0 if the signature is valid and 1 if not.
The routines dsasigalloc and dsasigfree are provided to manage signature storage.
mp(2), aes(2), blowfish(2), des(2), rc4(2), rsa(2), sechash(2), prime(2), rand(2)
dup duplicate an open file descriptor
#include <u.h>
#include <libc.h>
int dup(int oldfd, int newfd)
Given a file descriptor, oldfd, referring to an open file, dup returns a new file descriptor referring
to the same file.
If newfd is 1 the system chooses the lowest available file descriptor. Otherwise, dup will use
newfd for the new file descriptor (closing any old file associated with newfd). File descriptors are
allocated dynamically, so to prevent unwarranted growth of the file descriptor table, dup requires
that newfd be no greater than 20 more than the highest file descriptor ever used by the program.
intro(2), dup(3)
Sets errstr.
dynfindsym, dynfreeimport, dynloadfd, dynloadgen, dynobjfree, dyntabsize load object file
dynfindsym(char *name, Dynsym *syms, int nsym);
dynloadfd(int fd, Dynsym *exports, int nexport,
ulong maxsize);
dynloadgen(void *file, long (*read)(void*,void*,long),
vlong (*seek)(void*,vlong,int), void (*err)(char*),
Dynsym *exports, int nexport, ulong maxsize);
dynimport(Dynobj *o, char *name, ulong sig);
dynfreeimport(Dynobj *o);
dynobjfree(Dynobj *o);
dyntabsize(Dynsym *t);
extern Dynsym
These functions allow a process to load further code and data into the currently executing image.
A dynamically-loadable file, called a module here, is a variant of the a.out(6) executable format
with some extra components. The loader for the architecture (see 2l(1)) creates a module file from
component object file(s) when given the −u option. A module contains text and data sections, an
import table, an export table, and relocation data. The import table lists the symbols the module
needs from the loading program; the export table lists symbols the module provides when loaded.
A program that loads a module provides a table of its own symbols to match the symbols in the
modules import table.
A symbol entry in a symbol table names a global function or data item, and has an associated
signature value representing the type of the corresponding function or data in the source code.
The Dynsym structure defines a symbol:
typedef struct
} Dynsym;
The structure is known to the loaders 2l(1). Name is the linkage name of the function or data.
Addr is its address, which is relative to the start of the module before loading, and an address in
the current address space after loading. The signature sig is the value produced by the C
compilers signof operator applied to the type. Symbol tables must be sorted by name.
An executable that wishes to load modules will normally be linked using the −x option to the
appropriate loader 2l(1). The resulting executable contains an export table _exporttab that
lists all the exported symbols of the program (by default, all external symbols). A nil name marks
the end of the table. See 2l(1) for details. The table can be given to the functions below to allow a
loaded module to access those symbols.
A loaded module is described by a Dynobj structure:
typedef struct
size in bytes */
of text */
of data */
of bss */
of text, data, bss */
} Dynobj;
/* export table */
/* import table */
Several fields give sizes of the modules components, as noted in comments above. Base gives the
address at which the module has been loaded. All its internal references have been adjusted
where needed to reflect its current address. Export points to a symbol table listing the symbols
exported by the module; nexport gives the tables length. Import points to a list of symbols
imported by the module; note that each entry actually points to an entry in a symbol table provided
by the program that loaded the module (see below). Nimport gives the import tables length. If
the import table is not required, call dynfreeimport on the module pointer to free it.
Dynfindysm looks up the entry for the given name in symbol table syms (of length nsym). It
returns a pointer to the entry if found; nil otherwise. The symbol table must be sorted by name in
ascending order.
Dyntabsize returns the length of symbol table t, defined to be the number of Dynsym values start­
ing at t that have non-nil name fields. It is used to find the length of _exporttab.
Dynloadfd loads a module from the file open for reading on fd, and returns the resulting module
pointer on success, or nil on error. If maxsize is non-zero the size of the dynamically-loaded
modules code and data is limited to maxsize bytes. Exports is an array of nexport symbols in the
current program that can be imported by the current module. It uses read(2) and seek(2) to
access fd, and calls werrstr (see errstr(2)) to set the error string if necessary.
Dynloadgen is a more general function that can load a module from an arbitrary source, not just an
open file descriptor. (In particular, it can be called by the kernel using functions internal to the
kernel instead of making system calls.) Exports, nexport and maxsize are just as for dynloadfd.
File is a pointer to a structure defined by the caller that represents the file containing the module.
It is passed to read and seek. Read is invoked as (*read)(file,buf, nbytes). Read should
read nbytes of data from file into buf and return the number of bytes transferred. It should return
-1 on error. Seek is invoked as (*seek)(file,n, type) where n and type are just as for
seek(2); it should seek to the requested offset in file, or return -1 on error. Dynloadgen returns a
pointer to the loaded module on success. On error, it returns nil after calling its err parameter to
set the error string.
Dynimport returns a pointer to the value of the symbol name in loaded module o, or nil if o does
not export a symbol with the given name. If sig is non-zero, the exported symbols signature must
equal sig, or dynimport again returns nil. For example:
Dev *d;
d = dynimport(obj, "XXXdevtab", signof(*d));
if(d == nil)
error("not a dynamically−loadable driver");
Dynobjfree frees the module o. There is no reference counting: it is the callers responsibility to
decide whether a module is no longer needed.
2l(1), mach(2), a.out(6)
Functions that return pointers return nil on error. Dynloadfd sets the error string and returns nil.
eggen, egencrypt, egdecrypt, egsign, egverify, egpuballoc, egpubfree, egprivalloc, egprivfree, egsi­
galloc, egsigfree, egprivtopub - elgamal encryption
eggen(int nlen, int nrep)
egencrypt(EGpub *k, mpint *in, mpint *out)
egdecrypt(EGpriv *k, mpint *in, mpint *out)
egsign(EGpriv *k, mpint *m)
egverify(EGpub *k, EGsig *sig, mpint *m)
Elgamal is a public key encryption and signature algorithm. The owner of a key publishes the pub­
lic part of the key:
struct EGpub
*p; // modulus
// generator
// (encryption key) alpha**secret mod p
This part can be used for encrypting data (with egencrypt) to be sent to the owner. The owner
decrypts (with egdecrypt) using his private key:
struct EGpriv
*secret; // (decryption key)
Keys are generated using eggen. 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. Egprivtopub returns a newly allocated copy of the public key corresponding to the private
The routines egpuballoc, egpubfree, egprivalloc, and egprivfree are provided to manage key stor­
Egsign signs message m using a private key k yielding a
struct EGsig
*r, *s;
Egverify returns 0 if the signature is valid and 1 if not.
The routines egsigalloc and egsigfree are provided to manage signature storage.
mp(2), aes(2), blowfish(2), des(2), dsa(2), rc4(2), rsa(2), sechash(2), prime(2), rand(2)
dec64, enc64, dec32, enc32, dec16, enc16, encodefmt encoding byte arrays as strings
#include <u.h>
#include <libc.h>
dec64(uchar *out, int lim, char *in, int n)
enc64(char *out, int lim, uchar *in, int n)
dec32(uchar *out, int lim, char *in, int n)
enc32(char *out, int lim, uchar *in, int n)
dec16(uchar *out, int lim, char *in, int n)
enc16(char *out, int lim, uchar *in, int n)
Enc16, enc32 and 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 lim, the length of the output
buffer, is too small.
Dec16, dec32 and 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.
Encodefmt can be used with fmtinstall(2) and print(2) to print encoded representations of byte
arrays. The verbs are
base 16 (i.e. hexadecimal). The default encoding is in upper case. The l flag forces lower
base 32
base 64 (same as MIME)
The length of the array is specified as f2. For example, to display a 15 byte array as hex:
char x[15];
fmtinstall(’H’, encodefmt);
print("%.*H\n", sizeof x, x);
encrypt, decrypt, netcrypt DES encryption
#include <u.h>
#include <libc.h>
encrypt(void *key, void *data, int len)
decrypt(void *key, void *data, int len)
netcrypt(void *key, void *data)
Encrypt and decrypt perform DES encryption and decryption. Key is an array of DESKEYLEN
(defined as 7 in <auth.h>) bytes containing the encryption key. Data is an array of len bytes; it
must be at least 8 bytes long. The bytes are encrypted or decrypted in place.
The DES algorithm encrypts an individual 8-byte block of data. 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. Decrypt
uses the inverse algorithm.
Netcrypt performs the same encryption as a SecureNet Key. Data points to an ASCII string of deci­
mal 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 format­
ted as two digit ASCII hexadecimal numbers, and the string is copied into data.
These routines return 1 if the data was encrypted, and 0 if the encryption fails. Encrypt and
decrypt fail if the data passed is less than 8 bytes long. Netcrypt can fail if it is passed invalid
The implementation is broken in a way that makes it unsuitable for anything but authentication.
waserror, poperror, nexterror, error, fmterror, silenterror exception handling for threaded pro­
error(char *err);
fmterror(char *fmt, ...);
silenterror(char *fmt, ...);
The functions in this library provide an aexception handling mechanism modelled on that in the
Plan 9 kernel. A construct such as
if(…) raise(exception);
handle exception
using this library becomes:
handle exception
if(…) error("exception");
Waserror and poperror are the bracketing elements around the code in which an exception might
be raied with a call to error.
Waserror sets a point to which control returns if an exception occurs and returns zero. If the
exception occurs, control transfers back to waserror and it then clears the point previously set and
returns non-zero.
Poperror clears the exception-return point previously set by waserror.
Error, fmterror and silenterror all raise an error and they all set the error string. Fmterror and
silenterror take a format string, while error just takes a simple string. Error and fmterror print the
string on standard error as well. Silenterror does not.
Exception contexts bracketed by waserror and poperror can be nested. When an exception has
been handled in the innermost context, a call to nexterror transfers it to the next larger context.
Using exceptions to free dynamic memory:
p = malloc(something);
fmterror("%s: %r", x);
Excerpt from the worker library. The worker calls a user-spcified function that may raise an error.
The error is caught and the worker prepares for the next customer:
static void
worker(void *arg)
Worker *w;
w = arg;
w−>r = recvp(w−>chan);
w−>r−>func(w, w−>r−>arg);
sendp(workerthreads, w);
Waserror returns non-zero when an error was raised.
The error stack is only 32 levels deep.
Sape Mullender
errstr, rerrstr, werrstr description of last system call error
#include <u.h>
#include <libc.h>
int errstr(char *err, uint nerr)
void rerrstr(char *err, uint nerr)
void werrstr(char *fmt, ...)
When a system call fails it returns 1 and records a null terminated string describing the error in a
per-process buffer. Errstr swaps the contents of that buffer with the contents of the array err.
Errstr will write at most nerr bytes into 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 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 errstr.
The per-process buffer is ERRMAX bytes long. Any error string provided by the user will be trun­
cated at ERRMAX−1 bytes. ERRMAX is defined in <libc.h>.
If no system call has generated an error since the last call to errstr with an empty string, the result
is an empty string.
The verb r in print(2) calls errstr and outputs the error string.
Rerrstr reads the error string but does not modify the per-process buffer, so a subsequent errstr
will recover the same string.
Werrstr takes a print style format as its argument and uses it to format a string to pass to errstr.
The string returned from errstr is discarded.
Errstr always returns 0.
intro(2), perror(2)
event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, eread­
mouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, emoveto, esetcursor, Event,
Mouse, Menu graphics events
einit(ulong keys)
event(Event *e)
ereadmouse(Mouse *m)
eatomouse(Mouse *m, char *buf, int n)
estart(ulong key, int fd, int n)
estartfn(int id, ulong key, int fd, int n,
int (*fn)(Event*, uchar*, int))
etimer(ulong key, int n)
eread(ulong keys, Event *e)
ecanread(ulong keys)
eresized(int new)
Rectangle egetrect(int but, Mouse *m)
edrawgetrect(Rectangle r, int up)
emenuhit(int but, Mouse *m, Menu *menu)
emoveto(Point p)
esetcursor(Cursor *c)
extern Mouse
Emouse = 1,
Ekeyboard = 2,
These routines provide an interface to multiple sources of input for unthreaded programs.
Threaded programs (see thread(2)) should instead use the threaded mouse and keyboard interface
described in mouse(2) and keyboard (2).
Einit must be called first. If the argument to einit has the Emouse and Ekeyboard bits set, the
mouse and keyboard events will be enabled; in this case, initdraw (see graphics(2)) must have
already been called. The user must provide a function called eresized to be called whenever the
window in which the process is running has been resized; the argument new is a flag specifying
whether the program must call getwindow (see graphics(2)) to re-establish a connection to its win­
dow. After resizing (and perhaps calling getwindow), the global variable screen will be updated
to point to the new windows Image structure.
As characters are typed on the keyboard, they are read by the event mechanism and put in a
queue. Ekbd returns the next rune from the queue, blocking until the queue is non-empty. The
characters are read in raw mode (see cons(3)), so they are available as soon as a complete rune is
When the mouse moves or a mouse button is pressed or released, a new mouse event is queued by
the event mechanism. Emouse returns the next mouse event from the queue, blocking until the
queue is non-empty. Emouse returns a Mouse structure:
struct Mouse
Point xy;
ulong msec;
Buttons&1 is set when the left mouse button is pressed, buttons&2 when the middle button
is pressed, and buttons&4 when the right button is pressed. The current mouse position is
always returned in xy. Msec is a time stamp in units of milliseconds.
Ecankbd and ecanmouse return non-zero when there are keyboard or mouse events available to be
Ereadmouse reads the next mouse event from the file descriptor connected to the mouse, converts
the textual data into a Mouse structure by calling eatomouse with the buffer and count from the
read call, and returns the number of bytes read, or 1 for an error.
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. Estartfn is similar
to estart, but processes the data received by calling fn before returning the event to the user. The
function fn is called with the id of the event; it should return id if the event is to be passed to the
user, 0 if it is to be ignored. The variable Event.v can be used by fn to attach an arbitrary data
item to the returned Event structure.
Ekeyboard and Emouse are the keyboard and mouse
event keys.
Etimer starts a repeating timer with a period of 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.
Eread waits for the next event specified by the mask keys of event keys submitted to estart. It fills
in the appropriate field of the argument Event structure, which looks like:
struct Event
Mouse mouse;
void *v;
uchar data[EMAXMSG];
Data is an array which is large enough to hold a 9P message. Eread returns the key for the event
which was chosen. For example, if a mouse event was read, Emouse will be returned.
Event waits for the next event of any kind. The return is the same as for eread.
As described in graphics(2), the graphics functions are buffered. Event, eread, emouse, and ekbd
all cause a buffer flush unless there is an event of the appropriate type already queued.
Ecanread checks whether a call to eread(keys) would block, returning 0 if it would, 1 if it
would not.
Getrect prompts the user to sweep a rectangle. It should be called with m holding the mouse
event that triggered the egetrect (or, if none, a Mouse with buttons set to 7). It changes to the
sweep cursor, waits for the buttons all to be released, and then waits for button number but to be
pressed, marking the initial corner. If another button is pressed instead, egetrect returns a rectan­
gle with zero for both corners, after waiting for all the buttons to be released. Otherwise, egetrect
continually draws the swept rectangle until the button is released again, and returns the swept
rectangle. The mouse structure pointed to by m will contain the final mouse event.
Egetrect uses successive calls to edrawgetrect to maintain the red rectangle showing the sweepin-progress. The rectangle to be drawn is specified by rc and the up parameter says whether to
draw (1) or erase (0) the rectangle.
Emenuhit displays a menu and returns a selected menu item number. It should be called with m
holding the mouse event that triggered the emenuhit; it will call emouse to update it. A Menu is a
struct Menu
char **item;
char *(*gen)(int);
If item is nonzero, it should be a null-terminated array of the character strings to be displayed as
menu items. Otherwise, gen should be a function that, given an item number, returns the charac­
ter string for that item, or zero if the number is past the end of the list. Items are numbered start­
ing at zero. Menuhit waits until but is released, and then returns the number of the selection, or
1 for no selection. The m argument is filled in with the final mouse event.
Emoveto moves the mouse cursor to the position p on the screen.
Esetcursor changes the cursor image to that described by the Cursor c (see mouse(2)). If c is nil,
it restores the image to the default arrow.
rio(1), graphics(2), plumb(2), cons(3), draw(3)
exec, execl, _privates, _nprivates, _tos execute a file
#include <u.h>
#include <libc.h>
void* exec(char *name, char* argv[])
void* execl(char *name, ...)
void **_privates;
#include <tos.h>
typedef struct Tos Tos;
struct Tos {
struct { ... } prof;
uvlong cyclefreq;
/* top of stack is here
profiling data */
cycle clock frequency */
kernel cycles */
process cycles (kernel + user) */
process id */
profiling clock */
extern Tos *_tos;
Exec and execl overlay the calling process with the named file, then transfer to the entry point of
the image of the file.
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 stat(2)). It should also be a valid binary image, as
defined in the a.out(6) for the current machine architecture, or a shell script (see rc(1)). The first
line of a shell script must begin with #! followed by the name of the program to interpret the file
and any initial arguments to that program, for example
ls | mc
When a C program is executed, it is called as follows:
void main(int argc, char *argv[])
Argv is a copy of the array of argument pointers passed to exec; that array must end in a null
pointer, and argc is the number of elements before the null pointer. By convention, the first argu­
ment should be the name of the program to be executed. Execl is like exec except that argv will
be an array of the parameters that follow name in the call. The last argument to execl must be a
null pointer.
For a file beginning #!, the arguments passed to the program (/bin/rc in the example above)
will be the name of the file being executed, any arguments on the #! line, the name of the file
again, and finally the second and subsequent arguments given to the original exec call. The result
honors the two conventions of a program accepting as argument a file to be interpreted and
argv[0] naming the file being executed.
Most attributes of the calling process are carried into the result; in particular, files remain open
across exec (except those opened with OCEXEC ORd into the open mode; see open(2)); and the
working directory and environment (see env(3)) remain the same. However, a newly exec’ed pro­
cess has no notification handler (see notify(2)).
The global cell _privates points to an array of _nprivates elements of per-process private
data. This storage is private for each process, even if the processes share data segments.
When the new program begins, the global pointer _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 rforks and execs. If there
is a user-space accessible fast clock (a processor cycle counter), cyclefreq will be set to its fre­
quency in Hz. Kcycles (pcycles) counts the number of cycles this process has spent in kernel
mode (kernel and user mode). Pid is the current processs id. Clock is the user-profiling clock
(see 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.
The above conventions apply to C programs; the raw system interface to the new image is as fol­
lows: the word pointed to by the stack pointer is argc; the words beyond that are the zeroth and
subsequent elements of argv, followed by a terminating null pointer; and the return register (e.g.
R0 on the 68020) contains the address of the clock information.
prof(1), intro(2), stat(2)
If these functions fail, they return and set errstr. There can be no return to the calling process
from a successful exec or execl; the calling image is lost.
There is a large but finite limit on the size of an argment list, typically around 409,600 bytes. The
kernel constant TSTKSIZ controls this.
exits, _exits, atexit, atexitdont, terminate terminate process, process cleanup
#include <u.h>
#include <libc.h>
void _exits(char *msg)
void exits(char *msg)
void atexitdont(void(*)(void))
Exits is the conventional way to terminate a process. _Exits is the underlying system call. They can
never return.
Msg conventionally includes a brief (maximum length ERRLEN) explanation of the reason for exit­
ing, 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 wait(2).
Before calling _exits with msg as an argument, exits calls in reverse order all the functions
recorded by atexit.
Atexit records fn as a function to be called by 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, exits only calls those atexit-registered functions that were registered by the same
process as that calling exits.
Calling atexit twice (or more) with the same function argument causes exits to invoke the function
twice (or more).
There is a limit to the number of exit functions that will be recorded; atexit returns 0 if that limit
has been reached.
Atexitdont cancels a previous registration of an exit function.
fork(2), wait(2)
exp, log, log10, pow, pow10, sqrt exponential, logarithm, power, square root
#include <u.h>
#include <libc.h>
double exp(double x)
double log(double x)
double log10(double x)
double pow(double x, double y)
double pow10(int n)
double sqrt(double x)
Exp returns the exponential function of x.
Log returns the natural logarithm of x; log10 returns the base 10 logarithm.
Pow returns xy and pow10 returns 10n as a double.
Sqrt returns the square root of x.
All these routines have portable C implementations in /sys/src/libc/port. Most also have
hypot(2), sinh(2), intro(2)
fauth set up authentication on a file descriptor to a file server
#include <u.h>
#include <libc.h>
fauth(int fd, char *aname)
Fauth is used to establish authentication for the current user to access the resources available
through the 9P connection represented by fd. The return value is a file descriptor, conventionally
called afd, that is subsequently used to negotiate the authentication protocol for the server, typi­
cally using auth_proxy or fauth_proxy (see auth(2)). After successful authentication, afd may be
passed as the second argument to a subsequent mount call (see bind(2)), with the same aname,
as a ticket-of-entry for the user.
If fauth returns -1, the error case, that means the file server does not require authentication for
the connection, and afd should be set to -1 in the call to mount.
It is rare to use fauth directly; more commonly amount (see auth(2)) is used.
attach(5), auth(2) (particularly amount), authsrv(6), auth(8)
Sets errstr.
Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt, dirmodefmt, read9pmsg,
statcheck, sizeS2M, sizeD2M interface to Plan 9 File protocol
#include <u.h>
#include <libc.h>
#include <fcall.h>
uint convS2M(Fcall *f, uchar *ap, uint nap)
uint convD2M(Dir *d, uchar *ap, uint nap)
uint convM2S(uchar *ap, uint nap, Fcall *f)
uint convM2D(uchar *ap, uint nap, Dir *d, char *strs)
int dirfmt(Fmt*)
int fcallfmt(Fmt*)
int dirmodefmt(Fmt*)
int read9pmsg(int fd, uchar *buf, uint nbuf)
int statcheck(uchar *buf, uint nbuf)
uint sizeS2M(Fcall *f)
uint sizeD2M(Dir *d)
These routines convert messages in the machine-independent format of the Plan 9 file protocol,
9P, to and from a more convenient form, an Fcall structure:
#define MAXWELEM 16
struct Fcall
uchar type;
union {
struct {
struct {
struct {
struct {
struct {
struct {
/* Tversion, Rversion */
/* Tversion, Rversion */
/* Tflush */
/* Rerror */
/* Rattach, Ropen, Rcreate */
/* Ropen, Rcreate */
/* Rauth */
/* Tauth, Tattach */
/* Tauth, Tattach */
/* Tauth, Tattach */
struct {
struct {
struct {
struct {
struct {
/* Tcreate */
/* Tcreate */
/* Tcreate, Topen */
/* Twalk */
/* Twalk */
/* Twalk */
/* Rwalk */
/* Rwalk */
/* Tread, Twrite */
/* Tread, Twrite, Rread */
/* Twrite, Rread */
/* Twstat, Rstat */
/* Twstat, Rstat */
} Fcall;
/* these are implemented as macros */
PBIT8(uchar*, uchar)
PBIT16(uchar*, ushort)
PBIT32(uchar*, ulong)
PBIT64(uchar*, vlong)
This structure is defined in <fcall.h>. See section 5 for a full description of 9P messages and
their encoding. For all message types, the type field of an Fcall holds one of Tversion,
Rversion, Tattach, Rattach, etc. (defined in an enumerated type in <fcall.h>). Fid is
used by most messages, and tag is used by all messages. The other fields are used selectively by
the message types given in comments.
ConvM2S takes a 9P message at ap of length nap, and uses it to fill in Fcall structure f. If the
passed message including any data for Twrite and Rread messages is formatted properly, the
return value is the number of bytes the message occupied in the buffer ap, which will always be
less than or equal to nap; otherwise it is 0. For Twrite and Tread messages, data is set to a
pointer into the argument message, not a copy.
ConvS2M does the reverse conversion, turning f into a message starting at ap. The length of the
resulting message is returned. For Twrite and Rread messages, count bytes starting at
data are copied into the message.
The constant IOHDRSZ is a suitable amount of buffer to reserve for storing the 9P header; the
data portion of a Twrite or Rread will be no more than the buffer size negotiated in the
Tversion/Rversion exchange, minus IOHDRSZ.
The routine sizeS2M returns the number of bytes required to store the machine-independent rep­
resentation of the Fcall structure f, including its initial 32-bit size field. In other words, it
reports the number of bytes produced by a successful call to convS2M.
Another structure is Dir, used by the routines described in stat(2). ConvM2D converts the
machine-independent form starting at ap into d and returns the length of the machineindependent encoding. The strings in the returned Dir structure are stored at successive loca­
tions starting at strs. Usually strs will point to storage immediately after the Dir itself. It can
also be a nil pointer, in which case the string pointers in the returned Dir are all nil; however,
the return value still includes their length.
ConvD2M does the reverse translation, also returning the length of the encoding. If the buffer is
too short, the return value will be BIT16SZ and the correct size will be returned in the first
BIT16SZ bytes. (If the buffer is less that BIT16SZ, the return value is zero; therefore a correct
test for complete packing of the message is that the return value is greater than BIT16SZ). The
macro GBIT16 can be used to extract the correct value. The related macros with different sizes
retrieve the corresponding-sized quantities. PBIT16 and its brethren place values in messages.
With the exception of handling short buffers in convD2M, these macros are not usually needed
except by internal routines.
Analogous to sizeS2M, sizeD2M returns the number of bytes required to store the machineindependent representation of the Dir structure d, including its initial 16-bit size field.
The routine statcheck checks whether the nbuf bytes of buf contain a validly formatted
machine-independent Dir entry suitable as an argument, for example, for the wstat (see
stat(2)) system call. It checks that the sizes of all the elements of the the entry sum to exactly
nbuf, which is a simple but effective test of validity. Nbuf and buf should include the second twobyte (16-bit) length field that precedes the entry when formatted in a 9P message (see stat(5)); in
other words, nbuf is 2 plus the sum of the sizes of the entry itself. Statcheck also verifies that the
length field has the correct value (that is, nbuf−2). It returns 0 for a valid entry and −1 for an
incorrectly formatted entry.
Dirfmt, fcallfmt, and dirmodefmt are formatting routines, suitable for fmtinstall(2). They convert
Dir*, Fcall*, and long values into string representations of the directory buffer, Fcall
buffer, or file mode value. Fcallfmt assumes that dirfmt has been installed with format letter D
and dirmodefmt with format letter M.
Read9pmsg calls read(2) multiple times, if necessary, to read an entire 9P message into buf. The
return value is 0 for end of file, or -1 for error; it does not return partial messages.
intro(2), 9p(2), stat(2), intro(5)
fd2path return file name associated with file descriptor
#include <u.h>
#include <libc.h>
int fd2path(int fd, char *buf, int nbuf)
As described in 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. Fd2path returns the path name
associated with open file descriptor fd. Up to nbuf bytes of the name are stored in buf; if the name
is too long, it will be silently truncated at a UTF-8 character boundary. The name is always nullterminated. The return value of fd2path will be zero unless an error occurs.
Changes to the underlying name space do not update the path name stored with the file descrip­
tor. Therefore, the path returned by 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.
As an example, getwd(2) is implemented by opening . and executing fd2path on the resulting file
bind(1), ns(1), bind(2), intro(2), getwd(2), proc(3)
Sets errstr.
fgetc, getc, getchar, fputc, putc, putchar, ungetc, fgets, gets, fputs, puts, fread, fwrite Stdio input
and output
#include <u.h>
#include <stdio.h>
fgetc(FILE *f)
getc(FILE *f)
fputc(int c, FILE *f)
putc(int c, FILE *f)
putchar(int c)
ungetc(int c, FILE *f)
char *fgets(char *s, int n, FILE *f)
char *gets(char *s)
fputs(char *s, FILE *f)
puts(char *s)
long fread(void *ptr, long itemsize, long nitems, FILE *stream)
long fwrite(void *ptr, long itemsize, long nitems, FILE *stream)
The functions described here work on open Stdio streams (see fopen).
Fgetc returns as an int the next unsigned char from input stream f. If the stream is at endof-file, the end-of-file indicator for the stream is set and fgetc returns EOF. If a read error
occurs, the error indicator for the stream is set and fgetc returns EOF. Getc is like fgetc except
that it is implemented as a macro. Getchar is like getc except that it always reads from stdin.
Ungetc pushes character c back onto the input stream f. The pushed-back character will be
returned by subsequent reads in the reverse order of their pushing. A successful intervening
fseek, fsetpos, or rewind on f discards any pushed-back characters for f. One character of pushback is guaranteed. Ungetc returns the character pushed back (converted to unsigned char),
or EOF if the operation fails. A successful call to ungetc clears the end-of-file indicator for the
stream. The file position indicator for the stream after reading or discarding all pushed-back char­
acters is the same as it was before the characters were pushed back.
Fputc writes character c (converted to unsigned char) to output stream f at the position indi­
cated 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. Fputc returns the character written or EOF if there was a write
error. Putc is like fputc but is implemented as a macro. Putchar is like putc except that it always
writes to stdout.
All other input takes place as if characters were read by successive calls to fgetc and all other out­
put takes place as if characters were written by successive calls to fputc.
Fgets reads up to and including the next newline, but not past end-of-file or more than n-1 char­
acters, from stream f into array s. A null character is written immediately after the last character
read into the array (if any characters are read at all). Fgets returns s if successful, otherwise a null
pointer. Gets is similar to fgets except that it always reads from stdin and it discards the termi­
nating newline, if any. Gets does not check for overflow of the receiving array, so its use is depre­
Fputs writes the string s to stream f, returning EOF if a write error occurred, otherwise a nonnega­
tive value. The terminating null character is not written. Puts is the same, writing to stdout.
Fread reads from the named input stream at most nitems of data of size itemsize and the type of
*ptr into a block beginning at ptr. It returns the number of items actually read.
Fwrite appends to the named output stream at most nitems of data of size itemsize and the type of
*ptr from a block beginning at ptr. It returns the number of items actually written.
read(2), fopen(2), bio(2)
Stdio does not handle UTF or runes; use Bio instead.
deflateinit, deflate, deflatezlib, deflateblock, deflatezlibblock, inflateinit, inflate, inflatezlib, inflate­
block, inflatezlibblock, flateerr, mkcrctab, blockcrc, adler32 deflate compression
#include <u.h>
#include <libc.h>
#include <flate.h>
deflate(void *wr, int (*w)(void*,void*,int),
void *rr, int (*r)(void*,void*,int),
int level, int debug)
deflatezlib(void *wr, int (*w)(void*,void*,int),
void *rr, int (*r)(void*,void*,int),
int level, int debug)
deflateblock(uchar *dst, int dsize,
uchar *src, int ssize,
int level, int debug)
deflatezlibblock(uchar *dst, int dsize,
uchar *src, int ssize,
int level, int debug)
inflate(void *wr, int (*w)(void*, void*, int),
void *getr, int (*get)(void*))
inflatezlib(void *wr, int (*w)(void*, void*, int),
void *getr, int (*get)(void*))
inflateblock(uchar *dst, int dsize,
uchar *src, int ssize)
inflatezlibblock(uchar *dst, int dsize,
uchar *src, int ssize)
*flateerr(int error)
*mkcrctab(ulong poly)
blockcrc(ulong *tab, ulong crc, void *buf, int n)
adler32(ulong adler, void *buf, int n)
These routines compress and decompress data using the deflate compression algorithm, which is
used for most gzip, zip, and zlib files.
Deflate compresses input data retrieved by calls to r with arguments rr, an input buffer, and a
count of bytes to read. 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 w with arguments wr, the output data, and the number of bytes to write. W should return the
number of bytes written; writing fewer than the requested number of bytes is an error. Level indi­
cates the amount of computation deflate should do while compressing the data. Higher levels usu­
ally take more time and produce smaller outputs. Valid values are 1 to 9, inclusive; 6 is a good
compromise. If debug is non-zero, cryptic debugging information is produced on standard error.
Inflate reverses the process, converting compressed data into uncompressed output. Input is
retrieved one byte at a time by calling get with the argument getr. End of input of signaled by
returning a negative value. The uncompressed output is written to w, which has the same inter­
face as for deflate.
Deflateblock and inflateblock operate on blocks of memory but are otherwise similar to deflate and
The zlib functions are similar, but operate on files with a zlib header and trailer.
Deflateinit or inflateinit must be called once before any call to the corresponding routines.
If the above routines fail, they return a negative number indicating the problem. The possible val­
ues are FlateNoMem , FlateInputFail, FlateOutputFail, FlateCorrupted, and FlateInternal. Flateerr
converts the number into a printable message. FlateOk is defined to be zero, the successful return
value for deflateinit, deflate, deflatezlib, inflateinit, inflate, and inflatezlib. The block functions
return the number of bytes produced when they succeed.
Mkcrctab allocates (using malloc(2)), initializes, and returns a table for rapid computation of 32 bit
CRC values using the polynomial poly. Blockcrc uses tab, a table returned by mkcrctab, to update
crc for the n bytes of data in buf, and returns the new value. Crc should initially be zero. Blockcrc
pre-conditions and post-conditions crc by ones complementation.
Adler32 updates the Adler 32-bit checksum of the n butes of data in buf. The initial value of adler
(that is, its value after seeing zero bytes) should be 1.
fabs, fmod, floor, ceil absolute value, remainder, floor, ceiling functions
#include <u.h>
#include <libc.h>
double floor(double x)
double ceil(double x)
double fabs(double x)
double fmod(double x, double y)
Fabs returns the absolute value | x |.
Floor returns the largest integer not greater than x.
Ceil returns the smallest integer not less than x.
Fmod returns x if y is zero, otherwise the number f with the same sign as x, such that x = iy + f for
some integer i, and | f | < | y |.
abs(2), frexp(2)
fmtinstall, dofmt, dorfmt, fmtprint, fmtvprint, fmtrune, fmtstrcpy, fmtrunestrcpy, fmtfdinit, fmtfd­
flush, fmtstrinit, fmtstrflush, runefmtstrinit, runefmtstrflush, errfmt support for user-defined
print formats and output routines
#include <u.h>
#include <libc.h>
typedef struct Fmt Fmt;
struct Fmt{
runes; /* output buffer is runes or chars? */
*start; /* of buffer */
/* current place in the buffer */
*stop; /* end of the buffer; overwritten if flush fails */
(*flush)(Fmt*);/* called when to == stop */
*farg; /* to make flush a closure */
/* num chars formatted so far */
va_list args;
/* args passed to dofmt */
/* % format Rune */
FmtWidth << 1,
FmtLeft << 1,
FmtPrec << 1,
FmtSharp << 1,
FmtSpace << 1,
FmtSign << 1,
FmtZero << 1,
FmtUnsigned << 1,
FmtShort << 1,
FmtLong << 1,
FmtVLong << 1,
= FmtComma << 1
fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);
fmtfdflush(Fmt *f);
fmtstrinit(Fmt *f);
char* fmtstrflush(Fmt *f);
runefmtstrinit(Fmt *f);
Rune* runefmtstrflush(Fmt *f);
fmtinstall(int c, int (*fn)(Fmt*));
dofmt(Fmt *f, char *fmt);
dorfmt(Fmt*, Rune *fmt);
fmtprint(Fmt *f, char *fmt, ...);
fmtvprint(Fmt *f, char *fmt, va_list v);
fmtrune(Fmt *f, int r);
fmtstrcpy(Fmt *f, char *s);
fmtrunestrcpy(Fmt *f, Rune *s);
errfmt(Fmt *f);
The interface described here allows the construction of custom print(2) verbs and output routines.
In essence, they provide access to the workings of the formatted print code.
The print(2) suite maintains its state with a data structure called Fmt. A typical call to print(2) or
its relatives initializes a Fmt structure, passes it to subsidiary routines to process the output, and
finishes by emitting any saved state recorded in the Fmt. The details of the Fmt are unimportant
to outside users, except insofar as the general design influences the interface. The 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 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.
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.
To write to a file descriptor, call fmtfdinit to initialize the local Fmt structure f, giving the file
descriptor fd, the buffer buf, and its size nbuf. Then call fmtprint or fmtvprint to generate the
output. These behave like fprint (see print(2)) or vfprint except that the characters are buf­
fered until fmtfdflush is called and the return value is either 0 or 1. A typical example of this
sequence appears in the Examples section.
The same basic sequence applies when outputting to an allocated string: call fmtstrinit to initialize
the Fmt, then call fmtprint and fmtvprint to generate the output. Finally, fmtstrflush will return
the allocated string, which should be freed after use. To output to a rune string, use
runefmtstrinit and runefmtstrflush. Regardless of the output style or type, fmtprint or fmtvprint
generates the characters.
Custom format verbs
Fmtinstall is used to install custom verbs and flags labeled by character c, which may be any nonzero Unicode character. Fn should be declared as
Fp−>r is the flag or verb character to cause fn to be called. In fn, fp−>width, fp−>prec are
the width and precision, and fp−>flags the decoded flags for the verb (see print(2) for a
description of these items). The standard flag values are: FmtSign (+), FmtLeft (−),
FmtSpace (’ ’), FmtSharp (#), FmtComma (,), FmtLong (l), FmtShort (h),
FmtUnsigned (u), and FmtVLong (ll). The flag bits FmtWidth and FmtPrec identify
whether a width and precision were specified.
Fn is passed a pointer to the Fmt structure recording the state of the output. If fp−>r is a verb
(rather than a flag), fn should use Fmt−>args to fetch its argument from the list, then format it,
and return zero. If fp−>r is a flag, fn should return one. All interpretation of fp−>width,
fp−>prec, and fp−>flags is left up to the conversion routine. Fmtinstall returns 0 if the instal­
lation succeeds, 1 if it fails.
Fmtprint and fmtvprint may be called to help prepare output in custom conversion routines. How­
ever, these functions clear the width, precision, and flags. Both functions return 0 for success and
1 for failure.
The functions dofmt and dorfmt are the underlying formatters; they use the existing contents of
Fmt and should be called only by sophisticated conversion routines. These routines return the
number of characters (bytes of UTF or runes) produced.
Some internal functions may be useful to format primitive types. They honor the width, precision
and flags as described in print(2). Fmtrune formats a single character r. Fmtstrcpy formats a
string s; fmtrunestrcpy formats a rune string s. 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.
2c(1) describes the C directive #pragma varargck that can be used to provide type-checking
for custom print verbs and output routines.
This function prints an error message with a variable number of arguments and then quits. Com­
pared to the corresponding example in print(2), this version uses a smaller buffer, will never trun­
cate the output message, but might generate multiple write system calls to produce its output.
#pragma varargck argpos
fatal(char *fmt, ...)
Fmt f;
char buf[64];
va_list arg;
fmtfdinit(&f, 1, buf, sizeof buf);
fmtprint(&f, "fatal: ");
va_start(arg, fmt);
fmtvprint(&f, fmt, arg);
fmtprint(&f, "\n");
exits("fatal error");
This example adds a verb to print complex numbers.
typedef struct {
r, i;
} Complex;
#pragma varargck type "X" Complex
Xfmt(Fmt *f)
Complex c;
c = va_arg(f−>args, Complex);
return fmtprint(f, "(%g,%g)", c.r, c.i);
Complex x = (Complex){ 1.5, −2.3 };
fmtinstall(’X’, Xfmt);
print("x = %X\n", x);
print(2), utf(6), errstr(2)
These routines return negative numbers or nil for errors and set errstr.
fopen, freopen, fdopen, fileno, fclose, sopenr, sopenw, sclose, fflush, setvbuf, setbuf, fgetpos,
ftell, fsetpos, fseek, rewind, feof, ferror, clearerr standard buffered input/output package
#include <u.h>
#include <stdio.h>
FILE *fopen(char *filename, char *mode)
FILE *freopen(char *filename, char *mode, FILE *f)
FILE *fdopen(int fd, char *mode)
fileno(FILE *f)
FILE *sopenr(char *s)
FILE *sopenw(void)
char *sclose(FILE *f)
fclose(FILE *f)
fflush(FILE *f)
setvbuf(FILE *f, char *buf, int type, long size)
void setbuf(FILE *f, char *buf)
fgetpos(FILE *f, long *pos)
long ftell(FILE *f)
fsetpos(FILE *f, long *pos)
fseek(FILE *f, long offset, int whence)
void rewind(FILE *f)
feof(FILE *f)
ferror(FILE *f)
void clearerr(FILE *f)
The functions described in this and related pages (fgetc(2), fprintf(2), fscanf(2), and tmpfile(2))
implement the ANSI C buffered I/O package with extensions.
A file with associated buffering is called a stream and is declared to be a pointer to a defined type
FILE. 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 point­
ers declared in the include file and associated with the standard open files:
stdin standard input file
stdout standard output file
stderr standard error file
A constant pointer NULL designates no stream at all.
Fopen opens the file named by filename and associates a stream with it. Fopen returns a pointer to
be used to identify the stream in subsequent operations, or NULL if the open fails. Mode is a char­
acter string having one of the following values:
open for reading
truncate to zero length or create for writing
append; open or create for writing at end of file
"r+" open for update (reading and writing)
"w+" truncate to zero length or create for update
"a+" append; open or create for update at end of file
In addition, each of the above strings can have a b somewhere after the first character, meaning
binary file, but this implementation makes no distinction between binary and text files.
Fclose causes the stream pointed to by f to be flushed (see below) and does a close (see open(2))
on the associated file. It frees any automatically allocated buffer. Fclose is called automatically on
exits(2) for all open streams.
Freopen is like open except that it reuses stream pointer f. Freopen first attempts to close any file
associated with f; it ignores any errors in that close.
Fdopen associates a stream with an open Plan 9 file descriptor.
Fileno returns the number of the Plan 9 file descriptor associated with the stream.
Sopenr associates a read-only stream with a null-terminated string.
Sopenw opens a stream for writing. No file descriptor is associated with the stream; instead, all
output is written to the stream buffer.
Sclose closes a stream opened with sopenr or sopenw. It returns a pointer to the 0 terminated
buffer associated with the stream.
By default, output to a stream is fully buffered: it is accumulated in a buffer until the buffer is full,
and then write (see 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 buf­
fered by default; this means that read(2) is used to fill a buffer as much as it can, and then charac­
ters are taken from that buffer until it empties. Setvbuf changes the buffering method for file f
according to type: either _IOFBF for fully buffered, _IOLBF for line buffered, or _IONBF for
unbuffered (each character causes a read or write). If buf is supplied, it is used as the buffer and
size should be its size; If buf is zero, a buffer of the given size is allocated (except for the
unbuffered case) using malloc(2).
Setbuf is an older method for changing buffering. If buf is supplied, it changes to fully buffered
with the given buffer, which should be of size BUFSIZ (defined in stdio.h). If buf is zero, the
buffering method changes to unbuffered.
Fflush flushes the buffer of output stream f, delivering any unwritten buffered data to the host file.
There is a 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 fgetc(2).
Fgetpos stores the current value of the file position indicator for stream f in the object pointed to
by pos. It returns zero on success, nonzero otherwise. Ftell returns the current value of the file
position indicator. The file position indicator is to be used only as an argument to fseek.
Fsetpos sets the file position indicator for stream f to the value of the object pointed to by pos,
which shall be a value returned by an earlier call to fgetpos on the same stream. It returns zero on
success, nonzero otherwise. Fseek obtains a new position, measured in characters from the begin­
ning of the file, by adding offset to the position specified by whence: the beginning of the file if
whence is SEEK_SET; the current value of the file position indicator for SEEK_CUR; and the
end-of-file for SEEK_END. Rewind sets the file position indicator to the beginning of the file.
An integer constant EOF is returned upon end of file or error by integer-valued functions that deal
with streams. Feof returns non-zero if and only if f is at its end of file.
Ferror returns non-zero if and only if f is in the error state. It can get into the error state if a sys­
tem call failed on the associated file or a memory allocation failed. Clearerr takes a stream out of
the error state.
fprintf(2), fscanf(2), fgetc(2)
open(2), read(2)
The value EOF is returned uniformly to indicate that a FILE pointer has not been initialized with
fopen, input (output) has been attempted on an output (input) stream, or a FILE pointer desig­
nates corrupt or otherwise unintelligible FILE data.
Some of these functions set errstr.
Buffering of output can prevent output data from being seen until long after it is computed per­
haps never, as when an abort occurs between buffer filling and flushing.
Buffering of input can cause a process to consume more input than it actually uses. This can
cause trouble across exec(2).
Buffering may delay the receipt of a write error until a subsequent stdio writing, seeking, or fileclosing call.
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.
Fdopen, fileno, sopenr, sopenw, and sclose are not ANSI Stdio functions.
Stdio offers no support for runes or UTF characters. Unless external compatibility is necessary, use
bio(2), which supports UTF and is smaller, faster, and simpler than Stdio.
fork, rfork manipulate process resources
#include <u.h>
#include <libc.h>
int fork(void)
int rfork(int flags)
Forking is the only way new processes are created. The flags argument to 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 env(3)), the note group (the set of processes that receive notes written
to a members notepg file; see proc(3)), the set of rendezvous tags (see rendezvous (2)); and
open files. Flags is the logical OR of some subset of
If set a new process is created; otherwise changes affect the current process.
If set, the child process will be dissociated from the parent. Upon exit the child will
leave no Waitmsg (see wait(2)) for the parent to collect.
If set, the new process inherits a copy of the parents name space; otherwise the
new process shares the parents name space. Is mutually exclusive with
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 RFNAMEG.
If set, subsequent mounts into the new name space and dereferencing of path­
names starting with # are disallowed.
If set, the environment variables are copied; otherwise the two processes share envi­
ronment variables. Is mutually exclusive with RFCENVG.
If set, the new process starts with an empty environment. Is mutually exclusive with
Each process is a member of a group of processes that all receive notes when a note
is written to any of their notepg files (see proc(3)). The group of a new process is
by default the same as its parent, but if RFNOTEG is set (regardless of RFPROC),
the process becomes the first in a new group, isolated from previous processes.
If set, the invokers file descriptor table (see intro(2)) is copied; otherwise the two
processes share a single table.
If set, the new process starts with a clean file descriptor table. Is mutually exclusive
with RFFDG.
If set, the process will be unable to rendezvous (2) with any of its ancestors; its chil­
dren will, however, be able to rendezvous with it. In effect, RFREND makes the
process the first in a group of processes that share a space for rendezvous tags.
If set, the child and the parent will share data and 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 RFPROC.
File descriptors in a shared file descriptor table are kept open until either they are explicitly closed
or all processes sharing the table exit.
If 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 RFPROC, the return value is zero. Process ids
range from 1 to the maximum integer (int) value. Rfork will sleep, if necessary, until required
process resources are available.
Fork is just a call of rfork(RFFDG|RFREND|RFPROC).
intro(2), proc(3),
These functions set errstr.
fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf, vsnprintf print formatted output
#include <u.h>
#include <stdio.h>
int fprintf(FILE *f, char *format, ...)
int printf(char *format, ...)
int sprintf(char *s, char *format, ...)
int snprintf(char *s, int n, char *format, ...)
int vfprintf(FILE *f, char *format, va_list args)
int vprintf(char *format, va_list args)
int vsprintf(char *s, char *format, va_list args)
int vsnprintf(char *s, int n, char *format, va_list args)
Fprintf places output on the named output stream f (see fopen(2)). Printf places output on the
standard output stream stdout. Sprintf places output followed by the null character (\0) in consec­
utive bytes starting at s; it is the users responsibility to ensure that enough storage is available.
Snprintf is like sprintf but writes at most n bytes (including the null character) into s. Vfprintf,
vprintf, vsnprintf, and vsprintf are the same, except the args argument is the argument list of the
calling function, and the effect is as if the calling functions argument list from that point on is
passed to the printf routines.
Each function returns the number of characters transmitted (not including the \0 in the case of
sprintf and friends), or a negative value if an output error was encountered.
These functions convert, format, and print their trailing arguments under control of a 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 argu­
ments for the format. If the format is exhausted while arguments remain, the excess are ignored.
Each conversion specification is introduced by the character %. After the %, the following appear in
Zero or more flags, which modify the meaning of the conversion specification.
An optional decimal digit string specifying a minimum 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.
An optional precision that gives the minimum number of digits to appear for the d, i, o, u,
x, and X conversions, the number of digits to appear after the decimal point for the e, E,
and f conversions, the maximum number of significant digits for the g and G conversions,
or the maximum number of characters to be written from a string in s conversion. The
precision takes the form of a period (.) followed by an optional decimal integer; if the inte­
ger is omitted, it is treated as zero.
An optional h specifying that a following d, i, o, u, x or X conversion specifier applies to a
short int or unsigned short argument (the argument will have been promoted
according to the integral promotions, and its value shall be converted to short or
unsigned short before printing); an optional h specifying that a following n conversion
specifier applies to a pointer to a short argument; an optional l (ell) specifying that a fol­
lowing d, i, o, u, x, or X conversion character applies to a long or unsigned long
argument; an optional l specifying that a following n conversion specifier applies to a
pointer to a long int argument; or an optional L specifying that a following e, E, f, g,
or G conversion specifier applies to a long double argument. If an h, l, or L appears
with any other conversion specifier, the behavior is undefined.
A character that indicates the type of conversion to be applied.
A field width or precision, or both, may be indicated by an asterisk (*) instead of a digit string. In
this case, an int 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 − flag followed by a positive field width. A negative
precision is taken as if it were missing.
The flag characters and their meanings are:
The result of the conversion is left-justified within the field.
The result of a signed conversion always begins with a sign (+ or −).
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 +
flags both appear, the blank flag is ignored.
The result is to be converted to an alternate form. For o conversion, it increases the
precision to force the first digit of the result to be a zero. For x or X conversion, a
non-zero result has 0x or 0X prefixed to it. For e, E, f, g, and G conversions, the
result always contains a decimal point, even if no digits follow the point (normally, a dec­
imal point appears in the result of these conversions only if a digit follows it). For g and
G conversions, trailing zeros are not be removed from the result as they normally are.
For other conversions, the behavior is undefined.
For d, i, o, u, x, X, e, E, f, g, and G conversions, leading zeros (following any indica­
tion of sign or base) are used to pad the field width; no space padding is performed. If
the 0 and − flags both appear, the 0 flag will be ignored. For d, i, o, u, x, and X con­
versions, if a precision is specified, the 0 flag will be ignored. For other conversions, the
behavior is undefined.
The conversion characters and their meanings are:
The integer arg is converted to signed decimal (d or i), unsigned octal (o), unsigned
decimal (u), or unsigned hexadecimal notation (x or X); the letters abcdef are used for
x conversion and the letters ABCDEF for X conversion. The precision specifies the min­
imum 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.
The double argument is converted to decimal notation in the style []ddd.ddd, 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 0, no decimal point
The double argument is converted in the style []d.ddde±dd, 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 E format code produces a number with E instead of e introducing the
exponent. The exponent always contains at least two digits.
The double argument is printed in style f or e (or in style E in the case of a G conver­
sion 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 con­
verted: style 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.
The int argument is converted to an unsigned char, and the resulting character is
The argument is taken to be a string (character pointer) and characters from the string
are printed until a null character (\0) is encountered or the number of characters indi­
cated 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.
The void* argument is printed in an implementation-defined way (for Plan 9: the
address as hexadecimal number).
The argument shall be a pointer to an integer into which is written the number of char­
acters written to the output stream so far by this call to fprintf. No argument is
Print a %; no argument is converted.
If a conversion specification is invalid, the behavior is undefined.
If any argument is, or points to, a union or an aggregate (except for an array of character type
using %s conversion, or a pointer cast to be a pointer to void using %P conversion), the behavior
is undefined.
In no case does a nonexistent or small field width cause truncation of a field; if the result of a con­
version is wider than the field width, the field is expanded to contain the conversion result.
fopen(2), fscanf(2), print(2)
There is no way to print a wide character (rune); use print(2) or bio(2).
frinit, frsetrects, frinittick, frclear, frcharofpt, frptofchar, frinsert, frdelete, frselect, frtick, frselect­
paint, frdrawsel, frdrawsel0, frgetmouse frames of text
frinit(Frame *f, Rectangle r, Font *ft, Image *b, Image **cols)
frsetrects(Frame *f, Rectangle r, Image *b)
frinittick(Frame *f)
frclear(Frame *f, int resize)
ulong frcharofpt(Frame *f, Point pt)
Point frptofchar(Frame *f, ulong p)
frinsert(Frame *f, Rune *r0, Rune *r1, ulong p)
frdelete(Frame *f, ulong p0, ulong p1)
frselect(Frame *f, Mousectl *m)
frtick(Frame *f, Point pt, int up)
frselectpaint(Frame *f, Point p0, Point p1, Image *col)
frdrawsel(Frame *f, Point pt0, ulong p0, ulong p1,
int highlighted)
frdrawsel0(Frame *f, Point pt0, ulong p0, ulong p1,
Image *back, Image *text)
This library supports frames of editable text in a single font on raster displays, such as in sam(1)
and rio(1). Frames may hold any character except NUL (0). Long lines are folded and tabs are at
fixed intervals.
The user-visible data structure, a Frame, is defined in <frame.h>:
typedef struct Frame Frame;
struct Frame
Rectangle r;
Rectangle entire;
p0, p1;
nbox, nalloc;
of chars in the frame */
on which frame appears */
on which frame appears */
text and background colors */
in which text appears */
of full frame */
/* selection */
/* max size of tab, in pixels */
# runes in frame */
# lines with text */
total # lines in frame */
last line fills frame */
changed since frselect() */
typing tick */
saved image under tick */
flag: is tick onscreen? */
Frbox is an internal type and is not used by the interface. P0 and p1 may be changed by the
application provided the selection routines are called afterwards to maintain a consistent display.
Maxtab determines the size of tab stops. Frinit sets it to 8 times the width of a 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.
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 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 Frame; the appli­
cation must check maxlines, nlines, and lastlinefull to determine, for example,
whether new text needs to be appended at the end of the Frame after calling frdelete (q.v.).
There are no routines in the library to allocate Frames; instead the interface assumes that
Frames will be components of larger structures. Frinit prepares the Frame f so characters
drawn in it will appear in the single Font ft. It then calls frsetrects and frinittick to initialize the
geometry for the Frame. The Image b is where the Frame is to be drawn; Rectangle r
defines the limit of the portion of the Image the text will occupy. The Image pointer may be
null, allowing the other routines to be called to maintain the associated data structure in, for exam­
ple, an obscured window.
The array of Images cols sets the colors in which text and borders will be drawn. The back­
ground of the frame will be drawn in cols[BACK]; the background of highlighted text in
cols[HIGH]; borders and scroll bar in cols[BORD]; regular text in cols[TEXT]; and high­
lighted text in cols[HTEXT].
Frclear frees the internal structures associated with f, permitting another frinit or frsetrects on the
Frame. It does not clear the associated display. If f is to be deallocated, the associated Font
and Image must be freed separately. The 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 associ­
ated with the font.
To resize a Frame, use frclear and frinit and then frinsert (q.v.) to recreate the display. If a
Frame is being moved but not resized, that is, if the shape of its containing rectangle is
unchanged, it is sufficient to use draw(2) to copy the containing rectangle from the old to the new
location and then call frsetrects to establish the new geometry. (It is unnecessary to call frinittick
unless the font size has changed.) No redrawing is necessary.
Frames hold text as runes, not as bytes. Frptofchar returns the location of the upper left corner
of the p’th rune, starting from 0, in the Frame f. If f holds fewer than p runes, frptofchar returns
the location of the upper right corner of the last character in f. Frcharofpt is the inverse: it returns
the index of the closest rune whose images upper left corner is up and to the left of pt.
Frinsert inserts into Frame f starting at rune index p the runes between r0 and 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 frdelete.
Frdelete deletes from the Frame the text between p0 and p1; p1 points at the first rune beyond
the deletion.
Frselect tracks the mouse to select a contiguous string of text in the Frame. When called, a
mouse button is typically down. Frselect will return when the button state has changed (some but­
tons may still be down) and will set f−>p0 and f−>p1 to the selected range of text.
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 charac­
ters, and the colored region representing a non-null selection. Frtick draws (if up is non-zero) or
removes (if up is zero) the tick at the screen position indicated by pt. Frdrawsel repaints a section
of the frame, delimited by character positions p0 and p1, either with plain background or entirely
highlighted, according to the flag highlighted, managing the tick appropriately. The point pt0 is
the geometrical location of p0 on the screen; like all of the selection-helper routines Point argu­
ments, it must be a value generated by frptofchar. Frdrawsel0 is a lower-level routine, taking as
arguments a background color, back, and text color, text. It assumes that the tick is being handled
(removed beforehand, replaced afterwards, as required) by its caller. Frselectpaint uses a solid
color, col, to paint a region of the frame defined by the Points p0 and p1.
graphics(2), draw(2), cachechars(2).
frexp, ldexp, modf split into mantissa and exponent
#include <u.h>
#include <libc.h>
double frexp(double value, int *eptr)
double ldexp(double value, int exp)
double modf(double value, double *iptr)
Frexp returns the mantissa of value and stores the exponent indirectly through eptr, so that value
= frexp(value)×2 (*eptr)
Ldexp returns the quantity
value×2 exp .
Modf returns the signed fractional part of value and stores the integer part indirectly through iptr.
Ldexp returns 0 for underflow and the appropriately signed infinity for overflow.
fscanf, scanf, sscanf, vfscanf scan formatted input
#include <u.h>
#include <stdio.h>
int fscanf(FILE *f, char *format, ...)
int scanf(char *format, ... )
int sscanf(char *s, char *format, ...)
int vfscanf(FILE *stream, char *format, char *args)
Fscanf reads from the named input stream f (see fopen(2)) under control of the string pointed to
by 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 other­
wise ignored.
Scanf and sscanf are the same, but they read from stdin and the character string s, respectively.
Vfscanf is like scanf, except the args argument is a pointer to an argument in an argument list of
the calling function and the effect is as if the calling functions argument list from that point on is
passed to the scanf routines.
The format is composed of zero or more directives: one or more white-space characters; an ordi­
nary character (not %); or a conversion specification. Each conversion specification is introduced
by the character %. After the %, the following appear in sequence:
An optional assignment-suppressing character *.
An optional decimal integer that specifies the maximum field width.
An optional h, l (ell) or L indicating the size of the receiving object. The conversion speci­
fiers d, i, and n shall be preceded by h if the corresponding argument is a pointer to
short rather than a pointer to int, or by l if it is a pointer to long. Similarly, the con­
version specifiers o, u, and x shall be preceded by h if the corresponding argument is a
pointer to unsigned short rather than a pointer to unsigned, or by l if it is a pointer
to unsigned long. Finally, the conversion specifiers e, f, and g shall be preceded by l
if the corresponding argument is a pointer to double rather than a pointer to float, or
by L if it is a pointer to long double. If an h, l, or L appears with any other conversion
specifier, the behavior is undefined.
A character that specifies the type of conversion to be applied. The valid conversion speci­
fiers are described below.
Fscanf executes each directive of the format in turn. If a directive fails, as detailed below, fscanf
returns. Failures are described as input failures (due to the unavailability of input), or matching
failures (due to inappropriate input).
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.
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 subse­
quent characters remain unread.
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:
Input white-space characters (as specified by isspace, see ctype(2)) are skipped, unless the specifi­
cation includes a [, c, or n specifier.
An input item is read from the stream, unless the specification includes an 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.
Except in the case of a % specifier, the input item (or, in the case of a %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 *, the result of the conversion is placed in the
object pointed to by the first argument following the 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.
The following conversion specifiers are valid:
Matches an optionally signed decimal integer, whose format is the same as expected for the
subject sequence of the strtol (see atof(2)) function with 10 for the base argument. The
corresponding argument shall be a pointer to int.
Matches an optionally signed decimal integer, whose format is the same as expected for the
subject sequence of the strtol function with 0 for the base argument. The corresponding
argument shall be a pointer to int.
Matches an optionally signed octal integer, whose format is the same as expected for the
subject sequence of the strtoul (see atof(2)) function with 8 for the base argument. The
corresponding argument shall be a pointer to unsigned int.
Matches an optionally signed decimal integer, whose format is the same as expected for the
subject sequence of the strtoul function with 10 for the base argument. The corresponding
argument shall be a pointer to unsigned int.
Matches an optionally signed hexadecimal integer, whose format is the same as expected for
the subject sequence of the strtoul function with 16 for the base argument. The corre­
sponding argument shall be a pointer to unsigned int.
Matches an optionally signed floating-point number, whose format is the same as expected
for the subject string of the strtod (see atof(2)) function. The corresponding argument shall
be a pointer to float.
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 termi­
nating NUL (0) character, which will be added automatically.
Matches a nonempty sequence of characters from a set of expected characters (the 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 auto­
matically. The conversion specifier includes all subsequent characters in the format string,
up to and including the matching right brace (]). The characters between the brackets (the
scanlist) comprise the scanset, unless the character after the left bracket is a circumflex (^),
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 [] or [^], the right bracket character is in the scanlist and the next right bracket char­
acter is the matching right bracket that ends the specification. If a − character is in the
scanlist and is not the first, nor the second where the first character is a ^, nor the last char­
acter, the behavior is implementation-defined (in Plan 9: the scanlist includes all characters
in the ASCII (sic) range between the two characters on either side of the −).
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 ini­
tial character of an array large enough to accept the sequence. No NUL character is added.
Matches an implementation-defined set of sequences, which should be the same as the set
of sequences that may be produced by the %P conversion of the fprintf(2) function (in Plan
9, a hexadecimal number). The corresponding argument shall be a pointer to a pointer to
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 %P conversion is undefined.
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 fscanf.
Execution of a %n directive does not increment the assignment count returned at the com­
pletion of fscanf.
Matches a single %; no conversion or assignment occurs. The complete conversion specifica­
tion shall be %%.
If a conversion specification is invalid, the behavior is undefined.
The conversion specifiers E, G, and X are also valid and behave the same as, respectively, e, g,
and x.
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 fol­
lowing directive (if any) is terminated with an input failure.
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 %n directive.
The return value from fscanf is the number of input items assigned, which can be fewer than pro­
vided for, or even zero, in the event of an early matching failure. However, if an input failure
occurs before any conversion, EOF is returned.
fopen(2), fgetc(2)
Does not know about UTF.
fversion initialize 9P connection and negotiate version
#include <u.h>
#include <libc.h>
fversion(int fd, int bufsize, char *version, int nversion)
Fversion is used to initialize the 9P connection represented by fd and to negotiate the version of
the protocol to be used.
The 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 version is a text string that represents the highest ver­
sion level the protocol will support. The version will be overwritten with the negotiated, possibly
lower, version of the protocol. The return value of fversion is the length of the returned version
string; the value of nversion is therefore not the length of the version string presented to the sys­
tem call, but the total length of the buffer to accept the final result, in the manner of a read system
Default values of zero for bufsize and the empty string for version will negotiate sensible defaults
for the connection. If version is the empty string, nversion must still be large enough to receive
the returned version string.
The interpretation of the version strings is defined in version(5).
It is rare to use fversion directly; usually the default negotiation performed by the kernel during
mount (see bind(2)) or even more commonly amount (see auth(2)) is sufficient.
intro(5), version(5), fauth(2).
Sets errstr.
getcallerpc fetch return PC of current function
#include <u.h>
#include <libc.h>
uintptr getcallerpc(void *firstarg)
Getcallerpc is a portable way to discover the PC to which the current function will return. Firstarg
should be a pointer to the first argument to the function in question.
printpc(int arg)
print("Called from %p\n", getcallerpc(&arg));
main(int argc, char *argv[])
The firstarg parameter should not be necessary.
getenv, putenv access environment variables
#include <u.h>
#include <libc.h>
char* getenv(char *name)
putenv(char *name, char *val)
Getenv reads the contents of /env/name (see env(3)) into memory allocated with malloc(2), 0terminates it, and returns a pointer to that area. If no file exists, 0 is returned.
Putenv creates the file /env/name and writes the string val to it. The terminating 0 is not writ­
ten. If the file value cannot be written, 1 is returned.
Sets errstr.
getfcr, setfcr, getfsr, setfsr control floating point
#include <u.h>
#include <libc.h>
ulong getfcr(void)
void setfcr(ulong fcr)
ulong getfsr(void)
void setfsr(ulong fsr)
These routines provide a fairly portable interface to control the rounding and exception character­
istics of IEEE 754 floating point units. In effect, they define a pair of pseudo-registers, the floating
point control register, fcr, which affects rounding, precision, and exceptions, and the floating
point status register, fsr, which holds the accrued exception bits. Each register has a get routine
to retrieve its value, a set routine to modify it, and macros that identify its contents.
The fcr contains bits that, when set, halt execution upon exceptions: FPINEX (enable inexact
exceptions), FPOVFL (enable overflow exceptions), FPUNFL (enable underflow exceptions),
FPZDIV (enable zero divide exceptions), and FPINVAL (enable invalid operation exceptions).
Rounding is controlled by installing in fcr, under mask FPRMASK, one of the values FPRNR
(round to nearest), FPRZ (round towards zero), FPRPINF (round towards positive infinity), and
FPRNINF (round towards negative infinity). Precision is controlled by installing in fcr, under
mask FPPMASK, one of the values FPPEXT (extended precision), FPPSGL (single precision), and
FPPDBL (double precision).
The fsr holds the accrued exception bits FPAINEX, FPAOVFL, FPAUNFL, FPAZDIV, and
FPAINVAL, corresponding to the fsr bits without the A in the name.
Not all machines support all modes. If the corresponding mask is zero, the machine does not sup­
port the rounding or precision modes. On some machines it is not possible to clear selective
accrued exception bits; a setfsr clears them all. The exception bits defined here work on all archi­
tectures. Where possible, the initial state is equivalent to
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.
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):
setfcr((getfcr() & ~FPPMASK) | FPPDBL | FPOVFL);
getfields, gettokens, tokenize break a string into fields
#include <u.h>
#include <libc.h>
getfields(char *str, char **args, int maxargs, int multiflag,
char *delims)
gettokens(char *str, char **args, int maxargs, char *delims)
tokenize(char *str, char **args, int maxargs)
Getfields places into the array args pointers to the first maxargs fields of the null terminated UTF
string str. Delimiters between these fields are set to null.
Fields are substrings of str whose definition depends on the value of multiflag. If multiflag is zero,
adjacent fields are separated by exactly one delimiter. For example
getfields("#alice#bob##charles###", arg, 3, 0, "#");
yields three substrings: null-string , alice, and bob##charles###. If the multiflag argument
is not zero, a field is a non-empty string of non-delimiters. For example
getfields("#alice#bob##charles###", arg, 3, 1, "#");
yields the three substrings: alice, bob, and charles###.
Getfields returns the number of fields pointed to.
Gettokens is the same as getfields with multiflag non-zero, except that fields may be quoted using
single quotes, in the manner of rc(1). Any such quotes remain in the resulting args. See quote(2)
for related quote-handling software.
Tokenize is similar to gettokens with delims set to "\t\r\n ", except that quotes are interpreted
but do not appear in the resulting args.
strtok in strcat(2), quote(2).
getpid, getppid get process ids
#include <u.h>
#include <libc.h>
int getpid(void)
int getppid(void)
Getpid reads /dev/pid (see 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 getpid.
Getppid reads /dev/ppid (see cons(3)) and converts it to get the id of the parent of the current
intro(2), exec(2), cons(3), proc(3)
Returns 0 and sets errstr if unsuccessful.
getuser, sysname get user or system name
#include <u.h>
#include <libc.h>
Getuser returns a pointer to static data which contains the null-terminated name of the user who
owns the current process. Getuser reads /dev/user to find the name.
Sysname provides the same service for the file #c/sysname, which contains the name of the
machine. Unlike getuser, sysname caches the string, reading the file only once.
intro(2), cons(3)
getwd get current directory
#include <u.h>
#include <libc.h>
char* getwd(char *buf, int size)
Getwd fills buf with a null-terminated string representing the current directory and returns buf.
Getwd places no more than size bytes in the buffer provided.
pwd(1), fd2path(2)
On error, zero is returned. Errstr(2) may be consulted for more information.
Although the name returned by getwd is guaranteed to be the path used to reach the directory, if
the name space has changed underfoot, the name may be incorrect.
Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getde­
font, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, openfont,
buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth interactive graphics
initdraw(void (*errfun)(Display*, char*), char *font,
char *label)
geninitdraw(char *devdir, void(*errfun)(Display*, char*),
char *font, char *label, char *mousedir, char *windir,
int ref)
newwindow(char *str)
drawerror(Display *d, char *msg)
Display*initdisplay(char *devdir, char *win, void(*errfun)(Display*, char*))
closedisplay(Display *d)
Subfont*getdefont(Display *d)
flushimage(Display *d, int vis)
uchar*bufimage(Display *d, int n)
lockdisplay(Display *d)
unlockdisplay(Display *d)
getwindow(Display *d, int ref)
gengetwindow(Display *d, char *winname,
Image **ip, Screen **sp, int ref)
Font* openfont(Display *d, char *name)
Font* buildfont(Display *d, char *desc, char *name)
freefont(Font *f)
ulong strtochan(char *s)
char* chantostr(char *s, ulong chan)
chantodepth(ulong chan)
extern Display *display
extern Image
extern Screen
extern Font
A Display structure represents a connection to the graphics device, draw(3), holding all graph­
ics resources associated with the connection, including in particular raster image data in use by
the client program. The structure is defined (in part) as:
struct Display
(*error)(Display*, char*);
Image *black;
Image *white;
Image *opaque;
Image *transparent;
Image *image;
A Point is a location in an Image (see below and draw(2)), such as the display, and is defined as:
struct Point {
int x;
int y;
} Point;
The coordinate system has x increasing to the right and y increasing down.
A Rectangle is a rectangular area in an image.
struct Rectangle {
Point min;
Point max;
} Rectangle;
/* upper left */
/* lower right */
By definition, min.xdmax.x and min.ydmax.y. By convention, the right (maximum x) and
bottom (maximum y) edges are excluded from the represented rectangle, so abutting rectangles
have no points in common. Thus, max contains the coordinates of the first point beyond the rect­
The Image data structure is defined in draw(2).
A Font is a set of character images, indexed by runes (see utf(6)). The images are organized into
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 cachechars(2), is immaterial for most
applications. Font and Subfont structures contain two interrelated fields: ascent, the dis­
tance from the top of the highest character (actually the top of the image holding all the charac­
ters) to the baseline, and height, the distance from the top of the highest character to the bot­
tom of the lowest character (and hence, the interline spacing). See cachechars(2) for more details.
Buildfont parses the font description in the buffer desc, returning a Font* pointer that can be
used by string (see draw(2)) to draw characters from the font. Openfont does the same, but
reads the description from the named file. Freefont frees a font. The convention for naming font
files is:
where size is approximately the height in pixels of the lower case letters (without ascenders or
descenders). Range gives some indication of which characters will be available: for example
ascii, latin1, euro, or unicode. Euro includes most European languages, punctuation
marks, the International Phonetic Alphabet, etc., but no Oriental languages. Unicode includes
every character for which appropriate-sized images exist on the system.
A Cursor is defined:
typedef struct
Cursor {
Point offset;
uchar clr[2*16];
uchar set[2*16];
} Cursor;
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 offset to the current mouse
position, using clr as a mask to draw white at the pixels where clr is one, and then drawing
black at the pixels where set is one. Setcursor and moveto (see mouse(2)) and esetcursor and
emoveto (see event(2)) change the cursor image and its location on the screen.
The routine initdraw connects to the display; it returns 1 if it fails and sets the error string.
Initdraw sets up the global variables display (the Display structure representing the connec­
tion), screen (an Image representing the display memory itself or, if rio(1) is running, the
clients window), and font (the default font for text). The arguments to initdraw include a label,
which is written to /dev/label if non-nil so that it can be used to identify the window when
hidden (see rio(1)). The font is created by reading the named font file. If font is null, initdraw
reads the file named in the environment variable $font; if $font is not set, it imports the
default (usually minimal) font from the operating system. The global font will be set to point to
the resulting Font structure. The errfun argument is a 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 errfun is nil, the library provides a default, called drawerror. Another effect of
initdraw is that it installs print(2) formats Pfmt and Rfmt as %P and %R for printing Points and
The geninitdraw function provides a less automated way to establish a connection, for programs
that wish to connect to multiple displays. Devdir is the name of the directory containing the device
files for the display (if nil, default /dev); errfun, font, and label are as in initdraw; mousedir and
windir are the directories holding the mouse and winname files; and ref specifies the refresh
function to be used to create the window, if running under rio(1) (see window(2)).
The function newwindow may be called before initdraw or 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 str argument, if non-null, is concatenated to the string "new " that is used to create the win­
dow (see rio(4)). For example, newwindow("−hide −dy 100") will cause the program to
run in a newly created, hidden window 100 pixels high.
Initdisplay is part of geninitdraw; it sets up the display structures but does not allocate any fonts
or call getwindow. The arguments are similar to those of initdraw; win names the directory, default
/dev, in which the files associated with the window reside. Closedisplay disconnects the display
and frees the associated data structures. Getdefont builds a Subfont structure from in-core data
describing a default subfont. None of these routines is needed by most programs, since initdraw
calls them as needed.
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 display−>locking to 1, to notify the library to use a locking protocol for its own
accesses, and call lockdisplay and unlockdisplay around any calls to the graphics library that will
cause messages to be sent to the display device. Initdraw and geninitdraw initialize the display to
the locked state.
Getwindow returns a pointer to the window associated with the application; it is called automati­
cally by initdraw to establish the screen pointer but must be called after each resizing of the
window to restore the librarys connection to the window. If rio is not running, it returns
display−>image; otherwise it negotiates with rio by looking in /dev/winname to find the
name of the window and opening it using namedimage (see allocimage(2)). The resulting window
will be created using the refresh method ref (see window(2)); this should almost always be
Refnone because rio provides backing store for the window.
Getwindow overwrites the global variables screen, a pointer to the Image defining the window
(or the overall display, if no window system is running); and _screen, a pointer to the Screen
representing the root of the windows hierarchy. (See window(2). The overloading of the screen
word is an unfortunate historical accident.) Getwindow arranges that screen point to the portion
of the window inside the border; sophisticated clients may use _screen to make further subwin­
dows. Programs desiring multiple independent windows may use the mechanisms of rio(4) to cre­
ate more windows (usually by a fresh mount of the window sytem in a directory other than /dev),
then use gengetwindow to connect to them. Gengetwindows extra arguments are the full path of
the windows winname file and pointers to be overwritten with the values of the global Image
and Screen variables for the new window.
The graphics functions described in draw(2), allocimage(2), cachechars(2), and subfont(2) are
implemented by writing commands to files under /dev/draw (see draw(3)); the writes are buf­
fered, so the functions may not take effect immediately. Flushimage flushes the buffer, doing all
pending graphics operations. If 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 event(2)); most programs do not need
to call flushimage. It returns 1 on error.
Bufimage is used to allocate space for n bytes in the display buffer. It is used by all the graphics
routines to send messages to the display.
The functions strtochan and chantostr convert between the channel descriptor strings used by
image(6) and the internal ulong representation used by the graphics protocol (see draw(3)s b
message). Chantostr writes at most nine bytes into the buffer pointed at by s and returns s on
success, 0 on failure. Chantodepth returns the number of bits per pixel used by the format
specified by chan. Both chantodepth and strtochan return 0 when presented with bad
To reconnect to the window after a resize event,
if(getwindow(display, Refnone) < 0)
sysfatal("resize failed: %r");
To create and set up a new rio(1) window,
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 rio(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 */
directory of fonts
rio(1), addpt(2), allocimage(2), cachechars(2), subfont(2), draw(2), event(2), frame(2), print(2),
window(2), draw(3), rio(4), image(6), font(6)
An error function may call errstr(2) for further diagnostics.
The names clr and set in the Cursor structure are reminders of an archaic color map and
might be more appropriately called white and black.
parsehtml, printitems, validitems, freeitems, freedocinfo, dimenkind, dimenspec, targetid, target­
name, fromStr, toStr HTML parser
#include <u.h>
#include <libc.h>
#include <html.h>
parsehtml(uchar* data, int datalen, Rune* src, int mtype,
int chset, Docinfo** pdi)
printitems(Item* items, char* msg)
validitems(Item* items)
freeitems(Item* items)
freedocinfo(Docinfo* d)
dimenkind(Dimen d)
dimenspec(Dimen d)
targetid(Rune* s)
targetname(int targid)
uchar* fromStr(Rune* buf, int n, int chset)
toStr(uchar* buf, int n, int chset)
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.
Parsehtml parses an entire HTML document contained in the buffer data and having length
datalen. The URL of the document should be passed in as src. Mtype is the media type of the doc­
ument, which should be either TextHtml or TextPlain. The character set of the document is
described in chset, which can be one of US_Ascii, ISO_8859_1, UTF_8 or Unicode. The
return value is a linked list of Item structures, described in detail below. As a side effect, *pdi is
set to point to a newly created Docinfo structure, containing information pertaining to the entire
The library expects two allocation routines to be provided by the caller, emalloc and
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, emalloc is required to
zero the memory.
For debugging purposes, printitems may be called to display the contents of an item list; individ­
ual items may be printed using the %I print verb, installed on the first call to parsehtml.
validitems traverses the item list, checking that all of the pointers are valid. It returns 1 is every­
thing is ok, and 0 if an error was found. Normally, one would not call these routines directly.
Instead, one sets the global variable dbgbuild and the library calls them automatically. One can
also set warn, to cause the library to print a warning whenever it finds a problem with the input
document, and dbglex, to print debugging information in the lexer.
When an item list is finished with, it should be freed with freeitems. Then, freedocinfo should be
called on the pointer returned in *pdi.
Dimenkind and dimenspec are provided to interpret the Dimen type, as described in the section
Dimension Specifications.
Frame target names are mapped to integer ids via a global, permanent mapping. To find the value
for a given name, call targetid, which allocates a new id if the name hasnt been seen before. The
name of a given, known id may be retrieved using targetname. The library predefines FTtop,
FTself, FTparent and FTblank.
The library handles all text as Unicode strings (type Rune*). Character set conversion is provided
by fromStr and toStr. FromStr takes n Unicode characters from buf and converts them to the
character set described by chset. ToStr takes n bytes from buf, interpretted as belonging to char­
acter set chset, and converts them to a Unicode string. Both routines null-terminate the result,
and use emalloc to allocate space for it.
The return value of parsehtml is a linked list of variant structures, with the generic portion
described by the following definition:
typedef struct Item Item;
struct Item
Genattr* genattr;
The field next points to the successor in the linked list of items, while width, height, and
ascent are intended for use by the caller as part of the layout process. Anchorid, if non-zero,
gives the integer id assigned by the parser to the anchor that this item is in (see section Anchors).
State is a collection of flags and values described as follows:
IFbrk =
IFbrksp =
IFnobrk =
IFcleft =
IFcright =
IFwrap =
IFhang =
IFrjust =
IFcjust =
IFsmap =
IFindentshift =
IFindentmask =
IFhangmask =
IFbrk is set if a break is to be forced before placing this item. IFbrksp is set if a 1 line space
should be added to the break (in which case IFbrk is also set). IFnobrk is set if a break is not
permitted before the item. 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 IFcright is set for right
floats. In both cases, IFbrk is also set. IFwrap is set if the line containing this item is allowed to
wrap. IFhang is set if this item hangs into the left indent. IFrjust is set if the line containing
this item should be right justified, and IFcjust is set for center justified lines. IFsmap is used
to indicate that an image is a server-side map. The low 8 bits, represented by IFhangmask,
indicate the current hang into left indent, in tenths of a tabstop. The next 8 bits, represented by
IFindentmask and IFindentshift, indicate the current indent in tab stops.
The field genattr is an optional pointer to an auxiliary structure, described in the section
Generic Attributes.
Finally, tag describes which variant type this item has. It can have one of the values Itexttag,
Iruletag, Iimagetag, Iformfieldtag, Itabletag, Ifloattag or 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.
Items of type Itexttag represent a piece of text, using the following structure:
struct Itext
Rune* s;
uchar voff;
uchar ul;
Here s is a null-terminated Unicode string of the actual characters making up this text item, fnt
is the font number (described in the section Font Numbers), and fg is the RGB encoded color for
the text. Voff measures the vertical offset from the baseline; subtract Voffbias to get the
actual value (negative values represent a displacement down the page). The field ul is the under­
line style: ULnone if no underline, ULunder for conventional underline, and ULmid for strikethrough.
Items of type Iruletag represent a horizontal rule, as follows:
struct Irule
uchar align;
uchar noshade;
Dimen wspec;
Here align is the alignment specification (described in the corresponding section), noshade is
set if the rule should not be shaded, size is the height of the rule (as set by the size attribute),
and wspec is the desired width (see section Dimension Specifications).
Items of type Iimagetag describe embedded images, for which the following structure is
struct Iimage
Iimage* nextimage;
Here imsrc is the URL of the image source, imwidth and imheight, if non-zero, contain the
specified width and height for the image, and altrep is the text to use as an alternative to the
image, if the image is not displayed. Map, if set, points to a structure describing an associated
client-side image map. Ctlid is reserved for use by the application, for handling animated
images. Align encodes the alignment specification of the image. Hspace contains the number
of pixels to pad the image with on either side, and Vspace the padding above and below.
Border is the width of the border to draw around the image. Nextimage points to the next
image in the document (the head of this list is Docinfo.images).
For items of type Iformfieldtag, the following structure is defined:
struct Iformfield
Formfield* formfield;
This adds a single field, formfield, which points to a structure describing a field in a form,
described in section Forms.
For items of type Itabletag, the following structure is defined:
struct Itable
Table* table;
Table points to a structure describing the table, described in the section Tables.
For items of type Ifloattag, the following structure is defined:
struct Ifloat
Ifloat* nextfloat;
The item points to a single item (either a table or an image) that floats (the text of the document
flows around it), and side indicates the margin that this float sticks to; it is either ALleft or
ALright. X and y are reserved for use by the caller; these are typically used for the coordinates
of the top of the float. Infloats is used by the caller to keep track of whether it has placed the
float. Nextfloat is used by the caller to link together all of the floats that it has placed.
For items of type Ispacertag, the following structure is defined:
struct Ispacer
Spkind encodes the kind of spacer, and may be one of ISPnull (zero height and width),
ISPvline (takes on height and ascent of the current font), ISPhspace (has the width of a
space in the current font) and ISPgeneral (for all other purposes, such as between markers and
Generic Attributes
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:
typedef struct Genattr Genattr;
struct Genattr
SEvent* events;
Fields id, class, style and title, when non-nil, contain values of correspondingly named
attributes of the HTML tag associated with this item. Events is a linked list of events (with corre­
sponding scripted actions) associated with the item:
typedef struct SEvent SEvent;
struct SEvent
SEvent* next;
Here, next points to the next event in the list, type is one of SEonblur, SEonchange,
SEonclick, SEondblclick, SEonfocus, SEonkeypress, SEonkeyup, SEonload,
SEonmousedown, SEonmousemove, SEonmouseout, SEonmouseover, SEonmouseup,
SEonreset, SEonselect, SEonsubmit or SEonunload, and script is the text of the
associated script.
Dimension Specifications
Some structures include a dimension specification, used where a number can be followed by a % or
a * to indicate percentage of total or relative weight. This is encoded using the following struc­
typedef struct Dimen Dimen;
struct Dimen
int kindspec;
Separate kind and spec values are extracted using dimenkind and dimenspec. Dimenkind returns
one of Dnone, Dpixels, Dpercent or Drelative. Dnone means that no dimension was
specified. In all other cases, dimenspec should be called to find the absolute number of pixels, the
percentage of total, or the relative weight.
Background Specifications
It is possible to set the background of the entire document, and also for some parts of the docu­
ment (such as tables). This is encoded as follows:
typedef struct Background Background;
struct Background
Rune* image;
Image, if non-nil, is the URL of an image to use as the background. If this is nil, color is used
instead, as the RGB value for a solid fill color.
Alignment Specifications
Certain items have alignment specifiers taken from the following enumerated type:
ALnone = 0, ALleft, ALcenter, ALright, ALjustify,
ALchar, ALtop, ALmiddle, ALbottom, ALbaseline
These values correspond to the various alignment types named in the HTML 4.0 standard. If an
item has an alignment of ALleft or ALright, the library automatically encapsulates it inside a
float item.
Tables, and the various rows, columns and cells within them, have a more complex alignment
specification, composed of separate vertical and horizontal alignments:
typedef struct Align Align;
struct Align
uchar halign;
uchar valign;
Halign can be one of ALnone, ALleft, ALcenter, ALright, ALjustify or ALchar.
Valign can be one of ALnone, ALmiddle, ALbottom, ALtop or ALbaseline.
Font Numbers
Text items have an associated font number (the fnt field), which is encoded as
style*NumSize+size. Here, style is one of FntR, FntI, FntB or FntT, for roman,
italic, bold and typewriter font styles, respectively, and size is Tiny, Small, Normal, Large or
Verylarge. The total number of possible font numbers is NumFnt, and the default font num­
ber is DefFnt (which is roman style, normal size).
Document Info
Global information about an HTML page is stored in the following structure:
typedef struct Docinfo Docinfo;
struct Docinfo
// stuff from HTTP headers, doc head, and body tag
Background background;
// info needed to respond to user actions
DestAnchor* dests;
Src gives the URL of the original source of the document, and base is the base URL. Doctitle
is the documents title, as set by a <title> element. Background is as described in the sec­
tion Background Specifications, and backgrounditem is set to be an image item for the
documents background image (if given as a URL), or else nil. Text gives the default foregound
text color of the document, link the unvisited hyperlink color, vlink the visited hyperlink color,
and alink the color for highlighting hyperlinks (all in 24-bit RGB format). Target is the default
target frame id. Chset and mediatype are as for the chset and mtype parameters to
parsehtml. Scripttype is the type of any scripts contained in the document, and is always
TextJavascript. Hasscripts is set if the document contains any scripts. Scripting is cur­
rently unsupported. Refresh is the contents of a <meta http−equiv=Refresh ...>
tag, if any. Kidinfo is set if this document is a frameset (see section Frames). Frameid is this
documents frame id.
Anchors is a list of hyperlinks contained in the document, and dests is a list of hyperlink desti­
nations within the page (see the following section for details). Forms, tables and maps are
lists of the various forms, tables and client-side maps contained in the document, as described in
subsequent sections. Images is a list of all the image items in the document.
The library builds two lists for all of the <a> elements (anchors) in a document. Each anchor is
assigned a unique anchor id within the document. For anchors which are hyperlinks (the href
attribute was supplied), the following structure is defined:
typedef struct Anchor Anchor;
struct Anchor
Anchor* next;
Next points to the next anchor in the list (the head of this list is Docinfo.anchors). Index
is the anchor id; each item within this hyperlink is tagged with this value in its anchorid field.
Name and href are the values of the correspondingly named attributes of the anchor (in particu­
lar, href is the URL to go to). Target is the value of the target attribute (if provided) converted to
a frame id.
Destinations within the document (anchors with the name attribute set) are held in the
Docinfo.dests list, using the following structure:
typedef struct DestAnchor DestAnchor;
struct DestAnchor
DestAnchor* next;
Next is the next element of the list, index is the anchor id, name is the value of the name
attribute, and item is points to the item within the parsed document that should be considered to
be the destination.
Any forms within a document are kept in a list, headed by Docinfo.forms. The elements of
this list are as follows:
typedef struct
struct Form
Form Form;
Next points to the next form in the list. Formid is a serial number for the form within the docu­
ment. Name is the value of the forms name or id attribute. Action is the value of any action
attribute. Target is the value of the target attribute (if any) converted to a frame target id.
Method is one of HGet or HPost. Nfields is the number of fields in the form, and fields
is a linked list of the actual fields.
The individual fields in a form are described by the following structure:
typedef struct Formfield Formfield;
struct Formfield
Here, next points to the next field in the list. Ftype is the type of the field, which can be one of
Ftext, Fpassword, Fcheckbox, Fradio, Fsubmit, Fhidden, Fimage, Freset,
Ffile, Fbutton, Fselect or Ftextarea. Fieldid is a serial number for the field within
the form. Form points back to the form containing this field. Name, value, size,
maxlength, rows and cols each contain the values of corresponding attributes of the field, if
present. Flags contains per-field flags, of which FFchecked and FFmultiple are defined.
Image is only used for fields of type Fimage; it points to an image item containing the image to
be displayed. Ctlid is reserved for use by the caller, typically to store a unique id of an associ­
ated control used to implement the field. Events is the same as the corresponding field of the
generic attributes associated with the item containing this field. Options is only used by fields
of type Fselect; it consists of a list of possible options that may be selected for that field, using
the following structure:
typedef struct Option Option;
struct Option
Option* next;
Next points to the next element of the list. Selected is set if this option is to be displayed ini­
tially. Value is the value to send when the form is submitted if this option is selected.
Display is the string to display on the screen for this option.
The library builds a list of all the tables in the document, headed by Docinfo.tables. Each
element of this list has the following format:
typedef struct Table Table;
struct Table
Tablecell*** grid;
Next points to the next element in the list of tables. Tableid is a serial number for the table
within the document. Rows is an array of row specifications (described below) and nrow is the
number of elements in this array. Similarly, cols is an array of column specifications, and ncol
the size of this array. Cells is a list of all cells within the table (structure described below) and
ncell is the number of elements in this list. Note that a cell may span multiple rows and/or
columns, thus ncell may be smaller than nrow*ncol. Grid is a two-dimensional array of
cells within the table; the cell at row i and column j is Table.grid[i][j]. A cell that spans
multiple rows and/or columns will be referenced by grid multiple times, however it will only
occur once in cells. Align gives the alignment specification for the entire table, and width
gives the requested width as a dimension specification. Border, cellspacing and
cellpadding give the values of the corresponding attributes for the table, and background
gives the requested background for the table. Caption is a linked list of items to be displayed
as the caption of the table, either above or below depending on whether caption_place is
ALtop or ALbottom. Most of the remaining fields are reserved for use by the caller, except
tabletok, which is reserved for internal use. The type Lay is not defined by the library; the
caller can provide its own definition.
The 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:
typedef struct Tablecol Tablecol;
struct Tablecol
Align align;
Point pos;
The rows in the table are specified as follows:
typedef struct Tablerow Tablerow;
struct Tablerow
Tablerow* next;
Tablecell* cells;
Background background;
Next is only used during parsing; it should be ignored by the caller. Cells provides a list of all
the cells in a row, linked through their nextinrow fields (see below). Height, ascent and
pos are reserved for use by the caller. Align is the alignment specification for the row, and
background is the background to use, if specified. Flags is used by the parser; ignore this
The individual cells of the table are described as follows:
typedef struct Tablecell Tablecell;
struct Tablecell
Tablecell* next;
Tablecell* nextinrow;
Background background;
Next is used to link together the list of all cells within a table (Table.cells), whereas
nextinrow is used to link together all the cells within a single row (Tablerow.cells).
Cellid provides a serial number for the cell within the table. Content is a linked list of the
items to be laid out within the cell. Lay is reserved for the user to describe how these items have
been laid out. Rowspan and colspan are the number of rows and columns spanned by this
cell, respectively. Align is the alignment specification for the cell. Flags is some combination
of TFparsing, TFnowrap and TFisth ord together. Here TFparsing is used internally by
the parser, and should be ignored. TFnowrap means that the contents of the cell should not be
wrapped if they dont fit the available width, rather, the table should be expanded if need be (this
is set when the nowrap attribute is supplied). TFisth means that the cell was created by the
<th> element (rather than the <td> element), indicating that it is a header cell rather than a data
cell. Wspec provides a suggested width as a dimension specification, and hspec provides a sug­
gested height in pixels. Background gives a background specification for the individual cell.
Minw, maxw, ascent and pos are reserved for use by the caller during layout. Row and col
give the indices of the row and column of the top left-hand corner of the cell within the table grid.
Client−side Maps
The library builds a list of client-side maps, headed by Docinfo.maps, and having the following
typedef struct Map Map;
struct Map
Map* next;
Rune* name;
Area* areas;
Next points to the next element in the list, name is the name of the map (use to bind it to an
image), and areas is a list of the areas within the image that comprise the map, using the follow­
ing structure:
typedef struct Area Area;
struct Area
Area* next;
Rune* href;
Dimen* coords;
Next points to the next element in the maps list of areas. Shape describes the shape of the
area, and is one of SHrect, SHcircle or SHpoly. Href is the URL associated with this area
in its role as a hypertext link, and target is the target frame it should be loaded in. Coords is
an array of coordinates for the shape, and ncoords is the size of this array (number of elements).
If the Docinfo.kidinfo field is set, the document is a frameset. In this case, it is typical for
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.
The Kidinfo structure itself reflects the fact that framesets can be nested within a document. If
is defined as follows:
typedef struct Kidinfo Kidinfo;
struct Kidinfo
Kidinfo* next;
// fields for "frame"
// fields for "frameset"
Kidinfo* kidinfos;
Kidinfo* nextframeset;
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. Isframeset is set when this structure represents a frame­
set; if clear, it is an individual frame.
Some fields are used only for framesets. Rows is an array of dimension specifications for rows in
the frameset, and nrows is the length of this array. Cols is the corresponding array for
columns, of length ncols. Kidinfos points to a list of components contained within this
frameset, each of which may be a frameset or a frame. Nextframeset is only used during pars­
ing, and should be ignored.
The remaining fields are used if the structure describes a frame, not a frameset. Src provides the
URL for the document that should be initially loaded into this frame. Note that this may be a rela­
tive URL, in which case it should be interpretted using the containing documents URL as the base.
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. Marginw, marginh and framebd are the values of the
marginwidth, marginheight and frameborder attributes, respectively. Flags can contain some
combination of the following: FRnoresize (the frame had the noresize attribute set, and the
user should not be allowed to resize it), FRnoscroll (the frame should not have any scroll bars),
FRhscroll (the frame should have a horizontal scroll bar), FRvscroll (the frame should have
a vertical scroll bar), FRhscrollauto (the frame should be automatically given a horizontal
scroll bar if its contents would not otherwise fit), and FRvscrollauto (the frame gets a vertical
scrollbar only if required).
W3C World Wide Web Consortium, HTML 4.01 Specification.
The entire HTML document must be loaded into memory before any of it can be parsed.
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,
routines for creating an http server
#include <u.h>
#include <libc.h>
#include <httpd.h>
HConnect HConnect;
HContent HContent;
HContents HContents;
HETag HETag;
HFields HFields;
Hio Hio;
Htmlesc Htmlesc;
HttpHead HttpHead;
HttpReq HttpReq;
HRange HRange;
HSPairs HSPairs;
typedef struct Bin Bin;
struct Htmlesc
struct HContent
struct HContents
/* desirability of this kind of fi
/* max uchars until worthless */
* generic http header with a list of tokens,
* each with an optional list of parameters
struct HFields
* list of pairs a strings
* used for tag=val pairs for a search or form submission,
* and attribute=value pairs in headers.
struct HSPairs
* byte ranges within
struct HRange
a file
/* is this a suffix request? */
/* ~0UL −> not given */
* list of http/1.1 entity tags
struct HETag
* HTTP custom IO
* supports chunked transfer encoding
* and initialization of the input buffer from a string.
Hsize = HBufSize
struct Hio {
next lower layer Hio, or nil if
associated file descriptor */
of start */
state of the file */
chunked transfer encoding state
current position in the buffer
last character active in the bu
/* start of data buffer */
/* remaining length of message bod
* request line
struct HttpReq
* header lines
struct HttpHead
/* http1.1 close connection after
/* http/1.1 requests a persistent
expect a 100−continue */
expect anything else; should re
if != ~0UL, length of included
if present, encoding of include
/* authorization info */
* experimental headers
* all of the state for a particular connection
struct HConnect
/* for the library clients */
(*replog)(HConnect*, char*, ...);/* called when reply sen
header[HBufSize + 2];
/* time at start of request */
/* buffer for making up or transfe
/* room for \n\0 */
* configuration for all connections within the server
*halloc(HConnect *c, ulong size);
*hbodypush(Hio *hh, ulong len, HFields *te);
hbuflen(Hio *h, void *p);
hcheckcontent(HContent*, HContent*, char*, int);
hfail(HConnect*, int, ...);
hgethead(HConnect *c, int many);
hinit(Hio*, int, int);
hiserror(Hio *h);
hload(Hio*, char*);
*hmkcontent(HConnect *c, char *generic, char *specific, HContent *nex
*hmkhfields(HConnect *c, char *s, HSPairs *p, HFields *next);
*hmkmimeboundary(HConnect *c);
*hmkspairs(HConnect *c, char *s, char *t, HSPairs *next);
hmoved(HConnect *c, char *uri);
hokheaders(HConnect *c);
hparseheaders(HConnect*, int timeout);
*hparsequery(HConnect *c, char *search);
hparsereq(HConnect *c, int timeout);
hprint(Hio*, char*, ...);
hputc(Hio*, int);
*hreadbuf(Hio *h, void *vsave);
hredirected(HConnect *c, char *how, char *uri);
hreqcleanup(HConnect *c);
*hrevhfields(HFields *hf);
*hrevspairs(HSPairs *sp);
*hstrdup(HConnect *c, char *s);
*httpunesc(HConnect *c, char *s);
hunallowed(HConnect *, char *allowed);
hungetc(Hio *h);
*hurlunesc(HConnect *c, char *s);
hvprint(Hio*, char*, va_list);
hwrite(Hio*, void*, int);
hxferenc(Hio*, int);
For now, look at the source, or httpd(8).
This is a rough implementation and many details are going to change.
hypot Euclidean distance
#include <u.h>
#include <libc.h>
double hypot(double x, double y)
Hypot returns
sqrt(x*x + y*y)
taking precautions against unwarranted overflows.
Intmap, allocmap, freemap, insertkey, caninsertkey, lookupkey, deletekey integer to data struc­
ture maps
allocmap(void (*inc)(void*))
freemap(Intmap *map, void (*dec)(void*))
lookupkey(Intmap *map, ulong key)
insertkey(Intmap *map, ulong key, void *val)
caninsertkey(Intmap *map, ulong key, void *val)
lookupkey(Intmap *map, ulong key)
deletekey(Intmap *map, ulong key)
An Intmap is an arbitrary mapping from integers to pointers. Allocmap creates a new map, and
freemap destroys it. The inc function is called each time a new pointer is added to the map; simi­
larly, 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 insertkey, which will
return the previous value associated with the given key, or zero if there was no previous value.
Caninsertkey is like insertkey but only inserts val if there is no current mapping. It returns 1 if val
was inserted, 0 otherwise. Lookupkey returns the pointer associated with key, or zero if there is
no such pointer. Deletekey removes the entry for id from the map, returning the associated
pointer, if any.
Concurrent access to Intmaps is safe, moderated via a QLock stored in the Intmap structure.
In anticipation of the storage of reference-counted structures, an increment function inc may be
specified at map creation time. Lookupkey calls 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 insertkey and the external
increment. Insertkey and caninsertkey do not call inc when inserting val into the map, nor do
insertkey or deletekey call 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 deletekey or the next insertkey.
Intmaps are used by the 9P library to implement Fidpools and Reqpools.
9p(2), 9pfid(2).
closeioproc, iocall, ioclose, iointerrupt, iodial, ioopen, ioproc, ioread, ioreadn, iowrite slave I/O
processes for threaded programs
#include <u.h>
#include <libc.h>
#include <thread.h>
typedef struct Ioproc Ioproc;
Ioproc* ioproc(void);
ioopen(Ioproc *io, char *file, int omode);
ioclose(Ioproc *io, int fd);
ioread(Ioproc *io, int fd, void *a, long n);
ioreadn(Ioproc *io, int fd, void *a, long n);
iowrite(Ioproc *io, int fd, void *a, long n);
iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp);
iointerrupt(Ioproc *io);
closeioproc(Ioproc *io);
iocall(Ioproc *io, long (*op)(va_list *arg), ...);
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.
Ioproc forks a new slave proc and returns a pointer to the Ioproc associated with it. Ioproc uses
mallocz and proccreate; if either fails, it calls sysfatal rather than return an error.
Ioopen, ioclose, ioread, ioreadn, iowrite, and iodial execute the similarly named library or system
calls (see open(2), read(2), and dial(2)) in the slave process associated with io. It is an error to exe­
cute more than one call at a time in an I/O proc.
Iointerrupt interrupts the call currently executing in the I/O proc.
iointerrupt is a no-op.
If no call is executing,
Closeioproc terminates the I/O proc and frees the associated Ioproc .
Iocall is a primitive that may be used to implement more slave I/O routines. Iocall arranges for op
to be called in ios proc, with arg set to the variable parameter list, returning the value that op
Relay messages between two file descriptors, counting the total number of bytes seen:
int tot;
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;
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);
If the two relaythread instances were running in different procs, the common access to tot would
be unsafe.
Implement ioread:
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);
ioread(Ioproc *io, int fd, void *a, long n)
return iocall(io, _ioread, fd, a, n);
dial(2), open(2), read(2), thread(2)
iounit return size of atomic I/O unit for file descriptor
#include <u.h>
#include <libc.h>
int iounit(int fd)
Reads and writes of files are transmitted using the 9P protocol (see intro(5)) and in general, opera­
tions 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.
The iounit routine uses the dup(3) interface to discover the I/O unit size for the file descriptor fd
and returns its value. Certain file descriptors, particularly those associated with devices, may have
no specific I/O unit, in which case iounit will return 0.
dup(3), read(5)
Returns zero if any error occurs or if the I/O unit size of the fd is unspecified or unknown.
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
#include <u.h>
#include <libc.h>
#include <ip.h>
parseip(uchar *ipaddr, char *str)
parseipmask(uchar *ipaddr, char *str)
v4parseip(uchar *ipaddr, char *str)
v4parsecidr(uchar *addr, uchar *mask, char *str)
parseether(uchar *eaddr, char *str)
myetheraddr(uchar *eaddr, char *dev)
myipaddr(uchar *ipaddr, char *net)
void maskip(uchar *from, uchar *mask, uchar *to)
equivip4(uchar *ipaddr1, uchar *ipaddr2)
equivip6(uchar *ipaddr1, uchar *ipaddr2)
defmask(uchar *ipaddr)
isv4(uchar *ipaddr)
void v4tov6(uchar *ipv6, uchar *ipv4)
void v6tov4(uchar *ipv4, uchar *ipv6)
nhgets(void *p)
uint nhgetl(void *p)
nhgetv(void *p)
void hnputs(void *p, ushort v)
void hnputl(void *p, uint v)
void hnputv(void *p, uvlong v)
ptclbsum(uchar *a, int n)
readipifc(char *net, Ipifc *ifc, int index)
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 unsigned
chars, Ethernet addresses as 6 unsigned 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, FFFF::1111 is equivalent to 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 repre­
/120. The string representation of Ethernet addresses is exactly 12 hexadecimal digits.
Eipfmt is a print(2) formatter for Ethernet (verb E) addresses, IP V6 (verb I) addresses, IP V4 (verb
V) addresses, and IP V6 (verb M) masks.
Parseip converts a string pointed to by str to a 16-byte IP address starting at ipaddr. As a conces­
sion 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. Parseipmask converts
a string pointed to by str to a 6-byte IP mask starting at ipaddr. It too returns an unsigned long
big-endian V4 address or 6. Both routines return -1 on errors.
V4parseip converts a string pointed to by str to a 4-byte V4 IP address starting at ipaddr.
V4parsecidr converts a string of the form addr/mask, pointed to by str, to a 4-byte V4 IP address
starting at ipaddr and a 4-byte V4 IP mask starting at mask.
Myipaddr returns the first valid IP address in the IP stack rooted at net.
Parseether converts a string pointed to by str to a 6-byte Ethernet address starting at eaddr.
Myetheraddr reads the Ethernet address string from file dev/addr and parses it into eaddr. Both
routines return a negative number on errors.
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.
Equivip returns non-zero if the IP addresses pointed to by its two arguments are equal. Equivip4
operates on v4 addresses, equivip6 operates on v6 addresses.
Defmask returns the standard class A, B, or C mask for ipaddr.
Isv4 returns non-zero if the V6 address is in the V4 space, that is, if it starts with
0:0:0:0:0:0:FFFF. V4tov6 converts the 4-byte V4 address, v4ip, to a V6 address and puts
the result in v6ip. V6tov4 converts the V6 address, v6ip, to a 4-byte V4 address and puts the
result in v4ip.
Hnputs, hnputl and hnputv are used to store 16-bit, 32-bit, and 64-bit integers, respectively, into
IP big-endian form. Nhgets, nhgetl and nhgetv convert big-endian 2, 4 and 8 byte quantities into
integers (or uvlongs).
Pctlbsum returns the ones complement checksum used in IP protocols, typically invoked as
hnputs(hdr−>cksum, ~ptclbsum(data, len) & 0xffff);
A number of standard IP addresses in V6 format are also defined. They are:
V4 broadcast address
V4 all systems multicast address
V4 all routers multicast address
V6 all bits on address
V6 null address, all zeros
IP V6 prefix to all embedded V4 addresses
Readipifc returns information about a particular interface (index >= 0) or all IP interfaces (index <
0) configured under a mount point net, default /net. Each interface is described by one Ipifc
structure which in turn points to a linked list of Iplifc structures describing the addresses assigned
to this interface. If the list ifc is supplied, that list is freed. Thus, subsequent calls can be used to
free the list returned by the previous call. Ipifc is:
typedef struct Ipifc
/* local addressses */
/* per ip interface */
int index;
/* number of interface in ipifc dir */
char dev[64]; /* associated physical device */
int mtu;
/* max transfer unit */
} Ipifc;
/* on == send router adv */
/* on == rcv router adv */
/* packets read */
/* packets written */
/* read errors */
/* write errors */
/* route advertisement params */
Iplifc is:
struct Iplifc
/* ip & mask */
/* preferred lifetime */
/* valid lifetime */
Ipv6rp is:
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;
Dev contains the first 64 bytes of the device configured with this interface. Net is ip&mask if the
network is multipoint or the remote address if the network is point to point.
print(2), ip(3)
isalpharune, islowerrune, isspacerune, istitlerune, isupperrune, isdigitrune, tolowerrune, toti­
tlerune, toupperrune Unicode character classes and cases
#include <u.h>
#include <libc.h>
int isalpharune(Rune c)
int islowerrune(Rune c)
int isspacerune(Rune c)
int istitlerune(Rune c)
int isupperrune(Rune c)
int isdigitrune(Rune c)
Rune tolowerrune(Rune c)
Rune totitlerune(Rune c)
Rune toupperrune(Rune c)
These routines examine and operate on Unicode characters, in particular a subset of their proper­
ties as defined in the Unicode standard. Unicode defines some characters as alphabetic and speci­
fies three cases: upper, lower, and title. Analogously to ctype(2) for ASCII, these routines test types
and modify cases for Unicode characters. The names are self-explanatory.
The case-conversion routines return the character unchanged if it has no case.
ctype(2), The Unicode Standard.
initkeyboard, ctlkeyboard, closekeyboard keyboard control
*initkeyboard(char *file)
ctlkeyboard(Keyboardctl *kc, char *msg)
closekeyboard(Keyboard *kc)
These functions access and control a keyboard interface for character-at-a-time I/O in a multithreaded environment, usually in combination with mouse(2). They use the message-passing
Channel interface in the threads library (see thread(2)); programs that wish a more event-driven,
single-threaded approach should use event(2).
Initkeyboard opens a connection to the keyboard and returns a Keyboardctl structure:
typedef struct Keyboardct Keyboardctl;
struct Keyboardctl
Channel *c;
/* chan(Rune[20]) */
/* to cons file */
/* to ctl file */
/* of slave proc */
The argument to initkeyboard is a file naming the device file from which characters may be read,
typically /dev/cons. If file is nil, /dev/cons is assumed.
Once the Keyboardctl is set up a message containing a Rune will be sent on the Channel
Keyboardctl.c to report each character read from the device.
Ctlkeyboard is used to set the state of the interface, typically to turn raw mode on and off (see
cons(3)). It writes the string msg to the control file associated with the device, which is assumed to
be the regular device file name with the string ctl appended.
Closekeyboard closes the file descriptors associated with the keyboard, kills the slave processes,
and frees the Keyboardctl structure.
graphics(2), draw(2), event(2), thread(2).
Because the interface delivers complete runes, there is no way to report lesser actions such as shift
keys or even individual bytes.
lock, canlock, unlock, qlock, canqlock, qunlock, rlock, canrlock, runlock, wlock, canwlock, wun­
lock, rsleep, rwakeup, rwakeupall, incref, decref spin locks, queueing rendezvous locks, readerwriter locks, rendezvous points, and reference counts
#include <u.h>
#include <libc.h>
void lock(Lock *l)
int canlock(Lock *l)
void unlock(Lock *l)
void qlock(QLock *l)
int canqlock(QLock *l)
void qunlock(QLock *l)
void rlock(RWLock *l)
int canrlock(RWLock *l)
void runlock(RWLock *l)
void wlock(RWLock *l)
int canwlock(RWLock *l)
void wunlock(RWLock *l)
typedef struct Rendez {
QLock *l;
} Rendez;
void rsleep(Rendez *r)
int rwakeup(Rendez *r)
int rwakeupall(Rendez *r)
#include <thread.h>
typedef struct Ref {
long ref;
} Ref;
void incref(Ref*)
long decref(Ref*)
These routines are used to synchronize processes sharing memory.
Locks are spin locks, QLocks and RWLocks are different types of queueing rendezvous locks,
and Rendezes are rendezvous points.
Locks and rendezvous points work in regular programs as well as programs that use the thread
library (see thread(2)). The thread library replaces the rendezvous (2) system call with its own
implementation, threadrendezvous , so that threads as well as processes may be synchronized by
locking calls in threaded programs.
Used carelessly, spin locks can be expensive and can easily generate deadlocks. Their use is dis­
couraged, especially in programs that use the thread library because they prevent context switches
between threads.
Lock blocks until the lock has been obtained. Canlock is non-blocking. It tries to obtain a lock
and returns a non-zero value if it was successful, 0 otherwise. Unlock releases a lock.
QLocks have the same interface but are not spin locks; instead if the lock is taken qlock will sus­
pend execution of the calling task until it is released.
Although Locks are the more primitive lock, they have limitations; for example, they cannot syn­
chronize between tasks in the same proc. Use QLocks instead.
RWLocks manage access to a data structure that has distinct readers and writers. Rlock grants
read access; runlock releases it. Wlock grants write access; wunlock releases it. Canrlock and
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.
All types of lock should be initialized to all zeros before use; this puts them in the unlocked state.
Rendezes are rendezvous points. Each Rendez r is protected by a QLock r−>l, which must
be held by the callers of rsleep, rwakeup, and rwakeupall. Rsleep atomically releases r−>l and
suspends execution of the calling task. After resuming execution, rsleep will reacquire r−>l
before returning. If any processes are sleeping on r, rwakeup wakes one of them. it returns 1 if a
process was awakened, 0 if not. Rwakeupall wakes all processes sleeping on r, returning the num­
ber of processes awakened. Rwakeup and rwakeupall do not release r−>l and do not suspend
execution of the current task.
Before use, Rendezes should be initialized to all zeros except for r−>l pointer, which should
point at the QLock that will guard r. It is important that this QLock is the same one that protects
the rendezvous condition; see the example.
A Ref contains a long that can be incremented and decremented atomically: Incref increments
the Ref in one atomic operation. Decref atomically decrements the Ref and returns zero if the
resulting value is zero, non-zero otherwise.
Implement a buffered single-element channel using rsleep and rwakeup:
typedef struct Chan
QLock l;
Rendez full, empty;
int val, haveval;
} Chan;
Chan *c;
c = mallocz(sizeof *c, 1);
c−>full.l = &c−>l;
c−>empty.l = &c−>l;
return c;
send(Chan *c, int val)
c−>haveval = 1;
c−>val = val;
rwakeup(&c−>empty); /* no longer empty */
recv(Chan *c)
int v;
c−>haveval = 0;
v = c−>val;
return v;
/* no longer full */
Note that the QLock protecting the Chan is the same QLock used for the Rendez; this ensures
that wakeups are not missed.
rfork in fork(2)
Locks are not strictly spin locks. After each unsuccessful attempt, lock calls sleep(0) to yield
the CPU; this handles the common case where some other process holds the lock. After a thou­
sand unsuccessful attempts, lock sleeps for 100ms between attempts. After another thousand
unsuccessful attempts, lock sleeps for a full second between attempts. 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.
It is an error for a program to 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.
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
int crackhdr(int fd, Fhdr *fp)
void machbytype(int type)
int machbyname(char *name)
Map *newmap(Map *map, int n)
int setmap(Map *map, int fd, ulong base, ulong end,
ulong foffset, char *name)
int findseg(Map *map, char *name)
void unusemap(Map *map, int seg)
Map *loadmap(Map *map, int fd, Fhdr *fp)
Map *attachproc(int pid, int kflag, int corefd, Fhdr *fp)
int get1(Map *map, ulong addr, uchar *buf, int n)
int get2(Map *map, ulong addr, ushort *val)
int get4(Map *map, ulong addr, long *val)
int get8(Map *map, ulong addr, vlong *val)
int put1(Map *map, ulong addr, uchar *buf, int n)
int put2(Map *map, ulong addr, ushort val)
int put4(Map *map, ulong addr, long val)
int put8(Map *map, ulong addr, vlong val)
ushort beswab(ushort val)
long beswal(long val)
long beswav(vlong val)
ushort leswab(ushort val)
long leswal(long val)
long leswav(vlong val)
extern Mach mach;
extern Machdata machdata;
These functions provide a processor-independent interface for accessing the executable files or
executing images of all architectures. Related library functions described in symbol(2) and
object(2) provide similar access to symbol tables and object files.
An executable is a file containing an executable program or the text file of the /proc file sys­
tem associated with an executing process as described in proc(3). After opening an executable, an
application invokes a library function which parses the file header, determines the target architec­
ture and initializes data structures with parameters and pointers to functions appropriate for that
architecture. Next, the application invokes functions to construct one or more maps, data struc­
tures that translate references in the address space of the executable to offsets in the file. Each
map comprises one or more 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
Crackhdr interprets the header of the executable associated with the open file descriptor fd. It
loads the data structure fp with a machine-independent description of the header information and
points global variable mach to the Mach data structure containing processor-dependent parame­
ters of the target architecture.
Machbytype selects architecture-specific data structures and parameter values based on the code
stored in the field named type in the Fhdr data structure. Machbyname performs the same selec­
tion based on the name of a processor class; see 2c(1) for a list of valid names. Both functions
point global variables mach and machdata to the Mach and Machdata data structures appropriate
for the target architecture and load global variable asstype with the proper disassembler type
Newmap creates an empty map with n segments. If map is zero, the new map is dynamically allo­
cated, 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.
Setmap loads the first unused segment in map with the segment mapping parameters. Fd is an
open file descriptor associated with an executable. Base and end contain the lowest and highest
virtual addresses mapped by the segment. Foffset is the offset to the start of the segment in the
file. Name is a name to be attached to the segment.
Findseg returns the index of the the segment named name in map. A return of -1 indicates that no
segment matches name.
Unusemap marks segment number seg in map map unused. Other segments in the map remain
Loadmap initializes a default map containing segments named text and data that map the
instruction and data segments of the executable described in the Fhdr structure pointed to by fp.
Usually that structure was loaded by crackhdr and can be passed to this function without modifica­
tion. If map is non-zero, that map, which must have been dynamically allocated, is resized to con­
tain two segments; otherwise a new map is allocated. This function returns zero if allocation fails.
Loadmap is usually used to build a map for accessing a static executable, for example, an exe­
cutable program file.
Attachproc constructs a map for accessing a running process. It returns the address of a Map con­
taining segments mapping the address space of the running process whose process ID is pid. If
kflag is non-zero, the process is assumed to be a kernel process. Corefd is an file descriptor
opened to /proc/pid/mem. Fp points to the Fhdr structure describing the header of the exe­
cutable. For most architectures the resulting 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 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.
Attachproc returns zero if it is unable to build the map for the specified process.
Get1, get2, get4, and get8 retrieve the data stored at address addr in the executable associated
with map. Get1 retrieves n bytes of data beginning at addr into buf. Get2, get4 and get8 retrieve
16-bit, 32-bit and 64-bit values respectively, into the location pointed to by 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 get2, get4, and get8 may not be the same as the byte sequences
returned by get1 when 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 seg­
ment in 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.
Put1, put2, put4, and put8 write to the executable associated with map. The address is translated
using the map parameters and multi-byte quantities are byte-swapped, if necessary, before they
are written. Put1 transfers n bytes stored at buf; put2, put4, and put8 write the 16-bit, 32-bit or
64-bit quantity contained in val, respectively. The number of bytes transferred is returned. A 1
return value indicates an error.
Beswab, beswal, and beswav return the ushort, long, and vlong big-endian representation of
val, respectively. Leswab, leswal, and leswav return the little-endian representation of the
ushort, long, and vlong contained in val.
2c(1), symbol(2), object(2), errstr(2), proc(3), a.out(6)
These routines set errstr.
malloc, mallocalign, mallocz, free, realloc, calloc, msize, setmalloctag, setrealloctag, getmalloctag,
getrealloctag, malloctopoolblock memory allocator
#include <u.h>
#include <libc.h>
void* malloc(ulong size)
void* mallocalign(ulong size, ulong align, long offset, ulong span)
void* mallocz(ulong size, int clr)
free(void *ptr)
void* realloc(void *ptr, ulong size)
void* calloc(ulong nelem, ulong elsize)
ulong msize(void *ptr)
setmalloctag(void *ptr, ulong tag)
ulong getmalloctag(void *ptr)
setrealloctag(void *ptr, ulong tag)
ulong getrealloctag(void *ptr)
void* malloctopoolblock(void*)
Malloc and free provide a simple memory allocation package. Malloc returns a pointer to a new
block of at least size bytes. The block is suitably aligned for storage of any type of object. No two
active pointers from malloc will have the same value. The call malloc(0) returns a valid pointer
rather than null.
The argument to free is a pointer to a block previously allocated by 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 malloc are undefined. Mallocz behaves as malloc, except that if clr is
non-zero, the memory returned will be zeroed.
Mallocalign allocates a block of at least n bytes of memory respecting alignment contraints. If
align is non-zero, the returned pointer is aligned to be equal to offset modulo align. If span is
non-zero, the n byte block allocated will not span a span-byte boundary.
Realloc changes the size of the block pointed to by ptr to 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.
Realloc takes on special meanings when one or both arguments are zero:
realloc(0, size)
means malloc(size); returns a pointer to the newly-allocated memory
realloc(ptr, 0)
means free(ptr); returns null
realloc(0, 0)
no-op; returns null
Calloc allocates space for an array of nelem elements of size elsize. The space is initialized to
zeros. Free frees such a block.
When a block is allocated, sometimes there is some extra unused space at the end. Msize grows
the block to encompass this unused space and returns the new number of bytes that may be used.
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
setmalloctag, getmalloctag, setrealloctag, and getrealloctag. When allocating blocks directly with
malloc and realloc, these tags will be set properly. If a custom allocator wrapper is used, the allo­
cator wrapper can set the tags itself (usually by passing the result of getcallerpc(2) to
setmalloctag) to provide more useful information about the source of allocation.
Malloctopoolblock takes the address of a block returned by malloc and returns the address of the
corresponding block allocated by the pool(2) routines.
leak(1), trump (in acid(1)), brk(2), getcallerpc(2), pool(2)
Malloc, realloc and calloc return 0 if there is no available memory. Errstr is likely to be set. If the
allocated blocks have no malloc or realloc tags, getmalloctag and getrealloctag return ~0.
After including pool.h, the call 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
mainmem−>flags |= POOL_NOREUSE;
at the beginning of your program. This will cause malloc not to reallocate blocks even once they
are freed; poolcheck(mainmem) will then detect writes to freed blocks.
The trump library for acid can be used to obtain traces of malloc execution; see acid(1).
The different specification of calloc is bizarre.
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 malloc and free detect such corruption, they abort.
ident, matmul, matmulr, determinant, adjoint, invertmat, xformpoint, xformpointd, xformplane,
pushmat, popmat, rot, qrot, scale, move, xform, ixform, persp, look, viewport Geometric trans­
#include <draw.h>
#include <geometry.h>
void ident(Matrix m)
void matmul(Matrix a, Matrix b)
void matmulr(Matrix a, Matrix b)
double determinant(Matrix m)
void adjoint(Matrix m, Matrix madj)
double invertmat(Matrix m, Matrix inv)
Point3 xformpoint(Point3 p, Space *to, Space *from)
Point3 xformpointd(Point3 p, Space *to, Space *from)
Point3 xformplane(Point3 p, Space *to, Space *from)
Space *pushmat(Space *t)
Space *popmat(Space *t)
void rot(Space *t, double theta, int axis)
void qrot(Space *t, Quaternion q)
void scale(Space *t, double x, double y, double z)
void move(Space *t, double x, double y, double z)
void xform(Space *t, Matrix m)
void ixform(Space *t, Matrix m, Matrix inv)
int persp(Space *t, double fov, double n, double f)
void look(Space *t, Point3 eye, Point3 look, Point3 up)
void viewport(Space *t, Rectangle r, double aspect)
These routines manipulate 3-space affine and projective transformations, represented as 4×4
matrices, thus:
typedef double Matrix[4][4];
Ident stores an identity matrix in its argument. Matmul stores a×b in a. Matmulr stores b×a in b.
Determinant returns the determinant of matrix m. Adjoint stores the adjoint (matrix of cofactors)
of m in madj. Invertmat stores the inverse of matrix m in minv, returning ms determinant.
Should m be singular (determinant zero), invertmat stores its adjoint in minv.
The rest of the routines described here manipulate Spaces and transform Point3s. A Point3 is a
point in three-space, represented by its homogeneous coordinates:
typedef struct Point3 Point3;
struct Point3{
double x, y, z, w;
The homogeneous coordinates (x, y, z, w) represent the Euclidean point (x/w, y/w, z/w) if w`0,
and a point at infinity if w=0.
A Space is just a data structure describing a coordinate system:
typedef struct Space Space;
struct Space{
Matrix t;
Matrix tinv;
Space *next;
It contains a pair of transformation matrices and a pointer to the Spaces parent. The matrices
transform points to and from the root coordinate system, which is represented by a null Space
Pushmat creates a new Space. Its argument is a pointer to the parent space. Its result is a newly
allocated copy of the parent, but with its next pointer pointing at the parent. Popmat discards
the Space that is its argument, returning a pointer to the stack. Nominally, these two functions
define a stack of transformations, but pushmat can be called multiple times on the same Space
multiple times, creating a transformation tree.
Xformpoint and Xformpointd both transform points from the Space pointed to by from to the
space pointed to by to. Either pointer may be null, indicating the root coordinate system. The dif­
ference between the two functions is that xformpointd divides x, y, z, and w by w, if w`0,
making (x, y, z) the Euclidean coordinates of the point.
Xformplane transforms planes or normal vectors. A plane is specified by the coefficients (a, b, c,
d) of its implicit equation ax+by+cz+d=0. Since this representation is dual to the homogeneous
representation of points, libgeometry represents planes by Point3 structures, with (a, b, c,
d) stored in (x, y, z, w).
The remaining functions transform the coordinate system represented by a Space. Their Space
* argument must be non-null you cant modify the root Space. Rot rotates by angle theta (in
radians) about the given axis, which must be one of XAXIS, YAXIS or ZAXIS. Qrot transforms
by a rotation about an arbitrary axis, specified by Quaternion q.
Scale scales the coordinate system by the given scale factors in the directions of the three axes.
Move translates by the given displacement in the three axial directions.
Xform transforms the coordinate system by the given Matrix. If the matrixs inverse is known a
priori, calling ixform will save the work of recomputing it.
Persp does a perspective transformation. The transformation maps the frustum with apex at the
origin, central axis down the positive y axis, and apex angle fov and clipping planes y=n and y=f
into the double-unit cube. The plane y=n maps to y=-1, y=f maps to y=1.
Look does a view-pointing transformation. The eye point is moved to the origin. The line
through the eye and look points is aligned with the y axis, and the plane containing the eye,
look and up points is rotated into the x-y plane.
Viewport maps the unit-cube window into the given screen viewport. The viewport rectangle r has
r.min at the top left-hand corner, and r.max just outside the lower right-hand corner. Argu­
ment aspect is the aspect ratio (dx/dy) of the viewports 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 viewports aspect ratio. The window is viewed down
the y axis, with x to the left and z up. The viewport has x increasing to the right and y increasing
down. The windows y coordinates are mapped, unchanged, into the viewports z coordinates.
Memimage, Memdata, Memdrawparam, memimageinit, wordaddr, byteaddr, memimagemove,
allocmemimage, allocmemimaged, readmemimage, creadmemimage, writememimage, freememim­
age, memsetchan, loadmemimage, cloadmemimage, unloadmemimage, memfillcolor, memarc,
mempoly, memellipse, memfillpoly, memimageline, memimagedraw, drawclip, memlinebbox,
memlineendsize, allocmemsubfont, openmemsubfont, freememsubfont, memsubfontwidth, get­
memdefont, memimagestring, iprint, hwdraw drawing routines for memory-resident images
typedef struct
} Memdata;
enum {
typedef struct
} Memimage;
allocated data pointer */
first byte of actual data; word−aligned */
number of Memimages using this data */
last image that pointed at this */
is this malloc’d? */
is replicated */
is 1x1 */
is grey */
has explicit alpha */
has cmap channel */
has only 8−bit channels */
rectangle in data area, local coords */
clipping region */
number of bits of storage per pixel */
number of channels */
channel descriptions */
pointer to data */
data−>bdata+zero==&byte containing (0,0) */
width in words of a single scan line */
nil if not a layer*/
typedef struct Memdrawparam
Memimage *dst;
Rectangle r;
Memimage *src;
Rectangle sr;
Memimage *mask;
Rectangle mr;
} Memdrawparam;
wordaddr(Memimage *i, Point p)
byteaddr(Memimage *i, Point p)
memimagemove(void *from, void *to)
allocmemimage(Rectangle r, ulong chan)
allocmemimaged(Rectangle r, ulong chan, Memdata *data)
readmemimage(int fd)
creadmemimage(int fd)
writememimage(int fd, Memimage *i)
freememimage(Memimage *i)
memsetchan(Memimage*, ulong)
loadmemimage(Memimage *i, Rectangle r,
uchar *buf, int nbuf)
cloadmemimage(Memimage *i, Rectangle r,
uchar *buf, int nbuf)
unloadmemimage(Memimage *i, Rectangle r,
uchar *buf, int nbuf)
memfillcolor(Memimage *i, ulong color)
memarc(Memimage *dst, Point c, int a, int b, int thick,
Memimage *src, Point sp, int alpha, int phi, Drawop op)
mempoly(Memimage *dst, Point *p, int np, int end0,
int end1, int radius, Memimage *src, Point sp, Drawop op)
memellipse(Memimage *dst, Point c, int a, int b,
int thick, Memimage *src, Point sp, Drawop op)
memfillpoly(Memimage *dst, Point *p, int np, int wind,
Memimage *src, Point sp, Drawop op)
memimageline(Memimage *dst, Point p0, Point p1, int end0,
int end1, int radius, Memimage *src, Point sp, Drawop op)
memimagedraw(Memimage *dst, Rectangle r, Memimage *src,
Point sp, Memimage *mask, Point mp, Drawop op)
drawclip(Memimage *dst, Rectangle *dr, Memimage *src,
Point *sp, Memimage *mask, Point *mp,
Rectangle *sr, Rectangle *mr)
memlinebbox(Point p0, Point p1, int end0, int end1,
int radius)
memlineendsize(int end)
Memsubfont* allocmemsubfont(char *name, int n, int height,
int ascent, Fontchar *info, Memimage *i)
Memsubfont* openmemsubfont(char *name)
freememsubfont(Memsubfont *f)
memsubfontwidth(Memsubfont *f, char *s)
Memsubfont* getmemdefont(void)
memimagestring(Memimage *dst, Point p, Memimage *color,
Point cp, Memsubfont *f, char *cs)
iprint(char *fmt, ...)
hwdraw(Memdrawparam *param)
The Memimage type defines memory-resident rectangular pictures and the methods to draw upon
them; Memimages differ from Images (see draw(2)) in that they are manipulated directly in user
memory rather than by RPCs to the /dev/draw hierarchy. The memdraw library is the basis for
the kernel draw(3) driver and also used by a number of programs that must manipulate images
without a display.
The r, clipr, depth, nchan, and chan structure elements are identical to the ones of the
same name in the Image structure.
The flags element of the Memimage structure holds a number of bits of information about the
image. In particular, it subsumes the purpose of the repl element of Image structures.
Memimageinit initializes various static data that the library depends on, as well as the replicated
solid color images memopaque, memtransparent, memblack, and memwhite. It should be
called before referring to any of these images and before calling any of the other library functions.
Each Memimage points at a Memdata structure that in turn points at the actual pixel data for the
image. This allows multiple images to be associated with the same Memdata. The first word of
the data pointed at by the base element of Memdata points back at the Memdata structure, so
that the memory allocator (see pool(2)) can compact image memory using memimagemove.
Because images can have different coordinate systems, the zero element of the Memimage
structure contains the offset that must be added to the bdata element of the corresponding
Memdata structure in order to yield a pointer to the data for the pixel (0,0). Adding width
machine words to this pointer moves it down one scan line. The 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 corre­
sponding to pixels within the image rectangle. Wordaddr and byteaddr perform these calcula­
tions, returning pointers to the word and byte, respectively, that contain the beginning of the data
for a given pixel.
Allocmemimage allocages images with a given rectangle and channel descriptor (see strtochan
in graphics(2)), creating a fresh Memdata structure and associated storage. Allocmemimaged is
similar but uses the supplied Memdata structure rather than a new one. The readmemimage func­
tion reads an uncompressed bitmap from the given file descriptor, while creadmemimage reads a
compressed bitmap. Writememimage writes a compressed representation of i to file descriptor fd.
For more on bitmap formats, see image(6). Freememimage frees images returned by any of these
routines. The Memimage structure contains some tables that are used to store precomputed val­
ues depending on the channel descriptor. Memsetchan updates the chan element of the structure
as well as these tables, returning 1 if passed a bad channel descriptor.
Loadmemimage and cloadmemimage replace the pixel data for a given rectangle of an image with
the given buffer of uncompressed or compressed data, respectively. When calling
cloadmemimage, the buffer must contain an integral number of compressed chunks of data that
exactly cover the rectangle. 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.
Memfillcolor fills an image with the given color, a 32-bit number as described in color(2).
Memarc, mempoly, memellipse, memfillpoly, memimageline, and memimagedraw are identical to
the arc, poly, ellipse, fillpoly, line, and gendraw, routines described in draw(2), except that they
operate on Memimages rather than Images. Similarly, allocmemsubfont, openmemsubfont,
freememsubfont, memsubfontwidth, getmemdefont, and memimagestring are the Memimage
analogues of allocsubfont, openfont, freesubfont, strsubfontwidth, getdefont, and string (see
subfont(2) and graphics(2)), except that they operate only on Memsubfonts rather than Fonts.
Drawclip takes the images involved in a draw operation, together with the destination rectangle dr
and source and mask alignment points sp and mp, and clips them according to the clipping rect­
angles of the images involved. It also fills in the rectangles sr and mr with rectangles congruent
to the returned destination rectangle but translated so the upper left corners are the returned sp
and mp. Drawclip returns zero when the clipped rectangle is empty. Memlinebbox returns a con­
servative bounding box containing a line between two points with given end styles and radius.
Memlineendsize calculates the extra length added to a line by attaching an end of a given style.
The hwdraw and iprint functions are no-op stubs that may be overridden by clients of the library.
Hwdraw is called at each call to memimagedraw with the current requests 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. Iprint should for­
mat and print its arguments; it is given much debugging output when the global integer variable
drawdebug is non-zero. In the kernel, iprint prints to a serial line rather than the screen, for
obvious reasons.
addpt(2), color(2), draw(2), graphics(2), memlayer(2), stringsize(2), subfont(2), color(6), utf(6)
Memimagestring is unusual in using a subfont rather than a font, and in having no parameter to
align the source.
memdraw, memlalloc, memldelete, memlexpose, memlfree, memlhide, memline, memlnorefresh,
memload, memunload, memlorigin, memlsetrefresh, memltofront, memltofrontn, memltorear,
memltorearn windows of memory-resident images
typedef struct Memscreen Memscreen;
typedef struct Memlayer Memlayer;
typedef void (*Refreshfn)(Memimage*, Rectangle, void*);
struct Memscreen
Memimage *frontmost;
Memimage *rearmost;
Memimage *image;
Memimage *fill;
struct Memlayer
Rectangle screenr;
Memscreen *screen;
Memimage *front;
Memimage *rear;
Memimage *save;
Refreshfn refreshfn; /*
frontmost layer on screen */
rearmost layer on screen */
upon which all layers are drawn */
if non−zero, picture to use when repainting */
true position of layer on screen */
add delta to go from image coords to screen */
screen this layer belongs to */
window in front of this one */
window behind this one*/
layer is fully visible */
save area for obscured parts */
fn to refresh obscured parts if save==nil */
argument to refreshfn */
Memimage* memlalloc(Memscreen *s, Rectangle r, Refreshfn fn, void *arg, ulong c
memlnorefresh(Memimage *i, Rectangle r, void *arg)
memlsetrefresh(Memimage *i, Refreshfn fn, void *arg)
memldelete(Memimage *i)
memlfree(Memimage *i)
memlexpose(Memimage *i, Rectangle r)
memlhide(Memimage *i, Rectangle r)
memltofront(Memimage *i)
memltofrontn(Memimage**ia, int n)
memltorear(Memimage *i)
memltorearn(Memimage **ia , int n)
memlorigin(Memimage *i, Point log, Point phys)
memdraw(Image *dst, Rectangle r,
Image *src, Point sp, Image *mask, Point mp, Drawop op)
memload(Memimage *i, Rectangle r,
uchar *buf, int n, int iscompressed)
memunload(Memimage *i, Rectangle r,
uchar *buf, int n)
These functions build upon the 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 draw(3) and window(2) and probably have little use outside of the kernel.
The basic function is to extend the definition of a Memimage (see memdraw(2)) to include over­
lapping windows defined by the Memlayer type. The first fields of the Memlayer structure are
identical to those in Memimage, permitting a function that expects a Memimage to be passed a
Memlayer, and vice versa. Both structures have a save field, which is nil in a Memimage and
points to backing store in a Memlayer. The layer routines accept Memimages or
Memlayers; if the image is a Memimage the underlying Memimage routine is called; otherwise
the layer routines recursively subdivide the geometry, reducing the operation into a smaller com­
ponent that ultimately can be performed on a Memimage, either the display on which the window
appears, or the backing store.
Memlayers are associated with a Memscreen that holds the data structures to maintain the
windows and connects them to the associated image. The fill color is used to paint the back­
ground when a window is deleted. There is no function to establish a Memscreen; to create one,
allocate the memory, zero frontmost and rearmost, set fill to a valid fill color or image,
and set image to the Memimage (or Memlayer) on which the windows will be displayed.
Memlalloc allocates a Memlayer of size r on Memscreen s. If col is not DNofill, the new win­
dow will be initialized by painting it that color.
The refresh function fn and associated argument 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 arg recorded when the
window was created. A couple of predefined functions provide built-in management methods:
memlnorefresh does no backup at all, useful for making efficient temporary windows; while a nil
function specifies that the backing store ( will be used to keep the obscured
data. Other functions may be provided by the client. Memlsetrefresh allows one to change the
function associated with the window.
Memldelete deletes the window i, restoring the underlying display. Memlfree frees the data struc­
tures without unlinking the window from the associated Memscreen or doing any graphics.
Memlexpose restores rectangle r within the window, using the backing store or appropriate refresh
method. Memlhide goes the other way, backing up r so that that portion of the screen may be
modified without losing the data in this window.
Memltofront pulls i to the front of the stack of windows, making it fully visible. Memltofrontn pulls
the n windows in the array ia to the front as a group, leaving their internal order unaffected.
Memltorear and memltorearn push the windows to the rear.
Memlorigin changes the coordinate systems associated with the window i. The points log and phys
represent the upper left corner (min) of the windows internal coordinate system and its physical
location on the screen. Changing 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 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
memlorigin(i, i−>r.min, i−>r.min)
would be a no-op.
Memdraw and memline are implemented in the layer library but provide the main entry points for
drawing on memory-resident windows. They have the signatures of memimagedraw and
memimageline (see memdraw(2)) but accept Memlayer or Memimage arguments both.
Memload and memunload are similarly layer-savvy versions of loadmemimage and
unloadmemimage. The iscompressed flag to memload specifies whether the n bytes of data in buf
are in compressed image format (see image(6)).
graphics(2), memdraw(2), stringsize(2), window(2), draw(3)
memccpy, memchr, memcmp, memcpy, memmove, memset memory operations
#include <u.h>
#include <libc.h>
void* memccpy(void *s1, void *s2, int c, ulong n)
void* memchr(void *s, int c, ulong n)
memcmp(void *s1, void *s2, ulong n)
void* memcpy(void *s1, void *s2, ulong n)
void* memmove(void *s1, void *s2, ulong n)
void* memset(void *s, int c, ulong n)
These functions operate efficiently on memory areas (arrays of bytes bounded by a count, not ter­
minated by a zero byte). They do not check for the overflow of any receiving memory area.
Memccpy copies bytes from memory area s2 into s1, stopping after the first occurrence of byte c
has been copied, or after n bytes have been copied, whichever comes first. It returns a pointer to
the byte after the copy of c in s1, or zero if c was not found in the first n bytes of s2.
Memchr returns a pointer to the first occurrence of byte c in the first n bytes of memory area s, or
zero if c does not occur.
Memcmp compares its arguments, looking at the first n bytes only, and returns an integer less
than, equal to, or greater than 0, according as s1 is lexicographically less than, equal to, or greater
than s2. The comparison is bytewise unsigned.
Memcpy copies n bytes from memory area s2 to s1. It returns s1.
Memmove works like memcpy, except that it is guaranteed to work if s1 and s2 overlap.
Memset sets the first n bytes in memory area s to the value of byte c. It returns s.
All these routines have portable C implementations in /sys/src/libc/port. Most also have
machine-dependent assembly language implementations in /sys/src/libc/$objtype.
ANSI C does not require memcpy to handle overlapping source and destination; on Plan 9, it does,
so memmove and memcpy behave identically.
If memcpy and memmove are handed a negative count, they abort.
mktemp make a unique file name
#include <u.h>
#include <libc.h>
char* mktemp(char *template)
Mktemp replaces template by a unique file name, and returns the address of the template. The
template should look like a file name with eleven trailing Xs. The Xs are replaced by a letter fol­
lowed by the current process id. Letters from a to z are tried until a name that can be accessed
(see access(2)) is generated. If no such name can be generated, mktemp returns "/" .
getpid(2), access(2)
initmouse, readmouse, closemouse, moveto, getrect, drawgetrect, menuhit, setcursor mouse
*initmouse(char *file, Image *i)
readmouse(Mousectl *mc)
closemouse(Mousectl *mc)
moveto(Mousectl *mc, Point pt)
setcursor(Mousectl *mc, Cursor *c)
Rectangle getrect(int but, Mousectl *mc)
drawgetrect(Rectangle r, int up)
menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr)
These functions access and control a mouse in a multi-threaded environment. They use the
message-passing Channel interface in the threads library (see thread(2)); programs that wish a
more event-driven, single-threaded approach should use event(2).
The state of the mouse is recorded in a structure, Mouse, defined in <mouse.h>:
typedef struct Mouse Mouse;
struct Mouse
/* bit array: LMR=124 */
The Point xy records the position of the cursor, 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 msec, a millisecond time stamp.
The routine initmouse returns a structure through which one may access the mouse:
typedef struct Mousectl Mousectl;
struct Mousectl
/* chan(Mouse)[16] */
*resizec; /* chan(int)[2] */
mouse file */
cursor file */
slave proc */
associated window/display */
The arguments to initmouse are a file naming the device file connected to the mouse and an Image
(see draw(2)) on which the mouse will be visible. Typically the file is nil, which requests the
default /dev/mouse; and the image is the window in which the program is running, held in the
variable screen after a call to initdraw.
Once the Mousectl is set up, mouse motion will be reported by messages of type Mouse sent
on the Channel Mousectl.c. Typically, a message will be sent every time a read of
/dev/mouse succeeds, which is every time the state of the mouse changes.
When the window is resized, a message is sent on Mousectl.resizec. The actual value sent
may be discarded; the receipt of the message tells the program that it should call getwindow
(see graphics(2)) to reconnect to the window.
Readmouse updates the Mouse structure held in the Mousectl, blocking if the state has not
changed since the last readmouse or message sent on the channel. It calls flushimage (see
graphics(2)) before blocking, so any buffered graphics requests are displayed.
Closemouse closes the file descriptors associated with the mouse, kills the slave processes, and
frees the Mousectl structure.
Moveto moves the mouse cursor on the display to the position specified by pt.
Setcursor sets the image of the cursor to that specified by c. If c is nil, the cursor is set to the
default. The format of the cursor data is spelled out in <cursor.h> and described in
Getrect returns the dimensions of a rectangle swept by the user, using the mouse, in the manner
rio(1) or sam(1) uses to create a new window. The but argument specifies which button the user
must press to sweep the window; any other button press cancels the action. The returned rectan­
gle is all zeros if the user cancels.
Getrect uses successive calls to drawgetrect to maintain the red rectangle showing the sweep-inprogress. The rectangle to be drawn is specified by rc and the up parameter says whether to draw
(1) or erase (0) the rectangle.
Menuhit provides a simple menu mechanism. It uses a Menu structure defined in <mouse.h>:
typedef struct Menu Menu;
struct Menu
Menuhit behaves the same as its namesake emenuhit described in event(2), with two exceptions.
First, it uses a Mousectl to access the mouse rather than using the event interface; and second,
it creates the menu as a true window on the Screen scr (see window(2)), permitting the menu to
be displayed in parallel with other activities on the display. If scr is null, menuhit behaves like
emenuhit, creating backing store for the menu, writing the menu directly on the display, and
restoring the display when the menu is removed.
graphics(2), draw(2), event(2), keyboard (2), thread(2).
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
#include <u.h>
#include <libc.h>
#include <mp.h>
mpnew(int n)
mpfree(mpint *b)
mpsetminbits(int n)
mpbits(mpint *b, int n)
mpnorm(mpint *b)
mpcopy(mpint *b)
mpassign(mpint *old, mpint *new)
mprand(int bits, void (*gen)(uchar*, int), mpint *b)
strtomp(char *buf, char **rptr, int base, mpint *b)
mptoa(mpint *b, int base, char *buf, int blen)
betomp(uchar *buf, uint blen, mpint *b)
mptobe(mpint *b, uchar *buf, uint blen, uchar **bufp)
letomp(uchar *buf, uint blen, mpint *b)
mptole(mpint *b, uchar *buf, uint blen, uchar **bufp)
uitomp(uint, mpint*)
itomp(int, mpint*)
vtomp(vlong, mpint*)
uvtomp(uvlong, mpint*)
mpadd(mpint *b1, mpint *b2, mpint *sum)
mpmagadd(mpint *b1, mpint *b2, mpint *sum)
mpsub(mpint *b1, mpint *b2, mpint *diff)
mpmagsub(mpint *b1, mpint *b2, mpint *diff)
mpleft(mpint *b, int shift, mpint *res)
mpright(mpint *b, int shift, mpint *res)
mpmul(mpint *b1, mpint *b2, mpint *prod)
mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
mpmod(mpint *b, mpint *m, mpint *remainder)
mpdiv(mpint *dividend, mpint *divisor,
mpint *remainder)
mpint *quotient,
mpcmp(mpint *b1, mpint *b2)
mpmagcmp(mpint *b1, mpint *b2)
mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x,
mpint *y)
mpinvert(mpint *b, mpint *m, mpint *res)
mpsignif(mpint *b)
mplowbits0(mpint *b)
mpdigdiv(mpdigit *dividend, mpdigit divisor,
mpdigit *quotient)
mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen,
mpdigit *sum)
mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen,
mpdigit *diff)
mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p)
mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen,
mpdigit *p)
mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen)
CRTpre* crtpre(int nfactors, mpint **factors)
CRTres* crtin(CRTpre *crt, mpint *x)
crtout(CRTpre *crt, CRTres *r, mpint *x)
crtprefree(CRTpre *cre)
crtresfree(CRTres *res)
*mpzero, *mpone, *mptwo
These routines perform extended precision integer arithmetic. The basic type is mpint, which
points to an array of mpdigits, stored in little-endian order:
typedef struct mpint
struct mpint
int sign;
int size;
int top;
char flags;
+1 or −1 */
allocated digits */
significant digits */
The sign of 0 is +1.
The size of mpdigit is architecture-dependent and defined in /$cputype/include/u.h.
Mpints are dynamically allocated and must be explicitly freed. Operations grow the array of dig­
its as needed.
In general, the result parameters are last in the argument list.
Routines that return an mpint will allocate the mpint if the result parameter is nil. This
includes strtomp, itomp, uitomp, and btomp. These functions, in addition to mpnew and mpcopy,
will return nil if the allocation fails.
Input and result parameters may point to the same mpint. The routines check and copy where
Mpnew creates an mpint with an initial allocation of n bits. If n is zero, the allocation will be
whatever was specified in the last call to mpsetminbits or to the initial value, 1056. Mpfree frees
an mpint. Mpbits grows the allocation of b to fit at least n bits. If b−>top doesnt cover n bits,
mpbits increases it to do so. Unless you are writing new basic operations, you can restrict yourself
to mpnew(0) and mpfree(b).
Mpnorm normalizes the representation by trimming any high order zero digits. All routines except
mpbits return normalized results.
Mpcopy creates a new mpint with the same value as b while mpassign sets the value of new to be
that of old.
Mprand creates an n bit random number using the generator gen. Gen takes a pointer to a string
of uchars and the number to fill in.
Strtomp and mptoa convert between ASCII and mpint representations using the base indicated.
Only the bases 10, 16, 32, and 64 are supported. Anything else defaults to 16. Strtomp skips any
leading spaces or tabs. Strtomps scan stops when encountering a digit not valid in the base. If
rptr is not zero, *rptr is set to point to the character immediately after the string converted. If the
parse pterminates before any digits are found, strtomp return nil. Mptoa returns a pointer to the
filled buffer. If the parameter buf is nil, the buffer is allocated. Mpfmt can be used with
fmtinstall(2) and print(2) to print hexadecimal representations of mpints. The conventional verb
is B, for which mp.h provides a pragma.
Mptobe and mptole convert an mpint to a byte array. The former creates a big endian representa­
tion, the latter a little endian one. If the destination buf is not nil, it specifies the buffer of length
blen for the result. If the representation is less than blen bytes, the rest of the buffer is zero filled.
If buf is nil, then a buffer is allocated and a pointer to it is deposited in the location pointed to by
bufp. Sign is ignored in these conversions, i.e., the byte array version is always positive.
Betomp, and letomp convert from a big or little endian byte array at buf of length blen to an mpint.
If b is not nil, it refers to a preallocated mpint for the result. If b is nil, a new integer is allocated
and returned as the result.
The integer conversions are:
mpint->unsigned int
unsigned int->mpint
mpint->unsigned vlong
unsigned vlong->mpint
When converting to the base integer types, if the integer is too large, the largest integer of the
appropriate sign and size is returned.
The mathematical functions are:
sum = b1 + b2.
sum = abs(b1) + abs(b2).
diff = b1 − b2.
diff = abs(b1) − abs(b2).
res = b<<shift.
res = b>>shift.
prod = b1*b2.
if m is nil, res = b**e. Otherwise, res = b**e mod m.
remainder = b % m.
dividend/divisor. remainder
returns -1, 0, or +1 as b1 is less than, equal to, or greater than b2.
the same as mpcmp but ignores the sign and just compares magnitudes.
Mpextendedgcd computes the greatest common denominator, d, of a and b. It also computes x
and y such that a*x + b*y = d. Both a and b are required to be positive. If called with nega­
tive arguments, it will return a gcd of 0.
Mpinverse computes the multiplicative inverse of b mod m.
Mpsignif returns the number of significant bits in b. Mplowbits0 returns the number of consecutive
zero bits at the low end of the significant bits. For example, for 0x14, mpsignif returns 5 and
mplowbits0 returns 2. For 0, mpsignif and mplowbits0 both return 0.
The remaining routines all work on arrays of mpdigit rather than mpints. 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.
quotient = dividend[0:1] / divisor.
sum[0:alen] = a[0:alen−1] + b[0:blen−1]. We assume
alen >= blen and that sum has room for alen+1 digits.
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.
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 dig­
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.
p[0:alen*blen] = a[0:alen−1] * b[0:blen−1]. We assume
that p has room for alen*blen+1 digits.
This returns -1, 0, or +1 as a - b is negative, 0, or positive.
mptwo, mpone and mpzero are the constants 2, 1 and 0. These cannot be freed.
Chinese remainder theorem
When computing in a non-prime modulus, n, it is possible to perform the computations on the
residues modulo the prime factors of n instead. Since these numbers are smaller, multiplication
and exponentiation can be much faster.
Crtin computes the residues of x and returns them in a newly allocated structure:
typedef struct CRTres
int n;
/* number of residues */
/* residues */
Crtout takes a residue representation of a number and converts it back into the number. It also
frees the residue structure.
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.
Crtprefree and crtresfree free CRTpre and CRTres structures respectively.
muldiv, umuldiv high-precision multiplication and division
#include <u.h>
#include <libc.h>
long muldiv(long a, long b, long c)
ulong umuldiv(ulong a, ulong b, ulong c)
Muldiv returns a*b/c, using a vlong to hold the intermediate result. Umuldiv is the equivalent
for unsigned integers. They can be used to scale integer values without worry about overflowing
the intermediate result.
On some architectures, these routines can generate a trap if the final result does not fit in a long
or ulong; on others they will silently truncate.
NaN, Inf, isNaN, isInf not-a-number and infinity functions
#include <u.h>
#include <libc.h>
double NaN(void)
double Inf(int)
isInf(double, int)
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 setfcr (see getfcr(2)) can change that behavior.
NaN returns a double that is not-a-number. IsNaN returns true if its argument is not-a-number.
Inf(i) returns positive infinity if i is greater than or equal to zero, else negative infinity. IsInf
returns true if its first argument is infinity with the same sign as the second argument.
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
ndbopen(char *file)
ndbcat(Ndb *db1, Ndb *db2)
ndbchanged(Ndb *db)
ndbreopen(Ndb *db)
ndbclose(Ndb *db)
ndbsearch(Ndb *db, Ndbs *s, char *attr, char *val)
ndbsnext(Ndbs *s, char *attr, char *val)
ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char *val,
char *rattr, Ndbtuple **tp)
char *rattr, Ndbtuple **tp)
ipattr(char *name)
ndbgetipaddr(Ndb *db, char *sys);
ndbipinfo(Ndb *db, char *attr, char *val, char **attrs,
int nattr)
csipinfo(char *netroot, char *attr, char *val,
char **attrs, int nattr)
ndbhash(char *val, int hlen)
ndbparse(Ndb *db)
dnsquery(char *netroot, char *domainname, char *type)
ndbfindattr(Ndbtuple *entry, Ndbtuple *line, char *attr)
ndbfree(Ndbtuple *db)
ndbconcatenate(Ndbtuple *a, Ndbtuple *b)
ndbreorder(Ndbtuple *t, Ndbtuple *a)
ndbsubstitute(Ndbtuple *t, Ndbtuple *from, Ndbtuple *to)
ndbsetmalloctag(Ndbtuple *t, uintptr tag)
*t, Ndbtuple *a)
These routines are used by network administrative programs to search the network database.
They operate on the database files described in ndb(6).
Ndbopen opens the database file and calls malloc(2) to allocate a buffer for it. If file is zero, all
network database files are opened.
Ndbcat concatenates two open databases. Either argument may be nil.
Ndbreopen throws out any cached information for the database files associated with db and
reopens the files.
Ndbclose closes any database files associated with db and frees all storage associated with them.
Ndbsearch and ndbsnext search a database for an entry containing the attribute/value pair,
attr=val. Ndbsearch is used to find the first match and ndbsnext is used to find each successive
match. On a successful search both return a linked list of Ndbtuple structures acquired by
malloc(2) that represent the attribute/value pairs in the entry. On failure they return zero.
typedef struct Ndbtuple Ndbtuple;
struct Ndbtuple {
Ndbtuple *entry;
Ndbtuple *line;
/* for the application; starts 0 */
valbuf[Ndbvlen]; /* initial allocation for val */
The entry pointers chain together all pairs in the entry in a null-terminated list. The 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.
The argument s of ndbsearch has type Ndbs and should be pointed to valid storage before calling
ndbsearch, which will fill it with information used by ndbsnext to link successive searches. The
structure Ndbs looks like:
typedef struct Ndbs Ndbs;
struct Ndbs {
/* data base file being searched */
Ndbtuple *t;
/* last attribute value pair found */
The t field points to the pair within the entry matched by the ndbsearch or ndbsnext.
Ndbgetvalue searches the database for an entry containing not only an attribute/value pair,
attr=val, but also a pair with the attribute rattr. If successful, it returns a malloced copy of the
NUL-terminated value associated with rattr. If tp is non nil, *tp will point to the entry. Otherwise
the entry will be freed.
Csgetvalue is like 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
Ndbfree frees a list of tuples returned by one of the other routines.
Ipattr takes the name of an IP system and returns the attribute it corresponds to:
domain name
Internet number
system name
Ndbgetipaddr looks in db for an entry matching sys as the value of a sys= or dom=
attribute/value pair and returns all IP addresses in the entry. If sys is already an IP address, a tuple
containing just that address is returned.
Ndbipinfo looks up Internet protocol information about a system. This is an IP aware search. It
looks first for information in the systems 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,
attr=val. Ndbipinfo returns a list of tuples whose attributes match the attributes in the n element
array attrs. If any attrs begin with @, the @ 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.
ipnet=big ip=
ipnet=dept ip= ipmask=
ndbipinfo(db, "dom", "", ["bootf" "smtp" "dns"], 3)
will return the tuples bootf=/386/9pc,, and
Csipinfo is to ndbipinfo as csgetval is to ndbgetval.
The next three routines are used by programs that create the hash tables and database files.
Ndbhash computes a hash offset into a table of length hlen for the string val. Ndbparse reads and
parses the next entry from the database file. Multiple calls to ndbparse parse sequential entries in
the database file. A zero is returned at end of file.
Dnsquery submits a query about domainname to the ndb/dns mounted at netroot/dns. It
returns a linked list of Ndbtuple’s representing a single database entry. The tuples are logically
arranged into lines using the line field in the structure. The possible types of query are and the
attributes on each returned tuple line is:
find the IP addresses. Returns domain name (dom) and ip address (ip)
look up the mail exchangers. Returns preference (pref) and exchanger (mx)
do a reverse query. Here domainname must be an ASCII IP address. Returns reverse name
(ptr) and domain name (dom)
get the system that this name is a nickname for. Returns the nickname (dom) and the real
name (cname)
return the start of area record for this field. Returns area name (dom), primary name
server (ns), serial number (serial), refresh time in seconds (refresh), retry time in seconds
(retry), expiration time in seconds (expire), and minimum time to lie (ttl).
name servers. Returns domain name (dom) and name server (ns)
Ndbfindattr searches entry for the tuple with attribute attr and returns a pointer to the tuple. If
line points to a particular line in the entry, the search starts there and then wraps around to the
beginning of the entry.
All of the routines provided to search the database provide an always consistent view of the rele­
vant files. However, it may be advantageous for an application to read in the whole database using
ndbopen and ndbparse and provide its own search routines. The 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.
Finally, a number of routines are provided for manipulating tuples.
Ndbdiscard removes attr/val pair a from tuple t and frees it. If a isnt in t it is just freed.
Ndbconcatenate concatenates two tuples and returns the result. Either or both tuples may be nil.
Ndbreorder reorders a tuple t to make the line containing attr/val pair a first in the entry and mak­
ing a first in its line.
Ndbsubstitute replaces a single att/val pair from in t with the tuple to. All attr/val pairs in to end
up on the same line. from is freed.
Ndbsetmalloctag sets the malloc tag (see setmalloctag in malloc(2)) of each tuple in the list t to
directory of network database files
ndb(6), ndb(8)
Ndbgetvalue , csgetvalue, and ndblookvalue set errstr to buffer too short if the buffer pro­
vided isnt long enough for the returned value.
Ndbgetval, csgetval, and ndblookval are deprecated versions of ndbgetvalue, csgetvalue, and
ndblookvalue . They expect a fixed 64 byte long result buffer and existed when the values of a
Ndbtuple structure were fixed length.
notify, noted, atnotify handle asynchronous process notification
#include <u.h>
#include <libc.h>
int notify(void (*f)(void*, char*))
int noted(int v)
int atnotify(int (*f)(void*, char*), int in)
When a process raises an exceptional condition such as dividing by zero or writing on a closed
pipe, a note is posted to communicate the exception. A note may also be posted by a write (see
read(2)) to the processs /proc/n/note file or to the /proc/m/notepg file of a process in
the same process group (see 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 "suicide: ", is printed on the processs standard error file and
the process is suspended in the Broken state for debugging.
These default actions may be overridden. The notify function registers a notification handler to be
called within the process when a note is received. The argument to notify replaces the previous
handler, if any. An argument of zero cancels a previous handler, restoring the default action. A
fork(2) system call leaves the handler registered in both the parent and the child; exec(2) restores
the default behavior. Handlers may not perform floating point operations.
After a note is posted, the handler is called with two arguments: the first is a pointer to a Ureg
structure (defined in /$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 ERRLEN charac­
ters in it including the terminal NUL. The 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
A notification handler must finish either by exiting the program or by calling noted; if the handler
returns the behavior is undefined and probably erroneous. Until the program calls noted, any fur­
ther externally-generated notes (e.g., hangup or 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 noted defines the action to take: NDFLT instructs the system to perform the
default action as if the handler had never been registered; NCONT instructs the system to resume
the process at the point it was notified. In neither case does noted return to the handler. If the
note interrupted an incomplete system call, that call returns an error (with error string
interrupted) after the process resumes. A notification handler can also jump out to an envi­
ronment set up with setjmp using the notejmp function (see setjmp(2)), which is implemented by
modifying the saved state and calling noted(NCONT).
Regardless of the origin of the note or the presence of a handler, if the process is being debugged
(see proc(3)) the arrival of a note puts the process in the Stopped state and awakens the debug­
Rather than using the system calls notify and noted, most programs should use atnotify to register
notification handlers. The parameter in is non-zero to register the function 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 regis­
tered with atnotify is called with arguments as described above until one of the handlers returns
non-zero. Then noted is called with argument NCONT. If no registered function returns non-zero,
atnotify calls noted with argument NDFLT.
Noted has two other possible values for its argument. 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 Ureg structure. Typically, the program counter will be
overridden by the first note handler to be the address of a separate function; NSAVE is then a
trampoline to that handler. That handler may executed noted(NRSTR) to return to the origi­
nal program, usually after restoring the original program counter. NRSTR is identical to NCONT
except that it can only be executed after an NSAVE. NSAVE and NRSTR are designed to improve
the emulation of signals by the ANSI C/POSIX environment; their use elsewhere is discouraged.
The set of notes a process may receive is system-dependent, but there is a common set that
sys: breakpoint
sys: bad address
sys: odd address
sys: bad sys call
sys: odd stack
sys: write on closed pipe
sys: fp: fptrap
sys: trap: trap
user interrupt (DEL key)
I/O connection closed
alarm expired
breakpoint instruction
system call address argument out of range
system call address argument unaligned
system call number out of range
system call user stack unaligned
write on closed pipe
floating point exception
other exception (see below)
The notes prefixed sys: are generated by the operating system. They are suffixed by the user
program counter in format pc=0x1234. If the note is due to a floating point exception, just
before the pc is the address of the offending instruction in format fppc=0x1234. Notes are
limited to ERRLEN bytes; if they would be longer they are truncated but the pc is always reported
The types and syntax of the trap and fptrap portions of the notes are machine-dependent.
intro(2), notejmp in setjmp(2)
Since exec(2) discards the notification handler, there is a window of vulnerability to notes in a new
objtype, readobj, objtraverse, isar, nextar, readar object file interpretation functions
objtype(Biobuf *bp, char **name)
readobj(Biobuf *bp, int objtype)
objtraverse(void(*)(Sym*, void*), void*)
int isar(Biobuf *bp)
int nextar(Biobuf *bp, int offset, char *buf)
int readar(Biobuf *bp, int objtype, int end)
These functions provide machine-independent access to object files in a directory or an archive.
Mach(2) and symbol(2) describe additional library functions for interpreting executable files and
executing images.
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 symbol(2)
and a.out(6): a vector of Sym data structures defining the name, type and relative offset of each
Objtype reads the header at the current position of the file associated with bp (see 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.
Readobj constructs a symbol table for the object file associated with bp. The second argument
contains the type code produced by function objtype. The file must be positioned at the start of
the object file. Each invocation of readobj destroys the symbol definitions for any previous file.
Objtraverse scans the symbol table previously built by readobj or readar. 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 Sym data structure as
the first argument and the generic pointer as the second.
Isar reads the header at the current point in the file associated with 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 begin­
ning of the first member of the archive.
Nextar extracts information describing the archive member stored at offset in the file associated
with bp. If the header describing the member can be extracted and decoded, the size of the mem­
ber is returned. Adding this value to 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 buf, a buffer of SARNAME characters. If there are no more mem­
bers, nextar returns zero; a negative return indicates a missing or malformed header.
Readar constructs the symbol table of the object file stored at the current position in the archive
associated with bp. This function operates exactly as readobj ; the only difference is the extra argu­
ment, end, specifying the offset to the beginning of the next member in the archive. Readar
leaves the file positioned at that point.
mach(2), symbol(2), bio(2), a.out(6)
These routines set errstr.
open, create, close open a file for reading or writing, create file
#include <u.h>
#include <libc.h>
int open(char *file, int omode)
int create(char *file, int omode, ulong perm)
int close(int fd)
Open opens the file for I/O and returns an associated file descriptor. Omode is one of OREAD,
OWRITE, ORDWR, or 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 omode: OTRUNC says to
truncate the file to zero length before opening it; OCEXEC says to close the file when an exec(2) or
execl system call is made; and ORCLOSE says to remove the file when it is closed (by everyone
who has a copy of the file descriptor). Open fails if the file does not exist or the user does not
have permission to open it for the requested purpose (see stat(2) for a description of permissions).
The user must have write permission on the file if the OTRUNC bit is set. For the open system call
(unlike the implicit open in exec(2)), OEXEC is actually identical to OREAD.
Create creates a new file or prepares to rewrite an existing file, opens it according to omode (as
described for 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 permis­
sions to 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 DMDIR bit is set in perm, an exclusive-use file if the DMEXCL bit is set,
and an append-only file if the 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 open(5).
Create fails if the path up to the last element of file cannot be evaluated, if the user doesnt have
write permission in the final directory, if the file already exists and does not permit the access
defined by 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 intro(2)) then the constituent directory where the file is created depends on
the structure of the union: see bind(2).
Since create may succeed even if the file exists, a special mechanism is necessary for those appli­
cations that require an atomic create operation. If the OEXCL (0x1000) bit is set in the mode for
a create, the call succeeds only if the file does not already exist; see open(5) for details.
Close closes the file associated with a file descriptor. Provided the file descriptor is a valid open
descriptor, close is guaranteed to close it; there will be no error. Files are closed automatically
upon termination of a process; close allows the file descriptor to be reused.
intro(2), bind(2), stat(2)
These functions set errstr.
perror, syslog, sysfatal system error messages
#include <u.h>
#include <libc.h>
void perror(char *s)
void syslog(int cons, char *logname, char *fmt, ...)
void sysfatal(char *fmt, ...)
Perror produces a short error message on the standard error file describing the last error encoun­
tered during a call to the system. First the argument string s is printed, then a colon, then the
message and a newline. If s is nil, only the error message and newline are printed.
Syslog logs messages in the file named by logname in the directory /sys/log; the file must
already exist and should be append-only. 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 mes­
sage specified by the print(2) format fmt and any following arguments; and a final newline. If cons
is set or the log file cannot be opened, the message is also printed on the system console. Syslog
can be used safely in multi-threaded programs.
Sysfatal prints to standard error the name of the running program, a colon and a space, the mes­
sage described by the print(2) format string fmt and subsequent arguments, and a newline. It
then calls exits(2) with the formatted message as argument. The programs name is the value of
argv0, which will be set if the program uses the arg(2) interface to process its arguments. If
argv0 is null, it is ignored and the following colon and space are suppressed.
intro(2), errstr(2), the %r format in print(2)
Perror is a holdover; the %r format in print(2) is preferred.
pipe create an interprocess channel
#include <u.h>
#include <libc.h>
int pipe(int fd[2])
Pipe creates a buffered channel for interprocess I/O communication. Two file descriptors are
returned in fd. Data written to fd[1] is available for reading from fd[0] and data written to
fd[0] is available for reading from fd[1].
After the pipe has been established, cooperating processes created by subsequent fork(2) calls
may pass data through the pipe with read and write calls. The bytes placed on a pipe by one write
are contiguous even if many processes are writing. Write boundaries are preserved: each read ter­
minates when the read buffer is full or after reading the last byte of a write, whichever comes first.
The number of bytes available to a read(2) is reported in the Length field returned by fstat or
dirfstat on a pipe (see stat(2)).
When all the data has been read from a pipe and the writer has closed the pipe or exited, read(2)
will return 0 bytes. Writes to a pipe with no reader will generate a note sys: write on
closed pipe.
intro(2), read(2), pipe(3)
Sets errstr.
If a read or a write of a pipe is interrupted, some unknown number of bytes may have been trans­
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.
eplumb, plumbfree, plumbopen, plumbsend, plumbsendtext, plumblookup, plumbpack, plumb­
packattr, plumbaddattr, plumbdelattr, plumbrecv, plumbunpack, plumbunpackpartial, plumbun­
packattr, Plumbmsg plumb messages
#include <u.h>
#include <libc.h>
#include <plumb.h>
plumbopen(char *port, int omode)
plumbsend(int fd, Plumbmsg *m)
plumbsendtext(int fd, char *src, char *dst, char *wdir,
char *data)
plumbfree(Plumbmsg *m)
plumbrecv(int fd)
plumbpack(Plumbmsg *m, int *np)
plumbunpack(char *buf, int n)
plumbunpackpartial(char *buf, int n, int *morep)
plumbpackattr(Plumbattr *a)
Plumbattr* plumbunpackattr(char *a)
plumblookup(Plumbattr *a, char *name)
Plumbattr* plumbaddattr(Plumbattr *a, Plumbattr *new)
Plumbattr* plumbdelattr(Plumbattra *a, char *name)
eplumb(int key, char *port)
These routines manipulate plumb(6) messages, transmitting them, receiving them, and converting
them between text and these data structures:
struct Plumbmsg
Plumbattr *attr;
} Plumbmsg;
struct Plumbattr
Plumbattr *next;
} Plumbattr;
Plumbopen opens the named plumb port, using open(2) mode omode. If port begins with a slash,
it is taken as a literal file name; otherwise plumbopen searches for the location of the plumber(4)
service and opens the port there.
For programs using the event(2) interface, eplumb registers, using the given key, receipt of mes­
sages from the named port.
Plumbsend formats and writes message m to the file descriptor fd, which will usually be the result
of plumbopen("send", OWRITE). Plumbsendtext is a simplified version for text-only mes­
sages; it assumes type is text, sets attr to nil, and sets ndata to strlen(data).
Plumbfree frees all the data associated with the message m, all the components of which must
therefore have been allocated with malloc(2).
Plumbrecv returns the next message available on the file descriptor fd, or nil for error.
Plumbpack encodes message m as a character string in the format of plumb(6), setting *np to the
length in bytes of the string. Plumbunpack does the inverse, translating the n bytes of buf into a
Plumbunpackpartial enables unpacking of messages that arrive in pieces. The first call to
plumbunpackpartial for a given message must be sufficient to unpack the header; subsequent
calls permit unpacking messages with long data sections. For each call, buf points to the begin­
ning of the complete message received so far, and n reports the total number of bytes received for
that message. If the message is complete, the return value will be as in plumbunpack. If not, and
morep is not null, the return value will be nil and *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 buf+n, and the message unpacked
again. If an error is encountered, the return value will be nil and *morep will be zero.
Plumbpackattr converts the list a of 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. Plumbunpackattr converts the nullterminated string a back into a list of Plumbattr structures.
Plumblookup searches the Plumbattr list a for an attribute with the given 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.
Plumbaddattr appends the new Plumbattr (which may be a list) to the attribute list a and
returns the new list. Plumbattr searches the list a for the first attribute with name name and
deletes it from the list, returning the resulting list. Plumbdelattr is a no-op if no such attribute
plumb(1), event(2), plumber(4), plumb(6)
When appropriate, including when a plumbsend fails, these routine set errstr.
poolalloc, poolallocalign, poolfree, poolmsize, poolrealloc, poolcompact, poolcheck, pool­
blockcheck, pooldump general memory management routines
#include <u.h>
#include <libc.h>
#include <pool.h>
poolalloc(Pool* pool, ulong size)
poolallocalign(Pool *pool, ulong size,
ulong align, long offset, ulong span)
void poolfree(Pool* pool, void* ptr)
poolmsize(Pool* pool, void* ptr)
poolrealloc(Pool* pool, void* ptr, ulong size)
void poolcompact(Pool* pool)
void poolcheck(Pool *pool)
void poolblockcheck(Pool *pool, void *ptr)
void pooldump(Pool *pool);
These routines provide a general memory management facility. Memory is retrieved from a
coarser allocator (e.g. sbrk or the kernels xalloc) and then allocated to callers. The routines are
locked and thus may safely be used in multiprocess programs.
Poolalloc attempts to allocate a block of size size; it returns a pointer to the block when success­
ful and nil otherwise. The call poolalloc(0) returns a non-nil pointer. 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 poolalloc. The call poolfree(nil) is legal and is a no-op.
Poolallocalign attempts to allocate a block of size size with the given alignment constraints. If
align is non-zero, the returned pointer is aligned to be equal to offset modulo align. If span is
non-zero, the n byte block allocated will not span a span-byte boundary.
Poolrealloc attempts to resize to nsize bytes the block associated with ptr, which must have
been previously returned by poolalloc or poolrealloc. If the blocks 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 poolrealloc, the return value should be used rather
than ptr to access the block. If the request cannot be satisfied, poolrealloc returns nil, and the
old pointer remains valid.
When blocks are allocated, there is often some extra space left at the end that would usually go
unused. Poolmsize grows the block to encompass this extra space and returns the new size.
The poolblockcheck and poolcheck routines validate a single allocated block or the entire pool,
respectively. They call panic (see below) if corruption is detected. Pooldump prints a summary
line for every block in the pool, using the print function (see below).
The Pool structure itself provides much of the setup interface.
typedef struct Pool Pool;
struct Pool {
char* name;
ulong maxsize;
ulong cursize;
ulong curfree;
ulong curalloc;
ulong minarena;
ulong quantum;
ulong minblock;
of entire Pool */
of Pool */
total free bytes in Pool */
total allocated bytes in Pool */
smallest size of new arena */
allocated blocks should be multiple of */
smallest newly allocated block */
/* number of calls to free */
lastcompact; /* nfree at time of last poolcompact */
(*merge)(void*, void*);
(*move)(void* from, void* to);
(*print)(Pool*, char*, ...);
(*panic)(Pool*, char*, ...);
enum { /* flags */
The pool obtains arenas of memory to manage by calling the the given alloc routine. The total
number of requested bytes will not exceed maxsize. Each allocation request will be for at least
minarena bytes.
When a new arena is allocated, the pool routines try to merge it with the surrounding arenas, in an
attempt to combat fragmentation. If merge is non-nil, it is called with the addresses of two
blocks from alloc that the pool routines suspect might be adjacent. If they are not mergeable,
merge must return zero. If they are mergeable, merge should merge them into one block in its
own bookkeeping and return non-zero.
To ease fragmentation and make block reuse easier, the sizes requested of the pool routines are
rounded up to a multiple of quantum before the carrying out requests. If, after rounding, the
block size is still less than minblock bytes, minblock will be used as the block size.
Poolcompact defragments the pool, moving blocks in order to aggregate the free space. Each time
it moves a block, it notifies the move routine that the contents have moved. At the time that
move is called, the contents have already moved, so from should never be dereferenced. If no
move routine is supplied (i.e. it is nil), then calling poolcompact is a no-op.
When the pool routines need to allocate a new arena but cannot, either because alloc has
returned nil or because doing so would use more than maxsize bytes, poolcompact is called once
to defragment the memory and the request is retried.
Pools are protected by the pool routines calling lock (when non-nil) before modifying the pool,
and calling unlock when finished.
When internal corruption is detected, panic is called with a print(2) style argument that specifies
what happened. It is assumed that panic never returns. When the pool routines wish to convey
a message to the caller (usually because logging is turned on; see below), print is called, also
with a print(2) style argument.
Flags is a bit vector that tweaks the behavior of the pool routines in various ways. Most are use­
ful for debugging in one way or another. When POOL_ANTAGONISM is set, poolalloc fills blocks
with non-zero garbage before releasing them to the user, and 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-ored 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 0xF7000000, newly allocated blocks
0xF9000000, and newly created unallocated blocks 0xF1000000. For example, if
POOL_ANTAGONISM is set and poolalloc returns a block starting at 0x00012345, each word of
the block will contain the value 0xF90012345. Recognizing these numbers in memory-related
crashes can help diagnose things like double-frees or dangling pointers.
Setting POOL_PARANOIA causes the allocator to walk the entire pool whenever locking or unlock­
ing itself, looking for corruption. This slows runtime by a few orders of magnitude when many
blocks are in use. If POOL_VERBOSITY is set, the entire pool structure is printed (via print)
each time the pool is locked or unlocked. POOL_DEBUGGING enables internal debugging output,
whose format is unspecified and volatile. It should not be used by most programs. When
POOL_LOGGING is set, a single line is printed via print at the beginning and end of each pool
call. If logstack is not nil, it will be called as well. This provides a mechanism for external pro­
grams to search for leaks. (See leak(1) for one such program.)
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 poolrealloc or free (or at the next entry into the allocator, when POOL_PARANOIA is set), and
panic will be called. Since forgetting to allocate space for the terminating NUL on strings is such
a common error, if POOL_TOLERANCE is set and a single NUL is found written past the end of a
block, print will be called with a notification, but panic will not be.
When POOL_NOREUSE is set, poolfree fills the passed block with garbage rather than return it
to the free pool.
malloc(2), brk(2)
/sys/src/libc/port/malloc.c is a complete example.
postnote send a note to a process or process group
#include <u.h>
#include <libc.h>
postnote(int who, int pid, char *note)
Postnote sends a note to a process or process group. If who is PNPROC, then note is written to
/proc/pid/note. If who is PNGROUP, the note is delivered to the process group by writing
note to /proc/pid/notepg. For PNGROUP only, if the calling process is in the target group,
the note is not delivered to that process.
If the write is successful, zero is returned. Otherwise 1 is returned.
notify(2), intro(2), proc(3)
Sets errstr.
genprime, gensafeprime, genstrongprime, DSAprimes, probably_prime, smallprimetest prime
number generation
smallprimetest(mpint *p)
probably_prime(mpint *p, int nrep)
void genprime(mpint *p, int n, int nrep)
void gensafeprime(mpint *p, mpint *alpha, int n, int accuracy)
void genstrongprime(mpint *p, int n, int nrep)
void DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen])
Public key algorithms abound in prime numbers. The following routines generate primes or test
numbers for primality.
Smallprimetest checks for divisibility by the first 10000 primes. It returns 0 if p is not divisible by
the primes and 1 if it is.
Probably_prime uses the Miller-Rabin test to test p. It returns non-zero if P is probably prime.
The probability of it not being prime is 1/4**nrep.
Genprime generates a random n bit prime. Since it uses the Miller-Rabin test, nrep is the repeti­
tion count passed to probably_prime . Gensafegprime generates an n-bit prime p and a generator
alpha of the multiplicative group of integers mod p; there is a prime q such that p−1=2*q.
Genstrongprime generates a prime, p, with the following properties:
(p-1)/2 is prime. Therefore p-1 has a large prime factor, p.
p-1 has a large prime factor
p+1 has a large prime factor
DSAprimes generates two primes, q and p, using the NIST recommended algorithm for DSA
primes. q divides p-1. The random seed used is also returned, so that skeptics can later confirm
the computation. Be patient; this is a slow algorithm.
aes(2) blowfish(2), des(2), elgamal(2), rsa(2)
print, fprint, sprint, snprint, seprint, smprint, runesprint, runesnprint, runeseprint, runesmprint,
vfprint, vsnprint, vseprint, vsmprint, runevsnprint, runevseprint, runevsmprint print formatted
#include <u.h>
#include <libc.h>
print(char *format, ...)
fprint(int fd, char *format, ...)
sprint(char *s, char *format, ...)
snprint(char *s, int len, char *format, ...)
char* seprint(char *s, char *e, char *format, ...)
char* smprint(char *format, ...)
runesprint(Rune *s, char *format, ...)
runesnprint(Rune *s, int len, char *format, ...)
Rune* runeseprint(Rune *s, Rune *e, char *format, ...)
Rune* runesmprint(char *format, ...)
vfprint(int fd, char *format, va_list v)
vsnprint(char *s, int len, char *format, va_list v)
char* vseprint(char *s, char *e, char *format, va_list v)
char* vsmprint(char *format, va_list v)
runevsnprint(Rune *s, int len, char *format, va_list v)
Rune* runevseprint(Rune *s, Rune *e, char *format, va_list v)
Rune* runevsmprint(Rune *format, va_list v)
Print writes text to the standard output. Fprint writes to the named output file descriptor; a buf­
fered form is described in bio(2). Sprint places text followed by the NUL character (\0) in consecu­
tive bytes starting at s; it is the users responsibility to ensure that enough storage is available.
Each function returns the number of bytes transmitted (not including the NUL in the case of
sprint), or a negative value if an output error was encountered.
Snprint is like sprint, but will not place more than len bytes in s. Its result is always NULterminated and holds the maximal number of complete UTF-8 characters that can fit. Seprint is
like snprint, except that the end is indicated by a pointer e rather than a count and the return
value points to the terminating NUL of the resulting string. Smprint is like sprint, except that it
prints into and returns a string of the required length, which is allocated by malloc(2).
The routines runesprint, runesnprint, runeseprint, and runesmprint are the same as sprint,
snprint, seprint and smprint except that their output is rune strings instead of byte strings.
Finally, the routines vfprint, vsnprint, vseprint, vsmprint, runevsnprint, runevseprint, and
runevsmprint are like their v−less relatives except they take as arguments a va_list parame­
ter, so they can be called within a variadic function. The Example section shows a representative
Each of these functions converts, formats, and prints its trailing arguments under control of a
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
Each conversion specification has the following format:
% [flags] verb
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 width, the second precision. A period can be
used to separate them, and if the period is present then width and precision are taken to be zero if
missing, otherwise they are omitted. Either or both of the numbers may be replaced with the
character *, meaning that the actual number will be obtained from the argument list as an integer.
The flags and numbers are arguments to the verb described below.
The numeric verbs d, o, b, x, and X format their arguments in decimal, octal, binary, hexadecimal,
and upper case hexadecimal. Each interprets the flags 0, h, hh, l, u, +, −, ,, and # to mean pad
with zeros, short, byte, long, unsigned, always print a sign, left justified, commas every three dig­
its, and alternate format. Also, a space character in the flag position is like +, but prints a space
instead of a plus sign for non-negative values. If neither short nor long is specified, then the argu­
ment is an int. If unsigned is specified, then the argument is interpreted as a positive number
and no sign is output. If two l flags are given, then the argument is interpreted as a vlong (usu­
ally an 8-byte, sometimes a 4-byte integer). If precision is not omitted, the number is padded on
the left with zeros until at least precision digits appear. Then, if alternate format is specified, for o
conversion, the number is preceded by a 0 if it doesnt already begin with one; for x conversion,
the number is preceded by 0x; for X conversion, the number is preceded by 0X. Finally, if 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 width characters long.
The floating point verbs f, e, E, g, and G take a double argument. Each interprets the flags +,
−, and # to mean always print a sign, left justified, and alternate format. Width is the minimum
field width and, if the converted value takes up less than width characters, it is padded on the left
(or right, if left justified) with spaces. Precision is the number of digits that are converted after
the decimal place for e, E, and f conversions, and precision is the maximum number of significant
digits for g and G conversions. The f verb produces output of the form [−]digits[.digits].
E conversion appends an exponent E[−]digits, and e conversion appends an exponent
e[−]digits. The g verb will output the argument in either e or 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 G verb is similar, but uses E format
instead of e. When alternate format is specified, the result will always contain a decimal point, and
for g and G conversions, trailing zeros are not removed.
The s verb copies a nul-terminated string (pointer to char) to the output. The number of charac­
ters copied (n) is the minimum of the size of the string and precision. These n characters are justi­
fied within a field of width characters as described above. If a precision is given, it is safe for the
string not to be nul-terminated as long as it is at least precision characters (not bytes!) long. The
S verb is similar, but it interprets its pointer as an array of runes (see utf(6)); the runes are con­
verted to UTF before output.
The c verb copies a single char (promoted to int) justified within a field of width characters as
described above. The C verb is similar, but works on runes.
The p verb formats a single pointer or pointer-sized integer (uintptr, see intro(2)) in hexadeci­
The r verb takes no arguments; it copies the error string returned by a call to errstr(2).
Custom verbs may be installed using fmtinstall(2).
This function prints an error message with a variable number of arguments and then quits.
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);
write(2, buf, out−buf);
exits("fatal error");
fmtinstall(2), fprintf(2), utf(6), errstr(2)
Routines that write to a file descriptor or call malloc set errstr.
The formatting is close to that specified for ANSI fprintf(2); the main difference is that b is not in
ANSI and u is a flag here instead of a verb. Also, and distinctly not a bug, print and friends gener­
ate UTF rather than ASCII.
There is no runeprint, runefprint, etc. because runes are byte-order dependent and
should not be written directly to a file; use the UTF output of print or fprint instead. Also, sprint is
deprecated for safety reasons; use snprint, seprint, or smprint instead. Safety also precludes the
existence of runesprint.
privalloc, privfree per-process private storage management
#include <u.h>
#include <libc.h>
void** privalloc(void)
privfree(void **p)
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 nil if there are no free
slots available.
Privfree releases a location allocated with privalloc. It is legal to call privfree with p set to nil.
prof - accumulate histogram of process execution
#include <u.h>
#include <libc.h>
void prof(void (*fn)(void*), void *arg, int entries, int what);
Prof arranges to accumulate entries of what data into a histogram by sampling from clock inter­
rupts and recording PCs, calls fn(arg), and finally dumps the accumulated profile. Possible val­
ues of what are:
No profiling.
Measure user time only.
Measure user + kernel time.
Measure total time.
Use clock interrupt to sample.
histogram for pid.
prof(1), exec(2)
rdproto parse and process a proto file listing
#include <u.h>
#include <libc.h>
#include <disk.h>
typedef void Protoenum(char *new, char *old, Dir *d, void *a)
typedef void Protowarn(char *msg, void *a)
int rdproto(char *proto, char *root, Protoenum *enm,
Protowarn *warn, void *a)
Rdproto reads and interprets the named proto file relative to the root directory root.
Each line of the proto file specifies a file to copy. Blank lines and lines beginning with # 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 − for permissions, owner, or group causes
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 − is useful when one wishes
to set, say, the file owner without setting the permissions.)
Names beginning with a $ are expanded as environment variables. If the first file specified in a
directory is *, all of the files in that directory are considered listed. If the first file is +, all of the
files are copied, and all subdirectories are recursively considered listed. All files are considered
relative to root.
For each file named by the proto, enm is called with new pointing at the name of the file (without
the root prefix), old pointing at the name of the source file (with the root prefix, when applicable),
and Dir at the desired directory information for the new file. Only the name, uid, gid, mode,
mtime, and length fields are guaranteed to be valid. The argument a is the same argument
passed to rdproto; typically it points at some extra state used by the enumeration function.
When files or directories do not exist or cannot be read by rdproto, it formats a warning message,
calls warn, and continues processing; if warn is nil, rdproto prints the warning message to stan­
dard error.
Rdproto returns zero if proto was processed, 1 if it could not be opened.
mk9660(8), mkfs(8)
directory of prototype files.
generic prototype file.
pushssl attach SSL version 2 encryption to a communication channel
#include <u.h>
#include <libc.h>
int pushssl(int fd, char *alg, char *secin, char *secout, int *cfd)
Pushssl opens an ssl(3) device, connects it to the communications channel fd, and starts up
encryption and message authentication as specified in alg. The algorithms are separated by a
space and either can be first. See ssl(3) for the possible algorithms. Secin and secout contain the
encryption keys for the two directions. If either is nil, the other is used in both directions. If cfd is
non-nil, the SSL control channel is opened and its fd returned.
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, fd.
dial(2), ssl(3),
return 1 on failure.
pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, readcert, read­
certchain attach TLS1 or SSL3 encryption to a communication channel
#include <u.h>
#include <libc.h>
pushtls(int fd, char *hashalg, char *encalg,
int isclient, char *secret, char *dir)
#include <mp.h>
#include <libsec.h>
tlsClient(int fd, TLSconn *conn)
tlsServer(int fd, TLSconn *conn)
uchar *readcert(char *filename, int *pcertlen)
PEMchain *readcertchain(char *filename)
Thumbprint *initThumbprints(char *ok, char *crl)
void freeThumbprints(Thumbprint *table)
okThumbprint(uchar *hash, Thumbprint *table)
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.
To use just the record layer, as described in tls(3), call pushtls to open the record layer device,
connect to the communications channel fd, and start up encryption and message authentication as
specified in hashalg, encalg, and secret. These parameters must have been arranged at the two
ends of the conversation by other means. For example, hashalg could be sha1, encalg could be
rc4_128, and secret could be the base-64 encoding of two (client-to-server and server-toclient) 20-byte digest keys and two corresponding 16-byte encryption keys. 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, fd. If dir is non-zero, the path name of the
connection directory is copied into dir. This path name is guaranteed to be less than 40 bytes
Alternatively, call tlsClient to speak the full handshake protocol, negotiate the algorithms and
secrets, and return a new data file descriptor for the data channel. Conn points to a (callerallocated) struct:
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;
defined in tls.h. On input, the caller can provide options such as cert, the local certificate, and
sessionID, used by a client to resume a previously negotiated security association. On output, the
connection directory is set, as with listen (see dial(2)). The input cert is freed and a freshly allo­
cated copy of the remotes certificate is returned in conn, to be checked by the caller according to
its needs. One way to check the remote certificate is to use initThumbprints and freeThumbprints
which allocate and free, respectively, a table of hashes from files of known trusted and revoked
certificates. okThumbprint confirms that a particular hash is in the table.
TlsClient will optionally compute a session key for use by higher-level protocols. To compute a
session key, the caller must set sessionType to a known session type; sessionKeylen to the desired
key length; sessionKey to a buffer of length sessionKeylen ; and sessionConst to the desired salting
constant. The only supported session type is ttls, as used by 802.1x.
TlsServer executes the server side of the handshake. The caller must initialize conn−>cert, usu­
ally by calling readcert to read and decode the PEM-encoded certificate from filename, return a
pointer to malloced storage containing the certificate, and store its length through pcertlen. The
private key corresponding to cert.pem should have been previously loaded into factotum. (See
rsa(8) for more about key generation.)
Readcertchain will read a PEM-encoded chain of certificates from filename and return a pointer to
a linked list of malloced PEMChain structures, defined in tls.h:
typedef struct PEMChain PEMChain;
struct PEMChain {
uchar *pem;
int pemlen;
By setting
conn−>chain = readcertchain("intermediate−certs.pem");
the server can present extra certificate evidence to establish the chain of trust to a root authority
known to the client.
Conn is not required for the ongoing conversation and may be freed by the application whenever
Start the client half of TLS and check the remote certificate:
uchar hash[SHA1dlen];
conn = (TLSconn*)mallocz(sizeof *conn, 1);
fd = tlsClient(fd, conn);
sha1(conn−>cert, conn−>certlen, hash, nil);
exits("suspect server");
Run the server side:
fd = accept(lcfd, ldir);
conn = (TLSconn*)mallocz(sizeof *conn, 1);
conn−>cert = readcert("cert.pem", &conn−>certlen);
fd = tlsServer(fd, conn);
thumbprints of trusted services
PEM certificate files
dial(2), tls(3), factotum(4), thumbprint(6)
Return 1 on failure.
Client certificates and client sessionIDs are not yet implemented.
Note that in the TLS protocol sessionID itself is public; it is used as a pointer to secrets stored in
qball 3-d rotation controller
#include <draw.h>
#include <geometry.h>
void qball(Rectangle r, Mouse *mousep,
Quaternion *orientation,
void (*redraw)(void), Quaternion *ap)
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 r, and diameter the smaller
of rs 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.
Argument mousep is a pointer to the mouse event that triggered the interaction. It should have
some button set. Qball will read more events into mousep, and return when no buttons are down.
While qball is reading mouse events, it calls out to the caller-supplied routine redraw, which is
expected to update the screen to reflect the changing orientation. Argument orientation is the ori­
entation that redraw should examine, represented as a unit Quaternion (see quaternion(9.2)). The
caller may set it to any orientation. It will be updated before each call to redraw (and on return) by
multiplying by the rotation specified with the mouse.
It is possible to restrict qball’s attention to rotations about a particular axis. If ap is null, the rota­
tion is unconstrained. Otherwise, the rotation will be about the same axis as *ap. This is accom­
plished by projecting points on the sphere to the nearest point also on the plane through the
spheres center and normal to the axis.
Ken Shoemake, Animating Rotation with Quaternion Curves, SIGGRAPH ’85 Conference Proceedings.
qsort quicker sort
#include <u.h>
#include <libc.h>
void qsort(void *base, long nel, long width,
int (*compar)(void*, void*))
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.
qtom, mtoq, qadd, qsub, qneg, qmul, qdiv, qunit, qinv, qlen, slerp, qmid, qsqrt Quaternion arith­
#include <draw.h>
#include <geometry.h>
Quaternion qadd(Quaternion q, Quaternion r)
Quaternion qsub(Quaternion q, Quaternion r)
Quaternion qneg(Quaternion q)
Quaternion qmul(Quaternion q, Quaternion r)
Quaternion qdiv(Quaternion q, Quaternion r)
Quaternion qinv(Quaternion q)
double qlen(Quaternion p)
Quaternion qunit(Quaternion q)
void qtom(Matrix m, Quaternion q)
Quaternion mtoq(Matrix mat)
Quaternion slerp(Quaternion q, Quaternion r, double a)
Quaternion qmid(Quaternion q, Quaternion r)
Quaternion qsqrt(Quaternion q)
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 r and an imaginary vector component v=(i,j,k). Quaternions add componentwise
and multiply according to the rule (r,v)(s,w)=(rs-v.w, rw+vs+v×w), where . and × are the ordinary
vector dot and cross products. The multiplicative inverse of a non-zero quaternion (r,v) is (r,−
v)/(r 2-v.v).
The following routines do arithmetic on quaternions, represented as
typedef struct Quaternion Quaternion;
struct Quaternion{
double r, i, j, k;
Add two quaternions.
Subtract two quaternions.
Negate a quaternion.
Multiply two quaternions.
Divide two quaternions.
Return the multiplicative inverse of a quaternion.
Return sqrt(q.r*q.r+q.i*q.i+q.j*q.j+q.k*q.k), the length of a quater­
Return a unit quaternion (length=1) with components proportional to qs.
A rotation by angle θ about axis A (where A is a unit vector) can be represented by the unit quater­
nion q=(cos θ/2, Asin θ/2). The same rotation is represented by −q; a rotation by −θ about −A is
the same as a rotation by θ about A. The quaternion q transforms points by (0,x’,y’,z’) =
q-1(0,x,y,z)q. Quaternion multiplication composes rotations. The orientation of an object in 3space can be represented by a quaternion giving its rotation relative to some standard orienta­
The following routines operate on rotations or orientations represented as unit quaternions:
Convert a rotation matrix (see matrix(2)) to a unit quaternion.
Convert a unit quaternion to a rotation matrix.
Spherical lerp. Interpolate between two orientations. The rotation that carries q to r is
q-1r, so slerp(q, r, t) is q(q-1r)t.
slerp(q, r, .5)
The square root of q. This is just a rotation about the same axis by half the angle.
matrix(2), qball(2)
quotestrdup, quoterunestrdup, unquotestrdup, unquoterunestrdup, quotestrfmt, quoterunestrfmt,
quotefmtinstall, doquote, needsrcquote quoted character strings
#include <u.h>
#include <libc.h>
char *quotestrdup(char *s)
Rune *quoterunestrdup(Rune *s)
char *unquotestrdup(char *s)
Rune *unquoterunestrdup(Rune *s)
int quotestrfmt(Fmt*)
int quoterunestrfmt(Fmt*)
void quotefmtinstall(void)
int (*doquote)(int c)
int needsrcquote(int c)
These routines manipulate character strings, either adding or removing quotes as necessary. In
the quoted form, the strings are in the style of rc(1), with single quotes surrounding the string.
Embedded single quotes are indicated by a doubled single quote. For instance,
Don’t worry!
when quoted becomes
’Don’’t worry!’
The empty string is represented by two quotes, ’’.
The first four functions act as variants of strdup (see strcat(2)). Each returns a freshly allocated
copy of the string, created using malloc(2). Quotestrdup returns a quoted copy of s, while
unquotestrdup returns a copy of s with the quotes evaluated. The rune versions of these functions
do the same for strings (see runestrcat(2)).
The string returned by quotestrdup or quoterunestrdup has the following properties:
If the original string s is empty, the returned string is ’’.
If s contains no quotes, blanks, or control characters, the returned string is identical to s.
If s needs quotes to be added, the first character of the returned string will be a quote. For
example, hello world becomes ’hello world’ not hello’ ’world.
The function pointer doquote is nil by default. If it is non-nil, characters are passed to that func­
tion 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
*doquote, blanks, control characters, and quotes are always quoted. Needsrcquote is provided as
a doquote function that flags any character special to rc(1).
Quotestrfmt and quoterunestrfmt are print(2) formatting routines that produce quoted strings as
output. They may be installed by hand, but quotefmtinstall installs them under the standard for­
mat characters q and Q. (They are not installed automatically.) If the format string includes the
alternate format character #, for example %#q, the printed string will always be quoted; otherwise
quotes will only be provided if necessary to avoid ambiguity. In <libc.h> there are #pragma
statements so the compiler can type-check uses of %q and %Q in print(2) format strings.
rc(1), malloc(2), print(2), strcat(2)
rand, lrand, frand, nrand, lnrand, srand, truerand, ntruerand, genrandom, prng, fastrand, nfas­
trand random number generators
#include <u.h>
#include <libc.h>
double frand(void)
nrand(int val)
lnrand(long val)
srand(long seed)
ntruerand(ulong val)
#include <mp.h>
#include <libsec.h>
genrandom(uchar *buf, int nbytes)
prng(uchar *buf, int nbytes)
nfastrand(ulong val)
Rand returns a uniform pseudo-random number x, 0dx<215.
Lrand returns a uniform long x, 0dx<231.
Frand returns a uniform double x, 0.0dx<1.0, This function calls lrand twice to generate a num­
ber with as many as 62 significant bits of mantissa.
Nrand returns a uniform integer x, 0dx<val. Lnrand is the same, but returns a long.
The algorithm is additive feedback with:
x[n] = (x[n−273] + x[n−607]) mod 231
giving a period of 230 × (2607 1).
The generators are initialized by calling srand with whatever you like as argument. To get a differ­
ent starting value each time,
will work as long as it is not called more often than once per second. Calling
will initialize the generators to their starting state.
Truerand returns a random unsigned long read from /dev/random. Due to the nature of
/dev/random, truerand can only return a few hundred bits a second.
Ntruerand returns a uniform random integer x, 0dx<vald232−1.
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 /dev/random.
Prng uses the native rand(2) pseudo-random number generator to fill the buffer. Used with
srand, this function can produce a reproducible stream of pseudo random numbers useful in test­
Both genrandom and prng may be passed to mprand (see mp(2)).
Fastrand uses genrandom to return a uniform unsigned long x, 0dx<232−1.
Nfastrand uses genrandom to return a uniform unsigned long x, 0dx<vald232−1.
cons(3), mp(2)
Truerand and ntruerand maintain a static file descriptor.
setupRC4state, rc4, rc4skip, rc4back - alleged rc4 encryption
void setupRC4state(RC4state *s, uchar *seed, int slen)
void rc4(RC4state *s, uchar *data, int dlen)
void rc4skip(RC4state *s, int nbytes)
void rc4back(RC4state *s, int nbytes)
This is an algorithm alleged to be Rivests RC4 encryption function. It is a pseudo-random number
generator with a 256 byte state and a long cycle. The input buffer is XORd with the output of the
generator both to encrypt and to decrypt. The seed, entered using setupRC4state, can be any
length. The generator can be run forward using rc4, skip over bytes using rc4skip to account lost
transmissions, or run backwards using rc4back to cover retransmitted data. The RC4state struc­
ture keeps track of the algorithm.
mp(2), aes(2), blowfish(2), des(2), dsa(2), elgamal(2), rsa(2), sechash(2), prime(2), rand(2)
read, readn, write, pread, pwrite read or write file
#include <u.h>
#include <libc.h>
long read(int fd, void *buf, long nbytes)
long readn(int fd, void *buf, long nbytes)
long write(int fd, void *buf, long nbytes)
long pread(int fd, void *buf, long nbytes, vlong offset)
long pwrite(int fd, void *buf, long nbytes, vlong offset)
Read reads nbytes bytes of data from the offset in the file associated with fd into memory at buf.
The offset is advanced by the number of bytes read. It is not guaranteed that all 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.
Readn is just like read, but does successive read calls until nbytes have been read, or a read sys­
tem call returns a non-positive count.
Write writes nbytes bytes of data starting at buf to the file associated with 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.
Pread and Pwrite are equivalent to a seek(2) to offset followed by a read or write. By combining
the operations in a single atomic call, they more closely match the 9P protocol (see intro(5)) and,
more important, permit multiprocess programs to execute multiple concurrent read and write
operations on the same file descriptor without interference.
intro(2), dirread(2), dup(2), open(2), pipe(2), readv(2)
These functions set errstr.
RGB, readcolmap, writecolmap access display color map
#include <u.h>
#include <libc.h>
#include <draw.h>
readcolmap(Display *d, RGB *map)
writecolmap(Display *d, RGB *map)
Colors are described by their red, green, and blue light intensities, in an RGB datum:
struct RGB {
ulong red;
ulong green;
ulong blue;
} RGB;
Black is represented by zero in all three positions and white has the maximum unsigned long
value in all three positions.
A color map is an array of RGBs, of length 2depth, giving the colors for pixels 0, 1, 2, etc. On dis­
plays 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.
Readcolmap reads the color map for the given display into the provided map, which must have
enough space to hold it. 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
Changing the hardware color map does not change the color map used by the draw(2) operator to
convert between mapped and true color or greyscale images, which is described in color(6).
graphics(2), draw(3), color(6)
readv, writev, preadv, pwritev scatter/gather read and write
#include <u.h>
#include <libc.h>
struct IOchunk
} IOchunk;
long readv(int fd, IOchunk *io, int nio)
long preadv(int fd, IOchunk *io, int nio, vlong off)
long writev(int fd, IOchunk *io, int nio)
long pwritev(int fd, IOchunk *io, int nio, vlong off)
These functions supplement the standard read and write operations of read(2) with facilities for
scatter/gather I/O. The set of I/O buffers is collected into an array of IOchunk structures passed
as an argument.
Readv reads data from fd and returns the total number of bytes received. The received data is
stored in the successive nio elements of the IOchunk array, storing io[0].len bytes at
io[0].addr, the next io[1].len at io[1].addr, and so on. Preadv does the same, but
implicitly seeks to I/O offset off by analogy with readv.
Writev and pwritev are the analogous write routines.
intro(2), read(2)
These functions set errstr.
The implementations use malloc(2) to build a single buffer for a standard call to read or write.
They are placeholders for possible future system calls.
regcomp, regcomplit, regcompnl, regexec, regsub, rregexec, rregsub, regerror regular expres­
#include <u.h>
#include <libc.h>
#include <regexp.h>
*regcomp(char *exp)
*regcomplit(char *exp)
*regcompnl(char *exp)
regexec(Reprog *prog, char *string, Resub *match, int msize)
void regsub(char *source, char *dest, int dlen, Resub *match, int msize)
rregexec(Reprog *prog, Rune *string, Resub *match, int msize)
void rregsub(Rune *source, Rune *dest, int dlen, Resub *match, int msize)
void regerror(char *msg)
Regcomp compiles a regular expression and returns a pointer to the generated description. The
space is allocated by malloc(2) and may be released by free. Regular expressions are exactly as in
Regcomplit is like regcomp except that all characters are treated literally. Regcompnl is like
regcomp except that the . metacharacter matches all characters, including newlines.
Regexec matches a null-terminated string against the compiled regular expression in prog. If it
matches, regexec returns 1 and fills in the array match with character pointers to the substrings of
string that correspond to the parenthesized subexpressions of exp: match[i].sp points to the
beginning and match[i].ep points just beyond the end of the ith substring. (Subexpression i
begins at the ith left parenthesis, counting from 1.) Pointers in match[0] pick out the substring
that corresponds to the whole regular expression. Unused elements of match are filled with zeros.
Matches involving *, +, and ? are extended as far as possible. The number of array elements in
match is given by msize. The structure of elements of match is:
typedef struct {
union {
char *sp;
Rune *rsp;
union {
char *ep;
Rune *rep;
} Resub;
If match[0].sp is nonzero on entry, regexec starts matching at that point within string. If
match[0].ep is nonzero on entry, the last character matched is the one preceding that point.
Regsub places in dest a substitution instance of source in the context of the last regexec performed
using match. Each instance of \n, where n is a digit, is replaced by the string delimited by
match[n].sp and match[n].ep. Each instance of & is replaced by the string delimited by
match[0].sp and match[0].ep. The substitution will always be null terminated and
trimmed to fit into dlen bytes.
Regerror, called whenever an error is detected in regcomp, writes the string msg on the standard
error file and exits. Regerror can be replaced to perform special error processing. If the user sup­
plied regerror returns rather than exits, regcomp will return 0.
Rregexec and rregsub are variants of regexec and regsub that use strings of Runes instead of
strings of chars. With these routines, the rsp and rep fields of the match array elements should
be used.
Regcomp returns 0 for an illegal expression or other failure. Regexec returns 0 if string is not
There is no way to specify or match a NUL character; NULs terminate patterns and strings.
remove remove a file
#include <u.h>
#include <libc.h>
int remove(char *file)
Remove removes file from the directory containing it and discards the contents of the file. The
user must have write permission in the containing directory. If file is a directory, it must be empty.
intro(2), remove(5), the description of ORCLOSE in open(2).
Sets errstr.
rendezvous user level process synchronization
#include <u.h>
#include <libc.h>
void* rendezvous(void* tag, void* value)
The rendezvous system call allows two processes to synchronize and exchange a value. In con­
junction with the shared memory system calls (see segattach(2) and fork(2)), it enables parallel
programs to control their scheduling.
Two processes wishing to synchronize call rendezvous with a common 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 value arguments are exchanged
between the processes and returned as the result of the respective rendezvous system calls. Both
processes are awakened when the rendezvous succeeds.
The set of tag values which two processes may use to rendezvoustheir tag spaceis inherited
when a process forks, unless RFREND is set in the argument to rfork; see fork(2).
If a rendezvous is interrupted the return value is ~0, so that value should not be used in normal
fork(2), lock(2), segattach(2)
Sets errstr.
asn1dump, asn1toRSApriv, decodePEM, rsadecrypt, rsaencrypt, rsagen, rsaprivalloc, rsaprivfree,
rsaprivtopub, rsapuballoc, rsapubfree, X509toRSApub, X509gen, X509verify RSA encryption algo­
RSApriv* rsagen(int nlen, int elen, int nrep)
rsaencrypt(RSApub *k, mpint *in, mpint *out)
rsadecrypt(RSApriv *k, mpint *in, mpint *out)
RSApriv* rsaprivalloc(void)
RSApriv* asn1toRSApriv(uchar *priv, int npriv)
asn1dump(uchar *der, int len)
decodePEM(char *s, char *type, int *len, char **new_s)
X509req(RSApriv *priv, char *subj, int *certlen);
X509verify(uchar *cert, int ncert, RSApub *pk)
RSA is a public key encryption algorithm. The owner of a key publishes the public part of the key:
struct RSApub
*n; /* modulus */
*ek; /* exp (encryption key) */
This part can be used for encrypting data (with rsaencrypt) to be sent to the owner. The owner
decrypts (with rsadecrypt) using his private key:
struct RSApriv
*dk; /* exp (decryption key) */
/* precomputed
crt values */
/* k mod p−1 */
/* k mod q−1 */
/* for converting residues to number */
Keys are generated using rsagen. 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. Rsagen returns a newly allocated structure
containing both public and private keys. Rsaprivtopub returns a newly allocated copy of the public
key corresponding to the private key.
The routines rsaalloc, rsafree, rsapuballoc, rsapubfree, rsaprivalloc, and rsaprivfree are provided
to aid in user provided key I/O.
Given a binary X.509 cert, the routine X509toRSApub returns the public key and, if name is not nil,
the CN part of the Distinguished Name of the certificates 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, sha1(cert), against a table or check the certificate by other means. X.509 certifi­
cates are often stored in PEM format; use dec64 to convert to binary before computing the finger­
print or calling X509toRSApub. For the special case of certificates signed by a known trusted key
(in a single step, without certificate chains), X509verify checks the signature on cert. It returns nil
if successful, else an error string.
X509gen creates a self-signed X.509 certificate, given an RSA keypair priv, a issuer/subject string
subj, and the starting and ending validity dates, valid. Length of the allocated binary certificate is
stored in certlen. The subject line is conventionally of the form
C=US ST=NJ L=07922 O=Lucent OU=’Bell Labs’ CN=Eric
using the quoting conventions of tokenize in getfields(2).
Asn1toRSApriv converts an ASN1 formatted RSA private key into the corresponding RSApriv
Asn1dump prints an ASN1 object to standard output.
DecodePEM takes a zero terminated string, s, and decodes the PEM (privacy-enhanced mail) for­
matted section for type within it. If successful, it returns malloced storage containing the decoded
section, which the caller must free, and sets *len to its decoded length. Otherwise nil is
returned and *len is undefined. If not nil, new_s is set to the first character beyond the type sec­
mp(2), aes(2), blowfish(2), des(2), dsa(2), elgamal(2), rc4(2), sechash(2), prime(2), rand(2), rsa(8)
runetochar, chartorune, runelen, runenlen, fullrune, utfecpy, utflen, utfnlen, utfrune, utfrrune,
utfutf rune/UTF conversion
#include <u.h>
#include <libc.h>
runetochar(char *s, Rune *r)
chartorune(Rune *r, char *s)
runelen(long r)
runenlen(Rune *r, int n)
fullrune(char *s, int n)
utfecpy(char *s1, char *es1, char *s2)
utflen(char *s)
utfnlen(char *s, long n)
utfrune(char *s, long c)
utfrrune(char *s, long c)
utfutf(char *s1, char *s2)
These routines convert to and from a UTF byte stream and runes.
Runetochar copies one rune at r to at most UTFmax bytes starting at s and returns the number of
bytes copied. UTFmax, defined as 3 in <libc.h>, is the maximum number of bytes required to
represent a rune.
Chartorune copies at most UTFmax bytes starting at s to one rune at r and returns the number of
bytes copied. If the input is not exactly in UTF format, chartorune will convert to Runeerror
(0xFFFD) and return 1.
Runelen returns the number of bytes required to convert r into UTF.
Runenlen returns the number of bytes required to convert the n runes pointed to by r into UTF.
Fullrune returns 1 if the string s of length n is long enough to be decoded by chartorune and 0
otherwise. This does not guarantee that the string contains a legal 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
The following routines are analogous to the corresponding string routines with utf substituted
for str and rune substituted for chr.
Utfecpy copies UTF sequences until a null sequence has been copied, but writes no sequences
beyond es1. If any sequences are copied, s1 is terminated by a null sequence, and a pointer to that
sequence is returned. Otherwise, the original s1 is returned.
Utflen returns the number of runes that are represented by the UTF string s.
Utfnlen returns the number of complete runes that are represented by the first n bytes of UTF
string s. If the last few bytes of the string contain an incompletely coded rune, utfnlen will not
count them; in this way, it differs from utflen, which includes every byte of the string.
Utfrune (utfrrune) returns a pointer to the first (last) occurrence of rune c in the UTF string s, or 0
if c does not occur in the string. The NUL byte terminating a string is considered to be part of the
string s.
Utfutf returns a pointer to the first occurrence of the UTF string s2 as a UTF substring of s1, or 0 if
there is none. If s2 is the null string, utfutf returns s1.
utf(6), tcs(1)
runestrcat, runestrncat, runestrcmp, runestrncmp, runestrcpy, runestrncpy, runestrecpy, runes­
trlen, runestrchr, runestrrchr, runestrdup, runestrstr rune string operations
#include <u.h>
#include <libc.h>
Rune* runestrcat(Rune *s1, Rune *s2)
Rune* runestrncat(Rune *s1, Rune *s2, long n)
runestrcmp(Rune *s1, Rune *s2)
runestrncmp(Rune *s1, Rune *s2, long n)
Rune* runestrcpy(Rune *s1, Rune *s2)
Rune* runestrncpy(Rune *s1, Rune *s2, long n)
Rune* runestrecpy(Rune *s1, Rune *es1, Rune *s2)
runestrlen(Rune *s)
Rune* runestrchr(Rune *s, Rune c)
Rune* runestrrchr(Rune *s, Rune c)
Rune* runestrdup(Rune *s)
Rune* runestrstr(Rune *s1, Rune *s2)
These functions are rune string analogues of the corresponding functions in strcat(2).
memory(2), rune(2), strcat(2)
The outcome of overlapping moves varies among implementations.
scribblealloc, recognize character recognition
Scribble *scribblealloc(void);
recognize(Scribble *);
The scribble library implements simple character recognition. All characters are drawn using a sin­
gle stroke of the pen (mouse button 1) as on a palmtop computer. A reference card is in
The library is not really intended for standalone use. Its primary use is by the scribble graphical
control (see control(2)).
Scribblealloc allocates and returns an appropriately initialized Scribble structure:
#define CS_LETTERS
#define CS_DIGITS
struct Scribble {
/* private state */
This structure encodes the points making up the stroke to be recognized, as well as the character
group in which the stroke should be searched.
There are three such groups: letters, digits, and punctuation. The current group is encoded in the
curCharSet field of the Scribble structure. Special strokes are recognized to switch
between groups. In addition, the charater recognized is influenced by mode parameters and modi­
fies them. These are identified by the capsLock, puncShift, tmpShift, and ctrlShift
fields of the Scribble structure. When puncShift is non-zero, the character is recognized in
the punctuation character set. Similarly, when the character recognized is printable and
ctrlShift is set, the associated control character is returned as if the control key were
depressed, and when the character is a letter and capsLock or tmpShift is set, the uppercase version is returned. The puncShift and tmpShift flags are turned off once a character
has been recognized; the others are left set.
The character to be recognized is encoded as an array of pen_points in the ps field. To allow easy
drawing of the stroke as it is drawn, the pt and ppasize fields are available to the application code
for storing an array of points for a call to poly (see draw(2)).
Recognize recognizes the character provided in the ps field of the Scribble structure; it returns
the rune or zero if nothing was recognized.
/sys/src/libscribble/quickref.gif serves as a quick reference card.
/sys/lib/scribble/classifiers contains the stroke definitions.
This library is adapted from software reproduced by permission:
Graffiti.c is based on the file Scribble.c copyrighted by Keith Packard:
Copyright © 1999 Keith Packard
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 docu­
mentation, 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.
Portions of the software Copyright © 1994 by Sun Microsystems Computer Company.
Portions of the software Copyright © 2000 by Compaq Computer Corporation.
Keyboard and prompter in bitsyload(1), draw(2), control(2)
openscsi, closescsi, scsiready, scsi, scsicmd, scsierror SCSI device operations
#include <u.h>
#include <libc.h>
#include <disk.h>
typedef struct Scsi {
char *inquire;
ulong changetime;
Scsi* openscsi(char *devdir)
closescsi(Scsi *s)
scsiready(Scsi *s)
scsi(Scsi *s, uchar *cmd, int ncmd,
void *data, int ndata, int dir)
scsicmd(Scsi *s, uchar *cmd, int ncmd,
void *data, int ndata, int dir)
char* scsierror(int asc, int ascq)
These routines provide an interface to a SCSI or ATAPI device via sd(3).
Openscsi attempts to open the file devdir/raw and use it to send raw SCSI commands. On suc­
cess, it reads the devices inquiry string and stores it in inquire in the returned Scsi structure.
Closescsi closes the connection and frees the Scsi structure.
Scsiready sends the unit ready command up to three times, returning zero if the unit responds
that it is ready, or 1 on error.
Scsierror returns a textual description of the SCSI status denoted by the ASC and ASCQ sense
codes. The description is found by consulting /sys/lib/scsicodes. The returned string will
be overwritten by the next call to scsierror.
Scsi and scsicmd execute a single SCSI command on the named device. There should be ncmd
bytes of command data in cmd; if dir is Sread, a successful operation will store up to ndata bytes
into data, returning the number of bytes stored. If dir is Swrite, the ndata bytes beginning at
data are transmitted as the data argument to the command, and the number of bytes written is
returned. If dir is Snone, data and ndata are ignored. On error, scsi and scsicmd return 1.
Scsicmd simply issues the command and returns the result; scsi works a bit harder and is the more
commonly used routine. Scsi attempts to send the command; if it is successful, scsi returns what
scsicmd returned. Otherwise, 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, scsi sends the request sense and unit ready commands
again and then uses scsierror to set errstr with a reason for failure.
The nchange and changetime fields in the 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
If scsiverbose is set, these commands will produce a fair amount of debugging output on file
descriptor 2 when SCSI commands fail.
List of textual messages corresponding to SCSI error codes; consulted by scsierror.
sd(3), scuzz(8)
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
#include <u.h>
#include <libc.h>
#include <mp.h>
#include <libsec.h>
#define DS DigestState /* only to abbreviate SYNOPSIS */
DS* md4(uchar *data, ulong dlen, uchar *digest, DS *state)
DS* md5(uchar *data, ulong dlen, uchar *digest, DS *state)
md5pickle(MD5state *state)
md5unpickle(char *p);
DS* sha1(uchar *data, ulong dlen, uchar *digest, DS *state)
sha1pickle(SHA1state *state)
SHA1state* sha1unpickle(char *p);
DS* sha2_224(uchar *data, ulong dlen, uchar *digest, DS *state)
DS* sha2_256(uchar *data, ulong dlen, uchar *digest, DS *state)
DS* sha2_384(uchar *data, ulong dlen, uchar *digest, DS *state)
DS* sha2_512(uchar *data, ulong dlen, uchar *digest, DS *state)
DS* aes(uchar *data, ulong dlen, uchar *digest, DS *state)
DS* hmac_x(uchar *p, ulong len, uchar *key,
*digest, DS *s, DS*(*x)(uchar*, ulong,
ulong klen, uchar
uchar*, DS*), int
DS* hmac_md5(uchar *data, ulong dlen, uchar *key, ulong klen, uchar
*digest, DS *state)
DS* hmac_sha1(uchar *data, ulong
uchar *digest, DS *state)
DS* hmac_sha2_224(uchar *data, ulong dlen, uchar *key, ulong klen,
uchar *digest, DS *state)
DS* hmac_sha2_256(uchar *data, ulong dlen, uchar *key, ulong klen,
uchar *digest, DS *state)
DS* hmac_sha2_384(uchar *data, ulong dlen, uchar *key, ulong klen,
uchar *digest, DS *state)
DS* hmac_sha2_512(uchar *data, ulong dlen, uchar *key, ulong klen,
uchar *digest, DS *state)
DS* hmac_aes(uchar *data, ulong dlen, uchar *key, ulong klen, uchar
*digest, DS *state)
We support several secure hash functions. The output of a hash is called a 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
The routines md4, md5, sha1, sha2_224, sha2_256, sha2_384, sha2_512, aes, hmac_md5,
hmac_sha1, hmac_sha2_224, hmac_sha2_256, hmac_sha2_384, hmac_sha2_512, and hmac_aes
differ only in the length of the resulting digest and in the security of the hash. Sha2_* and
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 nil
as the state parameter. This call returns a state which can be used to chain subsequent calls. The
last call should have digest non-nil. 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 digest.
The constants MD4dlen, MD5dlen, SHA1dlen , SHA2_224dlen , SHA2_256dlen , SHA2_384dlen,
SHA2_512dlen , and AESdlen define the lengths of the digests.
Hmac_md5, hmac_sha1, hmac_sha2_224, hmac_sha2_256, hmac_sha2_384, hmac_sha2_512,
and 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 hmac_x internally, but hmac_x is not
intended for general use.
The functions md5pickle and sha1pickle marshal the state of a digest for transmission.
Md5unpickle and sha1unpickle unmarshal a pickled digest. All four routines return a pointer to a
newly malloc(2)d object.
To hash a single buffer using md5:
uchar digest[MD5dlen];
md5(data, len, digest, nil);
To chain a number of buffers together, bounded on each end by some secret:
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);
aes(2), blowfish(2), des(2), elgamal(2), rc4(2), rsa(2)
/lib/rfc/rfc2104 HMAC specification
seek change file offset
#include <u.h>
#include <libc.h>
vlong seek(int fd, vlong n, int type)
Seek sets the offset for the file associated with fd as follows:
If type is 0, the offset is set to n bytes.
If type is 1, the pointer is set to its current location plus n.
If type is 2, the pointer is set to the size of the file plus n.
The new file offset value is returned.
Seeking in a directory is not allowed. Seeking in a pipe is a no-op.
intro(2), open(2)
Sets errstr.
segattach, segdetach, segfree map/unmap a segment in virtual memory
#include <u.h>
#include <libc.h>
void*segattach(int attr, char *class, void *va, ulong len)
segdetach(void *addr)
segfree(void *va, ulong len)
Segattach creates a new memory segment, adds it to the calling processs address space, and
returns its lowest address. Segments belong to system-dependent classes. Segment classes
memory (plain memory) and shared (shared memory) are available on all systems.
Shared segments are inherited by the children of the attaching process and remain untouched
across a fork(2). An exec(2) will release a shared segment if it overlaps the segments in the file
being exec’ed; otherwise the segment will be inherited.
Some machines provide a segment class lock. Lock segments allow access to special lock hard­
ware provided by some multiprocessors, in particular the SGI Power Series machines.
Systems may also provide interfaces to special hardware devices like frame buffers through the
segattach interface. Device memory mapped by this method is typically uncached by default.
If the specified class is unknown, segattach draws an error.
Attr specifies the new segments attributes. The only attributes implemented on all classes of seg­
ment is SG_RONLY, which allows only read access on the segment, and SG_CEXEC, which causes
the segment to be detached when the process does an exec(2). Specific devices may implement
attributes to control caching and allocation, but these will vary between devices.
Va and len specify the position of the segment in the processs address space. Va is rounded
down to the nearest page boundary and va+len is rounded up. The system does not permit seg­
ments to overlap. If va is zero, the system will choose a suitable address.
Segdetach removes a segment from a processs address space. Memory used by the segment is
freed. Addr may be any address within the bounds of the segment.
The system will not permit the initial stack segment to be detached from the address space.
Segfree tells the system that it may free any physical memory within the span [va, va+len), but
leaves that portion of the processs address space valid. The system will not free any memory out­
side that span, and may not free all or even any of the specified memory. If freed 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.
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 segattach a segment of class lock.
If this succeeds, the machine is an SGI Power Series and the memory contains hardware locks.
Each 4096-byte page has 64 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 segattach
fails, there is no hardware support but the operating system helps: Any COP3 instruction will be
trapped by the kernel and interpreted as a test-and-set. In the trap, R1 points to a long; on
return, R1 is greater or equal zero on success, negative on failure. The following assembly lan­
guage implements such a test-and-set.
MIPS test and set
tas(SB), $0
R1, sema+0(FP)
sema+0(FP), R1
R0, 1(R1)
/* save arg on stack */
R0, R0, R0 /* NOP */
$(023<<26) /* MFC3 R0, R0 */
R1, btas
lock(2), segbrk(2), segflush(2)
These functions set errstr. Segattach returns (void*)−1 on error.
There is a small fixed limit on the number of segments that may be attached, as well as a maxi­
mum segment size.
segbrk change memory allocation
#include <u.h>
#include <libc.h>
void* segbrk(void *saddr, void *addr)
Segbrk sets the systems idea of the lowest unused location of a segment to addr rounded up to
the next multiple of a page size, typically 4096 bytes. The segment is identified by saddr which
may be any valid address within the segment.
A call to segbrk with a zero addr argument returns the address of the top of bss.
The system will prevent segments from overlapping and will not allow the length of the text, data,
or stack segment to be altered.
brk(2), segattach(2), segflush(2)
Sets errstr. Segbrk returns (void*)−1 on error.
Segbrk is not fully defined or implemented. In particular, it cannot always return the top of bss
when called with a zero addr argument. The segbrk system call may go away or be reimplemented to give more general segment control, subsuming the functions of brk(2),
segflush(2) and segfree in segattach(2).
segflush flush instruction and data caches
#include <u.h>
#include <libc.h>
segflush(void *va, ulong len)
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
Va is an address within the segment to be flushed; it is rounded down to the nearest page bound­
ary. Len specifies the length in bytes of the memory to flush; va+len is rounded up to the nearest
page boundary. Segflush works correctly when the memory straddles multiple segments.
Correct use of segflush depends on an understanding of the cache architecture of the specific
segattach(2), segbrk(2)
Sets errstr.
semacquire, semrelease user level semaphores
#include <u.h>
#include <libc.h>
int semacquire(long *addr, int block);
long semrelease(long *addr, long count);
Semacquire and semrelease facilitate scheduling between processes sharing memory. Processes
arrange to share memory by using rfork with the RFMEM flag (see fork(2)), segattach(2), or
The semaphores value is the integer pointed at by addr. 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 block is zero and the semaphore is not
immediately available, semacquire returns 0 instead of waiting. Semrelease adds count to the
semaphores value and returns the new value.
Semacquire and semrelease can be thought of as efficient, correct replacements for:
semacquire(long *addr, int block)
while(*addr == 0){
return 0;
return −1;
return 1;
semrelease(long *addr, int count)
return *addr += count;
Like rendezvous (2), semacquire and semrelease are not typically used directly. Instead, they are
intended to be used to coordinate scheduling in higher-level abstractions such as locks, ren­
dezvous points, and channels (see lock(2) and thread(2)). Also like rendezvous , semacquire and
semrelease cannot be used to coordinate between threads in a single process. Use locks, ren­
dezvous points, or channels instead.
fork(2), lock(2), rendezvous (2), segattach(2), thread(2)
These functions set errstr.
setjmp, longjmp, notejmp non-local goto
#include <u.h>
#include <libc.h>
setjmp(jmp_buf env)
void longjmp(jmp_buf env, int val)
void notejmp(void *uregs, jmp_buf env, int val)
These routines are useful for dealing with errors and interrupts encountered in a low-level subrou­
tine of a program.
Setjmp saves its stack environment in env for later use by longjmp. It returns value 0.
Longjmp restores the environment saved by the last call of setjmp. It then causes execution to con­
tinue as if the call of setjmp had just returned with value val. The invoker of setjmp must not itself
have returned in the interim. All accessible data have values as of the time longjmp was called.
Notejmp is the same as longjmp except that it is to be called from within a note handler (see
notify(2)). The uregs argument should be the first argument passed to the note handler.
Setjmp and longjmp can also be used to switch stacks. Several macros are defined in
/$objtype/include/u.h that can be used to build jmp_bufs by hand. The following code
establishes a jmp_buf that may be called by longjmp to begin execution in a function f with
1024 bytes of stack:
#include <u.h>
#include <libc.h>
jmp_buf label;
#define NSTACK 1024
char stack[NSTACK];
label[JMPBUFPC] = ((ulong)f+JMPBUFDPC);
/* −2 leaves room for old pc and new pc in frame */
label[JMPBUFSP] =
Notejmp cannot recover from an address trap or bus error (page fault) on the 680x0 architectures.
sin, cos, tan, asin, acos, atan, atan2 trigonometric functions
#include <u.h>
#include <libc.h>
double sin(double x)
double cos(double x)
double tan(double x)
double asin(double x)
double acos(double x)
double atan(double x)
double atan2(double y, double x)
Sin, cos and tan return trigonometric functions of radian arguments. The magnitude of the argu­
ment should be checked by the caller to make sure the result is meaningful.
Asin returns the arc sine in the range À/2 to À/2.
Acos returns the arc cosine in the range 0 to À.
Atan returns the arc tangent in the range À/2 to À/2.
Atan2 returns the arc tangent of y/x in the range À to À.
The value of tan for arguments greater than about 231 is garbage.
sinh, cosh, tanh hyperbolic functions
#include <u.h>
#include <libc.h>
double sinh(double x)
double cosh(double x)
double tanh(double x)
These functions compute the designated hyperbolic functions for real arguments.
sleep, alarm delay, ask for delayed note
#include <u.h>
#include <libc.h>
int sleep(long millisecs)
long alarm(unsigned long millisecs)
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 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.
Alarm causes an alarm note (see notify(2)) to be sent to the invoking process after the number of
milliseconds given by the argument. Successive calls to alarm reset the alarm clock. A zero argu­
ment clears the alarm. The return value is the amount of time previously remaining in the alarm
These functions set errstr.
stat, fstat, wstat, fwstat, dirstat, dirfstat, dirwstat, dirfwstat, nulldir get and put file status
#include <u.h>
#include <libc.h>
int stat(char *name, uchar *edir, int nedir)
int fstat(int fd, uchar *edir, int nedir)
int wstat(char *name, uchar *edir, int nedir)
int fwstat(int fd, uchar *edir, int nedir)
Dir* dirstat(char *name)
Dir* dirfstat(int fd)
int dirwstat(char *name, Dir *dir)
int dirfwstat(int fd, Dir *dir)
void nulldir(Dir *d)
Given a files name, or an open file descriptor fd, these routines retrieve or modify file status infor­
mation. Stat, fstat, wstat, and fwstat are the system calls; they deal with machine-independent
directory entries. Their format is defined by stat(5). Stat and fstat retrieve information about name
or fd into edir, a buffer of length nedir, defined in <libc.h>. Wstat and fwstat write informa­
tion back, thus changing file attributes according to the contents of edir. The data returned from
the kernel includes its leading 16-bit length field as described in intro(5). For symmetry, this field
must also be present when passing data to the kernel in a call to wstat and fwstat, but its value is
Dirstat, dirfstat, dirwstat, and dirfwstat are similar to their counterparts, except that they operate
on Dir structures:
struct Dir {
/* system−modified data */
uint type;
/* server type */
uint dev;
/* server subtype */
/* file data */
/* 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;
The returned structure is allocated by malloc(2); freeing it also frees the associated strings.
This structure and the Qid structure are defined in <libc.h>. If the file resides on permanent
storage and is not a directory, the length returned by 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 connec­
tions), the length is the number of bytes that can be read without blocking.
Each file is the responsibility of some server: it could be a file server, a kernel device, or a user
process. Type identifies the server type, and dev says which of a group of servers of the same
type is the one responsible for this file. Qid is a structure containing path and vers fields:
path is guaranteed to be unique among all path names currently on the file server, and vers
changes each time the file is modified. The path is a long long (64 bits, vlong) and the
vers is an unsigned long (32 bits, ulong). Thus, if two files have the same type, dev,
and qid they are the same file.
The bits in mode are defined by