summaryrefslogtreecommitdiff
path: root/static/plan9-4e/man2/9p.2
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-26 16:38:00 -0400
committerJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-26 16:38:00 -0400
commit97d5c458cfa039d857301e1ca7d5af3beb37131d (patch)
treeb460cd850d0537eb71806ba30358840377b27688 /static/plan9-4e/man2/9p.2
parentb89dc2331a50c63f8b33272a5c4c61ab98abdaa3 (diff)
build: Better Build System
Diffstat (limited to 'static/plan9-4e/man2/9p.2')
-rw-r--r--static/plan9-4e/man2/9p.2678
1 files changed, 678 insertions, 0 deletions
diff --git a/static/plan9-4e/man2/9p.2 b/static/plan9-4e/man2/9p.2
new file mode 100644
index 00000000..f1191bb5
--- /dev/null
+++ b/static/plan9-4e/man2/9p.2
@@ -0,0 +1,678 @@
+.TH 9P 2
+.SH NAME
+Srv,
+dirread9p,
+emalloc9p,
+erealloc9p,
+estrdup9p,
+postfd,
+postmountsrv,
+readbuf,
+readstr,
+respond,
+threadpostmountsrv,
+srv \- 9P file service
+.SH SYNOPSIS
+.ft L
+.nf
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+.fi
+.PP
+.ft L
+.nf
+.ta \w'\fL1234'u +\w'\fLTree* 'u
+typedef struct Srv {
+ Tree* tree;
+
+ void (*attach)(Req*);
+ void (*auth)(Req*);
+ void (*open)(Req*);
+ void (*create)(Req*);
+ void (*read)(Req*);
+ void (*write)(Req*);
+ void (*remove)(Req*);
+ void (*flush)(Req*);
+ void (*stat)(Req*);
+ void (*wstat)(Req*);
+ void (*walk)(Req*);
+
+ char* (*walk1)(Fid *fid, char *name, Qid *qid);
+ char* (*clone)(Fid *oldfid, Fid *newfid);
+
+ void (*destroyfid)(Fid*);
+ void (*destroyreq)(Req*);
+ void (*end)(Srv*);
+ void* aux;
+} Srv;
+.fi
+.PP
+.nf
+.ft L
+.ta \w'\fLvoid* 'u
+int srv(Srv *s, int fd)
+int postmountsrv(Srv *s, char *srvname, char *mtpt, int flag)
+int threadpostmountsrv(Srv *s, char *srvname, char *mtpt, int flag)
+int postfd(char *srvname, int fd)
+void respond(Req *r, char *error)
+ulong readstr(Req *r, char *src)
+ulong readbuf(Req *r, void *src, ulong nsrc)
+typedef int Dirgen(int n, Dir *dir, void *aux)
+void dirread9p(Req *r, Dirgen *gen, void *aux)
+.fi
+.PP
+.nf
+.ft L
+.ta \w'\fLvoid* 'u
+void* emalloc9p(ulong n)
+void* erealloc9p(void *v, ulong n)
+char* estrdup9p(char *s)
+.fi
+.PP
+.nf
+.ft L
+extern int chatty9p;
+.fi
+.SH DESCRIPTION
+The function
+.I srv
+uses serves a 9P session by dispatching requests
+to the function pointers kept in
+.BR Srv .
+.PP
+.B Req
+and
+.B Fid
+structures are allocated one-to-one with uncompleted
+requests and active fids, and are described in
+.IR 9pfid (2).
+.PP
+The behavior of
+.I srv
+depends on whether there is a file tree
+(see
+.IR 9pfile (2))
+associated with the server, that is,
+whether the
+.B tree
+element is nonzero.
+The differences are made explicit in the
+discussion of the service loop below.
+The
+.B aux
+element is the client's, to do with as it pleases.
+At the end of its service loop,
+.I srv
+calls the
+.I endsrv
+function (if not zero)
+on the
+.I Srv
+structure itself.
+.I Endsrv
+should perform any necessary cleanup,
+which may include freeing the data associated
+with
+.IR aux ,
+or freeing the
+.B Srv
+structure itself.
+.PP
+.I Srv
+does not return until the 9P conversation is finished.
+.I Postmountsrv
+and
+.I threadpostmountsrv
+are wrappers that create a separate process in which to run
+.IR srv ,
+optionally posting the remote end of the service pipe in
+.BI /srv/ srvname
+or mounting it at
+.IR mtpt .
+They both return
+the file descriptor corresponding to the
+.I local
+end of the service pipe on success, or \-1 on failure.
+.I Threadpostmountsrv
+is intended for use in programs that utilize the
+.IR thread (2)
+library.
+.I Postfd
+posts the given file descriptor as
+.BI /srv/ srvname \fR,
+but does not mount and does not start the service loop.
+.PP
+Since it is usually run in a separate process so that
+the caller can exit, the service loop has little chance
+to return gracefully on out of memory errors.
+It calls
+.IR emalloc9p ,
+.IR erealloc9p ,
+and
+.I estrdup 9p
+to obtain its memory.
+The default implementations of these functions
+act as
+.IR malloc ,
+.IR realloc ,
+and
+.I strdup
+but abort the program if they run out of memory.
+If alternate behavior is desired, clients can link against
+alternate implementations of these functions.
+.SS Service functions
+The functions in a
+.B Srv
+structure named after 9P transactions
+are called to satisfy requests as they arrive.
+If a function is provided, it
+.I must
+arrange for
+.I respond
+to be called when the request is satisfied.
+The only parameter of each service function
+is a
+.B Req*
+parameter (say
+.BR r ).
+The incoming request parameters are stored in
+.IB r -> ifcall \fR;
+.IB r -> fid
+and
+.IB r -> newfid
+are pointers to
+.B Fid
+structures corresponding to the
+numeric fids in
+.IB r -> ifcall \fR;
+similarly,
+.IB r -> oldreq
+is the
+.B Req
+structure corresponding to
+.IB r -> ifcall.oldreq \fR.
+The outgoing response data should be stored in
+.IB r -> ofcall \fR.
+The one exception to this rule is that
+.B stat
+should fill in
+.IB r -> d
+rather than
+.IB r -> ofcall.stat \fR:
+the library will convert the structure into the machine-independent
+wire representation.
+Similarly,
+.B wstat
+may consult
+.IB r -> d
+rather than decoding
+.IB r -> ifcall . stat
+itself.
+When a request has been handled,
+.I respond
+should be called with
+.B r
+and an error string.
+If the request was satisfied successfully, the error
+string should be a nil pointer.
+Note that it is permissible for a function to return
+without itself calling
+.IR respond ,
+as long as it has arranged for
+.I respond
+to be called at some point in the future
+by another proc sharing its address space,
+but see the discussion of
+.B flush
+below.
+Once
+.I respond
+has been called, the
+.B Req*
+as well as any pointers it once contained must
+be considered freed and not referenced.
+.PP
+If the service loop detects an error in a request
+(e.g., an attempt to reuse an extant fid, an open of
+an already open fid, a read from a fid opened for write, etc.)
+it will reply with an error without consulting
+the service functions.
+.PP
+The service loop provided by
+.I srv
+(and indirectly by
+.I postmountsrv
+and
+.IR threadpostmountsrv )
+is single-threaded.
+If it is expected that some requests might
+block, arranging for alternate processes
+to handle them is suggested.
+.PP
+The constraints on the service functions are as follows.
+These constraints are checked while the server executes.
+If a service function fails to do something it ought to have,
+.I srv
+will call
+.I endsrv
+and then abort.
+.TP
+.I Auth
+If authentication is desired,
+the
+.I auth
+function should record that
+.B afid
+is the new authentication fid and
+set
+.I afid->qid
+and
+.IR ofcall.qid .
+.I Auth
+may be nil, in which case it will be treated as having
+responded with the error
+.RI `` "argv0: authentication not required" ,''
+where
+.I argv0
+is the program name variable as set by
+.I ARGBEGIN
+(see
+.IR arg (2)).
+.TP
+.I Attach
+The
+.I attach
+function should check the authentication state of
+.B afid
+if desired,
+and set
+.IB r -> fid -> qid
+and
+.I ofcall.qid
+to the qid of the file system root.
+.I Attach
+may be nil only if file trees are in use;
+in this case, the qid will be filled from the root
+of the tree, and no authentication will be done.
+.TP
+.B Walk
+If file trees are in use,
+.I walk
+is handled internally, and
+.IB srv -> walk
+is never called.
+.IP
+If file trees are not in use,
+.I walk
+should consult
+.B ifcall.wname
+and
+.BR ifcall.nwname ,
+filling in
+.B ofcall.qid
+and
+.BR ofcall.nqid ,
+and also copying any necessary
+.B aux
+state from
+.IB r -> fid
+to
+.IB r -> newfid
+when the two are different.
+As long as
+.I walk
+sets
+.B ofcall.nqid
+appropriately, it can
+.I respond
+with a nil error string even when 9P
+demands an error
+.RI ( e.g. ,
+in the case of a short walk);
+the library detects error conditions and handles them appropriately.
+.TP
+.B Walk1\fR, \fPClone
+Because implementing the full walk message is
+intricate and prone to error, the client may instead provide functions
+.IB srv -> walk1
+and (optionally)
+.IB srv -> clone \fR.
+.IR Clone ,
+if non-nil, is called to signal the creation of
+.I newfid
+from
+.IR oldfid .
+Typically a
+.I clone
+routine will copy or increment a reference count in
+.IR oldfid 's
+.I aux
+element.
+.I Walk1
+should walk
+.I fid
+to
+.IR name ,
+initializing both
+.IB fid -> qid
+and
+.BI * qid
+to the new path's qid.
+Rather than calling
+.IR respond ,
+both should return nil
+on success or an error message on error.
+.TP
+.B Open
+If file trees are in use, the file
+metadata will be consulted on open, create, remove, and wstat
+to see if the requester has the appropriate permissions.
+If not, an error will be sent back without consulting a service function.
+.PP
+If not using file trees or the user has the appropriate permissions,
+.I open
+is called with
+.IB r -> ofcall . qid
+already initialized to the one stored in the
+.B Fid
+structure (that is, the one returned in the previous walk).
+If the qid changes, both should be updated.
+.TP
+.B Create
+The
+.I create
+function must fill in
+both
+.IB r -> fid -> qid
+and
+.IB r -> ofcall . qid
+on success.
+When using file trees,
+.I create
+should allocate a new
+.B File
+with
+.IR createfile ;
+note that
+.I createfile
+may return nil (because, say, the file already exists).
+If the
+.I create
+function is nil,
+.I srv
+behaves as though it were a function that always responded
+with the error ``create prohibited''.
+.TP
+.B Remove
+.I Remove
+should mark the file as removed, whether
+by calling
+.I removefile
+when using file trees, or by updating an internal data structure.
+In general it is not a good idea to clean up the
+.I aux
+information associated with the corresponding
+.B File
+at this time, to avoid memory errors if other
+fids have references to that file.
+Instead, it is suggested that
+.I remove
+simply mark the file as removed (so that further
+operations on it know to fail) and wait until the
+file tree's destroy function is called to reclaim the
+.I aux
+pointer.
+If not using file trees, it is prudent to take the
+analogous measures.
+If
+.I remove
+is not provided, all remove requests will draw
+``remove prohibited'' errors.
+.TP
+.B Read
+The
+.I read
+function must be provided; it fills
+.IB r -> ofcall . data
+with at most
+.IB r -> ifcall . count
+bytes of data from offset
+.IB r -> ofcall . offset
+of the file.
+It also sets
+.IB r -> ofcall . count
+to the number of bytes being returned.
+If using file trees,
+.I srv
+will handle reads of directories internally, only
+calling
+.I read
+for requests on files.
+.I Readstr
+and
+.I readbuf
+are useful for satisfying read requests on a string or buffer.
+Consulting the request in
+.BR r->ifcall ,
+they fill
+.B r->ofcall.data
+and set
+.BR r->ofcall.count ;
+they do not call
+.BR respond .
+Similarly,
+.I dirread9p
+can be used to handle directory reads in servers
+not using file trees.
+The passed
+.I gen
+function will be called as necessary to
+fill
+.I dir
+with information for the
+.I n th
+entry in the directory.
+The string pointers placed in
+.I dir
+should be fresh copies
+made with
+.IR estrdup9p ;
+they will be freed by
+.I dirread9p
+after each successful call to
+.IR gen .
+.I Gen
+should return zero if it successfully filled
+.IR dir ,
+minus one on end of directory.
+.TP
+.B Write
+The
+.I write
+function is similar but need not be provided.
+If it is not, all writes will draw
+``write prohibited'' errors.
+Otherwise,
+.I write
+should attempt to write the
+.IB r -> ifcall . n
+bytes of
+.IB r -> ifcall . data
+to offset
+.IB r -> ifcall . offset
+of the file, setting
+.IB r -> ofcall . offset
+to the number of bytes actually written.
+Most programs consider it an error to
+write less than the requested amount.
+.TP
+.B Stat
+.I Stat
+should fill
+.IB r -> d
+with the stat information for
+.IB r -> fid \fR.
+If using file trees,
+.IB r -> d
+will have been initialized with the stat info from
+the tree, and
+.I stat
+itself may be nil.
+.TP
+.I Wstat
+The
+.I wstat
+consults
+.IB r -> d
+in changing the metadata for
+.IB r -> fid
+as described in
+.IR stat (5).
+When using file trees,
+.I srv
+will take care to check that the request satisfies
+the permissions outlined in
+.IR stat (5).
+Otherwise
+.I wstat
+should take care to enforce permissions
+where appropriate.
+.TP
+.B Flush
+Single-threaded servers, which always call
+.I respond
+before returning from the service functions,
+need not provide a
+.I flush
+implementation:
+.I flush
+is only necessary in multithreaded programs,
+which arrange for
+.I respond
+to be called asynchronously.
+.I Flush
+must ensure that once
+.I respond
+has been called on
+.BR r ,
+.I respond
+will
+.I never
+be called on
+.IB r -> oldreq \fR,
+and in fact that
+.IB r -> oldreq
+and the pointers it contains
+will never be accessed again (consider them freed).
+.I Flush
+must
+.I not
+call respond with a non-nil error string.
+.PD
+.PP
+.IR Destroyfid ,
+.IR destroyreq ,
+and
+.I end
+are auxiliary functions, not called in direct response to 9P requests.
+.TP
+.B Destroyfid
+When a
+.BR Fid 's
+reference count drops to zero
+.RI ( i.e.,
+it has been clunked and there are no outstanding
+requests referring to it),
+.I destroyfid
+is called to allow the program to dispose
+of the
+.B Fid.aux
+pointer.
+.TP
+.B Destroyreq
+Similarly, when a
+.BR Req 's
+reference count drops to zero
+.RI ( i.e. ,
+it has been handled via
+.I respond
+or has been successfully flushed),
+.I destroyreq
+is called to allow the program to dispose of the
+.B Req.aux
+pointer.
+.TP
+.B End
+Once the 9P service loop has finished
+(end of file been reached on the service pipe
+or a bad message has been read),
+.I end
+is called (if provided) to allow any final cleanup.
+For example, it is used by the Palm Pilot synchronization
+file system to gracefully close the serial connection once
+the file system has been unmounted.
+After calling
+.IR end ,
+the service loop (which runs in a separate process
+from its caller) terminates using
+.I _exits
+(see
+.IR exits (2)).
+.PD
+.PP
+If the
+.B chatty9p
+flag is at least one,
+a transcript of the 9P session is printed
+on standard error.
+If the
+.B chatty9p
+flag is greater than one,
+additional unspecified debugging output is generated.
+By convention, servers written using this library
+accept the
+.B -D
+option to increment
+.BR chatty9p .
+.SH EXAMPLES
+.IR Archfs (4),
+.IR cdfs (4),
+.IR nntpfs (4),
+.IR snap (4),
+and
+.B /sys/src/lib9p/ramfs.c
+are good examples of simple single-threaded file servers.
+.IR Webfs (4)
+and
+.I sshnet
+(see
+.IR ssh (1))
+are good examples of multithreaded file servers.
+.PP
+In general, the
+.B File
+interface is appropriate for maintaining arbitrary file trees (as in
+.IR ramfs ).
+The
+.B File
+interface is best avoided when the
+tree structure is easily generated as necessary;
+this is true when the tree is highly structured (as in
+.I cdfs
+and
+.IR nntpfs )
+or is maintained elsewhere.
+.SH SOURCE
+.B /sys/src/lib9p
+.SH SEE ALSO
+.IR 9pfid (2),
+.IR 9pfile (2),
+.IR srv (3),
+.IR intro (5)
+.SH BUGS
+The switch to 9P2000 was taken as an opportunity to tidy
+much of the interface; we promise to avoid such gratuitous change
+in the future.