mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-11 22:43:40 +00:00
os: implement virtual filesystem support
This allows applications to mount filesystems in the os package. This is useful for mounting external flash filesystems, for example.
This commit is contained in:
committed by
Ron Evans
parent
e907db1481
commit
6bcb40fe01
@@ -0,0 +1,85 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// mounts lists the mount points currently mounted in the filesystem provided by
|
||||
// the os package. To resolve a path to a mount point, it is scanned from top to
|
||||
// bottom looking for the first prefix match.
|
||||
var mounts []mountPoint
|
||||
|
||||
type mountPoint struct {
|
||||
// prefix is a filesystem prefix, that always starts and ends with a forward
|
||||
// slash. To denote the root filesystem, use a single slash: "/".
|
||||
// This allows fast checking whether a path lies within a mount point.
|
||||
prefix string
|
||||
|
||||
// filesystem is the Filesystem implementation that is mounted at this mount
|
||||
// point.
|
||||
filesystem Filesystem
|
||||
}
|
||||
|
||||
// Filesystem provides an interface for generic filesystem drivers mounted in
|
||||
// the os package. The errors returned must be one of the os.Err* errors, or a
|
||||
// custom error if one doesn't exist. It should not be a *PathError because
|
||||
// errors will be wrapped with a *PathError by the filesystem abstraction.
|
||||
//
|
||||
// WARNING: this interface is not finalized and may change in a future version.
|
||||
type Filesystem interface {
|
||||
// OpenFile opens the named file.
|
||||
OpenFile(name string, flag int, perm FileMode) (FileHandle, error)
|
||||
|
||||
// Mkdir creates a new directoy with the specified permission (before
|
||||
// umask). Some filesystems may not support directories or permissions.
|
||||
Mkdir(name string, perm FileMode) error
|
||||
|
||||
// Remove removes the named file or (empty) directory.
|
||||
Remove(name string) error
|
||||
}
|
||||
|
||||
// FileHandle is an interface that should be implemented by filesystems
|
||||
// implementing the Filesystem interface.
|
||||
//
|
||||
// WARNING: this interface is not finalized and may change in a future version.
|
||||
type FileHandle interface {
|
||||
// Read reads up to len(b) bytes from the file.
|
||||
Read(b []byte) (n int, err error)
|
||||
|
||||
// Write writes up to len(b) bytes to the file.
|
||||
Write(b []byte) (n int, err error)
|
||||
|
||||
// Close closes the file, making it unusable for further writes.
|
||||
Close() (err error)
|
||||
}
|
||||
|
||||
// findMount returns the appropriate (mounted) filesystem to use for a given
|
||||
// filename plus the path relative to that filesystem.
|
||||
func findMount(path string) (Filesystem, string) {
|
||||
for i := len(mounts) - 1; i >= 0; i-- {
|
||||
mount := mounts[i]
|
||||
if strings.HasPrefix(path, mount.prefix) {
|
||||
return mount.filesystem, path[len(mount.prefix)-1:]
|
||||
}
|
||||
}
|
||||
if isOS {
|
||||
// Assume that the first entry in the mounts slice is the OS filesystem
|
||||
// at the root of the directory tree. Use it as-is, to support relative
|
||||
// paths.
|
||||
return mounts[0].filesystem, path
|
||||
}
|
||||
return nil, path
|
||||
}
|
||||
|
||||
// Mount mounts the given filesystem in the filesystem abstraction layer of the
|
||||
// os package. It is not possible to unmount filesystems. Filesystems added
|
||||
// later will override earlier filesystems.
|
||||
//
|
||||
// The provided prefix must start and end with a forward slash. This is true for
|
||||
// the root directory ("/") for example.
|
||||
func Mount(prefix string, filesystem Filesystem) {
|
||||
if prefix[0] != '/' || prefix[len(prefix)-1] != '/' {
|
||||
panic("os.Mount: invalid prefix")
|
||||
}
|
||||
mounts = append(mounts, mountPoint{prefix, filesystem})
|
||||
}
|
||||
Reference in New Issue
Block a user