summaryrefslogtreecommitdiff
path: root/std/wasi
diff options
context:
space:
mode:
Diffstat (limited to 'std/wasi')
-rw-r--r--std/wasi/README.md2
-rw-r--r--std/wasi/snapshot_preview1.ts71
-rw-r--r--std/wasi/testdata/std_fs_file_metadata.rs23
3 files changed, 94 insertions, 2 deletions
diff --git a/std/wasi/README.md b/std/wasi/README.md
index 3848ae9a6..b81279dbf 100644
--- a/std/wasi/README.md
+++ b/std/wasi/README.md
@@ -19,7 +19,7 @@ This module provides an implementation of the WebAssembly System Interface
- [x] fd_fdstat_get
- [ ] fd_fdstat_set_flags
- [ ] fd_fdstat_set_rights
-- [ ] fd_filestat_get
+- [x] fd_filestat_get
- [ ] fd_filestat_set_size
- [x] fd_filestat_set_times
- [x] fd_pread
diff --git a/std/wasi/snapshot_preview1.ts b/std/wasi/snapshot_preview1.ts
index 0067499cc..78b29b968 100644
--- a/std/wasi/snapshot_preview1.ts
+++ b/std/wasi/snapshot_preview1.ts
@@ -523,7 +523,76 @@ export default class Module {
},
fd_filestat_get: (fd: number, buf_out: number): number => {
- return ERRNO_NOSYS;
+ const entry = this.fds[fd];
+ if (!entry) {
+ return ERRNO_BADF;
+ }
+
+ const view = new DataView(this.memory.buffer);
+
+ try {
+ const info = Deno.fstatSync(entry.handle.rid);
+
+ if (entry.type === undefined) {
+ switch (true) {
+ case info.isFile:
+ entry.type = FILETYPE_REGULAR_FILE;
+ break;
+
+ case info.isDirectory:
+ entry.type = FILETYPE_DIRECTORY;
+ break;
+
+ case info.isSymlink:
+ entry.type = FILETYPE_SYMBOLIC_LINK;
+ break;
+
+ default:
+ entry.type = FILETYPE_UNKNOWN;
+ break;
+ }
+ }
+
+ view.setBigUint64(buf_out, BigInt(info.dev ? info.dev : 0), true);
+ buf_out += 8;
+
+ view.setBigUint64(buf_out, BigInt(info.ino ? info.ino : 0), true);
+ buf_out += 8;
+
+ view.setUint8(buf_out, entry.type);
+ buf_out += 8;
+
+ view.setUint32(buf_out, Number(info.nlink), true);
+ buf_out += 8;
+
+ view.setBigUint64(buf_out, BigInt(info.size), true);
+ buf_out += 8;
+
+ view.setBigUint64(
+ buf_out,
+ BigInt(info.atime ? info.atime.getTime() * 1e6 : 0),
+ true
+ );
+ buf_out += 8;
+
+ view.setBigUint64(
+ buf_out,
+ BigInt(info.mtime ? info.mtime.getTime() * 1e6 : 0),
+ true
+ );
+ buf_out += 8;
+
+ view.setBigUint64(
+ buf_out,
+ BigInt(info.birthtime ? info.birthtime.getTime() * 1e6 : 0),
+ true
+ );
+ buf_out += 8;
+ } catch (err) {
+ return errno(err);
+ }
+
+ return ERRNO_SUCCESS;
},
fd_filestat_set_size: (fd: number, size: bigint): number => {
diff --git a/std/wasi/testdata/std_fs_file_metadata.rs b/std/wasi/testdata/std_fs_file_metadata.rs
new file mode 100644
index 000000000..93149fd1c
--- /dev/null
+++ b/std/wasi/testdata/std_fs_file_metadata.rs
@@ -0,0 +1,23 @@
+// { "preopens": { "/fixture": "fixture" } }
+
+fn main() {
+ let file = std::fs::File::open("/fixture/file").unwrap();
+ let metadata = file.metadata().unwrap();
+ assert!(metadata.is_file());
+ assert!(metadata.len() == 5);
+
+ let file = std::fs::File::open("/fixture/symlink_to_file").unwrap();
+ let metadata = file.metadata().unwrap();
+ assert!(metadata.is_file());
+ assert!(metadata.len() == 5);
+
+ let file = std::fs::File::open("/fixture/directory/file").unwrap();
+ let metadata = file.metadata().unwrap();
+ assert!(metadata.is_file());
+ assert!(metadata.len() == 15);
+
+ let file = std::fs::File::open("/fixture/directory/symlink_to_file").unwrap();
+ let metadata = file.metadata().unwrap();
+ assert!(metadata.is_file());
+ assert!(metadata.len() == 15);
+}