diff options
Diffstat (limited to 'std/wasi/snapshot_preview1.ts')
-rw-r--r-- | std/wasi/snapshot_preview1.ts | 105 |
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; } |