// Modified deno-wasi implementation for Deno, Bun, Node.js // https://github.com/guest271314/deno-wasi/blob/master/mod.ts // deno-fmt-ignore-file // deno-lint-ignore-file // This code was bundled using `deno bundle` and it's not recommended to edit it manually import process from "node:process"; import fs from "node:fs"; function assertPath(path) { if (typeof path !== "string") { throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`); } } const CHAR_FORWARD_SLASH = 47; function isPathSeparator(code) { return code === 47 || code === 92; } function isWindowsDeviceRoot(code) { return code >= 97 && code <= 122 || code >= 65 && code <= 90; } function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { let res = ""; let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; let code; for(let i = 0; i <= path.length; ++i){ if (i < path.length) code = path.charCodeAt(i); else if (isPathSeparator(code)) break; else code = CHAR_FORWARD_SLASH; if (isPathSeparator(code)) { if (lastSlash === i - 1 || dots === 1) {} else if (lastSlash !== i - 1 && dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf(separator); if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); } lastSlash = i; dots = 0; continue; } else if (res.length === 2 || res.length === 1) { res = ""; lastSegmentLength = 0; lastSlash = i; dots = 0; continue; } } if (allowAboveRoot) { if (res.length > 0) res += `${separator}..`; else res = ".."; lastSegmentLength = 2; } } else { if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); lastSegmentLength = i - lastSlash - 1; } lastSlash = i; dots = 0; } else if (code === 46 && dots !== -1) { ++dots; } else { dots = -1; } } return res; } function resolve(...pathSegments) { let resolvedDevice = ""; let resolvedTail = ""; let resolvedAbsolute = false; for(let i = pathSegments.length - 1; i >= -1; i--){ let path; // const { Deno: Deno1 } = globalThis; if (i >= 0) { path = pathSegments[i]; } else if (!resolvedDevice) { if (typeof process.cwd !== "function") { throw new TypeError("Resolved a drive-letter-less path without a CWD."); } path = process.cwd(); } else { if (typeof process?.env?.get !== "function" || typeof process?.cwd !== "function") { throw new TypeError("Resolved a relative path without a CWD."); } path = process.cwd(); if (path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) { path = `${resolvedDevice}\\`; } } assertPath(path); const len = path.length; if (len === 0) continue; let rootEnd = 0; let device = ""; let isAbsolute = false; const code = path.charCodeAt(0); if (len > 1) { if (isPathSeparator(code)) { isAbsolute = true; if (isPathSeparator(path.charCodeAt(1))) { let j = 2; let last = j; for(; j < len; ++j){ if (isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { const firstPart = path.slice(last, j); last = j; for(; j < len; ++j){ if (!isPathSeparator(path.charCodeAt(j))) break; } if (j < len && j !== last) { last = j; for(; j < len; ++j){ if (isPathSeparator(path.charCodeAt(j))) break; } if (j === len) { device = `\\\\${firstPart}\\${path.slice(last)}`; rootEnd = j; } else if (j !== last) { device = `\\\\${firstPart}\\${path.slice(last, j)}`; rootEnd = j; } } } } else { rootEnd = 1; } } else if (isWindowsDeviceRoot(code)) { if (path.charCodeAt(1) === 58) { device = path.slice(0, 2); rootEnd = 2; if (len > 2) { if (isPathSeparator(path.charCodeAt(2))) { isAbsolute = true; rootEnd = 3; } } } } } else if (isPathSeparator(code)) { rootEnd = 1; isAbsolute = true; } if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) { continue; } if (resolvedDevice.length === 0 && device.length > 0) { resolvedDevice = device; } if (!resolvedAbsolute) { resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; resolvedAbsolute = isAbsolute; } if (resolvedAbsolute && resolvedDevice.length > 0) break; } resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator); return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; } function isPosixPathSeparator(code) { return code === 47; } function resolve1(...pathSegments) { let resolvedPath = ""; let resolvedAbsolute = false; for(let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--){ let path; if (i >= 0) path = pathSegments[i]; else { // const { Deno: Deno1 } = globalThis; if (typeof process?.cwd !== "function") { throw new TypeError("Resolved a relative path without a CWD."); } path = process.cwd(); } assertPath(path); if (path.length === 0) { continue; } resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = isPosixPathSeparator(path.charCodeAt(0)); } resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); if (resolvedAbsolute) { if (resolvedPath.length > 0) return `/${resolvedPath}`; else return "/"; } else if (resolvedPath.length > 0) return resolvedPath; else return "."; } const osType = (()=>{ // const { Deno: Deno1 } = globalThis; if (typeof process?.build?.os === "string") { return process.build.os; } const { navigator } = globalThis; if (navigator?.appVersion?.includes?.("Win")) { return "windows"; } return "linux"; })(); const isWindows = osType === "windows"; function resolve2(...pathSegments) { return isWindows ? resolve(...pathSegments) : resolve1(...pathSegments); } const CLOCKID_REALTIME = 0; const CLOCKID_MONOTONIC = 1; const CLOCKID_PROCESS_CPUTIME_ID = 2; const CLOCKID_THREAD_CPUTIME_ID = 3; const ERRNO_SUCCESS = 0; const ERRNO_BADF = 8; const ERRNO_INVAL = 28; const ERRNO_NOSYS = 52; const ERRNO_NOTDIR = 54; const RIGHTS_FD_DATASYNC = 0x0000000000000001n; const RIGHTS_FD_READ = 0x0000000000000002n; const RIGHTS_FD_WRITE = 0x0000000000000040n; const RIGHTS_FD_ALLOCATE = 0x0000000000000100n; const RIGHTS_FD_READDIR = 0x0000000000004000n; const RIGHTS_FD_FILESTAT_SET_SIZE = 0x0000000000400000n; const FILETYPE_UNKNOWN = 0; const FILETYPE_CHARACTER_DEVICE = 2; const FILETYPE_DIRECTORY = 3; const FILETYPE_REGULAR_FILE = 4; const FILETYPE_SYMBOLIC_LINK = 7; const FDFLAGS_APPEND = 0x0001; const FDFLAGS_DSYNC = 0x0002; const FDFLAGS_NONBLOCK = 0x0004; const FDFLAGS_RSYNC = 0x0008; const FDFLAGS_SYNC = 0x0010; const FSTFLAGS_ATIM_NOW = 0x0002; const FSTFLAGS_MTIM_NOW = 0x0008; const OFLAGS_CREAT = 0x0001; const OFLAGS_DIRECTORY = 0x0002; const OFLAGS_EXCL = 0x0004; const OFLAGS_TRUNC = 0x0008; const PREOPENTYPE_DIR = 0; const clock_res_realtime = function() { return BigInt(1e6); }; const clock_res_monotonic = function() { return BigInt(1e3); }; const clock_res_process = clock_res_monotonic; const clock_res_thread = clock_res_monotonic; const clock_time_realtime = function() { return BigInt(Date.now()) * BigInt(1e6); }; const clock_time_monotonic = function() { const t = performance.now(); const s = Math.trunc(t); const ms = Math.floor((t - s) * 1e3); return BigInt(s) * BigInt(1e9) + BigInt(ms) * BigInt(1e6); }; const clock_time_process = clock_time_monotonic; const clock_time_thread = clock_time_monotonic; function errno(err) { switch(err.name){ case "NotFound": return 44; case "PermissionDenied": return 2; case "ConnectionRefused": return 14; case "ConnectionReset": return 15; case "ConnectionAborted": return 13; case "NotConnected": return 53; case "AddrInUse": return 3; case "AddrNotAvailable": return 4; case "BrokenPipe": return 64; case "InvalidData": return 28; case "TimedOut": return 73; case "Interrupted": return 27; case "BadResource": return 8; case "Busy": return 10; default: return 28; } } class Module { args; env; memory; fds; exports; constructor(options){ this.args = options?.args ? options.args : []; this.env = options?.env ? options.env : {}; this.memory = options?.memory; this.fds = [ { type: FILETYPE_CHARACTER_DEVICE, handle: process.stdin }, { type: FILETYPE_CHARACTER_DEVICE, handle: process.stdout }, { type: FILETYPE_CHARACTER_DEVICE, handle: process.stderr } ]; if (options?.preopens) { for (const [vpath, path] of Object.entries(options.preopens)){ const info = fs.statSync(path); if (!info.isDirectory) { throw new TypeError(`${path} is not a directory`); } const entry = { type: 3, path, vpath }; this.fds.push(entry); } } this.exports = { args_get: (argv_ptr, argv_buf_ptr)=>{ const args = this.args; const text = new TextEncoder(); const heap = new Uint8Array(this.memory.buffer); const view = new DataView(this.memory.buffer); for (let arg of args){ view.setUint32(argv_ptr, argv_buf_ptr, true); argv_ptr += 4; const data = text.encode(`${arg}\0`); heap.set(data, argv_buf_ptr); argv_buf_ptr += data.length; } return ERRNO_SUCCESS; }, args_sizes_get: (argc_out, argv_buf_size_out)=>{ const args = this.args; const text = new TextEncoder(); const view = new DataView(this.memory.buffer); view.setUint32(argc_out, args.length, true); view.setUint32(argv_buf_size_out, args.reduce(function(acc, arg) { return acc + text.encode(`${arg}\0`).length; }, 0), true); return ERRNO_SUCCESS; }, environ_get: (environ_ptr, environ_buf_ptr)=>{ const entries = Object.entries(this.env); const text = new TextEncoder(); const heap = new Uint8Array(this.memory.buffer); const view = new DataView(this.memory.buffer); for (let [key, value] of entries){ view.setUint32(environ_ptr, environ_buf_ptr, true); environ_ptr += 4; const data = text.encode(`${key}=${value}\0`); heap.set(data, environ_buf_ptr); environ_buf_ptr += data.length; } return ERRNO_SUCCESS; }, environ_sizes_get: (environc_out, environ_buf_size_out)=>{ const entries = Object.entries(this.env); const text = new TextEncoder(); const view = new DataView(this.memory.buffer); view.setUint32(environc_out, entries.length, true); view.setUint32(environ_buf_size_out, entries.reduce(function(acc, [key, value]) { return acc + text.encode(`${key}=${value}\0`).length; }, 0), true); return ERRNO_SUCCESS; }, clock_res_get: (id, resolution_out)=>{ const view = new DataView(this.memory.buffer); switch(id){ case CLOCKID_REALTIME: view.setBigUint64(resolution_out, clock_res_realtime(), true); break; case CLOCKID_MONOTONIC: view.setBigUint64(resolution_out, clock_res_monotonic(), true); break; case CLOCKID_PROCESS_CPUTIME_ID: view.setBigUint64(resolution_out, clock_res_process(), true); break; case CLOCKID_THREAD_CPUTIME_ID: view.setBigUint64(resolution_out, clock_res_thread(), true); break; default: return ERRNO_INVAL; } return ERRNO_SUCCESS; }, clock_time_get: (id, precision, time_out)=>{ const view = new DataView(this.memory.buffer); switch(id){ case CLOCKID_REALTIME: view.setBigUint64(time_out, clock_time_realtime(), true); break; case CLOCKID_MONOTONIC: view.setBigUint64(time_out, clock_time_monotonic(), true); break; case CLOCKID_PROCESS_CPUTIME_ID: view.setBigUint64(time_out, clock_time_process(), true); break; case CLOCKID_THREAD_CPUTIME_ID: view.setBigUint64(time_out, clock_time_thread(), true); break; default: return ERRNO_INVAL; } return ERRNO_SUCCESS; }, fd_advise: (fd, offset, len, advice)=>{ return ERRNO_NOSYS; }, fd_allocate: (fd, offset, len)=>{ return ERRNO_NOSYS; }, fd_close: (fd)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } entry.handle.close(); delete this.fds[fd]; return ERRNO_SUCCESS; }, fd_datasync: (fd)=>{ return ERRNO_NOSYS; }, fd_fdstat_get: (fd, stat_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } const view = new DataView(this.memory.buffer); view.setUint8(stat_out, entry.type); view.setUint16(stat_out + 4, 0, true); view.setBigUint64(stat_out + 8, 0n, true); view.setBigUint64(stat_out + 16, 0n, true); return ERRNO_SUCCESS; }, fd_fdstat_set_flags: (fd, flags)=>{ return ERRNO_NOSYS; }, fd_fdstat_set_rights: (fd, fs_rights_base, fs_rights_inheriting)=>{ return ERRNO_NOSYS; }, fd_filestat_get: (fd, buf_out)=>{ return ERRNO_NOSYS; }, fd_filestat_set_size: (fd, size)=>{ return ERRNO_NOSYS; }, fd_filestat_set_times: (fd, atim, mtim, fst_flags)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } if ((fst_flags & FSTFLAGS_ATIM_NOW) == FSTFLAGS_ATIM_NOW) { atim = BigInt(Date.now() * 1e6); } if ((fst_flags & FSTFLAGS_MTIM_NOW) == FSTFLAGS_MTIM_NOW) { mtim = BigInt(Date.now() * 1e6); } try { fs.utimeSync(entry.path, Number(atim), Number(mtim)); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, fd_pread: (fd, iovs_ptr, iovs_len, offset, nread_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } const seek = entry.handle.seekSync(0, 1); const view = new DataView(this.memory.buffer); let nread = 0; for(let i = 0; i < iovs_len; i++){ const data_ptr = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data_len = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data = new Uint8Array(this.memory.buffer, data_ptr, data_len); nread += entry.handle.readSync(data); } entry.handle.seekSync(seek, 0); view.setUint32(nread_out, nread, true); return ERRNO_SUCCESS; }, fd_prestat_get: (fd, buf_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.vpath) { return ERRNO_BADF; } const view = new DataView(this.memory.buffer); view.setUint8(buf_out, PREOPENTYPE_DIR); view.setUint32(buf_out + 4, new TextEncoder().encode(entry.vpath).byteLength, true); return ERRNO_SUCCESS; }, fd_prestat_dir_name: (fd, path_ptr, path_len)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.vpath) { return ERRNO_BADF; } const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); data.set(new TextEncoder().encode(entry.vpath)); return ERRNO_SUCCESS; }, fd_pwrite: (fd, iovs_ptr, iovs_len, offset, nwritten_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } const seek = entry.handle.seekSync(0, 1); const view = new DataView(this.memory.buffer); let nwritten = 0; for(let i = 0; i < iovs_len; i++){ const data_ptr = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data_len = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data = new Uint8Array(this.memory.buffer, data_ptr, data_len); nwritten += entry.handle.writeSync(data); } entry.handle.seekSync(seek, 0); view.setUint32(nwritten_out, nwritten, true); return ERRNO_SUCCESS; }, fd_read: (fd, iovs_ptr, iovs_len, nread_out)=>{ const entry = this.fds[fd]; // console.log("fd_read"); if (!entry) { return ERRNO_BADF; } const view = new DataView(this.memory.buffer); let nread = 0; for(let i = 0; i < iovs_len; i++){ const data_ptr = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data_len = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data = new Uint8Array(this.memory.buffer, data_ptr, data_len); nread += fs.readSync(entry.handle.fd, data);// entry.handle.readSync(data); } view.setUint32(nread_out, nread, true); return ERRNO_SUCCESS; }, fd_readdir: (fd, buf_ptr, buf_len, cookie, bufused_out)=>{ return ERRNO_NOSYS; }, fd_renumber: (fd, to)=>{ if (!this.fds[fd]) { return ERRNO_BADF; } if (!this.fds[to]) { return ERRNO_BADF; } this.fds[to].handle.close(); this.fds[to] = this.fds[fd]; delete this.fds[fd]; return ERRNO_SUCCESS; }, fd_seek: (fd, offset, whence, newoffset_out)=>{ // console.log("fd_seek"); const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } const view = new DataView(this.memory.buffer); try { const newoffset = entry.handle.seekSync(Number(offset), whence); view.setBigUint64(newoffset_out, BigInt(newoffset), true); } catch (err) { return ERRNO_INVAL; } return ERRNO_SUCCESS; }, fd_sync: (fd)=>{ return ERRNO_NOSYS; }, fd_tell: (fd, offset_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } const view = new DataView(this.memory.buffer); try { const offset = entry.handle.seekSync(0, 1); view.setBigUint64(offset_out, offset, true); } catch (err) { return ERRNO_INVAL; } return ERRNO_NOSYS; }, fd_write: (fd, iovs_ptr, iovs_len, nwritten_out)=>{ const entry = this.fds[fd]; // console.log("fd_write"); if (!entry) { return ERRNO_BADF; } const view = new DataView(this.memory.buffer); let nwritten = 0; for(let i = 0; i < iovs_len; i++){ const data_ptr = view.getUint32(iovs_ptr, true); iovs_ptr += 4; const data_len = view.getUint32(iovs_ptr, true); iovs_ptr += 4; nwritten += fs.writeSync(entry.handle.fd, new Uint8Array(this.memory.buffer, data_ptr, data_len)); } view.setUint32(nwritten_out, nwritten, true); return ERRNO_SUCCESS; }, path_create_directory: (fd, path_ptr, path_len)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, text.decode(data)); try { fs.mkdirSync(path); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_filestat_get: (fd, flags, path_ptr, path_len, buf_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, text.decode(data)); const view = new DataView(this.memory.buffer); try { const info = fs.statSync(path); 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; switch(true){ case info.isFile: view.setUint8(buf_out, FILETYPE_REGULAR_FILE); buf_out += 4; break; case info.isDirectory: view.setUint8(buf_out, FILETYPE_DIRECTORY); buf_out += 4; break; case info.isSymlink: view.setUint8(buf_out, FILETYPE_SYMBOLIC_LINK); buf_out += 4; break; default: view.setUint8(buf_out, FILETYPE_UNKNOWN); buf_out += 4; break; } view.setUint32(buf_out, Number(info.nlink), true); buf_out += 4; 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; }, path_filestat_set_times: (fd, flags, path_ptr, path_len, atim, mtim, fst_flags)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, text.decode(data)); if ((fst_flags & FSTFLAGS_ATIM_NOW) == FSTFLAGS_ATIM_NOW) { atim = BigInt(Date.now()) * BigInt(1e6); } if ((fst_flags & FSTFLAGS_MTIM_NOW) == FSTFLAGS_MTIM_NOW) { mtim = BigInt(Date.now()) * BigInt(1e6); } try { fs.utimesSync(path, Number(atim), Number(mtim)); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_link: (old_fd, old_flags, old_path_ptr, old_path_len, new_fd, new_path_ptr, new_path_len)=>{ const old_entry = this.fds[old_fd]; const new_entry = this.fds[new_fd]; if (!old_entry || !new_entry) { return ERRNO_BADF; } if (!old_entry.path || !new_entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const old_data = new Uint8Array(this.memory.buffer, old_path_ptr, old_path_len); const old_path = resolve2(old_entry.path, text.decode(old_data)); const new_data = new Uint8Array(this.memory.buffer, new_path_ptr, new_path_len); const new_path = resolve2(new_entry.path, text.decode(new_data)); try { fs.linkSync(old_path, new_path); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_open: (fd, dirflags, path_ptr, path_len, oflags, fs_rights_base, fs_rights_inherting, fdflags, opened_fd_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, text.decode(data)); const options = { read: false, write: false, append: false, truncate: false, create: false, createNew: false }; if ((oflags & OFLAGS_CREAT) !== 0) { options.create = true; options.write = true; } if ((oflags & OFLAGS_DIRECTORY) !== 0) {} if ((oflags & OFLAGS_EXCL) !== 0) { options.createNew = true; } if ((oflags & OFLAGS_TRUNC) !== 0) { options.truncate = true; options.write = true; } if ((BigInt(fs_rights_base) & BigInt(RIGHTS_FD_READ | RIGHTS_FD_READDIR)) != 0n) { options.read = true; } if ((BigInt(fs_rights_base) & BigInt(RIGHTS_FD_DATASYNC | RIGHTS_FD_WRITE | RIGHTS_FD_ALLOCATE | RIGHTS_FD_FILESTAT_SET_SIZE)) != 0n) { options.write = true; } if ((fdflags & FDFLAGS_APPEND) != 0) { options.append = true; } if ((fdflags & FDFLAGS_DSYNC) != 0) {} if ((fdflags & FDFLAGS_NONBLOCK) != 0) {} if ((fdflags & FDFLAGS_RSYNC) != 0) {} if ((fdflags & FDFLAGS_SYNC) != 0) {} if (!options.read && !options.write && !options.truncate) { options.read = true; } try { const handle = fs.openSync(path, options); const opened_fd = this.fds.push({ handle, 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; }, path_readlink: (fd, path_ptr, path_len, buf_ptr, buf_len, bufused_out)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const view = new DataView(this.memory.buffer); const heap = new Uint8Array(this.memory.buffer); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, new TextDecoder().decode(data)); try { const link = fs.readlinkSync(path); const data = new TextEncoder().encode(link); heap.set(new Uint8Array(data, 0, buf_len), buf_ptr); const bufused = Math.min(data.byteLength, buf_len); view.setUint32(bufused_out, bufused, true); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_remove_directory: (fd, path_ptr, path_len)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, text.decode(data)); try { if (!fs.statSync(path).isDirectory) { return ERRNO_NOTDIR; } fs.removeSync(path); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_rename: (fd, old_path_ptr, old_path_len, new_fd, new_path_ptr, new_path_len)=>{ const old_entry = this.fds[fd]; const new_entry = this.fds[new_fd]; if (!old_entry || !new_entry) { return ERRNO_BADF; } if (!old_entry.path || !new_entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const old_data = new Uint8Array(this.memory.buffer, old_path_ptr, old_path_len); const old_path = resolve2(old_entry.path, text.decode(old_data)); const new_data = new Uint8Array(this.memory.buffer, new_path_ptr, new_path_len); const new_path = resolve2(new_entry.path, text.decode(new_data)); try { fs.renameSync(old_path, new_path); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_symlink: (old_path_ptr, old_path_len, fd, new_path_ptr, new_path_len)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const old_data = new Uint8Array(this.memory.buffer, old_path_ptr, old_path_len); const old_path = text.decode(old_data); const new_data = new Uint8Array(this.memory.buffer, new_path_ptr, new_path_len); const new_path = resolve2(entry.path, text.decode(new_data)); try { fs.symlinkSync(old_path, new_path); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, path_unlink_file: (fd, path_ptr, path_len)=>{ const entry = this.fds[fd]; if (!entry) { return ERRNO_BADF; } if (!entry.path) { return ERRNO_INVAL; } const text = new TextDecoder(); const data = new Uint8Array(this.memory.buffer, path_ptr, path_len); const path = resolve2(entry.path, text.decode(data)); try { fs.removeSync(path); } catch (err) { return errno(err); } return ERRNO_SUCCESS; }, poll_oneoff: (in_ptr, out_ptr, nsubscriptions, nevents_out)=>{ return ERRNO_NOSYS; }, proc_exit: (rval)=>{ process.exit(rval); }, proc_raise: (sig)=>{ return ERRNO_NOSYS; }, sched_yield: ()=>{ return ERRNO_SUCCESS; }, random_get: (buf_ptr, buf_len)=>{ const buffer = new Uint8Array(this.memory.buffer, buf_ptr, buf_len); crypto.getRandomValues(buffer); return ERRNO_SUCCESS; }, sock_recv: (fd, ri_data_ptr, ri_data_len, ri_flags, ro_datalen_out, ro_flags_out)=>{ return ERRNO_NOSYS; }, sock_send: (fd, si_data_ptr, si_data_len, si_flags, so_datalen_out)=>{ return ERRNO_NOSYS; }, sock_shutdown: (fd, how)=>{ return ERRNO_NOSYS; } }; } } export { Module as Module }; export { Module as default };