forked from 3JoB/vfs
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
readonly.go
90 lines (77 loc) · 2.27 KB
/
readonly.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package vfs
import (
"errors"
"os"
)
// ReadOnly creates a readonly wrapper around the given filesystem.
// It disables the following operations:
//
// - Create
// - Remove
// - Rename
// - Mkdir
//
// And disables OpenFile flags: os.O_CREATE, os.O_APPEND, os.O_WRONLY
//
// OpenFile returns a File with disabled Write() method otherwise.
func ReadOnly(fs Filesystem) *RoFS {
return &RoFS{Filesystem: fs}
}
// RoFS represents a read-only filesystem and
// works as a wrapper around existing filesystems.
type RoFS struct {
Filesystem
}
// ErrorReadOnly is returned on every disabled operation.
var ErrReadOnly = errors.New("Filesystem is read-only")
// Remove is disabled and returns ErrorReadOnly
func (fs RoFS) Remove(name string) error {
return ErrReadOnly
}
// Rename is disabled and returns ErrorReadOnly
func (fs RoFS) Rename(oldpath, newpath string) error {
return ErrReadOnly
}
// Mkdir is disabled and returns ErrorReadOnly
func (fs RoFS) Mkdir(name string, perm os.FileMode) error {
return ErrReadOnly
}
func (fs RoFS) Symlink(oldname, newname string) error {
return ErrReadOnly
}
// Open opens the named file on the given Filesystem for reading.
// If successful, methods on the returned file can be used for reading.
// The associated file descriptor has mode os.O_RDONLY.
// If there is an error, it will be of type *PathError.
func (fs RoFS) Open(name string) (File, error) {
return fs.OpenFile(name, os.O_RDONLY, 0)
}
// OpenFile returns ErrorReadOnly if flag contains os.O_CREATE, os.O_APPEND, os.O_WRONLY.
// Otherwise it returns a read-only File with disabled Write(..) operation.
func (fs RoFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
if flag&os.O_CREATE == os.O_CREATE {
return nil, ErrReadOnly
}
if flag&os.O_APPEND == os.O_APPEND {
return nil, ErrReadOnly
}
if flag&os.O_WRONLY == os.O_WRONLY {
return nil, ErrReadOnly
}
f, err := fs.Filesystem.OpenFile(name, flag, perm)
if err != nil {
return ReadOnlyFile(f), err
}
return ReadOnlyFile(f), nil
}
// ReadOnlyFile wraps the given file and disables Write(..) operation.
func ReadOnlyFile(f File) File {
return &roFile{File: f}
}
type roFile struct {
File
}
// Write is disabled and returns ErrorReadOnly
func (f roFile) Write(p []byte) (n int, err error) {
return 0, ErrReadOnly
}