Skip to content

Commit

Permalink
Return os consistent error in ReadOnlyFs filter
Browse files Browse the repository at this point in the history
fixes spf13#350: Use `os.ErrPermission` instead of `syscall.EPerm` to make sure
that the error is consistent over different operating systems and can be
checked with `os.isPermission(err)`
  • Loading branch information
jochil committed May 3, 2022
1 parent 100c9a6 commit 8e474f5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ A thin wrapper around the source Fs providing a read only view.
```go
fs := afero.NewReadOnlyFs(afero.NewOsFs())
_, err := fs.Create("/file.txt")
// err = syscall.EPERM
// err = os.ErrPermission
```

# RegexpFs
Expand Down
23 changes: 11 additions & 12 deletions readonlyfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package afero

import (
"os"
"syscall"
"time"
)

Expand All @@ -21,15 +20,15 @@ func (r *ReadOnlyFs) ReadDir(name string) ([]os.FileInfo, error) {
}

func (r *ReadOnlyFs) Chtimes(n string, a, m time.Time) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) Chmod(n string, m os.FileMode) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) Chown(n string, uid, gid int) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) Name() string {
Expand Down Expand Up @@ -61,20 +60,20 @@ func (r *ReadOnlyFs) ReadlinkIfPossible(name string) (string, error) {
}

func (r *ReadOnlyFs) Rename(o, n string) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) RemoveAll(p string) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) Remove(n string) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
if flag&(os.O_WRONLY|syscall.O_RDWR|os.O_APPEND|os.O_CREATE|os.O_TRUNC) != 0 {
return nil, syscall.EPERM
if flag&(os.O_WRONLY|os.O_RDWR|os.O_APPEND|os.O_CREATE|os.O_TRUNC) != 0 {
return nil, os.ErrPermission
}
return r.source.OpenFile(name, flag, perm)
}
Expand All @@ -84,13 +83,13 @@ func (r *ReadOnlyFs) Open(n string) (File, error) {
}

func (r *ReadOnlyFs) Mkdir(n string, p os.FileMode) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) MkdirAll(n string, p os.FileMode) error {
return syscall.EPERM
return os.ErrPermission
}

func (r *ReadOnlyFs) Create(n string) (File, error) {
return nil, syscall.EPERM
return nil, os.ErrPermission
}
34 changes: 34 additions & 0 deletions readonlyfs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package afero

import (
"os"
"testing"
"time"
)

func checkForErrPermission(t *testing.T, err error) {
t.Helper()
if err == nil || !os.IsPermission(err) {
t.Errorf("Expected err !=nil && err == ErrPermission, got %[1]T (%[1]v)", err)
}
}

// Make sure that the ReadOnlyFs filter returns errors that can be
// checked with os.IsPermission
func TestReadOnlyFsErrPermission(t *testing.T) {
fs := NewReadOnlyFs(NewMemMapFs())

_, err := fs.Create("test")
checkForErrPermission(t, err)
checkForErrPermission(t, fs.Chtimes("test", time.Now(), time.Now()))
checkForErrPermission(t, fs.Chmod("test", os.ModePerm))
checkForErrPermission(t, fs.Chown("test", 0, 0))
checkForErrPermission(t, fs.Mkdir("test", os.ModePerm))
checkForErrPermission(t, fs.MkdirAll("test", os.ModePerm))
_, err = fs.OpenFile("test", os.O_CREATE, os.ModePerm)
checkForErrPermission(t, err)
checkForErrPermission(t, fs.Remove("test"))
checkForErrPermission(t, fs.RemoveAll("test"))
checkForErrPermission(t, fs.Rename("test", "test"))

}

0 comments on commit 8e474f5

Please sign in to comment.