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