Skip to content

Commit

Permalink
Fix fd_fdstat_set_flags truncating with O_TRUNC
Browse files Browse the repository at this point in the history
This commit fixes a buf when `fd_fdstat_set_flags` would erroneously
truncate an open file if it is opened with the O_TRUNC flag.  This
happens because the O_TRUNC flag causes the file to be truncated when it
is opened.

Signed-off-by: Yage Hu <[email protected]>
  • Loading branch information
yagehu committed Dec 12, 2023
1 parent 5796897 commit 5df6ce6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
36 changes: 36 additions & 0 deletions imports/wasi_snapshot_preview1/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,42 @@ func Test_fdFdstatGet_StdioNonblock(t *testing.T) {
}
}

func Test_fdFdstatSetFlagsWithTrunc(t *testing.T) {
tmpDir := t.TempDir()
fileName := "test"

mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().
WithFSConfig(wazero.NewFSConfig().WithDirMount(tmpDir, "/")))
defer r.Close(testCtx)

fsc := mod.(*wasm.ModuleInstance).Sys.FS()
preopen := fsc.RootFS()

fd, errno := fsc.OpenFile(preopen, fileName, experimentalsys.O_RDWR|experimentalsys.O_CREAT|experimentalsys.O_EXCL|experimentalsys.O_TRUNC, 0o600)
require.EqualErrno(t, 0, errno)

// Write the initial text to the file.
f, ok := fsc.LookupFile(fd)
require.True(t, ok)
n, errno := f.File.Write([]byte("abc"))

Check failure on line 500 in imports/wasi_snapshot_preview1/fs_test.go

View workflow job for this annotation

GitHub Actions / Pre-commit check

ineffectual assignment to errno (ineffassign)
require.Equal(t, n, 3)

buf, err := os.ReadFile(joinPath(tmpDir, fileName))
require.NoError(t, err)
require.Equal(t, "abc", string(buf))

requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdFdstatSetFlagsName, uint64(fd), uint64(0))
require.Equal(t, `
==> wasi_snapshot_preview1.fd_fdstat_set_flags(fd=4,flags=)
<== errno=ESUCCESS
`, "\n"+log.String())
log.Reset()

buf, err = os.ReadFile(joinPath(tmpDir, fileName))
require.NoError(t, err)
require.Equal(t, "abc", string(buf))
}

func Test_fdFdstatSetFlags(t *testing.T) {
tmpDir := t.TempDir() // open before loop to ensure no locking problems.

Expand Down
3 changes: 3 additions & 0 deletions internal/sysfs/osfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ func (f *osFile) SetAppend(enable bool) (errno experimentalsys.Errno) {
// Clear any create flag, as we are re-opening, not re-creating.
f.flag &= ^experimentalsys.O_CREAT

// Clear trunc flag, as we are re-opening.
f.flag &= ^experimentalsys.O_TRUNC

// appendMode (bool) cannot be changed later, so we have to re-open the
// file. https://github.com/golang/go/blob/go1.20/src/os/file_unix.go#L60
return fileError(f, f.closed, f.reopen())
Expand Down

0 comments on commit 5df6ce6

Please sign in to comment.