diff --git a/dummy.go b/dummy.go index a0359cd..31fcf15 100644 --- a/dummy.go +++ b/dummy.go @@ -21,6 +21,11 @@ func (fs DummyFS) PathSeparator() uint8 { return '/' } +// Open returns dummy error +func (fs DummyFS) Open(name string) (File, error) { + return fs.OpenFile(name, os.O_RDONLY, 0) +} + // OpenFile returns dummy error func (fs DummyFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { return nil, fs.err diff --git a/dummy_test.go b/dummy_test.go index 71af207..6b9ba17 100644 --- a/dummy_test.go +++ b/dummy_test.go @@ -13,6 +13,9 @@ func TestInterface(t *testing.T) { func TestDummyFS(t *testing.T) { fs := Dummy(errDum) + if _, err := fs.Open("/tmp/test123"); err != errDum { + t.Errorf("Open DummyError expected: %s", err) + } if _, err := fs.OpenFile("test", 0, 0); err != errDum { t.Errorf("OpenFile DummyError expected: %s", err) } diff --git a/memfs/memfs.go b/memfs/memfs.go index 6be44bd..1d5fee3 100644 --- a/memfs/memfs.go +++ b/memfs/memfs.go @@ -215,6 +215,14 @@ func hasFlag(flag int, flags int) bool { return flags&flag == flag } +// 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 *MemFS) Open(name string) (vfs.File, error) { + return fs.OpenFile(name, os.O_RDONLY, 0) +} + // OpenFile opens a file handle with a specified flag (os.O_RDONLY etc.) and perm (e.g. 0666). // If success the returned File can be used for I/O. Otherwise an error is returned, which // is a *os.PathError and can be extracted for further information. diff --git a/memfs/memfs_test.go b/memfs/memfs_test.go index d2f06d4..8975542 100644 --- a/memfs/memfs_test.go +++ b/memfs/memfs_test.go @@ -276,6 +276,27 @@ func TestReadWrite(t *testing.T) { } } +func TestOpen(t *testing.T) { + fs := Create() + f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDWR, 0666) + if err != nil { + t.Fatalf("OpenFile: %s", err) + } + _, err = f.Write([]byte("test")) + if err != nil { + t.Fatalf("Write: %s", err) + } + f.Close() + f2, err := fs.Open("/readme.txt") + if err != nil { + t.Errorf("Open: %s", err) + } + err = f2.Close() + if err != nil { + t.Errorf("Close: %s", err) + } +} + func TestOpenRO(t *testing.T) { fs := Create() f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDONLY, 0666) @@ -288,6 +309,7 @@ func TestOpenRO(t *testing.T) { t.Fatalf("Expected write error") } f.Close() + } func TestOpenWO(t *testing.T) { diff --git a/mountfs/mountfs.go b/mountfs/mountfs.go index aa0396c..bc065e7 100644 --- a/mountfs/mountfs.go +++ b/mountfs/mountfs.go @@ -2,10 +2,11 @@ package mountfs import ( "errors" - "github.com/blang/vfs" "os" filepath "path" "strings" + + "github.com/blang/vfs" ) // ErrBoundary is returned if an operation @@ -95,6 +96,14 @@ func (f innerFile) Name() string { return f.name } +// 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 MountFS) Open(name string) (vfs.File, error) { + return fs.OpenFile(name, os.O_RDONLY, 0) +} + // OpenFile find the mount of the given path and executes OpenFile // on the corresponding filesystem. // It wraps the resulting file to return the path inside mountfs on Name() diff --git a/mountfs/mountfs_test.go b/mountfs/mountfs_test.go index 03ea839..0846952 100644 --- a/mountfs/mountfs_test.go +++ b/mountfs/mountfs_test.go @@ -2,9 +2,10 @@ package mountfs import ( "errors" - "github.com/blang/vfs" "os" "testing" + + "github.com/blang/vfs" ) type mountTest struct { @@ -140,6 +141,11 @@ func TestOpenFile(t *testing.T) { if n := f.Name(); n != "/tmp/testfile" { t.Errorf("Unexpected filename: %s", n) } + + _, err = fs.Open("/tmp/testfile") + if err != nil { + t.Errorf("Open: %s", err) + } } func (fs *testDummyFS) Mkdir(name string, perm os.FileMode) error { diff --git a/os.go b/os.go index feb33bb..2e48e04 100644 --- a/os.go +++ b/os.go @@ -18,6 +18,11 @@ func (fs OsFS) PathSeparator() uint8 { return os.PathSeparator } +// Open wraps os.Open +func (fs OsFS) Open(name string) (File, error) { + return os.Open(name) +} + // OpenFile wraps os.OpenFile func (fs OsFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { return os.OpenFile(name, flag, perm) diff --git a/os_test.go b/os_test.go index 386cf73..8ada071 100644 --- a/os_test.go +++ b/os_test.go @@ -20,6 +20,14 @@ func TestOSCreate(t *testing.T) { if err != nil { t.Errorf("Close: %s", err) } + f2, err := fs.Open("/tmp/test123") + if err != nil { + t.Errorf("Open: %s", err) + } + err = f2.Close() + if err != nil { + t.Errorf("Close: %s", err) + } err = fs.Remove(f.Name()) if err != nil { t.Errorf("Remove: %s", err) diff --git a/readonly.go b/readonly.go index 406cd84..abb88dd 100644 --- a/readonly.go +++ b/readonly.go @@ -3,6 +3,8 @@ package vfs import ( "errors" "os" + + "github.com/blang/vfs" ) // ReadOnly creates a readonly wrapper around the given filesystem. @@ -44,6 +46,14 @@ func (fs RoFS) Mkdir(name string, perm os.FileMode) 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) (vfs.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) {