1
0
Fork
You've already forked ninepea
0
High-level 9P client library for Zig
  • Zig 100%
typedlambda 91e177cf17 release: v0.1.1
Package: ninepea
Source: main @ e645a3564a
2026年04月13日 23:13:29 +02:00
src release: v0.1.1 2026年04月13日 23:13:29 +02:00
.gitignore release: v0.1.0 2026年03月29日 22:45:04 +02:00
build.zig release: v0.1.0 2026年03月29日 22:45:04 +02:00
build.zig.zon release: v0.1.1 2026年04月13日 23:13:29 +02:00
LICENSE release: v0.1.0 2026年03月29日 22:45:04 +02:00
README.md release: v0.1.0 2026年03月29日 22:45:04 +02:00

ninepea

High-level 9P client library for Zig following the Plan 9 syscall interface.

Overview

ninepea provides a complete Plan 9-style namespace abstraction for 9P clients, with support for:

  • All three 9P dialects: 9P2000, 9P2000.u, 9P2000.L
  • Plan 9 namespace semantics: union directories, bind mounts, mount points
  • Async I/O: Full std.Io integration for cancelable, concurrent operations
  • RAII resource management: Automatic fid lifecycle with defer-safe cleanup
  • Dialect-aware routing: Automatically uses the best available protocol operation

Quick Start

conststd=@import("std");constninepea=@import("ninepea");pubfnmain(opts:std.Options)!void{vargpa:std.heap.DebugAllocator(.{})=.init;defer_=gpa.deinit();constio=opts.io;// Create a namespacevarns=tryninepea.Ns.init(gpa.allocator(),io);deferns.deinit();// Connect and mount a 9P serverconstaddr=trystd.Io.net.IpAddress.parseIp4("127.0.0.1",564);constconn=tryaddr.connect(io,.{});deferconn.close(io);tryns.mount(conn,"","/mnt",.{},"");// Open and read a filevarfile=tryns.openFile("/mnt/data.txt",.{.access=.read});deferfile.close()catch{};varbuf:[4096]u8=undefined;constn=tryfile.read(&buf);std.debug.print("Read {d} bytes\n",.{n});}

Features

Transport Support

  • Wire transport: Network connections (TCP, Unix sockets) and file descriptors
  • DirectPipe: In-process synchronous IPC for testing and embedded servers
  • AsyncDirectPipe: In-process async IPC with concurrent request handling

Namespace Management

// Mount a 9P connection (replaces any existing mount by default)tryns.mount(conn,"","/mnt",.{},"");// Create a union directory (multiple mount points)// First mount establishes the directorytryns.mount(conn1,"","/data",.{},"server1");// Second mount adds to the union, searched after conn1tryns.mount(conn2,"","/data",.{.after=true},"server2");// Mount a DirectPipe (in-process IPC)varpipe:nine_p.proto.DirectPipe(.{})=undefined;nine_p.proto.DirectPipe(.{}).initOwned(&pipe,8192);tryns.mountDirectPipe(&pipe,"","/local",.{},"");// Bind one path to anothertryns.bind("/remote/bin","/bin",.{});// Unmounttryns.unmount("/mnt",null);

File Operations

// Open and readvarfile=tryns.openFile("/path/to/file",.{.access=.read});deferfile.close()catch{};varbuf:[4096]u8=undefined;constn=tryfile.read(&buf);// Create and writevarfile=tryns.createFile("/path/to/new",0o644,.{.access=.write});deferfile.close()catch{};constwritten=tryfile.write("hello world");// Positioned I/Oconstn=tryfile.pread(&buf,1024);constw=tryfile.pwrite("data",2048);// Seekconstoffset=tryfile.seek(-100,.end);

Directory Operations

// Iterate directory entriesvardir=tryninepea.Dir.open(&ns,"/path");deferdir.close()catch{};while(trydir.next())|entry|{std.debug.print("{s}\n",.{entry.name});}// Create files and directoriestrydir.createFile("newfile.txt",0o644,.{.access=.write});trydir.mkdir("subdir",0o755);// Symlinks (9P2000.u / 9P2000.L)trydir.symlink("link","/target/path");

9P2000.L Extended Operations

// File lockingtryfile.lock(.write,0,1024,.{.block=true});deferfile.lock(.unlock,0,1024,.{})catch{};// Extended attributesvarxattr_buf:[256]u8=undefined;constn=tryfile.getxattr("user.comment",&xattr_buf);tryfile.setxattr("user.comment","my note",0);// Fsynctryfile.sync();

Plan 9 Syscall Compatibility

constsys=ninepea.syscalls;constfd=trysys.open(&ns,"/data/file.txt",.{.access=.read});defersys.close(&ns,fd)catch{};varbuf:[256]u8=undefined;constn=trysys.read(&ns,fd,&buf);constn2=trysys.pread(&ns,fd,&buf,1024);

Async Operations

vargroup:std.Io.Group=.init;group.async(io,readFile,.{io,&ns,"/data/file1.txt"});group.async(io,readFile,.{io,&ns,"/data/file2.txt"});group.async(io,readFile,.{io,&ns,"/data/file3.txt"});trygroup.await(io);

DirectPipe In-Process IPC

constnine_p=@import("nine_p");// Create an in-process pipevarpipe:nine_p.proto.DirectPipe(.{})=undefined;nine_p.proto.DirectPipe(.{}).initOwned(&pipe,8192);deferpipe.deinit();// Mount the client sidetryns.mountDirectPipe(&pipe,"","/proc",.{},"");// Run a server handler on pipe.server() in another taskvargroup:std.Io.Group=.init;group.async(io,runServer,.{io,&pipe});// Use files in /proc like any other mountvarfile=tryns.openFile("/proc/status",.{.access=.read});deferfile.close()catch{};

Architecture

See DESIGN.md for the complete design document.

Key Components

  • Ns: Namespace management (mount, bind, unmount, path resolution)
  • File: Open file handle (read, write, seek, stat, close)
  • Dir: Directory iteration and operations
  • MountPoint: 9P connection state (session, fid pool, cache)
  • NamespaceTree: Union mount table and path resolution
  • FidCache: Fid reuse optimization
  • DialectRouter: Automatic dialect-specific operation dispatch

Building

zig build

Testing

zig build test
zig build test --summary all

Dependencies

  • nine_p: Low-level 9P protocol library
  • std.Io: Standard library async I/O

Project Status

This is a design document and initial structure. Implementation is in progress.

See DESIGN.md for detailed architecture, API specifications, and implementation roadmap.

License

Same license as the parent 9p repository.