Documentation
¶
Overview ¶
Package fskitbridge helps implement FSKit file systems in Go.
An FSKit file system extension exposes three Objective-C classes: a file system that subclasses FSUnaryFileSystem, a volume that subclasses FSVolume, and an item that subclasses FSItem. A Server registers this class set and implements its operation selectors on top of a Go UnaryFileSystem: implementations work with Go values and errors, and the Server handles FSKit object identity, reply blocks, set-attribute requests, directory packing, and errno reporting. A minimal volume implements Volume; optional interfaces such as MutableVolume and XattrVolume add the remaining FSKit operations.
The lower layer remains available for file systems that need direct control of the selector set. RegisterClasses registers a class set with method implementations written in Go. FSKit passes each operation a reply block that the implementation must invoke to deliver its result; ReplyBlocks invokes the common reply block shapes and reports a reply that could not be delivered. When typed C shim functions are linked into the process, NewReplyBlocksWithShims routes invocation through them; otherwise the block's invoke pointer is called directly.
ItemAttributesBuilder assembles the FSItemAttributes values returned by lookup, enumeration, and attribute operations, and POSIXError constructs the POSIX-domain NSError values that reply blocks accept.
An extension built as a c-archive and hosted by ExtensionFoundation wraps its Server in an Extension, which owns the lifecycle the host needs: lazy, retryable initialization, last-error reporting, a reply fallback for calls that arrive before the Server is ready, and panic recovery for the exported entry points.
Index ¶
- Constants
- func POSIXError(errno syscall.Errno) objc.ID
- type AccessCheckVolume
- type CapabilitiesVolume
- type ClassConfig
- type ClassSet
- type DirEntry
- type Extension
- func (e *Extension) Init() error
- func (e *Extension) LastError() error
- func (e *Extension) LoadResource(self, resource, options, reply objc.ID)
- func (e *Extension) NewFileSystem() objc.ID
- func (e *Extension) ProbeResource(self, resource, reply objc.ID)
- func (e *Extension) Server() *Server
- func (e *Extension) UnloadResource(self, resource, options, reply objc.ID)
- type Item
- type ItemAttributesBuilder
- func (b ItemAttributesBuilder) AccessTime(ts syscall.Timespec) ItemAttributesBuilder
- func (b ItemAttributesBuilder) AllocSize(size uint64) ItemAttributesBuilder
- func (b ItemAttributesBuilder) BirthTime(ts syscall.Timespec) ItemAttributesBuilder
- func (b ItemAttributesBuilder) Build() fskit.FSItemAttributes
- func (b ItemAttributesBuilder) ChangeTime(ts syscall.Timespec) ItemAttributesBuilder
- func (b ItemAttributesBuilder) Flags(flags uint32) ItemAttributesBuilder
- func (b ItemAttributesBuilder) GID(gid uint32) ItemAttributesBuilder
- func (b ItemAttributesBuilder) ID(id fskit.FSItemID) ItemAttributesBuilder
- func (b ItemAttributesBuilder) LinkCount(n uint32) ItemAttributesBuilder
- func (b ItemAttributesBuilder) Mode(mode uint32) ItemAttributesBuilder
- func (b ItemAttributesBuilder) ModifyTime(ts syscall.Timespec) ItemAttributesBuilder
- func (b ItemAttributesBuilder) ParentID(id fskit.FSItemID) ItemAttributesBuilder
- func (b ItemAttributesBuilder) Size(size uint64) ItemAttributesBuilder
- func (b ItemAttributesBuilder) Type(t fskit.FSItemType) ItemAttributesBuilder
- func (b ItemAttributesBuilder) UID(uid uint32) ItemAttributesBuilder
- type LinkVolume
- type MutableVolume
- type OpenCloseVolume
- type PathConf
- type PathConfVolume
- type PreallocateVolume
- type ProbeResult
- type ReplyBlockShims
- type ReplyBlocks
- func (r *ReplyBlocks) BoolError(block objc.ID, value bool, err objc.ID) error
- func (r *ReplyBlocks) Error(block objc.ID, err objc.ID) error
- func (r *ReplyBlocks) ItemNameError(block objc.ID, item objc.ID, name objc.ID, err objc.ID) error
- func (r *ReplyBlocks) ObjectError(block objc.ID, object objc.ID, err objc.ID) error
- func (r *ReplyBlocks) SizeError(block objc.ID, size uintptr, err objc.ID) error
- func (r *ReplyBlocks) VerifierError(block objc.ID, verifier uint64, err objc.ID) error
- func (r *ReplyBlocks) Void(block objc.ID) error
- type Server
- func (s *Server) Classes() ClassSet
- func (s *Server) LoadResource(self, resource, options, reply objc.ID)
- func (s *Server) NewFileSystem() objc.ID
- func (s *Server) NewVolume(v Volume) (objc.ID, error)
- func (s *Server) ProbeResource(self, resource, reply objc.ID)
- func (s *Server) UnloadResource(self, resource, options, reply objc.ID)
- type ServerConfig
- type SetAttributes
- type StatisticsVolume
- type SymlinkVolume
- type UnaryFileSystem
- type Volume
- type XattrVolume
Constants ¶
const ENOATTR = syscall.Errno(93)
ENOATTR is Darwin's "attribute not found" errno, which the syscall package does not name. File systems mapping a backend's missing-attribute error report it for extended attribute operations.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AccessCheckVolume ¶
type AccessCheckVolume interface {
Volume
// CheckAccess reports whether the requested access to item is allowed.
CheckAccess(item Item, access fskit.FSAccessMask) (bool, error)
}
An AccessCheckVolume is a Volume that answers access checks itself. Without it the kernel checks access against the item mode bits.
type CapabilitiesVolume ¶
type CapabilitiesVolume interface {
Volume
// SupportedCapabilities returns the volume's capabilities.
SupportedCapabilities() fskit.FSVolumeSupportedCapabilities
}
A CapabilitiesVolume is a Volume that reports its own supported capabilities. Without it the Server reports 64-bit object IDs, hidden files, case sensitivity, and symbolic or hard link support according to the SymlinkVolume and LinkVolume interfaces.
type ClassConfig ¶
type ClassConfig struct {
FileSystemName string
VolumeName string
ItemName string
ExistingFileSystem objc.Class
FileSystemProtocols []string
VolumeProtocols []string
FileSystemMethods []objc.MethodDef
VolumeMethods []objc.MethodDef
ItemMethods []objc.MethodDef
}
ClassConfig describes the Objective-C classes and method implementations for an FSKit file system.
If ExistingFileSystem is nonzero it is used as the file system class as is and FileSystemMethods are not attached; this supports extensions whose file system class is provided by a host shim that routes operations to Go itself. If a class named VolumeName or ItemName is already registered, its methods are added or replaced instead of registering a new class, so registration can run again in the same process.
type ClassSet ¶
ClassSet is the set of Objective-C classes that implements an FSKit file system.
func RegisterClasses ¶
func RegisterClasses(cfg ClassConfig) (ClassSet, error)
RegisterClasses registers or extends the Objective-C class set for an FSKit file system.
type DirEntry ¶
type DirEntry struct {
Name string
Type fskit.FSItemType
Attributes fskit.FSItemAttributes // must include the entry's file ID
}
A DirEntry is one entry of a directory listing.
type Extension ¶
type Extension struct {
// contains filtered or unexported fields
}
An Extension hosts a Server inside an ExtensionFoundation extension built as a c-archive. It owns the lifecycle a hosted extension needs around the Server: lazy, retryable initialization; last-error reporting; a reply fallback for calls that arrive before the Server is ready; and panic recovery for the exported entry points.
A c-archive cannot re-export Go functions defined in an imported package, so the file system's principal class invokes per-extension //export wrappers. Each wrapper is a one-line call into the matching Extension method, which keeps the lifecycle in one place rather than duplicated across extensions.
The zero Extension is not usable; create one with NewExtension.
func NewExtension ¶
func NewExtension(shims ReplyBlockShims, newServer func() (*Server, error)) *Extension
NewExtension returns an Extension that builds its Server with newServer on first use. shims names the linked reply block shims so the fallback can answer calls that arrive before the Server is ready (see ReplyBlockShims).
func (*Extension) Init ¶
Init builds the Server if it is not already built and returns any error. A failure is not sticky: the next call retries, so an early call that races extension startup (before the principal class registers) does not poison the process.
func (*Extension) LoadResource ¶
LoadResource routes loadResource:options:replyHandler: to the Server, replying with EINVAL through the fallback if the Server is not ready.
func (*Extension) NewFileSystem ¶
NewFileSystem returns a new instance of the file system class, or 0 if the Server cannot be initialized.
func (*Extension) ProbeResource ¶
ProbeResource routes probeResource:replyHandler: to the Server, replying with EINVAL through the fallback if the Server is not ready.
func (*Extension) Server ¶
Server returns the built Server, or nil before Extension.Init succeeds.
func (*Extension) UnloadResource ¶
UnloadResource routes unloadResource:options:replyHandler: to the Server, replying with EINVAL through the fallback if the Server is not ready.
type Item ¶
type Item any
An Item identifies a file system object. Implementations define their own item values; the Server associates each value with the FSItem object it hands to FSKit and passes the value back to later operations.
type ItemAttributesBuilder ¶
type ItemAttributesBuilder struct {
// contains filtered or unexported fields
}
ItemAttributesBuilder builds FSItemAttributes with the common fields used by FSKit file systems.
func NewItemAttributes ¶
func NewItemAttributes() ItemAttributesBuilder
NewItemAttributes returns a builder for FSItemAttributes.
func (ItemAttributesBuilder) AccessTime ¶
func (b ItemAttributesBuilder) AccessTime(ts syscall.Timespec) ItemAttributesBuilder
AccessTime sets the access time.
func (ItemAttributesBuilder) AllocSize ¶
func (b ItemAttributesBuilder) AllocSize(size uint64) ItemAttributesBuilder
AllocSize sets the allocated size in bytes.
func (ItemAttributesBuilder) BirthTime ¶
func (b ItemAttributesBuilder) BirthTime(ts syscall.Timespec) ItemAttributesBuilder
BirthTime sets the creation time.
func (ItemAttributesBuilder) Build ¶
func (b ItemAttributesBuilder) Build() fskit.FSItemAttributes
Build returns the assembled attributes.
func (ItemAttributesBuilder) ChangeTime ¶
func (b ItemAttributesBuilder) ChangeTime(ts syscall.Timespec) ItemAttributesBuilder
ChangeTime sets the attribute change time.
func (ItemAttributesBuilder) Flags ¶
func (b ItemAttributesBuilder) Flags(flags uint32) ItemAttributesBuilder
Flags sets the BSD file flags.
func (ItemAttributesBuilder) GID ¶
func (b ItemAttributesBuilder) GID(gid uint32) ItemAttributesBuilder
GID sets the owning group ID.
func (ItemAttributesBuilder) ID ¶
func (b ItemAttributesBuilder) ID(id fskit.FSItemID) ItemAttributesBuilder
ID sets the file ID.
func (ItemAttributesBuilder) LinkCount ¶
func (b ItemAttributesBuilder) LinkCount(n uint32) ItemAttributesBuilder
LinkCount sets the hard link count.
func (ItemAttributesBuilder) Mode ¶
func (b ItemAttributesBuilder) Mode(mode uint32) ItemAttributesBuilder
Mode sets the POSIX mode bits.
func (ItemAttributesBuilder) ModifyTime ¶
func (b ItemAttributesBuilder) ModifyTime(ts syscall.Timespec) ItemAttributesBuilder
ModifyTime sets the content modification time.
func (ItemAttributesBuilder) ParentID ¶
func (b ItemAttributesBuilder) ParentID(id fskit.FSItemID) ItemAttributesBuilder
ParentID sets the parent directory's file ID.
func (ItemAttributesBuilder) Size ¶
func (b ItemAttributesBuilder) Size(size uint64) ItemAttributesBuilder
Size sets the file size in bytes.
func (ItemAttributesBuilder) Type ¶
func (b ItemAttributesBuilder) Type(t fskit.FSItemType) ItemAttributesBuilder
Type sets the item type.
func (ItemAttributesBuilder) UID ¶
func (b ItemAttributesBuilder) UID(uid uint32) ItemAttributesBuilder
UID sets the owning user ID.
type LinkVolume ¶
type LinkVolume interface {
Volume
// Link links item under a new name in dir.
Link(item Item, dir Item, name string) error
}
A LinkVolume is a Volume with hard links.
type MutableVolume ¶
type MutableVolume interface {
Volume
// Create creates a file (FSItemTypeFile) or directory
// (FSItemTypeDirectory) named name in dir.
Create(dir Item, name string, typ fskit.FSItemType, mode uint32) (Item, error)
// Remove removes the item named name from dir.
Remove(dir Item, name string, item Item) error
// Rename moves item, named srcName in srcDir, to dstName in dstDir.
// If over is non-nil the destination exists and is replaced; the
// Server reclaims over after a successful rename.
Rename(item Item, srcDir Item, srcName string, dstDir Item, dstName string, over Item) error
// SetAttributes applies the requested attribute changes to item and
// returns the subset it actually applied, as the fields left non-nil.
// A Volume that applied everything returns set unchanged.
//
// The Server reports the returned subset to FSKit as the consumed
// attributes, and FSKit takes an unconsumed attribute as one the file
// system does not support: that is how a caller learns a chown did not
// happen instead of believing a silent success. Returning the applied
// set rather than clearing an in-out parameter keeps the mistake of
// forgetting to report cheap -- the zero value claims nothing, so an
// implementer who gets it wrong under-claims.
SetAttributes(item Item, set SetAttributes) (applied SetAttributes, err error)
// Write writes data to file at offset, returning the number of bytes
// written.
Write(file Item, offset int64, data []byte) (int, error)
}
A MutableVolume is a Volume that supports mutation. Without it the Server reports EROFS for all mutating operations.
type OpenCloseVolume ¶
type OpenCloseVolume interface {
Volume
// Open notes that item was opened with the given modes.
Open(item Item, modes fskit.FSVolumeOpenModes) error
// Close notes that item was closed, keeping the given modes.
Close(item Item, modes fskit.FSVolumeOpenModes) error
}
An OpenCloseVolume is a Volume that tracks open and close of its items.
type PathConf ¶
type PathConf struct {
MaximumLinkCount int
MaximumNameLength int
MaximumFileSize uint64
MaximumXattrSize int
RestrictsOwnershipChanges bool
TruncatesLongNames bool
// OpenUnlinkEmulation asks FSKit to emulate open-unlink semantics,
// for volumes that cannot keep unlinked-but-open files alive.
OpenUnlinkEmulation bool
}
PathConf holds the path configuration limits and behavior the Server reports to FSKit. The Server reports the values as given; most implementations start from DefaultPathConf.
func DefaultPathConf ¶
func DefaultPathConf() PathConf
DefaultPathConf returns the path configuration the Server reports for volumes that do not implement PathConfVolume: no hard links, 255-byte names, 63-bit file sizes, 64 KiB extended attributes, and open-unlink emulation.
type PathConfVolume ¶
type PathConfVolume interface {
Volume
// PathConf returns the volume's path configuration limits.
PathConf() PathConf
}
A PathConfVolume is a Volume that reports its own path configuration limits. Without it the Server reports DefaultPathConf.
type PreallocateVolume ¶
type PreallocateVolume interface {
Volume
// Preallocate reserves length bytes at offset in file, returning the
// number of bytes reserved.
Preallocate(file Item, offset int64, length uint64) (uint64, error)
}
A PreallocateVolume is a Volume that supports preallocating space.
type ProbeResult ¶
type ProbeResult struct {
Name string
}
A ProbeResult names a successfully probed resource.
type ReplyBlockShims ¶
type ReplyBlockShims struct {
Error string
Object string
ItemName string
Verifier string
Bool string
Size string
}
ReplyBlockShims names optional linked functions used for typed FSKit reply block invocation. Each field names a C function that invokes a block of the corresponding shape; an empty name means no shim is linked for that shape.
type ReplyBlocks ¶
type ReplyBlocks struct {
// contains filtered or unexported fields
}
ReplyBlocks invokes FSKit reply blocks.
func NewReplyBlocks ¶
func NewReplyBlocks() *ReplyBlocks
NewReplyBlocks returns a reply block invoker with no linked shim names.
func NewReplyBlocksWithShims ¶
func NewReplyBlocksWithShims(shims ReplyBlockShims) *ReplyBlocks
NewReplyBlocksWithShims returns a reply block invoker that prefers linked typed shims when they are present.
func (*ReplyBlocks) BoolError ¶
BoolError invokes a reply block that takes a boolean and an NSError.
func (*ReplyBlocks) ItemNameError ¶
ItemNameError invokes a reply block that takes an FSItem, an FSFileName, and an NSError.
func (*ReplyBlocks) ObjectError ¶
ObjectError invokes a reply block that takes an object and an NSError.
func (*ReplyBlocks) SizeError ¶
SizeError invokes a reply block that takes a byte count and an NSError.
func (*ReplyBlocks) VerifierError ¶
VerifierError invokes a reply block that takes a directory verifier and an NSError.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
A Server adapts a UnaryFileSystem to FSKit. It registers the Objective-C class set, implements the FSKit operation selectors, tracks the FSItem and FSVolume objects it hands to FSKit, and reports operation errors as POSIX-domain NSErrors.
The Server declares the FSKit volume operation protocols and answers each protocol's inhibited query according to the optional interfaces the loaded Volume implements. Volume renaming is always inhibited.
Register a class set once per process: a second Server with the same class names takes over that class set's operations.
func NewServer ¶
func NewServer(cfg ServerConfig) (*Server, error)
NewServer registers the class set for cfg and returns its Server.
func (*Server) LoadResource ¶
LoadResource loads a resource, replies with its FSVolume, and marks the container ready. It is the implementation of loadResource:options:replyHandler:, exported for host shims that route the selector to Go themselves.
func (*Server) NewFileSystem ¶
NewFileSystem returns a new instance of the file system class.
func (*Server) NewVolume ¶
NewVolume returns a new instance of the volume class serving v, with its root item already resolved.
func (*Server) ProbeResource ¶
ProbeResource probes a resource and replies with an FSProbeResult. It is the implementation of probeResource:replyHandler:, exported for host shims that route the selector to Go themselves.
func (*Server) UnloadResource ¶
UnloadResource unloads the resource and replies. It is the implementation of unloadResource:options:replyHandler:, exported for host shims that route the selector to Go themselves.
type ServerConfig ¶
type ServerConfig struct {
// FileSystemName, VolumeName, and ItemName name the Objective-C
// classes the Server registers.
FileSystemName string
VolumeName string
ItemName string
// ExistingFileSystem, if nonzero, is used as the file system class
// instead of registering one; see [ClassConfig]. The host shim then
// routes operations to the Server through [Server.ProbeResource],
// [Server.LoadResource], and [Server.UnloadResource].
ExistingFileSystem objc.Class
// Shims names linked reply block shims; see [ReplyBlockShims].
Shims ReplyBlockShims
// FileSystem is the file system implementation.
FileSystem UnaryFileSystem
// Logf, if non-nil, receives diagnostic messages. If nil, failures
// to deliver a reply are reported through the log package and other
// diagnostics are dropped.
Logf func(format string, args ...any)
}
ServerConfig configures a Server.
type SetAttributes ¶
type SetAttributes struct {
Mode *uint32
UID *uint32
GID *uint32
Flags *uint32
Size *uint64
AccessTime *syscall.Timespec
ModifyTime *syscall.Timespec
}
SetAttributes holds the attributes of a set-attributes request. A nil field was not requested.
The Server reports back to FSKit only the fields a Volume returns from SetAttributes, so a Volume that cannot change ownership should omit UID and GID from what it returns rather than failing the whole request.
type StatisticsVolume ¶
type StatisticsVolume interface {
Volume
// Statistics returns the volume's statfs statistics.
Statistics() fskit.FSStatFSResult
}
A StatisticsVolume is a Volume that reports its own statfs statistics. Without it the Server reports single-block placeholder statistics under the volume name.
type SymlinkVolume ¶
type SymlinkVolume interface {
Volume
// Readlink returns the target of the symbolic link item.
Readlink(item Item) (string, error)
// Symlink creates a symbolic link named name to target in dir.
Symlink(dir Item, name, target string) (Item, error)
}
A SymlinkVolume is a Volume with symbolic links.
type UnaryFileSystem ¶
type UnaryFileSystem interface {
// Probe inspects a resource and names the file system that would
// mount it.
Probe(resource fskit.FSResource) (ProbeResult, error)
// Load prepares the resource and returns its volume.
Load(resource fskit.FSResource) (Volume, error)
// Unload releases the resource. It may be called more than once.
Unload() error
}
A UnaryFileSystem implements an FSKit unary file system: a file system that manages a single resource as a single volume. The Server adapts it to the FSUnaryFileSystemOperations protocol.
Errors report errnos to FSKit as described for Volume.
type Volume ¶
type Volume interface {
// VolumeName returns the volume's display name.
VolumeName() string
// Root returns the item for the root directory.
Root() (Item, error)
// Lookup resolves name within the directory dir.
Lookup(dir Item, name string) (Item, error)
// Reclaim releases any state held for item. The system is done with
// the item; it may be reclaimed more than once.
Reclaim(item Item)
// Attributes returns the item's attributes, including its file ID.
Attributes(item Item) (fskit.FSItemAttributes, error)
// ReadDir lists the directory dir.
ReadDir(dir Item) ([]DirEntry, error)
// Read reads from file at offset into buf, returning the number of
// bytes read. Reading past the end of the file returns 0, and io.EOF
// is not an error.
Read(file Item, offset int64, buf []byte) (int, error)
}
A Volume implements the core, read-only operations of an FSKit volume. The Server adapts a Volume to the FSVolumeOperations protocol and answers the mutating operations with EROFS unless the Volume also implements MutableVolume.
Optional interfaces extend a Volume with additional FSKit operations: MutableVolume, SymlinkVolume, LinkVolume, XattrVolume, PreallocateVolume, OpenCloseVolume, AccessCheckVolume, CapabilitiesVolume, StatisticsVolume, and PathConfVolume.
Operations report failure by returning an error. An error that is or wraps a syscall.Errno reports that errno to FSKit; fs.ErrNotExist, fs.ErrExist, fs.ErrPermission, fs.ErrInvalid, and errors.ErrUnsupported report ENOENT, EEXIST, EACCES, EINVAL, and ENOTSUP; any other error reports EIO. In xattr operations fs.ErrNotExist reports ENOATTR.
type XattrVolume ¶
type XattrVolume interface {
Volume
// GetXattr returns the value of the extended attribute name on item.
GetXattr(item Item, name string) ([]byte, error)
// SetXattr sets the extended attribute name on item to data.
SetXattr(item Item, name string, data []byte) error
// RemoveXattr removes the extended attribute name from item.
RemoveXattr(item Item, name string) error
// ListXattr lists the extended attribute names on item.
ListXattr(item Item) ([]string, error)
}
An XattrVolume is a Volume with extended attributes. The Server implements the FSKit set-xattr policies (must-create, must-replace, delete) in terms of these methods.