# lib9p/idl/2003-9P2000.p9p.9p - Definitions of plan9port extension messages # # Copyright (C) 2025 Luke T. Shumaker # SPDX-License-Identifier: AGPL-3.0-or-later # Plan 9 from User Space (a.k.a. plan9port)'s lib9pclient:fsopenfd(3) # and 9pserve(4) proxy server (which takes the place of the Plan 9 # kernel) add a special-purpose `openfd` command to 9P2000. # # https://9fans.github.io/plan9port/man/man9/openfd.htlm # https://github.com/9fans/plan9port/blob/master/man/man9/openfd.9p # https://github.com/9fans/plan9port/commit/32f69c36e0eec1227934bbd34854bfebd88686f2 # https://github.com/9fans/plan9port/pull/692 # BUG: There is no version-string for this extension; plan9port still # calls it vanilla "9P2000". version "9P2000.p9p" from ./2002-9P2000.9p import * # On Plan 9 the usual 9P client is the kernel, not normal userspace # programs. The kernel multiplexes multiple userspace processes onto # a single 9P connection; the userspace programs make 9P calls by # making syscalls. plan9port emulates this by having mock syscalls # that make 9P client calls over an AF_UNIX socket to a local # `9pserve` daemon that does the multiplexing (you add an "fs" prefix; # e.g. you replace syscall:`open()` with lib9pclient:`fsopen()`). # # "Unfortunately", programs in plan9port must deal both with 9P files # and native "Unix" files; and need to turn an 9P FID into a native # file descriptor. To do this, the `9pserve` program and lib9pclient # add an extension call to 9P2000: Topenfd/Ropenfd/fsopenfd(). # # An AF_UNIX socket has the ability to send a file descriptor over it # via an out-of-band "socket control message" ("CMSG" or "SCM"). # # Topenfd asks 9pserve to create a socketpair() file descriptor that # 9pserve will pump to/from a FID, and then send that pipe file # descriptor over a control-message to the client program. # # When replying, the server sends not just an in-band Ropenfd message, # but also an out-of-band control-message with a socketpair() file # descriptor. A successful call results in the FID being clunked. msg Topenfd = "size[4,val=end-&size] typ[1,val=98] tag[tag] fid[fid] mode[o]" msg Ropenfd = "size[4,val=end-&size] typ[1,val=99] tag[tag] qid[qid] iounit[4] unixfd[4]" # BUG: The "unixfd" field nominally indicates the the file descriptor # of the pipe, but really 9pserve doesn't know which FD it will end up # on the client process, and lib9pclient ignores the value here and # overwrites it with the file descriptor indicated from the CMSG