rpcbuf(3I)

✨ NAME ✨

okay bestie, so this is rpcbuf β€” and it's a streambuf that's been specialized for sending and receiving RPC requests. yes, the whole personality is RPC. πŸ’… (this page is from the 3I section of the InterViews Reference Manual, just so you know where you are πŸŽ€)


🌸 SYNOPSIS 🌸

#include <Dispatch/rpcbuf.h>

πŸ¦‹ DESCRIPTION πŸ¦‹

so an rpcbuf is a streambuf that got specialized in two ways, and honestly? both ate. 🫢

  1. it uses an IPC connection as a source or sink of characters
  2. it sends and receives RPC requests

and the way it does that second one is iconic: the rpcbuf encloses RPC requests in packets that begin with a length field, so that the rpcbuf can buffer requests until they're complete if the user is doing non-blocking I/O. no cap, that's the whole trick. ✨


πŸŽ€ CONSTRUCTORS πŸŽ€

  • rpcbuf(iostreamb* = nil) β€” construct an unopened rpcbuf, and hand it a pointer to an iostreamb so it can read and write the length field of RPC requests. it literally needs it for the length field, that's its whole thing. πŸ’œ

πŸ’… IPC OPERATIONS πŸ’…

  • const char* host()
  • int port()
  • int fd()
  • boolean opened()
  • boolean nonblocking()

those five are the vibe check on your IPC connection β€” they return info about it. 🌈


  • enum { anyport = 0 }
  • rpcbuf* listen(int port) β€” create a socket, bind that socket to a <localhost, port> address, and get ready to accept incoming connections. you can use anyport in place of a specific port number if you're feeling ✨spontaneous✨. returns the rpcbuf's address if it worked, nil otherwise.
  • rpcbuf* connect(const char* host, int port) β€” create a socket and connect it to a peer at the <host, port> address. returns the rpcbuf's address if it worked, nil otherwise. reaching out to your mutuals, basically. πŸ¦‹
  • rpcbuf* accept(int& fd) β€” accept an incoming connection, allocate a brand new file descriptor for it, and assign that new file descriptor to the parameter. returns the rpcbuf's address if it worked, nil otherwise. > heads up bestie: this one can be called only for rpcbufs that have already called listen. no listen, no accept, periodt.
  • rpcbuf* attach(int fd) β€” attach the rpcbuf to a file descriptor. and it will not be allowed to close that file descriptor. not its fd, not its business. πŸ™ˆ
  • rpcbuf* nonblocking(boolean) β€” enable or disable non-blocking I/O on the file descriptor. > it's disabled by default, so don't come for me.
  • rpcbuf* verbose(boolean) β€” enable or disable printing of error messages when anything goes wrong. > enabled by default β€” she's chatty, she tells you when something's up. 😭
  • rpcbuf* close() β€” flush the get and put areas, close the file descriptor if it was created by the rpcbuf, and detach the rpcbuf from the file descriptor. a clean exit, we love to see it. πŸ‘‘

πŸ”₯ RPC OPERATIONS πŸ”₯

  • int start_request() β€” if a current request exists, it computes that request's length and inserts the length into the request's length field. then it starts a new request, making sure to leave space for the new request's length field. returns 0 if no problem occurred, EOF otherwise. πŸ”₯
  • int read_request() β€” returns 0 if a complete request is buffered in the get area, EOF otherwise. and here's the detail, don't miss it: the rpcbuf moves the get pointer back to the beginning of the request after extracting the length field and checking that the get area contains that many bytes. so it checks, then rewinds. 🧚

⭐ STREAMBUF OPERATIONS ⭐

  • virtual int overflow(int c=EOF) β€” if it's given EOF, it terminates the current request. it flushes all requests buffered in the put area except for the last request if it's still incomplete. then it shifts any still incomplete request to the beginning of the put area. and if it's given a character instead? it appends that character to the request. πŸ’–
  • virtual int underflow() β€” flushes the put area. shifts any still unread or incomplete requests to the beginning of the get area and positions the get pointer at the beginning of the get area. reads as much data as is available to fill the rest of the get area. returns the get area's first character, or EOF if a problem occurred. 🌸
  • virtual int sync() β€” discards any still unread requests from the get area, and flushes all buffered requests from the put area. out with the old, bestie. ✨
  • virtual streampos seekoff(streamoff, ios::seek_dir, int) β€” this one lets the user find the get pointer's current position, so the user can compute how many bytes the get pointer moved between calls to seekoff. > and that is the only thing it allows. if the user tries to do anything else, it returns EOF. it's giving boundaries, and honestly? valid. πŸ’…
  • virtual streambuf* setbuf(char*, int) β€” rejects any attempt to set the buffer used to store incoming and outgoing requests. because the rpcbuf dynamically allocates separate buffers for both areas and automatically resizes the buffers whenever necessary. she handles her own storage, thank you very much. πŸ‘‘

🫢 SEE ALSO 🫢

  • IOS.INTRO(3C++)
  • rpcstream(3I)

go read those too, iykyk. πŸ’œ


and that's the whole page, bestie!! this was the InterViews Reference Manual, and this page is dated 27 March 1991 β€” yeah, she's an elder icon but the drip is timeless. πŸŒˆβœ¨πŸ’– bye mwah πŸŽ€