fs: Adds fd_sync (#1026)

Signed-off-by: Nuno Cruces <ncruces@users.noreply.github.com>
This commit is contained in:
Nuno Cruces
2023-01-13 23:16:14 +00:00
committed by GitHub
parent 40208a86e2
commit 59076bccf5
4 changed files with 64 additions and 8 deletions

View File

@@ -950,7 +950,24 @@ func fdSeekFn(_ context.Context, mod api.Module, params []uint64) Errno {
// and metadata of a file to disk.
//
// 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
// offset of a file descriptor.

View File

@@ -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) {
log := requireErrnoNosys(t, FdSyncName, 0)
require.Equal(t, `
--> wasi_snapshot_preview1.fd_sync(fd=0)
<-- errno=ENOSYS
`, log)
tmpDir := t.TempDir() // open before loop to ensure no locking problems.
pathName := "test_path"
mod, fd, log, r := requireOpenFile(t, tmpDir, pathName, []byte{}, false)
defer r.Close(testCtx)
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

View File

@@ -97,7 +97,8 @@ func maybeWrapFile(f file) file {
return struct {
readFile
io.Writer
}{f, &windowsWriter{f}}
syncer
}{f, &windowsWriter{f}, f}
}
// windowsWriter translates error codes not mapped properly by Go.

View File

@@ -142,4 +142,7 @@ type readFile interface {
type file interface {
readFile
io.Writer
syncer
}
type syncer interface{ Sync() error }