181 lines
5.8 KiB
Go
181 lines
5.8 KiB
Go
|
// Copyright 2018 Google Inc.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
package p9
|
||
|
|
||
|
import (
|
||
|
"syscall"
|
||
|
|
||
|
"gvisor.googlesource.com/gvisor/pkg/fd"
|
||
|
)
|
||
|
|
||
|
// Attacher is provided by the user.
|
||
|
type Attacher interface {
|
||
|
// Attach returns a new File.
|
||
|
Attach(attachName string) (File, error)
|
||
|
}
|
||
|
|
||
|
// File is a set of operations corresponding to a single node.
|
||
|
//
|
||
|
// Functions below MUST return syscall.Errno values.
|
||
|
// TODO: Enforce that with the type.
|
||
|
//
|
||
|
// These must be implemented in all circumstances.
|
||
|
type File interface {
|
||
|
// Walk walks to the path components given in names.
|
||
|
//
|
||
|
// Walk returns QIDs in the same order that the names were passed in.
|
||
|
//
|
||
|
// An empty list of arguments should return a copy of the current file.
|
||
|
Walk(names []string) ([]QID, File, error)
|
||
|
|
||
|
// StatFS returns information about the file system associated with
|
||
|
// this file.
|
||
|
StatFS() (FSStat, error)
|
||
|
|
||
|
// GetAttr returns attributes of this node.
|
||
|
GetAttr(req AttrMask) (QID, AttrMask, Attr, error)
|
||
|
|
||
|
// SetAttr sets attributes on this node.
|
||
|
SetAttr(valid SetAttrMask, attr SetAttr) error
|
||
|
|
||
|
// Remove removes the file.
|
||
|
//
|
||
|
// This is deprecated in favor of UnlinkAt below.
|
||
|
Remove() error
|
||
|
|
||
|
// Rename renames the file.
|
||
|
Rename(directory File, name string) error
|
||
|
|
||
|
// Close is called when all references are dropped on the server side,
|
||
|
// and Close should be called by the client to drop all references.
|
||
|
//
|
||
|
// For server-side implementations of Close, the error is ignored.
|
||
|
//
|
||
|
// Close must be called even when Open has not been called.
|
||
|
Close() error
|
||
|
|
||
|
// Open is called prior to using read/write.
|
||
|
//
|
||
|
// The *fd.FD may be nil. If an *fd.FD is provided, ownership now
|
||
|
// belongs to the caller and the FD must be non-blocking.
|
||
|
//
|
||
|
// If Open returns a non-nil *fd.FD, it should do so for all possible
|
||
|
// OpenFlags. If Open returns a nil *fd.FD, it should similarly return
|
||
|
// a nil *fd.FD for all possible OpenFlags.
|
||
|
//
|
||
|
// This can be assumed to be one-shot only.
|
||
|
Open(mode OpenFlags) (*fd.FD, QID, uint32, error)
|
||
|
|
||
|
// Read reads from this file.
|
||
|
//
|
||
|
// This may return io.EOF in addition to syscall.Errno values.
|
||
|
//
|
||
|
// Preconditions: Open has been called and returned success.
|
||
|
ReadAt(p []byte, offset uint64) (int, error)
|
||
|
|
||
|
// Write writes to this file.
|
||
|
//
|
||
|
// This may return io.EOF in addition to syscall.Errno values.
|
||
|
//
|
||
|
// Preconditions: Open has been called and returned success.
|
||
|
WriteAt(p []byte, offset uint64) (int, error)
|
||
|
|
||
|
// FSync syncs this node.
|
||
|
//
|
||
|
// Preconditions: Open has been called and returned success.
|
||
|
FSync() error
|
||
|
|
||
|
// Create creates a new regular file and opens it according to the
|
||
|
// flags given.
|
||
|
//
|
||
|
// See p9.File.Open for a description of *fd.FD.
|
||
|
Create(name string, flags OpenFlags, permissions FileMode, uid UID, gid GID) (*fd.FD, File, QID, uint32, error)
|
||
|
|
||
|
// Mkdir creates a subdirectory.
|
||
|
Mkdir(name string, permissions FileMode, uid UID, gid GID) (QID, error)
|
||
|
|
||
|
// Symlink makes a new symbolic link.
|
||
|
Symlink(oldname string, newname string, uid UID, gid GID) (QID, error)
|
||
|
|
||
|
// Link makes a new hard link.
|
||
|
Link(target File, newname string) error
|
||
|
|
||
|
// Mknod makes a new device node.
|
||
|
Mknod(name string, permissions FileMode, major uint32, minor uint32, uid UID, gid GID) (QID, error)
|
||
|
|
||
|
// RenameAt renames a given file to a new name in a potentially new
|
||
|
// directory.
|
||
|
//
|
||
|
// oldname must be a name relative to this file, which must be a
|
||
|
// directory. newname is a name relative to newdir.
|
||
|
//
|
||
|
// This is deprecated in favor of Rename.
|
||
|
RenameAt(oldname string, newdir File, newname string) error
|
||
|
|
||
|
// UnlinkAt the given named file.
|
||
|
//
|
||
|
// name must be a file relative to this directory.
|
||
|
//
|
||
|
// Flags are implementation-specific (e.g. O_DIRECTORY), but are
|
||
|
// generally Linux unlinkat(2) flags.
|
||
|
UnlinkAt(name string, flags uint32) error
|
||
|
|
||
|
// Readdir reads directory entries.
|
||
|
//
|
||
|
// This may return io.EOF in addition to syscall.Errno values.
|
||
|
//
|
||
|
// Preconditions: Open has been called and returned success.
|
||
|
Readdir(offset uint64, count uint32) ([]Dirent, error)
|
||
|
|
||
|
// Readlink reads the link target.
|
||
|
Readlink() (string, error)
|
||
|
|
||
|
// Flush is called prior to Close.
|
||
|
//
|
||
|
// Whereas Close drops all references to the file, Flush cleans up the
|
||
|
// file state. Behavior is implementation-specific.
|
||
|
//
|
||
|
// Flush is not related to flush(9p). Flush is an extension to 9P2000.L,
|
||
|
// see version.go.
|
||
|
Flush() error
|
||
|
|
||
|
// WalkGetAttr walks to the next file and returns its maximal set of
|
||
|
// attributes.
|
||
|
//
|
||
|
// Server-side p9.Files may return syscall.ENOSYS to indicate that Walk
|
||
|
// and GetAttr should be used separately to satisfy this request.
|
||
|
WalkGetAttr([]string) ([]QID, File, AttrMask, Attr, error)
|
||
|
|
||
|
// Connect establishes a new host-socket backed connection with a
|
||
|
// socket. A File does not need to be opened before it can be connected
|
||
|
// and it can be connected to multiple times resulting in a unique
|
||
|
// *fd.FD each time. In addition, the lifetime of the *fd.FD is
|
||
|
// independent from the lifetime of the p9.File and must be managed by
|
||
|
// the caller.
|
||
|
//
|
||
|
// The returned FD must be non-blocking.
|
||
|
//
|
||
|
// flags indicates the requested type of socket.
|
||
|
Connect(flags ConnectFlags) (*fd.FD, error)
|
||
|
}
|
||
|
|
||
|
// DefaultWalkGetAttr implements File.WalkGetAttr to return ENOSYS for server-side Files.
|
||
|
type DefaultWalkGetAttr struct{}
|
||
|
|
||
|
// WalkGetAttr implements File.WalkGetAttr.
|
||
|
func (DefaultWalkGetAttr) WalkGetAttr([]string) ([]QID, File, AttrMask, Attr, error) {
|
||
|
return nil, nil, AttrMask{}, Attr{}, syscall.ENOSYS
|
||
|
}
|