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  }