Initial revision

This commit is contained in:
rsc 2003-09-30 17:47:41 +00:00
parent 5f7d5e8d18
commit b2cfc4e2e7
242 changed files with 18177 additions and 0 deletions

336
man/man3/bio.3 Normal file
View file

@ -0,0 +1,336 @@
.TH BIO 3
.SH NAME
Bopen, Binit, Binits, Brdline, Brdstr, Bgetc, Bgetd, Bungetc, Bread, Bseek, Boffset, Bfildes, Blinelen, Bputc, Bprint, Bvprint, Bwrite, Bflush, Bterm, Bbuffered \- buffered input/output
.SH SYNOPSIS
.ta \w'Biobuf* 'u
.B #include <fmt.h>
.B #include <bio.h>
.PP
.B
Biobuf* Bopen(char *file, int mode)
.PP
.B
int Binit(Biobuf *bp, int fd, int mode)
.PP
.B
int Bterm(Biobuf *bp)
.PP
.B
int Bprint(Biobuf *bp, char *format, ...)
.PP
.B
int Bvprint(Biobuf *bp, char *format, va_list arglist);
.PP
.B
void* Brdline(Biobuf *bp, int delim)
.PP
.B
char* Brdstr(Biobuf *bp, int delim, int nulldelim)
.PP
.B
int Blinelen(Biobuf *bp)
.PP
.B
off_t Boffset(Biobuf *bp)
.PP
.B
int Bfildes(Biobuf *bp)
.PP
.B
int Bgetc(Biobuf *bp)
.PP
.B
long Bgetrune(Biobufhdr *bp)
.PP
.B
int Bgetd(Biobuf *bp, double *d)
.PP
.B
int Bungetc(Biobuf *bp)
.PP
.B
int Bungetrune(Biobufhdr *bp)
.PP
.B
off_t Bseek(Biobuf *bp, off_t n, int type)
.PP
.B
int Bputc(Biobuf *bp, int c)
.PP
.B
int Bputrune(Biobufhdr *bp, long c)
.PP
.B
long Bread(Biobuf *bp, void *addr, long nbytes)
.PP
.B
long Bwrite(Biobuf *bp, void *addr, long nbytes)
.PP
.B
int Bflush(Biobuf *bp)
.PP
.B
int Bbuffered(Biobuf *bp)
.PP
.SH DESCRIPTION
These routines implement fast buffered I/O.
I/O on different file descriptors is independent.
.PP
.I Bopen
opens
.I file
for mode
.B O_RDONLY
or creates for mode
.BR O_WRONLY .
It calls
.IR malloc (3)
to allocate a buffer.
.PP
.I Binit
initializes a buffer
with the open file descriptor passed in
by the user.
.PP
Arguments
of types pointer to Biobuf and pointer to Biobuf
can be used interchangeably in the following routines.
.PP
.IR Bopen ,
.IR Binit ,
or
.I Binits
should be called before any of the
other routines on that buffer.
.I Bfildes
returns the integer file descriptor of the associated open file.
.PP
.I Bterm
flushes the buffer for
.IR bp .
If the buffer was allocated by
.IR Bopen ,
the buffer is
.I freed
and the file is closed.
.PP
.I Brdline
reads a string from the file associated with
.I bp
up to and including the first
.I delim
character.
The delimiter character at the end of the line is
not altered.
.I Brdline
returns a pointer to the start of the line or
.L 0
on end-of-file or read error.
.I Blinelen
returns the length (including the delimiter)
of the most recent string returned by
.IR Brdline .
.PP
.I Brdstr
returns a
.IR malloc (3)-allocated
buffer containing the next line of input delimited by
.IR delim ,
terminated by a NUL (0) byte.
Unlike
.IR Brdline ,
which returns when its buffer is full even if no delimiter has been found,
.I Brdstr
will return an arbitrarily long line in a single call.
If
.I nulldelim
is set, the terminal delimiter will be overwritten with a NUL.
After a successful call to
.IR Brdstr ,
the return value of
.I Blinelen
will be the length of the returned buffer, excluding the NUL.
.PP
.I Bgetc
returns the next byte from
.IR bp ,
or a negative value
at end of file.
.I Bungetc
may be called immediately after
.I Bgetc
to allow the same byte to be reread.
.PP
.I Bgetrune
calls
.I Bgetc
to read the bytes of the next
.SM UTF
sequence in the input stream and returns the value of the rune
represented by the sequence.
It returns a negative value
at end of file.
.I Bungetrune
may be called immediately after
.I Bgetrune
to allow the same
.SM UTF
sequence to be reread as either bytes or a rune.
.I Bungetc
and
.I Bungetrune
may back up a maximum of five bytes.
.PP
.I Bgetd
uses
.I fmtcharstod
(undocumented)
and
.I Bgetc
to read the formatted
floating-point number in the input stream,
skipping initial blanks and tabs.
The value is stored in
.BR *d.
.PP
.I Bread
reads
.I nbytes
of data from
.I bp
into memory starting at
.IR addr .
The number of bytes read is returned on success
and a negative value is returned if a read error occurred.
.PP
.I Bseek
applies
.IR lseek (2)
to
.IR bp .
It returns the new file offset.
.I Boffset
returns the file offset of the next character to be processed.
.PP
.I Bputc
outputs the low order 8 bits of
.I c
on
.IR bp .
If this causes a
.IR write
to occur and there is an error,
a negative value is returned.
Otherwise, a zero is returned.
.PP
.I Bputrune
calls
.I Bputc
to output the low order
16 bits of
.I c
as a rune
in
.SM UTF
format
on the output stream.
.PP
.I Bprint
is a buffered interface to
.IR print (2).
If this causes a
.IR write
to occur and there is an error,
a negative value
.RB ( Beof )
is returned.
Otherwise, the number of bytes output is returned.
.I Bvprint
does the same except it takes as argument a
.B va_list
parameter, so it can be called within a variadic function.
.PP
.I Bwrite
outputs
.I nbytes
of data starting at
.I addr
to
.IR bp .
If this causes a
.IR write
to occur and there is an error,
a negative value is returned.
Otherwise, the number of bytes written is returned.
.PP
.I Bflush
causes any buffered output associated with
.I bp
to be written.
The return is as for
.IR Bputc .
.I Bflush
is called on
exit for every buffer still open
for writing.
.PP
.I Bbuffered
returns the number of bytes in the buffer.
When reading, this is the number of bytes still available from the last
read on the file; when writing, it is the number of bytes ready to be
written.
.PP
This library uses
.IR fmt (3)
for diagnostic messages about internal errors,
as well as for the implementation of
.I Bprint
and
.IR Bvprint .
It uses
.IR utf (3)
for the implementation of
.I Bgetrune
and
.IR Bputrune .
.SH SEE ALSO
.IR atexit (3).
.IR open (2),
.IR print (3),
.IR utf (7)
.SH DIAGNOSTICS
.I Bio
routines that return integers yield
.B Beof
if
.I bp
is not the descriptor of an open file.
.I Bopen
returns zero if the file cannot be opened in the given mode.
.SH HISTORY
The
.IR bio (3)
library originally appeared in Plan 9.
This is a port of the Plan 9 bio library.
.SH BUGS
.I Brdline
returns an error on strings longer than the buffer associated
with the file
and also if the end-of-file is encountered
before a delimiter.
.I Blinelen
will tell how many characters are available
in these cases.
In the case of a true end-of-file,
.I Blinelen
will return zero.
At the cost of allocating a buffer,
.I Brdstr
sidesteps these issues.
.PP
The data returned by
.I Brdline
may be overwritten by calls to any other
.I bio
routine on the same
.IR bp.

346
man/man3/fmtinstall.3 Normal file
View file

@ -0,0 +1,346 @@
.TH FMTINSTALL 3
.de EX
.nf
.ft B
..
.de EE
.fi
.ft R
..
.SH NAME
fmtinstall, dofmt, fmtprint, fmtvprint, fmtstrcpy, fmtfdinit, fmtfdflush, fmtstrinit, fmtstrflush \- support for user-defined print formats and output routines
.SH SYNOPSIS
.B #include <fmt.h>
.PP
.ft L
.nf
.ta \w' 'u +\w' 'u +\w' 'u +\w' 'u +\w' 'u
typedef struct Fmt Fmt;
struct Fmt{
void *start; /* of buffer */
void *to; /* current place in the buffer */
void *stop; /* end of the buffer; overwritten if flush fails */
int (*flush)(Fmt*); /* called when to == stop */
void *farg; /* to make flush a closure */
int nfmt; /* num chars formatted so far */
va_list args; /* args passed to dofmt */
int r; /* % format character */
int width;
int prec;
unsigned long flags;
};
enum{
FmtWidth = 1,
FmtLeft = FmtWidth << 1,
FmtPrec = FmtLeft << 1,
FmtSharp = FmtPrec << 1,
FmtSpace = FmtSharp << 1,
FmtSign = FmtSpace << 1,
FmtZero = FmtSign << 1,
FmtUnsigned = FmtZero << 1,
FmtShort = FmtUnsigned << 1,
FmtLong = FmtShort << 1,
FmtVLong = FmtLong << 1,
FmtComma = FmtVLong << 1,
FmtByte = FmtComma << 1,
FmtLDouble = FmtByte << 1,
FmtFlag = FmtLDouble << 1
};
.fi
.PP
.B
.ta \w'\fLchar* 'u
.PP
.B
int fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);
.PP
.B
int fmtfdflush(Fmt *f);
.PP
.B
int fmtstrinit(Fmt *f);
.PP
.B
char* fmtstrflush(Fmt *f);
.PP
.B
int fmtinstall(int c, int (*fn)(Fmt*));
.PP
.B
int dofmt(Fmt *f, char *fmt);
.PP
.B
int fmtprint(Fmt *f, char *fmt, ...);
.PP
.B
int fmtvprint(Fmt *f, char *fmt, va_list v);
.PP
.B
int fmtrune(Fmt *f, int r);
.PP
.B
int fmtstrcpy(Fmt *f, char *s);
.SH DESCRIPTION
The interface described here allows the construction of custom
.IR print (3)
verbs and output routines.
In essence, they provide access to the workings of the formatted print code.
.PP
The
.IR print (3)
suite maintains its state with a data structure called
.BR Fmt .
A typical call to
.IR print (3)
or its relatives initializes a
.B Fmt
structure, passes it to subsidiary routines to process the output,
and finishes by emitting any saved state recorded in the
.BR Fmt .
The details of the
.B Fmt
are unimportant to outside users, except insofar as the general
design influences the interface.
The
.B Fmt
records
the verb being processed, its precision and width,
and buffering parameters.
Most important, it also records a
.I flush
routine that the library will call if a buffer overflows.
When printing to a file descriptor, the flush routine will
emit saved characters and reset the buffer; when printing
to an allocated string, it will resize the string to receive more output.
The flush routine is nil when printing to fixed-size buffers.
User code need never provide a flush routine; this is done internally
by the library.
.SS Custom output routines
To write a custom output routine, such as an error handler that
formats and prints custom error messages, the output sequence can be run
from outside the library using the routines described here.
There are two main cases: output to an open file descriptor
and output to a string.
.PP
To write to a file descriptor, call
.I fmtfdinit
to initialize the local
.B Fmt
structure
.IR f ,
giving the file descriptor
.IR fd ,
the buffer
.IR buf ,
and its size
.IR nbuf .
Then call
.IR fmtprint
or
.IR fmtvprint
to generate the output.
These behave just like
.B fprint
(see
.IR print (3))
or
.B vfprint
except that the characters are buffered until
.I fmtfdflush
is called.
A typical example of this sequence appears in the Examples section.
.PP
The same basic sequence applies when outputting to an allocated string:
call
.I fmtstrinit
to initialize the
.BR Fmt ,
then call
.I fmtprint
and
.I fmtvprint
to generate the output.
Finally,
.I fmtstrflush
will return the allocated string, which should be freed after use.
Regardless of the output style or type,
.I fmtprint
or
.I fmtvprint
generates the characters.
.SS Custom format verbs
.I Fmtinstall
is used to install custom verbs and flags labeled by character
.IR c ,
which may be any non-zero Unicode character.
.I Fn
should be declared as
.IP
.EX
int fn(Fmt*)
.EE
.PP
.IB Fp ->r
is the flag or verb character to cause
.I fn
to be called.
In
.IR fn ,
.IB fp ->width ,
.IB fp ->prec
are the width and precision, and
.IB fp ->flags
the decoded flags for the verb (see
.IR print (3)
for a description of these items).
The standard flag values are:
.B FmtSign
.RB ( + ),
.B FmtLeft
.RB ( - ),
.B FmtSpace
.RB ( '\ ' ),
.B FmtSharp
.RB ( # ),
.B FmtComma
.RB ( , ),
.B FmtLong
.RB ( l ),
.B FmtShort
.RB ( h ),
.B FmtByte
.RB ( hh ),
.B FmtUnsigned
.RB ( u ),
.B FmtLDouble
.RB ( L ),
and
.B FmtVLong
.RB ( ll ).
The flag bits
.B FmtWidth
and
.B FmtPrec
identify whether a width and precision were specified.
.PP
.I Fn
is passed a pointer to the
.B Fmt
structure recording the state of the output.
If
.IB fp ->r
is a verb (rather than a flag),
.I fn
should use
.B Fmt->args
to fetch its argument from the list,
then format it, and return zero.
If
.IB fp ->r
is a flag,
.I fn
should return a negative value:
the negation of one of the above flag values, or some otherwise unused power of two.
All interpretation of
.IB fp ->width\f1,
.IB fp ->prec\f1,
and
.IB fp-> flags
is left up to the conversion routine.
.I Fmtinstall
returns 0 if the installation succeeds, \-1 if it fails.
.PP
.IR Fmtprint
and
.IR fmtvprint
may be called to
help prepare output in custom conversion routines.
However, these functions clear the width, precision, and flags.
The function
.I dofmt
is the underlying formatter; it
uses the existing contents of
.B Fmt
and should be called only by sophisticated conversion routines.
All these routines return the number of characters
produced.
.PP
Some internal functions may be useful to format primitive types.
They honor the width, precision and flags as described in
.IR print (3).
.I Fmtrune
formats a single character
.BR r .
.I Fmtstrcpy
formats a string
.BR s .
All these routines return zero for successful execution.
.SH EXAMPLES
This function prints an error message with a variable
number of arguments and then quits.
Compared to the corresponding example in
.IR print (3),
this version uses a smaller buffer, will never truncate
the output message, but might generate multiple
.B write
system calls to produce its output.
.IP
.EX
.ta 6n +6n +6n +6n +6n +6n +6n +6n +6n
void 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);
va_end(arg);
fmtprint(&f, "\en");
fmtfdflush(&f);
exits("fatal error");
}
.EE
.PP
This example adds a verb to print complex numbers.
.IP
.EX
typedef
struct {
double r, i;
} Complex;
int
Xfmt(Fmt *f)
{
Complex c;
c = va_arg(f->args, Complex);
return fmtprint(f, "(%g,%g)", c.r, c.i);
}
main(...)
{
Complex x;
x.r = 1.5;
x.i = -2.3;
fmtinstall('X', Xfmt);
print("x = %X\en", x);
}
.EE
.SH SEE ALSO
.IR print (3)
.SH HISTORY
This formatted print library originally
appeared as part of the Plan 9 C library.
.SH BUGS
The Plan 9 version supports Unicode strings and produces UTF output.
This version assumes that characters are always represented by 1-byte values.

179
man/man3/ioproc.3 Normal file
View file

@ -0,0 +1,179 @@
.TH IOPROC 2
.SH NAME
closeioproc,
iocall,
ioclose,
iointerrupt,
iodial,
ioopen,
ioproc,
ioread,
ioreadn,
iowrite \- slave I/O processes for threaded programs
.SH SYNOPSIS
.PP
.de XX
.ift .sp 0.5
.ifn .sp
..
.EX
.ta \w'Ioproc* 'u
#include <u.h>
#include <libc.h>
#include <thread.h>
.sp
typedef struct Ioproc Ioproc;
.sp
Ioproc* ioproc(void);
.XX
int ioopen(Ioproc *io, char *file, int omode);
int ioclose(Ioproc *io, int fd);
long ioread(Ioproc *io, int fd, void *a, long n);
long ioreadn(Ioproc *io, int fd, void *a, long n);
long iowrite(Ioproc *io, int fd, void *a, long n);
int iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp);
.XX
void iointerrupt(Ioproc *io);
void closeioproc(Ioproc *io);
.XX
long iocall(Ioproc *io, long (*op)(va_list *arg), ...);
.EE
.SH DESCRIPTION
.PP
These routines provide access to I/O in slave procs.
Since the I/O itself is done in a slave proc, other threads
in the calling proc can run while the calling thread
waits for the I/O to complete.
.PP
.I Ioproc
forks a new slave proc and returns a pointer to the
.B Ioproc
associated with it.
.I Ioproc
uses
.I mallocz
and
.IR proccreate ;
if either fails, it calls
.I sysfatal
rather than return an error.
.PP
.IR Ioopen ,
.IR ioclose ,
.IR ioread ,
.IR ioreadn ,
.IR iowrite ,
and
.IR iodial
are execute the
similarly named library or system calls
(see
.IR open (2),
.IR read (2),
and
.IR dial (2))
in the slave process associated with
.IR io .
It is an error to execute more than one call
at a time in an I/O proc.
.PP
.I Iointerrupt
interrupts the call currently executing in the I/O proc.
If no call is executing,
.IR iointerrupt
is a no-op.
.PP
.I Closeioproc
terminates the I/O proc and frees the associated
.B Ioproc .
.PP
.I Iocall
is a primitive that may be used to implement
more slave I/O routines.
.I Iocall
arranges for
.I op
to be called in
.IR io 's
proc, with
.I arg
set to the variable parameter list,
returning the value that
.I op
returns.
.SH EXAMPLE
Relay messages between two file descriptors,
counting the total number of bytes seen:
.IP
.EX
.ta +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
int tot;
void
relaythread(void *v)
{
int *fd, n;
char buf[1024];
Ioproc *io;
fd = v;
io = ioproc();
while((n = ioread(io, fd[0], buf, sizeof buf)) > 0){
if(iowrite(io, fd[1], buf, n) != n)
sysfatal("iowrite: %r");
tot += n;
}
closeioproc(io);
}
void
relay(int fd0, int fd1)
{
int fd[4];
fd[0] = fd[3] = fd0;
fd[1] = fd[2] = fd1;
threadcreate(relaythread, fd, 8192);
threadcreate(relaythread, fd+2, 8192);
}
.EE
.LP
If the two
.I relaythread
instances were running in different procs, the
common access to
.I tot
would be unsafe.
.EE
.PP
Implement
.IR ioread :
.IP
.EX
static long
_ioread(va_list *arg)
{
int fd;
void *a;
long n;
fd = va_arg(*arg, int);
a = va_arg(*arg, void*);
n = va_arg(*arg, long);
return read(fd, a, n);
}
long
ioread(Ioproc *io, int fd, void *a, long n)
{
return iocall(io, _ioread, fd, a, n);
}
.EE
.SH SOURCE
.B /sys/src/libthread/io*.c
.SH SEE ALSO
.IR dial (2),
.IR open (2),
.IR read (2),
.IR thread (2)

47
man/man3/isalpharune.3 Normal file
View file

@ -0,0 +1,47 @@
.TH ISALPHARUNE 3
.SH NAME
isalpharune, islowerrune, isspacerune, istitlerune, isupperrune, tolowerrune, totitlerune, toupperrune \- Unicode character classes and cases
.SH SYNOPSIS
.B #include <utf.h>
.PP
.B
int isalpharune(Rune c)
.PP
.B
int islowerrune(Rune c)
.PP
.B
int isspacerune(Rune c)
.PP
.B
int istitlerune(Rune c)
.PP
.B
int isupperrune(Rune c)
.PP
.B
Rune tolowerrune(Rune c)
.PP
.B
Rune totitlerune(Rune c)
.PP
.B
Rune toupperrune(Rune c)
.SH DESCRIPTION
These routines examine and operate on Unicode characters,
in particular a subset of their properties as defined in the Unicode standard.
Unicode defines some characters as alphabetic and specifies three cases:
upper, lower, and title.
Analogously to
.IR ctype (3)
for
.SM ASCII\c
,
these routines
test types and modify cases for Unicode characters.
The names are self-explanatory.
.PP
The case-conversion routines return the character unchanged if it has no case.
.SH "SEE ALSO
.IR ctype (3) ,
.IR "The Unicode Standard" .

469
man/man3/print.3 Normal file
View file

@ -0,0 +1,469 @@
.TH PRINT 3
.de EX
.nf
.ft B
..
.de EE
.fi
.ft R
..
.SH NAME
print, fprint, sprint, snprint, seprint, smprint, vfprint, vsnprint, vseprint, vsmprint \- print formatted output
.SH SYNOPSIS
.B #include <utf.h>
.PP
.B #include <fmt.h>
.PP
.ta \w'\fLchar* 'u
.B
int print(char *format, ...)
.PP
.B
int fprint(int fd, char *format, ...)
.PP
.B
int sprint(char *s, char *format, ...)
.PP
.B
int snprint(char *s, int len, char *format, ...)
.PP
.B
char* seprint(char *s, char *e, char *format, ...)
.PP
.B
char* smprint(char *format, ...)
.PP
.B
int runesprint(Rune *s, char *format, ...)
.PP
.B
int runesnprint(Rune *s, int len, char *format, ...)
.PP
.B
Rune* runeseprint(Rune *s, Rune *e, char *format, ...)
.PP
.B
Rune* runesmprint(char *format, ...)
.PP
.B
int vfprint(int fd, char *format, va_list v)
.PP
.B
int vsnprint(char *s, int len, char *format, va_list v)
.PP
.B
char* vseprint(char *s, char *e, char *format, va_list v)
.PP
.B
char* vsmprint(char *format, va_list v)
.PP
.B
int runevsnprint(Rune *s, int len, char *format, va_list v)
.PP
.B
Rune* runevseprint(Rune *s, Rune *e, char *format, va_list v)
.PP
.B
Rune* runevsmprint(Rune *format, va_list v)
.PP
.B
.SH DESCRIPTION
.I Print
writes text to the standard output.
.I Fprint
writes to the named output
file descriptor.
.I Sprint
places text
followed by the NUL character
.RB ( \e0 )
in consecutive bytes starting at
.IR s ;
it is the user's responsibility to ensure that
enough storage is available.
Each function returns the number of bytes
transmitted (not including the NUL
in the case of
.IR sprint ),
or
a negative value if an output error was encountered.
.PP
.I Snprint
is like
.IR sprint ,
but will not place more than
.I len
bytes in
.IR s .
Its result is always NUL-terminated and holds the maximal
number of characters that can fit.
.I Seprint
is like
.IR snprint ,
except that the end is indicated by a pointer
.I e
rather than a count and the return value points to the terminating NUL of the
resulting string.
.I Smprint
is like
.IR sprint ,
except that it prints into and returns a string of the required length, which is
allocated by
.IR malloc (3).
.PP
The routines
.IR runesprint ,
.IR runesnprint ,
.IR runeseprint ,
and
.I runesmprint
are the same as
.IR sprint ,
.IR snprint ,
.IR seprint
and
.I smprint
except that their output is rune strings instead of byte strings.
.PP
Finally, the routines
.IR vfprint ,
.IR vsnprint ,
.IR vseprint ,
.IR vsmprint ,
.IR runevsnprint ,
.IR runevseprint ,
and
.I runevsmprint
are like their
.BR v-less
relatives except they take as arguments a
.B va_list
parameter, so they can be called within a variadic function.
The Example section shows a representative usage.
.PP
Each of these functions
converts, formats, and prints its
trailing arguments
under control of a
.IR format
string.
The
format
contains two types of objects:
plain characters, which are simply copied to the
output stream,
and conversion specifications,
each of which results in fetching of
zero or more
arguments.
The results are undefined if there are arguments of the
wrong type or too few
arguments for the format.
If the format is exhausted while
arguments remain, the excess
is ignored.
.PP
Each conversion specification has the following format:
.IP
.B "% [flags] verb
.PP
The verb is a single character and each flag is a single character or a
(decimal) numeric string.
Up to two numeric strings may be used;
the first is called
.IR width ,
the second
.IR precision .
A period can be used to separate them, and if the period is
present then
.I width
and
.I precision
are taken to be zero if missing, otherwise they are `omitted'.
Either or both of the numbers may be replaced with the character
.BR * ,
meaning that the actual number will be obtained from the argument list
as an integer.
The flags and numbers are arguments to
the
.I verb
described below.
.PP
The numeric verbs
.BR d ,
.BR i ,
.BR u ,
.BR o ,
.BR b ,
.BR x ,
and
.B X
format their arguments in decimal, decimal,
unsigned decimal, octal, binary, hexadecimal, and upper case hexadecimal.
Each interprets the flags
.BR 0 ,
.BR h ,
.BR hh ,
.BR l ,
.BR + ,
.BR - ,
.BR , ,
and
.B #
to mean pad with zeros,
short, byte, long, always print a sign, left justified, commas every three digits,
and alternate format.
Also, a space character in the flag
position is like
.BR + ,
but prints a space instead of a plus sign for non-negative values.
If neither
short nor long is specified,
then the argument is an
.BR int .
If an unsigned verb is specified,
then the argument is interpreted as a
positive number and no sign is output;
space and
.B +
flags are ignored for unsigned verbs.
If two
.B l
flags are given,
then the argument is interpreted as a
.B vlong
(usually an 8-byte, sometimes a 4-byte integer).
If
.I precision
is not omitted, the number is padded on the left with zeros
until at least
.I precision
digits appear.
If
.I precision
is explicitly 0, and the number is 0,
no digits are generated, and alternate formatting
does not apply.
Then, if alternate format is specified,
for
.B o
conversion, the number is preceded by a
.B 0
if it doesn't already begin with one.
For non-zero numbers and
.B x
conversion, the number is preceded by
.BR 0x ;
for
.B X
conversion, the number is preceded by
.BR 0X .
Finally, if
.I width
is not omitted, the number is padded on the left (or right, if
left justification is specified) with enough blanks to
make the field at least
.I width
characters long.
.PP
The floating point verbs
.BR f ,
.BR e ,
.BR E ,
.BR g ,
and
.B G
take a
.B double
argument.
Each interprets the flags
.BR 0 ,
.BR L
.BR + ,
.BR - ,
and
.B #
to mean pad with zeros,
long double argument,
always print a sign,
left justified,
and
alternate format.
.I Width
is the minimum field width and,
if the converted value takes up less than
.I width
characters, it is padded on the left (or right, if `left justified')
with spaces.
.I Precision
is the number of digits that are converted after the decimal place for
.BR e ,
.BR E ,
and
.B f
conversions,
and
.I precision
is the maximum number of significant digits for
.B g
and
.B G
conversions.
The
.B f
verb produces output of the form
.RB [ - ] digits [ .digits\fR].
.B E
conversion appends an exponent
.BR E [ - ] digits ,
and
.B e
conversion appends an exponent
.BR e [ - ] digits .
The
.B g
verb will output the argument in either
.B e
or
.B f
with the goal of producing the smallest output.
Also, trailing zeros are omitted from the fraction part of
the output, and a trailing decimal point appears only if it is followed
by a digit.
The
.B G
verb is similar, but uses
.B E
format instead of
.BR e .
When alternate format is specified, the result will always contain a decimal point,
and for
.B g
and
.B G
conversions, trailing zeros are not removed.
.PP
The
.B s
verb copies a string
(pointer to
.BR char )
to the output.
The number of characters copied
.RI ( n )
is the minimum
of the size of the string and
.IR precision .
These
.I n
characters are justified within a field of
.I width
characters as described above.
If a
.I precision
is given, it is safe for the string not to be nul-terminated
as long as it is at least
.I precision
characters (not bytes!) long.
The
.B S
verb is similar, but it interprets its pointer as an array
of runes (see
.IR utf (7));
the runes are converted to
.SM UTF
before output.
.PP
The
.B c
verb copies a single
.B char
(promoted to
.BR int )
justified within a field of
.I width
characters as described above.
The
.B C
verb is similar, but works on runes.
.PP
The
.B p
verb formats a pointer value.
At the moment, it is a synonym for
.BR x ,
but that will change if pointers and integers are different sizes.
.PP
The
.B r
verb takes no arguments; it copies the error string returned by a call to
.IR strerror (3)
with an argument of
.IR errno.
.PP
Custom verbs may be installed using
.IR fmtinstall (3).
.SH EXAMPLE
This function prints an error message with a variable
number of arguments and then quits.
.IP
.EX
.ta 6n +6n +6n
void fatal(char *msg, ...)
{
char buf[1024], *out;
va_list arg;
out = vseprint(buf, buf+sizeof buf, "Fatal error: ");
va_start(arg, msg);
out = vseprint(out, buf+sizeof buf, msg, arg);
va_end(arg);
write(2, buf, out-buf);
exit(1);
}
.EE
.SH SEE ALSO
.IR fmtinstall (3),
.IR fprintf (3),
.IR utf (7)
.SH DIAGNOSTICS
Routines that write to a file descriptor or call
.IR malloc
set
.IR errstr .
.SH BUGS
The formatting is close to that specified for ANSI
.IR fprintf (3);
the main difference is that
.B b
and
.B r
are not in ANSI and some
.B C9X
verbs are missing.
Also, and distinctly not a bug,
.I print
and friends generate
.SM UTF
rather than
.SM ASCII.
.PP
There is no
.BR runeprint ,
.BR runefprint ,
etc. because runes are byte-order dependent and should not be written directly to a file; use the
UTF output of
.I print
or
.I fprint
instead.
Also,
.I sprint
is deprecated for safety reasons; use
.IR snprint ,
.IR seprint ,
or
.I smprint
instead.
Safety also precludes the existence of
.IR runesprint .

227
man/man3/regexp9.3 Normal file
View file

@ -0,0 +1,227 @@
.TH REGEXP9 3
.de EX
.nf
.ft B
..
.de EE
.fi
.ft R
..
.de LR
.if t .BR \\$1 \\$2
.if n .RB ` \\$1 '\\$2
..
.de L
.nh
.if t .B \\$1
.if n .RB ` \\$1 '
..
.SH NAME
regcomp, regcomplit, regcompnl, regexec, regsub, regerror \- Plan 9 regular expression library
.SH SYNOPSIS
.B #include <regexp9.h>
.PP
.ta \w'\fLRegprog 'u
.B
Reprog *regcomp(char *exp)
.PP
.B
Reprog *regcomplit(char *exp)
.PP
.B
Reprog *regcompnl(char *exp)
.PP
.nf
.B
int regexec(Reprog *prog, char *string, Resub *match, int msize)
.PP
.nf
.B
void regsub(char *source, char *dest, int dlen, Resub *match, int msize)
.PP
.nf
.B
int rregexec(Reprog *prog, Rune *string, Resub *match, int msize)
.PP
.nf
.B
void rregsub(Rune *source, Rune *dest, int dlen, Resub *match, int msize)
.PP
.B
void regerror(char *msg)
.SH DESCRIPTION
.I Regcomp
compiles a
regular expression and returns
a pointer to the generated description.
The space is allocated by
.IR malloc (3)
and may be released by
.IR free .
Regular expressions are exactly as in
.IR regexp9 (7).
.PP
.I Regcomplit
is like
.I regcomp
except that all characters are treated literally.
.I Regcompnl
is like
.I regcomp
except that the
.B .
metacharacter matches all characters, including newlines.
.PP
.I Regexec
matches a null-terminated
.I string
against the compiled regular expression in
.IR prog .
If it matches,
.I regexec
returns
.B 1
and fills in the array
.I match
with character pointers to the substrings of
.I string
that correspond to the
parenthesized subexpressions of
.IR exp :
.BI match[ i ].sp
points to the beginning and
.BI match[ i ].ep
points just beyond
the end of the
.IR i th
substring.
(Subexpression
.I i
begins at the
.IR i th
left parenthesis, counting from 1.)
Pointers in
.B match[0]
pick out the substring that corresponds to
the whole regular expression.
Unused elements of
.I match
are filled with zeros.
Matches involving
.LR * ,
.LR + ,
and
.L ?
are extended as far as possible.
The number of array elements in
.I match
is given by
.IR msize .
The structure of elements of
.I match
is:
.IP
.EX
typedef struct {
union {
char *sp;
Rune *rsp;
} s;
union {
char *ep;
Rune *rep;
} e;
} Resub;
.EE
.LP
If
.B match[0].s.sp
is nonzero on entry,
.I regexec
starts matching at that point within
.IR string .
If
.B match[0].e.ep
is nonzero on entry,
the last character matched is the one
preceding that point.
.PP
.I Regsub
places in
.I dest
a substitution instance of
.I source
in the context of the last
.I regexec
performed using
.IR match .
Each instance of
.BI \e n\f1,
where
.I n
is a digit, is replaced by the
string delimited by
.BI match[ n ].s.sp
and
.BI match[ n ].e.ep\f1.
Each instance of
.L &
is replaced by the string delimited by
.B match[0].s.sp
and
.BR match[0].e.ep .
The substitution will always be null terminated and
trimmed to fit into dlen bytes.
.PP
.IR Regerror ,
called whenever an error is detected in
.IR regcomp ,
writes the string
.I msg
on the standard error file and exits.
.I Regerror
can be replaced to perform
special error processing.
If the user supplied
.I regerror
returns rather than exits,
.I regcomp
will return 0.
.PP
.I Rregexec
and
.I rregsub
are variants of
.I regexec
and
.I regsub
that use strings of
.B Runes
instead of strings of
.BR chars .
With these routines, the
.I rsp
and
.I rep
fields of the
.I match
array elements should be used.
.SH "SEE ALSO"
.IR grep (1),
.IR regexp9 (7)
.SH DIAGNOSTICS
.I Regcomp
returns
.B 0
for an illegal expression
or other failure.
.I Regexec
returns 0
if
.I string
is not matched.
.SH HISTORY
This particular regular expression was first written by Rob Pike for Plan 9.
It has also appeared as part of the Inferno operating system.
.SH BUGS
There is no way to specify or match a NUL character; NULs terminate patterns and strings.

187
man/man3/rune.3 Normal file
View file

@ -0,0 +1,187 @@
.TH RUNE 3
.SH NAME
runetochar, chartorune, runelen, runenlen, fullrune, utfecpy, utflen, utfnlen, utfrune, utfrrune, utfutf \- rune/UTF conversion
.SH SYNOPSIS
.ta \w'\fLchar*xx'u
.B #include <utf.h>
.PP
.B
int runetochar(char *s, Rune *r)
.PP
.B
int chartorune(Rune *r, char *s)
.PP
.B
int runelen(long r)
.PP
.B
int runenlen(Rune *r, int n)
.PP
.B
int fullrune(char *s, int n)
.PP
.B
char* utfecpy(char *s1, char *es1, char *s2)
.PP
.B
int utflen(char *s)
.PP
.B
int utfnlen(char *s, long n)
.PP
.B
char* utfrune(char *s, long c)
.PP
.B
char* utfrrune(char *s, long c)
.PP
.B
char* utfutf(char *s1, char *s2)
.SH DESCRIPTION
These routines convert to and from a
.SM UTF
byte stream and runes.
.PP
.I Runetochar
copies one rune at
.I r
to at most
.B UTFmax
bytes starting at
.I s
and returns the number of bytes copied.
.BR UTFmax ,
defined as
.B 3
in
.BR <libc.h> ,
is the maximum number of bytes required to represent a rune.
.PP
.I Chartorune
copies at most
.B UTFmax
bytes starting at
.I s
to one rune at
.I r
and returns the number of bytes copied.
If the input is not exactly in
.SM UTF
format,
.I chartorune
will convert to 0x80 and return 1.
.PP
.I Runelen
returns the number of bytes
required to convert
.I r
into
.SM UTF.
.PP
.I Runenlen
returns the number of bytes
required to convert the
.I n
runes pointed to by
.I r
into
.SM UTF.
.PP
.I Fullrune
returns 1 if the string
.I s
of length
.I n
is long enough to be decoded by
.I chartorune
and 0 otherwise.
This does not guarantee that the string
contains a legal
.SM UTF
encoding.
This routine is used by programs that
obtain input a byte at
a time and need to know when a full rune
has arrived.
.PP
The following routines are analogous to the
corresponding string routines with
.B utf
substituted for
.B str
and
.B rune
substituted for
.BR chr .
.PP
.I Utfecpy
copies UTF sequences until a null sequence has been copied, but writes no
sequences beyond
.IR es1 .
If any sequences are copied,
.I s1
is terminated by a null sequence, and a pointer to that sequence is returned.
Otherwise, the original
.I s1
is returned.
.PP
.I Utflen
returns the number of runes that
are represented by the
.SM UTF
string
.IR s .
.PP
.I Utfnlen
returns the number of complete runes that
are represented by the first
.I n
bytes of
.SM UTF
string
.IR s .
If the last few bytes of the string contain an incompletely coded rune,
.I utfnlen
will not count them; in this way, it differs from
.IR utflen ,
which includes every byte of the string.
.PP
.I Utfrune
.RI ( utfrrune )
returns a pointer to the first (last)
occurrence of rune
.I c
in the
.SM UTF
string
.IR s ,
or 0 if
.I c
does not occur in the string.
The NUL byte terminating a string is considered to
be part of the string
.IR s .
.PP
.I Utfutf
returns a pointer to the first occurrence of
the
.SM UTF
string
.I s2
as a
.SM UTF
substring of
.IR s1 ,
or 0 if there is none.
If
.I s2
is the null string,
.I utfutf
returns
.IR s1 .
.SH HISTORY
These routines were written by Rob Pike and Ken Thompson
and first appeared in Plan 9.
.SH SEE ALSO
.IR utf (7),
.IR tcs (1)

65
man/man3/runestrcat.3 Normal file
View file

@ -0,0 +1,65 @@
.TH RUNESTRCAT 3
.SH NAME
runestrcat,
runestrncat,
runestrcmp,
runestrncmp,
runestrcpy,
runestrncpy,
runestrecpy,
runestrlen,
runestrchr,
runestrrchr,
runestrdup,
runestrstr \- rune string operations
.SH SYNOPSIS
.B #include <utf.h>
.PP
.ta \w'\fLRune* \fP'u
.B
Rune* runestrcat(Rune *s1, Rune *s2)
.PP
.B
Rune* runestrncat(Rune *s1, Rune *s2, long n)
.PP
.B
int runestrcmp(Rune *s1, Rune *s2)
.PP
.B
int runestrncmp(Rune *s1, Rune *s2, long n)
.PP
.B
Rune* runestrcpy(Rune *s1, Rune *s2)
.PP
.B
Rune* runestrncpy(Rune *s1, Rune *s2, long n)
.PP
.B
Rune* runestrecpy(Rune *s1, Rune *es1, Rune *s2)
.PP
.B
long runestrlen(Rune *s)
.PP
.B
Rune* runestrchr(Rune *s, Rune c)
.PP
.B
Rune* runestrrchr(Rune *s, Rune c)
.PP
.B
Rune* runestrdup(Rune *s)
.PP
.B
Rune* runestrstr(Rune *s1, Rune *s2)
.SH DESCRIPTION
These functions are rune string analogues of
the corresponding functions in
.IR strcat (3).
.SH HISTORY
These routines first appeared in Plan 9.
.SH SEE ALSO
.IR memmove (3),
.IR rune (3),
.IR strcat (2)
.SH BUGS
The outcome of overlapping moves varies among implementations.

576
man/man3/thread.3 Normal file
View file

@ -0,0 +1,576 @@
.TH THREAD 2
.SH NAME
alt,
chancreate,
chanfree,
chaninit,
chanprint,
mainstacksize,
proccreate,
procdata,
procexec,
procexecl,
procrfork,
recv,
recvp,
recvul,
send,
sendp,
sendul,
nbrecv,
nbrecvp,
nbrecvul,
nbsend,
nbsendp,
nbsendul,
threadcreate,
threaddata,
threadexits,
threadexitsall,
threadgetgrp,
threadgetname,
threadint,
threadintgrp,
threadkill,
threadkillgrp,
threadmain,
threadnotify,
threadid,
threadpid,
threadsetgrp,
threadsetname,
threadwaitchan,
yield \- thread and proc management
.SH SYNOPSIS
.PP
.EX
.ta 4n +4n +4n +4n +4n +4n +4n
#include <u.h>
#include <libc.h>
#include <thread.h>
.sp
#define CHANEND 0
#define CHANSND 1
#define CHANRCV 2
#define CHANNOP 3
#define CHANNOBLK 4
.sp
.ta \w' 'u +\w'Channel 'u
typedef struct Alt Alt;
struct Alt {
Channel *c;
void *v;
int op;
Channel **tag;
int entryno;
};
.fi
.de XX
.ift .sp 0.5
.ifn .sp
..
.PP
.nf
.ft L
.ta \w'\fLChannel* 'u +4n +4n +4n +4n
void threadmain(int argc, char *argv[])
int mainstacksize
int proccreate(void (*fn)(void*), void *arg, uint stacksize)
int procrfork(void (*fn)(void*), void *arg, uint stacksize,
int rforkflag)
int threadcreate(void (*fn)(void*), void *arg, uint stacksize)
void threadexits(char *status)
void threadexitsall(char *status)
void yield(void)
.XX
int threadid(void)
int threadgrp(void)
int threadsetgrp(int group)
int threadpid(int id)
.XX
int threadint(int id)
int threadintgrp(int group)
int threadkill(int id)
int threadkillgrp(int group)
.XX
void threadsetname(char *name)
char* threadgetname(void)
.XX
void** threaddata(void)
void** procdata(void)
.XX
int chaninit(Channel *c, int elsize, int nel)
Channel* chancreate(int elsize, int nel)
void chanfree(Channel *c)
.XX
int alt(Alt *alts)
int recv(Channel *c, void *v)
void* recvp(Channel *c)
ulong recvul(Channel *c)
int nbrecv(Channel *c, void *v)
void* nbrecvp(Channel *c)
ulong nbrecvul(Channel *c)
int send(Channel *c, void *v)
int sendp(Channel *c, void *v)
int sendul(Channel *c, ulong v)
int nbsend(Channel *c, void *v)
int nbsendp(Channel *c, void *v)
int nbsendul(Channel *c, ulong v)
int chanprint(Channel *c, char *fmt, ...)
.XX
int procexecl(Channel *cpid, char *file, ...)
int procexec(Channel *cpid, char *file, char *args[])
Channel* threadwaitchan(void)
.XX
int threadnotify(int (*f)(void*, char*), int in)
.EE
.SH DESCRIPTION
.PP
The thread library provides parallel programming support similar to that
of the languages
Alef and Newsqueak.
Threads
and
procs
occupy a shared address space,
communicating and synchronizing through
.I channels
and shared variables.
.PP
A
.I proc
is a Plan 9 process that contains one or more cooperatively scheduled
.IR threads .
Programs using threads must replace
.I main
by
.IR threadmain .
The thread library provides a
.I main
function that sets up a proc with a single thread executing
.I threadmain
on a stack of size
.I mainstacksize
(default eight kilobytes).
To set
.IR mainstacksize ,
declare a global variable
initialized to the desired value
.RI ( e.g. ,
.B int
.B mainstacksize
.B =
.BR 1024 ).
.PP
.I Threadcreate
creates a new thread in the calling proc, returning a unique integer
identifying the thread; the thread
executes
.I fn(arg)
on a stack of size
.IR stacksize .
Thread stacks are allocated in shared memory, making it valid to pass
pointers to stack variables between threads and procs.
.I Procrfork
creates a new proc, and inside that proc creates
a single thread as
.I threadcreate
would,
returning the id of the created thread.
.I Procrfork
creates the new proc by calling
.B rfork
(see
.IR fork (2))
with flags
.BR RFPROC|RFMEM|RFNOWAIT| \fIrforkflag\fR.
(The thread library depends on all its procs
running in the same rendezvous group.
Do not include
.B RFREND
in
.IR rforkflag .)
.I Proccreate
is identical to
.I procrfork
with
.I rforkflag
set to zero.
Be aware that the calling thread may continue
execution before
the newly created proc and thread
are scheduled.
Because of this,
.I arg
should not point to data on the stack of a function that could
return before the new process is scheduled.
.PP
.I Threadexits
terminates the calling thread.
If the thread is the last in its proc,
.I threadexits
also terminates the proc, using
.I status
as the exit status.
.I Threadexitsall
terminates all procs in the program,
using
.I status
as the exit status.
.PP
The threads in a proc are coroutines, scheduled nonpreemptively
in a round-robin fashion.
A thread must explicitly relinquish control of the processor
before another thread in the same proc is run.
Calls that do this are
.IR yield ,
.IR proccreate ,
.IR procexec ,
.IR procexecl ,
.IR threadexits ,
.IR alt ,
.IR send ,
and
.I recv
(and the calls related to
.I send
and
.IR recv \(emsee
their descriptions further on).
Procs are scheduled by the operating system.
Therefore, threads in different procs can preempt one another
in arbitrary ways and should synchronize their
actions using
.B qlocks
(see
.IR lock (2))
or channel communication.
System calls such as
.IR read (2)
block the entire proc;
all threads in a proc block until the system call finishes.
.PP
As mentioned above, each thread has a unique integer thread id.
Thread ids are not reused; they are unique across the life of the program.
.I Threadid
returns the id for the current thread.
Each thread also has a thread group id.
The initial thread has a group id of zero.
Each new thread inherits the group id of
the thread that created it.
.I Threadgrp
returns the group id for the current thread;
.I threadsetgrp
sets it.
.I Threadpid
returns the pid of the Plan 9 process containing
the thread identified by
.IR id ,
or \-1
if no such thread is found.
.PP
.I Threadint
interrupts a thread that is blocked in a channel operation
or system call.
.I Threadintgrp
interrupts all threads with the given group id.
.I Threadkill
marks a thread to die when it next relinquishes the processor
(via one of the calls listed above).
If the thread is blocked in a channel operation or system call,
it is also interrupted.
.I Threadkillgrp
kills all threads with the given group id.
Note that
.I threadkill
and
.I threadkillgrp
will not terminate a thread that never relinquishes
the processor.
.PP
Primarily for debugging,
threads can have string names associated with them.
.I Threadgetname
returns the current thread's name;
.I threadsetname
sets it.
The pointer returned by
.I threadgetname
is only valid until the next call to
.IR threadsetname .
.PP
.I Threaddata
returns a pointer to a per-thread pointer
that may be modified by threaded programs for
per-thread storage.
Similarly,
.I procdata
returns a pointer to a per-proc pointer.
.PP
.I Procexecl
and
.I procexec
are threaded analogues of
.I exec
and
.I execl
(see
.IR exec (2));
on success,
they replace the calling thread (which must be the only thread in its proc)
and invoke the external program, never returning.
On error, they return \-1.
If
.I cpid
is not null, the pid of the invoked program
will be sent along
.I cpid
once the program has been started, or \-1 will be sent if an
error occurs.
.I Procexec
and
.I procexecl
will not access their arguments after sending a result
along
.IR cpid .
Thus, programs that malloc the
.I argv
passed to
.I procexec
can safely free it once they have
received the
.I cpid
response.
.I Threadwaitchan
returns a channel of pointers to
.B Waitmsg
structures (see
.IR wait (2)).
When an exec'ed process exits, a pointer to a
.B Waitmsg
is sent to this channel.
These
.B Waitmsg
structures have been allocated with
.IR malloc (2)
and should be freed after use.
.PP
A
.B Channel
is a buffered or unbuffered queue for fixed-size messages.
Procs and threads
.I send
messages into the channel and
.I recv
messages from the channel. If the channel is unbuffered, a
.I send
operation blocks until the corresponding
.I recv
operation occurs and
.IR "vice versa" .
.I Chaninit
initializes a
.B Channel
for messages of size
.I elsize
and with a buffer holding
.I nel
messages.
If
.I nel
is zero, the channel is unbuffered.
.IR Chancreate
allocates a new channel and initializes it.
.I Chanfree
frees a channel that is no longer used.
.I Chanfree
can be called by either sender or receiver after the last item has been
sent or received. Freeing the channel will be delayed if there is a thread
blocked on it until that thread unblocks (but
.I chanfree
returns immediately).
.PP
.I Send
sends the element pointed at by
.I v
to the channel
.IR c .
If
.I v
is null, zeros are sent.
.I Recv
receives an element from
.I c
and stores it in
.IR v .
If
.I v
is null,
the received value is discarded.
.I Send
and
.I recv
return 1 on success, \-1 if interrupted.
.I Nbsend
and
.I nbrecv
behave similarly, but return 0 rather than blocking.
.PP
.IR Sendp ,
.IR nbsendp ,
.IR sendul ,
and
.I nbsendul
send a pointer or an unsigned long; the channel must
have been initialized with the appropriate
.IR elsize .
.IR Recvp ,
.IR nbrecvp ,
.IR recvul ,
and
.I nbrecvul
receive a pointer or an unsigned long;
they return zero when a zero is received,
when interrupted, or
(for
.I nbrecvp
and
.IR nbrecvul )
when the operation would have blocked.
To distinguish between these three cases,
use
.I recv
or
.IR nbrecv .
.PP
.I Alt
can be used to recv from or send to one of a number of channels,
as directed by an array of
.B Alt
structures,
each of which describes a potential send or receive operation.
In an
.B Alt
structure,
.B c
is the channel;
.B v
the value pointer (which may be null); and
.B op
the operation:
.B CHANSND
for a send operation,
.B CHANRECV
for a recv operation;
.B CHANNOP
for no operation
(useful
when
.I alt
is called with a varying set of operations).
The array of
.B Alt
structures is terminated by an entry with
.I op
.B CHANEND
or
.BR CHANNOBLK .
If at least one
.B Alt
structure can proceed, one of them is
chosen at random to be executed.
.I Alt
returns the index of the chosen structure.
If no operations can proceed and the list is terminated with
.BR CHANNOBLK ,
.I alt
returns the index of the terminating
.B CHANNOBLK
structure.
Otherwise,
.I alt
blocks until one of the operations can proceed,
eventually returning the index of the structure executes.
.I Alt
returns \-1 when interrupted.
The
.B tag
and
.B entryno
fields in the
.B Alt
structure are used internally by
.I alt
and need not be initialized.
They are not used between
.I alt
calls.
.PP
.I Chanprint
formats its arguments in the manner of
.IR print (2)
and sends the result to the channel
.IR c.
The string delivered by
.I chanprint
is allocated with
.IR malloc (2)
and should be freed upon receipt.
.PP
Thread library functions do not return on failure;
if errors occur, the entire program is aborted.
.PP
Threaded programs should use
.I threadnotify
in place of
.I atnotify
(see
.IR notify (2)).
.PP
It is safe to use
.B sysfatal
(see
.IR perror (2))
in threaded programs.
.I Sysfatal
will print the error string and call
.IR threadexitsall .
.PP
It is safe to use
.IR rfork
(see
.IR fork (2))
to manage the namespace, file descriptors, note group, and environment of a
single process.
That is, it is safe to call
.I rfork
with the flags
.BR RFNAMEG ,
.BR RFFDG ,
.BR RFCFDG ,
.BR RFNOTEG ,
.BR RFENVG ,
and
.BR RFCENVG.
(To create new processes, use
.I proccreate
and
.IR procrfork .)
As mentioned above,
the thread library depends on all procs being in the
same rendezvous group; do not change the rendezvous
group with
.IR rfork .
.SH FILES
.B /sys/lib/acid/thread
contains useful
.IR acid (1)
functions for debugging threaded programs.
.PP
.B /sys/src/libthread/example.c
contains a full example program.
.SH SOURCE
.B /sys/src/libthread
.SH SEE ALSO
.IR intro (2),
.IR ioproc (2)