github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/vfstest/write_unix.go (about) 1 // +build linux darwin freebsd 2 3 package vfstest 4 5 import ( 6 "runtime" 7 "testing" 8 9 "github.com/rclone/rclone/vfs/vfscommon" 10 "github.com/stretchr/testify/assert" 11 "golang.org/x/sys/unix" 12 ) 13 14 // TestWriteFileDoubleClose tests double close on write 15 func TestWriteFileDoubleClose(t *testing.T) { 16 run.skipIfVFS(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 < vfscommon.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 }