fs: Adds fd_sync (#1026)
Signed-off-by: Nuno Cruces <ncruces@users.noreply.github.com>
This commit is contained in:
@@ -950,7 +950,24 @@ func fdSeekFn(_ context.Context, mod api.Module, params []uint64) Errno {
|
|||||||
// and metadata of a file to disk.
|
// and metadata of a file to disk.
|
||||||
//
|
//
|
||||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_syncfd-fd---errno
|
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fd_syncfd-fd---errno
|
||||||
var fdSync = stubFunction(FdSyncName, []api.ValueType{i32}, "fd")
|
var fdSync = newHostFunc(FdSyncName, fdSyncFn, []api.ValueType{i32}, "fd")
|
||||||
|
|
||||||
|
func fdSyncFn(_ context.Context, mod api.Module, params []uint64) Errno {
|
||||||
|
fsc := mod.(*wasm.CallContext).Sys.FS()
|
||||||
|
fd := uint32(params[0])
|
||||||
|
|
||||||
|
type syncer interface{ Sync() error }
|
||||||
|
// Check to see if the file descriptor is available
|
||||||
|
if f, ok := fsc.LookupFile(fd); !ok {
|
||||||
|
return ErrnoBadf
|
||||||
|
// fs.FS doesn't declare Sync, but implementations such as os.File implement it.
|
||||||
|
} else if syncer, ok := f.File.(syncer); !ok {
|
||||||
|
return ErrnoBadf
|
||||||
|
} else if err := syncer.Sync(); err != nil {
|
||||||
|
return ErrnoIo
|
||||||
|
}
|
||||||
|
return ErrnoSuccess
|
||||||
|
}
|
||||||
|
|
||||||
// fdTell is the WASI function named FdTellName which returns the current
|
// fdTell is the WASI function named FdTellName which returns the current
|
||||||
// offset of a file descriptor.
|
// offset of a file descriptor.
|
||||||
|
|||||||
@@ -1666,13 +1666,48 @@ func Test_fdSeek_Errors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test_fdSync only tests it is stubbed for GrainLang per #271
|
// Test_fdSync only tests that the call succeeds; it's hard to test its effectiveness.
|
||||||
func Test_fdSync(t *testing.T) {
|
func Test_fdSync(t *testing.T) {
|
||||||
log := requireErrnoNosys(t, FdSyncName, 0)
|
tmpDir := t.TempDir() // open before loop to ensure no locking problems.
|
||||||
require.Equal(t, `
|
pathName := "test_path"
|
||||||
--> wasi_snapshot_preview1.fd_sync(fd=0)
|
mod, fd, log, r := requireOpenFile(t, tmpDir, pathName, []byte{}, false)
|
||||||
<-- errno=ENOSYS
|
defer r.Close(testCtx)
|
||||||
`, log)
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fd uint32
|
||||||
|
expectedErrno Errno
|
||||||
|
expectedLog string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "invalid fd",
|
||||||
|
fd: 42, // arbitrary invalid fd
|
||||||
|
expectedErrno: ErrnoBadf,
|
||||||
|
expectedLog: `
|
||||||
|
==> wasi_snapshot_preview1.fd_sync(fd=42)
|
||||||
|
<== errno=EBADF
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid fd",
|
||||||
|
fd: fd,
|
||||||
|
expectedErrno: ErrnoSuccess,
|
||||||
|
expectedLog: `
|
||||||
|
==> wasi_snapshot_preview1.fd_sync(fd=4)
|
||||||
|
<== errno=ESUCCESS
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tc := tt
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
defer log.Reset()
|
||||||
|
|
||||||
|
requireErrno(t, tc.expectedErrno, mod, FdSyncName, uint64(tc.fd))
|
||||||
|
require.Equal(t, tc.expectedLog, "\n"+log.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test_fdTell only tests it is stubbed for GrainLang per #271
|
// Test_fdTell only tests it is stubbed for GrainLang per #271
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ func maybeWrapFile(f file) file {
|
|||||||
return struct {
|
return struct {
|
||||||
readFile
|
readFile
|
||||||
io.Writer
|
io.Writer
|
||||||
}{f, &windowsWriter{f}}
|
syncer
|
||||||
|
}{f, &windowsWriter{f}, f}
|
||||||
}
|
}
|
||||||
|
|
||||||
// windowsWriter translates error codes not mapped properly by Go.
|
// windowsWriter translates error codes not mapped properly by Go.
|
||||||
|
|||||||
@@ -142,4 +142,7 @@ type readFile interface {
|
|||||||
type file interface {
|
type file interface {
|
||||||
readFile
|
readFile
|
||||||
io.Writer
|
io.Writer
|
||||||
|
syncer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type syncer interface{ Sync() error }
|
||||||
|
|||||||
Reference in New Issue
Block a user