Package plan9 contains an interface to the low-level operating system primitives for Plan 9.
golang.org/x/sys/plan9Package plan9 provides a direct interface to the low-level operating system primitives on Plan 9. The primary use of this package is inside other packages that provide a more portable interface to the system, such as os, time, and net. Use those packages rather than this one if you can.
These calls return err == nil to indicate success; otherwise err represents an operating system error describing the failure and holds a value of type syscall.ErrorString.
import "golang.org/x/sys/plan9"File I/O functions for opening, creating, reading, writing, and closing files.
func Open(path string, mode int) (fd int, err error)
func Create(path string, mode int, perm uint32) (fd int, err error)
func Read(fd int, p []byte) (n int, err error)
func Write(fd int, p []byte) (n int, err error)
func Pread(fd int, p []byte, offset int64) (n int, err error)
func Pwrite(fd int, p []byte, offset int64) (n int, err error)
func Close(fd int) (err error)
func Seek(fd int, offset int64, whence int) (newoffset int64, err error)
func Dup(oldfd int, newfd int) (fd int, err error)
func Fd2path(fd int) (path string, err error)Usage Example:
import "golang.org/x/sys/plan9"
// Open and read a file
fd, err := plan9.Open("/etc/hosts", plan9.O_RDONLY)
if err != nil {
panic(err)
}
defer plan9.Close(fd)
buf := make([]byte, 1024)
n, err := plan9.Read(fd, buf)
if err != nil {
panic(err)
}Functions for querying and modifying file metadata using Plan 9's stat protocol.
func Stat(path string, edir []byte) (n int, err error)
func Fstat(fd int, edir []byte) (n int, err error)
func Wstat(path string, edir []byte) (err error)
func Fwstat(fd int, edir []byte) (err error)Functions for manipulating directories and file system entries.
func Mkdir(path string, mode uint32) (err error)
func Remove(path string) error
func Chdir(path string) (err error)
func Fchdir(fd int) (err error)Plan 9's unique bind and mount operations for namespace manipulation.
func Bind(name string, old string, flag int) (err error)
func Mount(fd int, afd int, old string, flag int, aname string) (err error)
func Unmount(name, old string) (err error)Usage Example:
// Bind a directory
err := plan9.Bind("/tmp/foo", "/mnt/bar", plan9.MAFTER)
if err != nil {
panic(err)
}
// Unmount when done
err = plan9.Unmount("", "/mnt/bar")Functions for process identification, waiting, and exit.
func Getpid() (pid int)
func Getppid() (ppid int)
func Exit(code int)
func Await(w *Waitmsg) (err error)Create and manage pipes for inter-process communication.
func Pipe(p []int) (err error)Usage Example:
p := make([]int, 2)
err := plan9.Pipe(p)
if err != nil {
panic(err)
}
// p[0] is read end, p[1] is write end
defer plan9.Close(p[0])
defer plan9.Close(p[1])Functions for accessing and modifying environment variables.
func Getenv(key string) (value string, found bool)
func Setenv(key, value string) error
func Unsetenv(key string) error
func Clearenv()
func Environ() []stringUsage Example:
// Get environment variable
value, found := plan9.Getenv("PATH")
if found {
fmt.Println("PATH:", value)
}
// Set environment variable
err := plan9.Setenv("MYVAR", "myvalue")Functions for querying and changing the current working directory.
func Getwd() (wd string, err error)Functions for time-related system calls.
func Gettimeofday(tv *Timeval) error
func NsecToTimeval(nsec int64) (tv Timeval)Functions for user and group identification (stub implementations on Plan 9).
func Getuid() (uid int)
func Getgid() (gid int)
func Geteuid() (euid int)
func Getegid() (egid int)
func Getgroups() (gids []int, err error)
func Getpagesize() intUtility functions for converting between Go strings and C-style byte arrays.
func ByteSliceFromString(s string) ([]byte, error)
func BytePtrFromString(s string) (*byte, error)
func ByteSliceToString(s []byte) string
func BytePtrToString(p *byte) stringDirect system call interfaces for advanced usage.
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)The Dir structure contains metadata for a Plan 9 file.
type Dir struct {
Type uint16 // server type
Dev uint32 // server subtype
Qid Qid // unique id from server
Mode uint32 // permissions
Atime uint32 // last read time
Mtime uint32 // last write time
Length int64 // file length
Name string // last element of path
Uid string // owner name
Gid string // group name
Muid string // last modifier name
}
// Null assigns special "don't touch" values to members of d to
// avoid modifying them during plan9.Wstat.
func (d *Dir) Null()
// Marshal encodes a 9P stat message corresponding to d into b
func (d *Dir) Marshal(b []byte) (n int, err error)A Qid represents a 9P server's unique identification for a file.
type Qid struct {
Path uint64 // the file server's unique identification for the file
Vers uint32 // version number for given Path
Type uint8 // the type of the file (plan9.QTDIR for example)
}func UnmarshalDir(b []byte) (*Dir, error)Waitmsg represents the result of a process wait operation.
type Waitmsg struct {
Pid int
Time [3]uint32
Msg string
}
func (w Waitmsg) Exited() bool
func (w Waitmsg) Signaled() bool
func (w Waitmsg) ExitStatus() intA Note is a string describing a process note (Plan 9's signal equivalent).
type Note string
func (n Note) Signal()
func (n Note) String() stringTimespec represents a time value with nanosecond precision.
type Timespec struct {
Sec int32
Nsec int32
}
func (ts *Timespec) Unix() (sec int64, nsec int64)
func (ts *Timespec) Nano() int64Timeval represents a time value with microsecond precision.
type Timeval struct {
Sec int32
Usec int32
}
func (tv *Timeval) Unix() (sec int64, nsec int64)
func (tv *Timeval) Nano() int64File opening modes for Open() and Create().
const (
O_RDONLY = 0 // open for read only
O_WRONLY = 1 // open for write only
O_RDWR = 2 // open for read and write
O_TRUNC = 16 // truncate to zero length
O_CLOEXEC = 32 // close on exec
O_EXCL = 0x1000 // exclusive use
// Extended modes (compatibility with os package)
O_CREAT = 0x02000
O_APPEND = 0x00400
O_NOCTTY = 0x00000
O_NONBLOCK = 0x00000
O_SYNC = 0x00000
O_ASYNC = 0x00000
)File type bits for compatibility with os package.
const (
S_IFMT = 0x1f000 // type field mask
S_IFIFO = 0x1000 // named pipe (fifo)
S_IFCHR = 0x2000 // character special
S_IFDIR = 0x4000 // directory
S_IFBLK = 0x6000 // block special
S_IFREG = 0x8000 // regular file
S_IFLNK = 0xa000 // symbolic link
S_IFSOCK = 0xc000 // socket
)Flags for the rfork system call (Plan 9 process creation).
const (
RFNAMEG = 1 << 0 // new namespace
RFENVG = 1 << 1 // new environment
RFFDG = 1 << 2 // new file descriptor group
RFNOTEG = 1 << 3 // new note group
RFPROC = 1 << 4 // change process
RFMEM = 1 << 5 // share memory
RFNOWAIT = 1 << 6 // don't wait on exit
RFCNAMEG = 1 << 10 // close namespace
RFCENVG = 1 << 11 // close environment
RFCFDG = 1 << 12 // close file descriptor group
RFREND = 1 << 13 // rendez-vous
RFNOMNT = 1 << 14 // no mount
)Type bits for Qid.Type field.
const (
QTDIR = 0x80 // directory
QTAPPEND = 0x40 // append only
QTEXCL = 0x20 // exclusive use
QTMOUNT = 0x10 // mounted channel
QTAUTH = 0x08 // authentication file
QTTMP = 0x04 // temporary file (not backed up)
QTFILE = 0x00 // plain file
)Permission and type bits for Dir.Mode field.
const (
DMDIR = 0x80000000 // directory
DMAPPEND = 0x40000000 // append only
DMEXCL = 0x20000000 // exclusive use
DMMOUNT = 0x10000000 // mounted channel
DMAUTH = 0x08000000 // authentication file
DMTMP = 0x04000000 // temporary file
DMREAD = 0x4 // read permission
DMWRITE = 0x2 // write permission
DMEXEC = 0x1 // execute permission
)Constants for stat buffer handling.
const (
STATMAX = 65535 // maximum stat buffer size
ERRMAX = 128 // maximum error string length
STATFIXLEN = 49 // size of fixed length stat portion
)Flags for Mount() and Bind() operations.
const (
MREPL = 0x0000 // replace
MBEFORE = 0x0001 // before
MAFTER = 0x0002 // after
MORDER = 0x0003 // order mask
MCREATE = 0x0004 // create if not present
MCACHE = 0x0010 // cache
MMASK = 0x0017 // all flags
)System call numbers for use with Syscall functions.
const (
SYS_SYSR1 = 0
SYS_BIND = 2
SYS_CHDIR = 3
SYS_CLOSE = 4
SYS_DUP = 5
SYS_ALARM = 6
SYS_EXEC = 7
SYS_EXITS = 8
SYS_FAUTH = 10
SYS_SEGBRK = 12
SYS_OPEN = 14
SYS_OSEEK = 16
SYS_SLEEP = 17
SYS_RFORK = 19
SYS_PIPE = 21
SYS_CREATE = 22
SYS_FD2PATH = 23
SYS_BRK_ = 24
SYS_REMOVE = 25
SYS_NOTIFY = 28
SYS_NOTED = 29
SYS_SEGATTACH = 30
SYS_SEGDETACH = 31
SYS_SEGFREE = 32
SYS_SEGFLUSH = 33
SYS_RENDEZVOUS = 34
SYS_UNMOUNT = 35
SYS_SEMACQUIRE = 37
SYS_SEMRELEASE = 38
SYS_SEEK = 39
SYS_FVERSION = 40
SYS_ERRSTR = 41
SYS_STAT = 42
SYS_FSTAT = 43
SYS_WSTAT = 44
SYS_FWSTAT = 45
SYS_MOUNT = 46
SYS_AWAIT = 47
SYS_PREAD = 50
SYS_PWRITE = 51
SYS_TSEMACQUIRE = 52
SYS_NSEC = 53
)Standard input, output, and error file descriptors.
var (
Stdin = 0
Stdout = 1
Stderr = 2
)Standard error values.
var (
// Dir marshaling errors
ErrShortStat error // stat buffer too short
ErrBadStat error // malformed stat buffer
ErrBadName error // bad character in file name
// System errors
EINVAL error // bad arg in system call
ENOTDIR error // not a directory
EISDIR error // file is a directory
ENOENT error // file does not exist
EEXIST error // file already exists
EMFILE error // no free file descriptors
EIO error // i/o error
ENAMETOOLONG error // file name too long
EINTR error // interrupted
EPERM error // permission denied
EBUSY error // no free devices
ETIMEDOUT error // connection timed out
EPLAN9 error // not supported by plan 9
EACCES error // access permission denied
EAFNOSUPPORT error // address family not supported by protocol
)var SocketDisableIPv6 bool // force IPv6 sockets to return EAFNOSUPPORT (for testing)The plan9 package is only available on Plan 9 systems. Build tags ensure it's only compiled when GOOS=plan9.
All system calls return errors of type syscall.ErrorString which can be compared to the exported error variables like ENOENT, EPERM, etc.
fd, err := plan9.Open("/nonexistent", plan9.O_RDONLY)
if err == plan9.ENOENT {
fmt.Println("File not found")
}Plan 9's stat protocol uses variable-length byte buffers. Always allocate sufficient space:
edir := make([]byte, plan9.STATMAX)
n, err := plan9.Stat("/tmp/file", edir)
if err != nil {
panic(err)
}
edir = edir[:n] // trim to actual sizePlan 9's bind and mount operations are more flexible than Unix mount:
// Bind makes 'new' accessible at 'old'
err := plan9.Bind("/usr/alice/bin", "/bin", plan9.MAFTER)
// Mount attaches a file server to the namespace
err := plan9.Mount(fd, -1, "/n/remote", plan9.MREPL, "")Plan 9 uses Await() instead of Unix wait():
var w plan9.Waitmsg
err := plan9.Await(&w)
if err != nil {
panic(err)
}
fmt.Printf("Process %d exited: %s\n", w.Pid, w.Msg)