github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/cmd/mountlib/mounttest/write_unix.go (about) 1 // +build linux darwin freebsd 2 3 package mounttest 4 5 import ( 6 "runtime" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 "golang.org/x/sys/unix" 11 12 "github.com/rclone/rclone/vfs" 13 ) 14 15 // TestWriteFileDoubleClose tests double close on write 16 func TestWriteFileDoubleClose(t *testing.T) { 17 run.skipIfNoFUSE(t) 18 if runtime.GOOS == "darwin" { 19 t.Skip("Skipping test on OSX") 20 } 21 22 out, err := osCreate(run.path("testdoubleclose")) 23 assert.NoError(t, err) 24 fd := out.Fd() 25 26 fd1, err := unix.Dup(int(fd)) 27 assert.NoError(t, err) 28 29 fd2, err := unix.Dup(int(fd)) 30 assert.NoError(t, err) 31 32 // close one of the dups - should produce no error 33 err = unix.Close(fd1) 34 assert.NoError(t, err) 35 36 // write to the file 37 buf := []byte("hello") 38 n, err := out.Write(buf) 39 assert.NoError(t, err) 40 assert.Equal(t, 5, n) 41 42 // close it 43 err = out.Close() 44 assert.NoError(t, err) 45 46 // write to the other dup 47 _, err = unix.Write(fd2, buf) 48 if run.vfs.Opt.CacheMode < vfs.CacheModeWrites { 49 // produces an error if cache mode < writes 50 assert.Error(t, err, "input/output error") 51 } else { 52 // otherwise does not produce an error 53 assert.NoError(t, err) 54 } 55 56 // close the dup - should not produce an error 57 err = unix.Close(fd2) 58 assert.NoError(t, err) 59 60 run.waitForWriters() 61 run.rm(t, "testdoubleclose") 62 } 63 64 // writeTestDup performs the platform-specific implementation of the dup() unix 65 func writeTestDup(oldfd uintptr) (uintptr, error) { 66 newfd, err := unix.Dup(int(oldfd)) 67 return uintptr(newfd), err 68 }