PLUMB(3)
πΈ NAME πΈ
okay so this is PLUMB(3), from the Library Functions Manual, and it's the whole plumb-message situation, bestie. The stars of the show are: eplumb, plumbfree, plumbopen, plumbunmount, plumbopenfid, plumbsend, plumbsendtofid, plumbsendtext, plumblookup, plumbpack, plumbpackattr, plumbaddattr, plumbdelattr, plumbrecv, plumbrecvfid, plumbunpack, plumbunpackpartial, plumbunpackattr, Plumbmsg β plumb messages. periodt π
β¨ SYNOPSIS β¨
#include <u.h>
#include <libc.h>
#include <plumb.h>
int plumbopen(char *port, int omode)
int plumbunmount(void)
int plumbsend(int fd, Plumbmsg *m)
int plumbsendtext(int fd, char *src, char *dst, char *wdir, char *data)
void plumbfree(Plumbmsg *m)
Plumbmsg* plumbrecv(int fd)
char* plumbpack(Plumbmsg *m, int *np)
Plumbmsg* plumbunpack(char *buf, int n)
Plumbmsg* plumbunpackpartial(char *buf, int n, int *morep)
char* plumbpackattr(Plumbattr *a)
Plumbattr* plumbunpackattr(char *a)
char* plumblookup(Plumbattr *a, char *name)
Plumbattr* plumbaddattr(Plumbattr *a, Plumbattr *new)
Plumbattr* plumbdelattr(Plumbattra *a, char *name)
int eplumb(int key, char *port)
#include <9pclient.h>
CFid *plumbopenfid(char *port, int omode)
Plumbmsg* plumbrecvfid(CFid *fid)
int plumbsendtofid(CFid *fid, Plumbmsg *m)
yes bestie,Plumbattrais literally what the page says in thatplumbdelattrsignature β keeping it exactly, no cap π«Ά
π DESCRIPTION π
These routines are your group chat for plumb(7) messages: sending them, receiving them, and translating them between text and these data structures. iconic little setup:
typedef
struct Plumbmsg
{
char *src;
char *dst;
char *wdir;
char *type;
Plumbattr *attr;
int ndata;
char *data;
} Plumbmsg;
typedef
struct Plumbattr
{
char *name;
char *value;
Plumbattr *next;
} Plumbattr;
plumbopenβ opens the named plumb port usingopen(3)modeomode. Ifportstarts with a slash, it's treated as a literal file name. Otherwise, it goes looking for where theplumber(4)service lives and opens the port there. slay.eplumbβ for programs using theevent(3)interface, this registers receipt of messages from the named port using the givenkey.plumbunmountβ the library mounts theplumber(4)service on demand (via the9pclient(3)library) and reuses that mount for laterplumbopencalls.plumbunmountmakes the library throw away its cached mount. That's useful if the plumber service itself got restarted and a client wants to reconnect. fresh start energy β¨plumbsendβ formats messagemand writes it to file descriptorfd, which will usually be the result ofplumbopen("send", OWRITE). Main character behavior.plumbsendtextβ the simplified text-only version. It assumestypeis text, setsattrtonil, and setsndatatostrlen(data).plumbfreeβ frees all the data associated with messagem. Every component ofmmust therefore have been allocated withmalloc(3). no random stack vibes, bestie.plumbrecvβ returns the next message available on file descriptorfd, ornilfor error.plumbpackβ encodes messagemas a character string in the format ofplumb(7), and sets*npto the length in bytes of that string.plumbunpackβ the inverse ofplumbpack: it translates thenbytes ofbufinto aPlumbmsg.plumbunpackpartialβ for messages that show up in pieces. The first call for a given message must be enough to unpack the header; subsequent calls allow unpacking messages with long data sections. For each call,bufpoints to the beginning of the complete message received so far, andnreports the total number of bytes received for that message. If the message is complete, the return value is as inplumbunpack. If it's not complete, andmorepis not null, the return value isniland*morepgets set to the number of bytes remaining to be read for this message to be complete (recall that the byte count is in the header). Those bytes should be read by the caller, placed at locationbuf+n, and the message unpacked again. If an error happens, the return value isniland*morepis zero.plumbpackattrβ converts the listaofPlumbattrstructures into a null-terminated string. If an attribute value contains white space, quote characters, or equal signs, the value gets quoted appropriately. A newline character terminates processing. bougie formatting, but make it correct πplumbunpackattrβ converts the null-terminated stringaback into a list ofPlumbattrstructures.plumblookupβ searches thePlumbattrlistafor an attribute with the givennameand returns the associated value. The returned string is the original value, not a copy. If the attribute has no value, you get the empty string. If the attribute doesn't occur in the list at all, you getnil.plumbaddattrβ appends thenewPlumbattr(which may itself be a list) to the attribute listaand returns the new list.- the next sentence on the page says
Plumbattrsearches listaβ literally, the page saysPlumbattrhere, notPlumbdelattr, so I'm keeping that exact. It searches for the first attribute with namename, deletes it from the list, and returns the resulting list.Plumbdelattris a no-op if no such attribute exists. - error-detail tea β the file descriptor returned by
plumbopenis created withfsopenfd(see9pclient(3)), which masks information about read and write errors. That's acceptable for use inplumbrecv, but not forplumbsend, which depends on seeing details of write errors.plumbopenfid,plumbrecvfid, andplumbsendtofidgive you an explicit interface tolib9pclientthat preserves the exact error details. yup, that's the whole point π₯
π SOURCE π
/src/libplumb
π¦ SEE ALSO π¦
plumb(1), event(3), plumber(4), plumb(7)
π DIAGNOSTICS π
When appropriate β including when a plumbsend fails β these routines set errstr.
π BUGS π
To avoid rewriting clients that use plumbsend, the call plumbopen("send", OWRITE) returns a useless file descriptor (it is opened to /dev/null). Plumbsend looks for this particular file descriptor and uses a static copy of the CFid instead. yes, that's the little hack, bestie π
π okay that's the tea: this is the PLUMB(3) page from the Library Functions Manual, source /src/libplumb, and the footer/version-date situation is just PLUMB(3) β no extra date shown. bye bestie π«Άπ
π¦ where this page comes from
- alpine 3.24: plan9port-doc 0_git20260208-r0 Β· LPL-1.02
- arch rolling: plan9port 20261021-2 Β· custom
- nixos 26.05: plan9port 0-unstable-2025-11-10
- nixos 26.05: plan9port-wayland 0-unstable-2025-11-26
- nixpkgs unstable: plan9port 0-unstable-2025-11-10
- nixpkgs unstable: plan9port-wayland 0-unstable-2025-11-26
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms