summaryrefslogtreecommitdiff
path: root/std/wasi/snapshot_preview1.ts
diff options
context:
space:
mode:
Diffstat (limited to 'std/wasi/snapshot_preview1.ts')
-rw-r--r--std/wasi/snapshot_preview1.ts105
1 files changed, 92 insertions, 13 deletions
diff --git a/std/wasi/snapshot_preview1.ts b/std/wasi/snapshot_preview1.ts
index e42d7eec2..72ddd5d23 100644
--- a/std/wasi/snapshot_preview1.ts
+++ b/std/wasi/snapshot_preview1.ts
@@ -317,15 +317,12 @@ export default class Module {
if (options.preopens) {
for (const [vpath, path] of Object.entries(options.preopens)) {
- const info = Deno.statSync(path);
- if (!info.isDirectory) {
- throw new TypeError(`${path} is not a directory`);
- }
-
const type = FILETYPE_DIRECTORY;
+ const entries = Array.from(Deno.readDirSync(path));
const entry = {
type,
+ entries,
path,
vpath,
};
@@ -485,7 +482,10 @@ export default class Module {
return ERRNO_BADF;
}
- entry.handle.close();
+ if (entry.handle) {
+ entry.handle.close();
+ }
+
delete this.fds[fd];
return ERRNO_SUCCESS;
@@ -797,7 +797,70 @@ export default class Module {
cookie: bigint,
bufused_out: number
): number => {
- return ERRNO_NOSYS;
+ const entry = this.fds[fd];
+ if (!entry) {
+ return ERRNO_BADF;
+ }
+
+ const heap = new Uint8Array(this.memory.buffer);
+ const view = new DataView(this.memory.buffer);
+
+ let bufused = 0;
+
+ try {
+ const entries = Array.from(Deno.readDirSync(entry.path));
+ for (let i = Number(cookie); i < entries.length; i++) {
+ const name_data = new TextEncoder().encode(entries[i].name);
+
+ const entry_info = Deno.statSync(
+ resolve(entry.path, entries[i].name)
+ );
+ const entry_data = new Uint8Array(24 + name_data.byteLength);
+ const entry_view = new DataView(entry_data.buffer);
+
+ entry_view.setBigUint64(0, BigInt(i + 1), true);
+ entry_view.setBigUint64(
+ 8,
+ BigInt(entry_info.ino ? entry_info.ino : 0),
+ true
+ );
+ entry_view.setUint32(16, name_data.byteLength, true);
+
+ switch (true) {
+ case entries[i].isFile:
+ var type = FILETYPE_REGULAR_FILE;
+ break;
+
+ case entries[i].isDirectory:
+ var type = FILETYPE_REGULAR_FILE;
+ break;
+
+ case entries[i].isSymlink:
+ var type = FILETYPE_SYMBOLIC_LINK;
+ break;
+
+ default:
+ var type = FILETYPE_REGULAR_FILE;
+ break;
+ }
+
+ entry_view.setUint8(20, type);
+ entry_data.set(name_data, 24);
+
+ const data = entry_data.slice(
+ 0,
+ Math.min(entry_data.length, buf_len - bufused)
+ );
+ heap.set(data, buf_ptr + bufused);
+ bufused += data.byteLength;
+ }
+ } catch (err) {
+ return errno(err);
+ }
+
+ view.setUint32(bufused_out, bufused, true);
+
+ return ERRNO_SUCCESS;
},
fd_renumber: (fd: number, to: number): number => {
@@ -1126,6 +1189,28 @@ export default class Module {
const data = new Uint8Array(this.memory.buffer, path_ptr, path_len);
const path = resolve(entry.path, text.decode(data));
+ if ((oflags & OFLAGS_DIRECTORY) !== 0) {
+ // XXX (caspervonb) this isn't ideal as we can't get a rid for the
+ // directory this way so there's no native fstat but Deno.open
+ // doesn't work with directories on windows so we'll have to work
+ // around it for now.
+ try {
+ const entries = Array.from(Deno.readDirSync(path));
+ const opened_fd =
+ this.fds.push({
+ entries,
+ path,
+ }) - 1;
+
+ const view = new DataView(this.memory.buffer);
+ view.setUint32(opened_fd_out, opened_fd, true);
+ } catch (err) {
+ return errno(err);
+ }
+
+ return ERRNO_SUCCESS;
+ }
+
const options = {
read: false,
write: false,
@@ -1140,12 +1225,6 @@ export default class Module {
options.write = true;
}
- if ((oflags & OFLAGS_DIRECTORY) !== 0) {
- // TODO (caspervonb) review if we can
- // emulate this; unix supports opening
- // directories, windows does not.
- }
-
if ((oflags & OFLAGS_EXCL) !== 0) {
options.createNew = true;
}