Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package rc is a small shell over a Plan 9 namespace.

Readme View source

gno.land/p/moul/x/plan9/rc/v0

A small shell over a Plan 9 namespace: ls, cat, stat, ns, bind, mount, unmount, mkdir, rm, echo, cd, pwd, walk, help.

1import rc "gno.land/p/moul/x/plan9/rc/v0"
2
3sh, fs := rc.NewMemShell("g1...", rc.ReadWrite, runtime.ChainHeight)
4out, err := sh.Run("bind -ac /srv/dev /dev; echo hello > /tmp/greeting; ls -l /")

A namespace you cannot inspect is a namespace you cannot trust. Everything here operates on an ns.Ns and returns text, so one realm's Render becomes a file browser and one transaction becomes a shell command.

The mode split is the security model. A shell in ReadOnly mode refuses every mutating command, which is what lets a realm expose it through Render, where mutating anything would be a bug, while the same code backs a crossing Exec that may write.

On the first error the run stops and returns it. A realm should let that error panic, so a half-applied command line reverts with its transaction rather than leaving a namespace nobody asked for.

Two commands exist to make a namespace legible rather than to do work:

  • ns prints the mount table in ns(1) format.
  • walk /bin/rc prints how each element resolves, with the union width per step. It is where a bind stops being magic: the width column says exactly where one took effect, and that a union is top level only.

Quoting follows rc: single quotes, with '' inside a quoted string standing for one literal quote. Commands are separated by ; or newlines, and quoting is respected when splitting them. MaxCommands (32) bounds one run.

Live demo: r/moul/x/plan9/ns renders it. Design and analysis: moul/gno-contracts#136.


Not affiliated with Plan 9. Plan 9 from Bell Labs is the work of the Computing Science Research Center at Bell Labs; the name and the marks are theirs, and the copyright is held by the Plan 9 Foundation. This package borrows the vocabulary and none of the code: it is an independent homage, asking what that ecosystem's spirit looks like on a chain. Full attribution: NOTICE.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

Dependency graph:

gno.land/p/moul/x/plan9/rc/v0 dependency graph

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package rc is a small shell over a Plan 9 namespace.

It exists because a namespace you cannot inspect is a namespace you cannot trust. Everything here operates on a gno.land/p/moul/x/plan9/ns namespace and returns text, so one realm's Render becomes a file browser and one transaction becomes a shell command:

Example
1Exec("bind -a /srv/dev /dev; echo hello > /tmp/greeting")

The mode split is the security model. A Shell in ReadOnly mode refuses every mutating command, which is what lets a realm expose the shell through Render, where mutating anything would be a bug, while the same code backs a crossing Exec that may write.

Quoting follows rc: single quotes, with ” inside a quoted string standing for one literal quote. Commands are separated by ';' or newlines, and quoting is respected when splitting them.

On the first error the run STOPS and returns it. A realm should let that error panic, so a half-applied command line reverts with the transaction rather than leaving the namespace in a state nobody asked for.

NOTICE. Plan 9 from Bell Labs is the work of the Computing Science Research Center at Bell Labs; the name and the marks are theirs, and the copyright is held by the Plan 9 Foundation (https://p9f.org). This package is not affiliated with, endorsed by, or sponsored by them, and contains no Plan 9 code: it borrows the vocabulary so that the design reads without a glossary, and it is an homage, asking what that ecosystem's spirit looks like on a chain. Full attribution: NOTICE.md at the root of moul/gno-contracts.

Constants 2

const MaxCommands

1const MaxCommands = 32
source

MaxCommands bounds one run, so a single call cannot loop the VM.

Variables 1

var ErrReadOnly, ErrUsage, ErrUnknown, ErrQuote

 1var (
 2	// ErrReadOnly is returned when a mutating command runs in ReadOnly mode.
 3	ErrReadOnly = errors.New("read-only shell")
 4	// ErrUsage reports a malformed command line.
 5	ErrUsage = errors.New("usage")
 6	// ErrUnknown reports a command this shell does not have.
 7	ErrUnknown = errors.New("command not found")
 8	// ErrQuote reports an unterminated quoted string.
 9	ErrQuote = errors.New("unterminated '")
10)
source

Functions 2

func New

1func New(n *ns.Ns, mode Mode, now func() int64) *Shell
source

New returns a shell over n. now supplies the block height stamped on writes and may be nil in ReadOnly mode.

func NewMemShell

1func NewMemShell(uid string, mode Mode, now func() int64) (*Shell, *memfs.FS)
source

NewMemShell is the convenience a realm or a test wants: a fresh ram root, a namespace over it, and a shell. It exists here rather than in ns so that ns keeps no dependency on a particular file server.

Types 2

type Mode

ident
1type Mode uint8
source

Mode decides whether mutating commands are allowed.

type Shell

struct
1type Shell struct {
2	ns   *ns.Ns
3	mode Mode
4	now  func() int64
5}
source

Shell runs commands against one namespace.

Methods on Shell

func Ns

method on Shell
1func (s *Shell) Ns() *ns.Ns
source

Ns returns the namespace the shell operates on.

func Run

method on Shell
1func (s *Shell) Run(line string) (string, error)
source

Run executes a command line and returns its output. Execution stops at the first error.

Imports 6

Source Files 4