rclone/vfs/vfstest/os.go
Filipe Azevedo 1891b6848b vfs: Introduce symlink support
We enable symlink support using the --links command line switch.
On the VFS layer, symlinks always ends with the rclonelink suffix.
This is because it is what we send/get to/from the remote layer.
That mean than any regular operation like rename, remove etc on
symlinks files always need to have their rclonelink suffix.
That way, we don't mess the internal map of items and avoid lots of
troubles.
When symlink support is disabled, Symlink and Readlink functions will
transparently manage ".rclonelink" files as regular files.
2023-01-04 21:56:15 +01:00

140 lines
3.0 KiB
Go

package vfstest
import (
"os"
"time"
"github.com/rclone/rclone/lib/file"
"github.com/rclone/rclone/vfs"
)
// Oser defines the things that the "os" package can do
//
// This covers what the VFS can do also
type Oser interface {
Chtimes(name string, atime time.Time, mtime time.Time) error
Create(name string) (vfs.Handle, error)
Mkdir(name string, perm os.FileMode) error
Open(name string) (vfs.Handle, error)
OpenFile(name string, flags int, perm os.FileMode) (fd vfs.Handle, err error)
ReadDir(dirname string) ([]os.FileInfo, error)
ReadFile(filename string) (b []byte, err error)
Remove(name string) error
Rename(oldName, newName string) error
Stat(path string) (os.FileInfo, error)
Symlink(oldname, newname string) error
Readlink(name string) (s string, err error)
}
// realOs is an implementation of Oser backed by the "os" package
type realOs struct {
}
// realOsFile is an implementation of vfs.Handle
type realOsFile struct {
*os.File
}
// Flush
func (f realOsFile) Flush() error {
return nil
}
// Release
func (f realOsFile) Release() error {
return f.File.Close()
}
// Node
func (f realOsFile) Node() vfs.Node {
return nil
}
// Chtimes
func (r realOs) Chtimes(name string, atime time.Time, mtime time.Time) error {
return os.Chtimes(name, atime, mtime)
}
// Create
func (r realOs) Create(name string) (vfs.Handle, error) {
fd, err := file.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return nil, err
}
return realOsFile{File: fd}, err
}
// Mkdir
func (r realOs) Mkdir(name string, perm os.FileMode) error {
return os.Mkdir(name, perm)
}
// Open
func (r realOs) Open(name string) (vfs.Handle, error) {
fd, err := os.Open(name)
if err != nil {
return nil, err
}
return realOsFile{File: fd}, err
}
// OpenFile
func (r realOs) OpenFile(name string, flags int, perm os.FileMode) (vfs.Handle, error) {
fd, err := file.OpenFile(name, flags, perm)
if err != nil {
return nil, err
}
return realOsFile{File: fd}, err
}
// ReadDir
func (r realOs) ReadDir(dirname string) ([]os.FileInfo, error) {
entries, err := os.ReadDir(dirname)
if err != nil {
return nil, err
}
infos := make([]os.FileInfo, 0, len(entries))
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
return nil, err
}
infos = append(infos, info)
}
return infos, nil
}
// ReadFile
func (r realOs) ReadFile(filename string) (b []byte, err error) {
return os.ReadFile(filename)
}
// Remove
func (r realOs) Remove(name string) error {
return os.Remove(name)
}
// Rename
func (r realOs) Rename(oldName, newName string) error {
return os.Rename(oldName, newName)
}
// Stat
func (r realOs) Stat(path string) (os.FileInfo, error) {
return os.Stat(path)
}
// Symlink
func (r realOs) Symlink(oldname, newname string) error {
return os.Symlink(oldname, newname)
}
// Readlink
func (r realOs) Readlink(name string) (s string, err error) {
return os.Readlink(name)
}
// Check interfaces
var _ Oser = &realOs{}
var _ vfs.Handle = &realOsFile{}