mirror of
https://github.com/denoland/deno.git
synced 2025-02-08 15:21:26 -05:00
feat(std/wasi): implement fd_readdir (#6631)
This commit is contained in:
parent
9ac416913e
commit
79400b8f7d
3 changed files with 102 additions and 14 deletions
|
@ -27,7 +27,7 @@ This module provides an implementation of the WebAssembly System Interface
|
||||||
- [x] fd_prestat_dir_name
|
- [x] fd_prestat_dir_name
|
||||||
- [x] fd_pwrite
|
- [x] fd_pwrite
|
||||||
- [x] fd_read
|
- [x] fd_read
|
||||||
- [ ] fd_readdir
|
- [x] fd_readdir
|
||||||
- [x] fd_renumber
|
- [x] fd_renumber
|
||||||
- [x] fd_seek
|
- [x] fd_seek
|
||||||
- [x] fd_sync
|
- [x] fd_sync
|
||||||
|
|
|
@ -317,15 +317,12 @@ export default class Module {
|
||||||
|
|
||||||
if (options.preopens) {
|
if (options.preopens) {
|
||||||
for (const [vpath, path] of Object.entries(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 type = FILETYPE_DIRECTORY;
|
||||||
|
const entries = Array.from(Deno.readDirSync(path));
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
type,
|
type,
|
||||||
|
entries,
|
||||||
path,
|
path,
|
||||||
vpath,
|
vpath,
|
||||||
};
|
};
|
||||||
|
@ -485,7 +482,10 @@ export default class Module {
|
||||||
return ERRNO_BADF;
|
return ERRNO_BADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.handle.close();
|
if (entry.handle) {
|
||||||
|
entry.handle.close();
|
||||||
|
}
|
||||||
|
|
||||||
delete this.fds[fd];
|
delete this.fds[fd];
|
||||||
|
|
||||||
return ERRNO_SUCCESS;
|
return ERRNO_SUCCESS;
|
||||||
|
@ -797,7 +797,70 @@ export default class Module {
|
||||||
cookie: bigint,
|
cookie: bigint,
|
||||||
bufused_out: number
|
bufused_out: number
|
||||||
): 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 => {
|
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 data = new Uint8Array(this.memory.buffer, path_ptr, path_len);
|
||||||
const path = resolve(entry.path, text.decode(data));
|
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 = {
|
const options = {
|
||||||
read: false,
|
read: false,
|
||||||
write: false,
|
write: false,
|
||||||
|
@ -1140,12 +1225,6 @@ export default class Module {
|
||||||
options.write = true;
|
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) {
|
if ((oflags & OFLAGS_EXCL) !== 0) {
|
||||||
options.createNew = true;
|
options.createNew = true;
|
||||||
}
|
}
|
||||||
|
|
9
std/wasi/testdata/std_fs_read_dir.rs
vendored
Normal file
9
std/wasi/testdata/std_fs_read_dir.rs
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// { "preopens": { "/fixture": "fixture" } }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let entries = std::fs::read_dir("/fixture").unwrap();
|
||||||
|
assert_eq!(entries.count(), 4);
|
||||||
|
|
||||||
|
let entries = std::fs::read_dir("/fixture/directory").unwrap();
|
||||||
|
assert_eq!(entries.count(), 2);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue