fs_op object

This object implements all the standard Unix filesystem calls that operate on pathnames: open(), mkdir(), unlink() and so on. You can construct one of these objects given a root directory.

This object has one piece of state: the current working directory (cwd). This is allowed to be unset, in which case any operation that it relative to the cwd will return an error.

Notation:

Methods:

// duplicate the connection -- called before the fork() syscall
// (now obsolete; will be removed)
"Fork"
=>
"RFrk" + FD

"Copy"
=> "Okay" + fs_op/obj

"Gdir" pathname
=> "Okay" + dir/obj
Resolves `pathname' to get a directory, and returns the directory object.

"Grtd"
=> "Okay" + dir/obj
Same as <<"Gdir" "/">>.

"Gobj" pathname
=> "Okay" + obj
Resolved `pathname' to get any object; will follow symlinks.

// open() call
"Open" flags/int mode/int filename
=>
"ROpn" + FD
"RDfd" + FD + dir_stack/obj // This is returned when open() is used on a directory.
                            // FD is for /dev/null, and the object is a dir_stack.
"Fail" errno/int

// stat() and lstat() calls
"Stat" nofollow/int pathname
=>
"RSta" stat
"Fail" errno/int

// readlink() call
"Rdlk" pathname
=>
"RRdl" string
"Fail" errno/int

// chdir() call
"Chdr" pathname
=>
"RSuc"
"Fail" errno/int

// fchdir() call:  takes a dir_stack object as returned by open()
"Fchd" + dir_stack/obj
=>
"Okay"
"Fail" errno/int

// getcwd() call
"Gcwd"
=>
"RCwd" pathname
"Fail" errno/int

// list contents of directories: opendir() + readdir() + closedir()
"Dlst" pathname
=>
// same as `struct dirent' format:
"RDls" (inode/int type/int name_size/int name)*
"Fail" errno/int

// access() call
"Accs" mode/int pathname
=>
"RAcc"
"Fail" errno/int

// mkdir()
"Mkdr" mode/int pathname
=>
"RMkd"
"Fail" errno/int

// chmod() call
"Chmd" mode/int pathname
=>
"RChm"
"Fail" errno/int

// utime()/utimes()/lutimes() calls
"Utim" nofollow/int
	atime_sec/int atime_usec/int
	mtime_sec/int mtime_usec/int
	pathname
=>
"RUtm"
"Fail" errno/int

// rename() call
"Renm" newpath-length/int newpath oldpath
=>
"RRnm"
"Fail" errno/int

// link() call
"Link" newpath-length/int newpath oldpath
=>
"RLnk"
"Fail" errno/int

// symlink() call
"Syml" newpath-length/int newpath oldpath
=>
"RSym"
"Fail" errno/int

// unlink() call
"Unlk" pathname
=>
"RUnl"
"Fail" errno/int

// rmdir() call
"Rmdr" pathname
=>
"RRmd"
"Fail" errno/int

// connect() on Unix domain sockets
"Fcon" pathname + FD
=>
"RFco"
"Fail" errno/int

// bind() on Unix domain sockets
"Fbnd" pathname + FD
=>
"RFbd"
"Fail" errno/int

// part of execve() call
// The RExe result tells the client what it should pass to the exec syscall.
// The client allocates a spare FD slot; it tells the server the number.
// The server can then use this FD number in the arguments it returns.
// The client receives an FD; it must copy it into that slot using "dup2".
// This will be extended so that the server can also carry out the work of
// the new process.
// The RExo result returns an executable object which the client must invoke
// with full arguments, including the root directory.
"Exec" fd-number/int cmd-len/int cmd argc/int (arg-len/int arg)*
=>
"RExe" cmd-len/int cmd argc/int (arg-len/int arg)* + FD
"RExo" + CAP
"Fail" errno/int


where:

stat = dev ino mode nlink uid gid rdev size blksize blocks atime mtime ctime
       (all ints)