From b2cfc4e2e71d0f0a5113ddfbd93c8285cc4d74e4 Mon Sep 17 00:00:00 2001 From: rsc Date: Tue, 30 Sep 2003 17:47:41 +0000 Subject: Initial revision --- man/man3/bio.3 | 336 +++++++++++++++++++++++++++++ man/man3/fmtinstall.3 | 346 +++++++++++++++++++++++++++++ man/man3/ioproc.3 | 179 +++++++++++++++ man/man3/isalpharune.3 | 47 ++++ man/man3/print.3 | 469 ++++++++++++++++++++++++++++++++++++++++ man/man3/regexp9.3 | 227 +++++++++++++++++++ man/man3/rune.3 | 187 ++++++++++++++++ man/man3/runestrcat.3 | 65 ++++++ man/man3/thread.3 | 576 +++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 2432 insertions(+) create mode 100644 man/man3/bio.3 create mode 100644 man/man3/fmtinstall.3 create mode 100644 man/man3/ioproc.3 create mode 100644 man/man3/isalpharune.3 create mode 100644 man/man3/print.3 create mode 100644 man/man3/regexp9.3 create mode 100644 man/man3/rune.3 create mode 100644 man/man3/runestrcat.3 create mode 100644 man/man3/thread.3 (limited to 'man/man3') diff --git a/man/man3/bio.3 b/man/man3/bio.3 new file mode 100644 index 00000000..cf504631 --- /dev/null +++ b/man/man3/bio.3 @@ -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 +.B #include +.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. diff --git a/man/man3/fmtinstall.3 b/man/man3/fmtinstall.3 new file mode 100644 index 00000000..2a0e55bf --- /dev/null +++ b/man/man3/fmtinstall.3 @@ -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 +.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. diff --git a/man/man3/ioproc.3 b/man/man3/ioproc.3 new file mode 100644 index 00000000..1cada2de --- /dev/null +++ b/man/man3/ioproc.3 @@ -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 +#include +#include +.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) + diff --git a/man/man3/isalpharune.3 b/man/man3/isalpharune.3 new file mode 100644 index 00000000..f9f58cde --- /dev/null +++ b/man/man3/isalpharune.3 @@ -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 +.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" . diff --git a/man/man3/print.3 b/man/man3/print.3 new file mode 100644 index 00000000..1fab0ad8 --- /dev/null +++ b/man/man3/print.3 @@ -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 +.PP +.B #include +.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 . diff --git a/man/man3/regexp9.3 b/man/man3/regexp9.3 new file mode 100644 index 00000000..f2603562 --- /dev/null +++ b/man/man3/regexp9.3 @@ -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 +.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. diff --git a/man/man3/rune.3 b/man/man3/rune.3 new file mode 100644 index 00000000..7ce978ae --- /dev/null +++ b/man/man3/rune.3 @@ -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 +.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 , +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) diff --git a/man/man3/runestrcat.3 b/man/man3/runestrcat.3 new file mode 100644 index 00000000..c012e59e --- /dev/null +++ b/man/man3/runestrcat.3 @@ -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 +.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. diff --git a/man/man3/thread.3 b/man/man3/thread.3 new file mode 100644 index 00000000..3009ac84 --- /dev/null +++ b/man/man3/thread.3 @@ -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 +#include +#include +.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) -- cgit v1.2.3