Repository: tetratelabs/wazero (go)

Issue:
Failure executing sqlite3 after bedde6d (at and preopen semantics)
**Describe the bug**

After bedde6d I'm getting some rather inscrutable bugs while testing [`github.com/ncruces/go-sqlite3`](https://github.com/ncruces/go-sqlite3).

I'm not entirely sure what's going on.

**To Reproduce**

```sh
git clone --branch crash https://github.com/ncruces/go-sqlite3
cd go-sqlite3
./build_deps.sh
go run ./cmd
```

This panics inside my own code with the following error:
```
panic: module "sqlite3-1" closed with exit_code(71)

goroutine 1 [running]:
github.com/ncruces/go-sqlite3.(*Conn).free(0xc0000e26c0, 0x10cc20)
	/Users/cruces/Desktop/go-sqlite3/conn.go:166 +0xa5
github.com/ncruces/go-sqlite3.Open({0x11ab821, 0x7}, 0x0, {0x0, 0x0})
	/Users/cruces/Desktop/go-sqlite3/conn.go:92 +0xa29
main.main()
	/Users/cruces/Desktop/go-sqlite3/cmd/main.go:11 +0x2f
exit status 2
```

It's this section of code:
https://github.com/ncruces/go-sqlite3/blob/7c3b679b7dcc8fe36cf87a59447ab1048bf1b4d0/conn.go#L86-L94

After calling `c.api.open.Call` (which does a bunch of WASI FS calls) any function call seems to return this error (I'm panicking `free` errors). I'm guessing some `libc` internal state somehow gets corrupted?

**Expected behavior**

The above repro should print this:
```
2023/01/12 15:08:14 sqlite3: disk I/O error
exit status 1
````

Or, after #1026, it should succeed in creating a `test.db` with some tables in it.

Pull request description:
fs: fd_prestat_get return EBADF for not pre-opened
This fixes #1027.

WASI-libc prestats every fd from 3 until one returns EBADF. If any other error is returned, the process exits with code 71 (EX_OSERR).

Patch:
diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go
index c966aaa5..5fe86385 100644
--- a/imports/wasi_snapshot_preview1/fs.go
+++ b/imports/wasi_snapshot_preview1/fs.go
@@ -1370,7 +1370,7 @@ func preopenPath(fsc *sys.FSContext, dirFD uint32) (string, Errno) {
 	if f, ok := fsc.LookupFile(dirFD); !ok {
 		return "", ErrnoBadf // closed
 	} else if !f.IsPreopen {
-		return "", ErrnoInval
+		return "", ErrnoBadf
 	} else {
 		// TODO: multiple pre-opens
 		return fsc.FS().GuestDir(), ErrnoSuccess


Test patch:
diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go
index 41e5518d..cf293170 100644
--- a/imports/wasi_snapshot_preview1/fs_test.go
+++ b/imports/wasi_snapshot_preview1/fs_test.go
@@ -766,10 +766,10 @@ func Test_fdPrestatGet_Errors(t *testing.T) {
 			name:          "not pre-opened FD",
 			fd:            dirFD,
 			resultPrestat: 0, // valid offset
-			expectedErrno: ErrnoInval,
+			expectedErrno: ErrnoBadf,
 			expectedLog: `
 ==> wasi_snapshot_preview1.fd_prestat_get(fd=4)
-<== (prestat=,errno=EINVAL)
+<== (prestat=,errno=EBADF)
 `,
 		},
 		{
@@ -890,10 +890,10 @@ func Test_fdPrestatDirName_Errors(t *testing.T) {
 			fd:            dirFD,
 			path:          validAddress,
 			pathLen:       pathLen,
-			expectedErrno: ErrnoInval,
+			expectedErrno: ErrnoBadf,
 			expectedLog: `
 ==> wasi_snapshot_preview1.fd_prestat_dir_name(fd=4)
-<== (path=,errno=EINVAL)
+<== (path=,errno=EBADF)
 `,
 		},
 	}