From 4c280e82ac5673505a92e5ce3bc4f9fbf20a787a Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:47:42 +1100 Subject: [PATCH 1/3] Added PosixTest.RmdirWhileOpenedForReading. --- samples/memfs/posix_test.go | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/samples/memfs/posix_test.go b/samples/memfs/posix_test.go index 4224ced..1cbd283 100644 --- a/samples/memfs/posix_test.go +++ b/samples/memfs/posix_test.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "os" "path" + "syscall" "testing" . "github.com/jacobsa/oglematchers" @@ -313,3 +314,50 @@ func (t *PosixTest) HardLinkDirectory() { ExpectThat(err, Error(HasSubstr("link"))) ExpectThat(err, Error(HasSubstr("not permitted"))) } + +func (t *PosixTest) RmdirWhileOpenedForReading() { + var err error + + // Create a directory. + err = os.Mkdir(path.Join(t.dir, "dir"), 0700) + AssertEq(nil, err) + + // Open the directory for reading. + f, err := os.Open(path.Join(t.dir, "dir")) + defer func() { + if f != nil { + ExpectEq(nil, f.Close()) + } + }() + + AssertEq(nil, err) + + // Remove the directory. + err = os.Remove(path.Join(t.dir, "dir")) + AssertEq(nil, err) + + // Create a new directory, with the same name even, and add some contents + // within it. + err = os.MkdirAll(path.Join(t.dir, "dir/foo"), 0700) + AssertEq(nil, err) + + err = os.MkdirAll(path.Join(t.dir, "dir/bar"), 0700) + AssertEq(nil, err) + + err = os.MkdirAll(path.Join(t.dir, "dir/baz"), 0700) + AssertEq(nil, err) + + // We should still be able to stat the open file handle. It should show up as + // unlinked. + fi, err := f.Stat() + + ExpectEq("dir", fi.Name()) + ExpectEq(0, fi.Sys().(*syscall.Stat_t).Nlink) + + // Attempt to read from the directory. This should succeed even though it has + // been unlinked, and we shouldn't see any junk from the new directory. + entries, err := f.Readdir(0) + + AssertEq(nil, err) + ExpectThat(entries, ElementsAre()) +} From b064d6b33f6ad4d5b7514d34d607fb57e03a468a Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:56:21 +1100 Subject: [PATCH 2/3] Revised "rmdir while open for reading" tests for Linux's behavior. --- samples/memfs/memfs_test.go | 12 ++++++++---- samples/memfs/posix_test.go | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/samples/memfs/memfs_test.go b/samples/memfs/memfs_test.go index e332107..6030236 100644 --- a/samples/memfs/memfs_test.go +++ b/samples/memfs/memfs_test.go @@ -734,12 +734,16 @@ func (t *MemFSTest) Rmdir_OpenedForReading() { // https://github.com/bazillion/fuse/issues/66 // ExpectEq(0, fi.Sys().(*syscall.Stat_t).Nlink) - // Attempt to read from the directory. This should succeed even though it has - // been unlinked, and we shouldn't see any junk from the new directory. + // Attempt to read from the directory. This shouldn't see any junk from the + // new directory. It should either succeed with an empty result or should + // return ENOENT. entries, err := f.Readdir(0) - AssertEq(nil, err) - ExpectThat(entries, ElementsAre()) + if err != nil { + ExpectThat(err, Error(HasSubstr("no such file"))) + } else { + ExpectThat(entries, ElementsAre()) + } } func (t *MemFSTest) CaseSensitive() { diff --git a/samples/memfs/posix_test.go b/samples/memfs/posix_test.go index 1cbd283..4e10718 100644 --- a/samples/memfs/posix_test.go +++ b/samples/memfs/posix_test.go @@ -354,10 +354,14 @@ func (t *PosixTest) RmdirWhileOpenedForReading() { ExpectEq("dir", fi.Name()) ExpectEq(0, fi.Sys().(*syscall.Stat_t).Nlink) - // Attempt to read from the directory. This should succeed even though it has - // been unlinked, and we shouldn't see any junk from the new directory. + // Attempt to read from the directory. This shouldn't see any junk from the + // new directory. It should either succeed with an empty result or should + // return ENOENT. entries, err := f.Readdir(0) - AssertEq(nil, err) - ExpectThat(entries, ElementsAre()) + if err != nil { + ExpectThat(err, Error(HasSubstr("no such file"))) + } else { + ExpectThat(entries, ElementsAre()) + } } From acff636a2e0f9e010e2daead261052f016ae2bed Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 16 Mar 2015 13:58:36 +1100 Subject: [PATCH 3/3] Removed an assertion that doesn't pass on OS X. For whatever reason, the directory shows up with Nlink == 2 there. --- samples/memfs/posix_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/samples/memfs/posix_test.go b/samples/memfs/posix_test.go index 4e10718..65e9e36 100644 --- a/samples/memfs/posix_test.go +++ b/samples/memfs/posix_test.go @@ -22,7 +22,6 @@ import ( "io/ioutil" "os" "path" - "syscall" "testing" . "github.com/jacobsa/oglematchers" @@ -347,12 +346,9 @@ func (t *PosixTest) RmdirWhileOpenedForReading() { err = os.MkdirAll(path.Join(t.dir, "dir/baz"), 0700) AssertEq(nil, err) - // We should still be able to stat the open file handle. It should show up as - // unlinked. + // We should still be able to stat the open file handle. fi, err := f.Stat() - ExpectEq("dir", fi.Name()) - ExpectEq(0, fi.Sys().(*syscall.Stat_t).Nlink) // Attempt to read from the directory. This shouldn't see any junk from the // new directory. It should either succeed with an empty result or should