diff --git a/src/fs_core.ts b/src/fs_core.ts index 4532ee3..48fb89b 100644 --- a/src/fs_core.ts +++ b/src/fs_core.ts @@ -122,6 +122,27 @@ export class Directory { return entry; } + get_parent_dir_for_path(path: string): Directory | null { + if (path === "") return null; + let entry: File | Directory | SyncOPFSFile = this; + let parentEntry: File | Directory | SyncOPFSFile = entry; + for (const component of path.split("/")) { + if (component === "") break; + if (component === ".") continue; + if (!(entry instanceof Directory)) { + debug.log(entry); + return null; + } + if (entry.contents[component] === undefined) { + debug.log(component); + return null; + } + parentEntry = entry; + entry = entry.contents[component]; + } + return parentEntry; + } + create_entry_for_path( path: string, is_dir: boolean, diff --git a/src/fs_fd.ts b/src/fs_fd.ts index 8b3a3f5..f4f7068 100644 --- a/src/fs_fd.ts +++ b/src/fs_fd.ts @@ -314,6 +314,56 @@ export class OpenDirectory extends Fd { 0, ).ret; } + + path_unlink_file(path: string): number { + path = this.clean_path(path); + const parentDirEntry = this.dir.get_parent_dir_for_path(path); + const pathComponents = path.split("/"); + const fileName = pathComponents[pathComponents.length - 1]; + const entry = this.dir.get_entry_for_path(path); + if (entry === null) { + return wasi.ERRNO_NOENT; + } + if (entry.stat().filetype === wasi.FILETYPE_DIRECTORY) { + return wasi.ERRNO_ISDIR; + } + delete parentDirEntry.contents[fileName]; + return wasi.ERRNO_SUCCESS; + } + + path_remove_directory(path: string): number { + path = this.clean_path(path); + const parentDirEntry = this.dir.get_parent_dir_for_path(path); + const pathComponents = path.split("/"); + const fileName = pathComponents[pathComponents.length - 1]; + + const entry = this.dir.get_entry_for_path(path); + + if (entry === null) { + return wasi.ERRNO_NOENT; + } + if ( + !(entry instanceof Directory) || + entry.stat().filetype !== wasi.FILETYPE_DIRECTORY + ) { + return wasi.ERRNO_NOTDIR; + } + if (Object.keys(entry.contents).length !== 0) { + return wasi.ERRNO_NOTEMPTY; + } + if (parentDirEntry.contents[fileName] === undefined) { + return wasi.ERRNO_NOENT; + } + delete parentDirEntry.contents[fileName]; + return wasi.ERRNO_SUCCESS; + } + + clean_path(path: string): string { + while (path.length > 0 && path[path.length - 1] === "/") { + path = path.slice(0, path.length - 1); + } + return path; + } } export class PreopenDirectory extends OpenDirectory {