@vscode/wasm-wasi
Advanced tools
Comparing version 0.8.2 to 0.9.0
@@ -91,2 +91,5 @@ "use strict"; | ||
return path.join(...paths); | ||
}, | ||
normalize(value) { | ||
return path.normalize(value); | ||
} | ||
@@ -93,0 +96,0 @@ }) |
import { WASI, Options, Environment, DeviceDescription, FileDescriptorDescription } from './wasi'; | ||
import { BigInts } from './converter'; | ||
import { s64, ptr } from './baseTypes'; | ||
import { rights } from './wasiTypes'; | ||
export { s64, ptr, WASI, Options, Environment, DeviceDescription, FileDescriptorDescription, BigInts }; | ||
export * from '@vscode/sync-api-client'; | ||
export { WASI, Options, Environment, DeviceDescription, FileDescriptorDescription, BigInts }; | ||
export * from './wasiTypes'; | ||
export * from './deviceDriver'; | ||
type ExportRights = { | ||
base: rights; | ||
inheriting: rights; | ||
}; | ||
export declare namespace VSCodeFS { | ||
const DirectoryRights: ExportRights; | ||
const FileRights: ExportRights; | ||
} |
@@ -21,3 +21,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BigInts = exports.WASI = void 0; | ||
exports.VSCodeFS = exports.BigInts = exports.WASI = void 0; | ||
const wasi_1 = require("./wasi"); | ||
@@ -27,4 +27,16 @@ Object.defineProperty(exports, "WASI", { enumerable: true, get: function () { return wasi_1.WASI; } }); | ||
Object.defineProperty(exports, "BigInts", { enumerable: true, get: function () { return converter_1.BigInts; } }); | ||
const vscodeFileSystemDriver_1 = require("./vscodeFileSystemDriver"); | ||
__exportStar(require("@vscode/sync-api-client"), exports); | ||
__exportStar(require("./wasiTypes"), exports); | ||
__exportStar(require("./deviceDriver"), exports); | ||
var VSCodeFS; | ||
(function (VSCodeFS) { | ||
VSCodeFS.DirectoryRights = { | ||
base: vscodeFileSystemDriver_1.DirectoryBaseRights, | ||
inheriting: vscodeFileSystemDriver_1.DirectoryInheritingRights | ||
}; | ||
VSCodeFS.FileRights = { | ||
base: vscodeFileSystemDriver_1.FileBaseRights, | ||
inheriting: vscodeFileSystemDriver_1.FileInheritingRights | ||
}; | ||
})(VSCodeFS = exports.VSCodeFS || (exports.VSCodeFS = {})); |
@@ -1,7 +0,8 @@ | ||
export declare type u8 = number; | ||
export declare type u16 = number; | ||
export declare type u32 = number; | ||
export declare type u64 = bigint; | ||
export declare type s64 = bigint; | ||
export declare type ptr<_size = u8> = number; | ||
export declare type size = u32; | ||
export type u8 = number; | ||
export type u16 = number; | ||
export type u32 = number; | ||
export type u64 = bigint; | ||
export type s64 = bigint; | ||
export type ptr<_type = u8> = number; | ||
export type size = u32; | ||
export type cstring = u8[]; |
import { URI } from 'vscode-uri'; | ||
import { ApiClient } from '@vscode/sync-api-client'; | ||
import { ApiShape } from '@vscode/sync-api-client'; | ||
import RAL from './ral'; | ||
import { CharacterDeviceDriver } from './deviceDriver'; | ||
export declare function create(apiClient: ApiClient, uri: URI, decoder: RAL.TextDecoder): CharacterDeviceDriver; | ||
export declare function create(apiClient: ApiShape, uri: URI, decoder: RAL.TextDecoder): CharacterDeviceDriver; |
@@ -10,2 +10,5 @@ "use strict"; | ||
const deviceDriver_1 = require("./deviceDriver"); | ||
const ConsoleBaseRights = wasiTypes_1.Rights.fd_read | wasiTypes_1.Rights.fd_fdstat_set_flags | wasiTypes_1.Rights.fd_write | | ||
wasiTypes_1.Rights.fd_filestat_get | wasiTypes_1.Rights.poll_fd_readwrite; | ||
const ConsoleInheritingRights = 0n; | ||
class ConsoleFileDescriptor extends deviceDriver_1.BaseFileDescriptor { | ||
@@ -20,3 +23,3 @@ constructor(deviceId, fd, rights_base, rights_inheriting, fdflags, inode) { | ||
function createConsoleFileDescriptor(fd) { | ||
return new ConsoleFileDescriptor(deviceId, fd, wasiTypes_1.Rights.CharacterDeviceBase, wasiTypes_1.Rights.CharacterDeviceInheriting, 0, inodeCounter++); | ||
return new ConsoleFileDescriptor(deviceId, fd, ConsoleBaseRights, ConsoleInheritingRights, 0, inodeCounter++); | ||
} | ||
@@ -23,0 +26,0 @@ return Object.assign({}, deviceDriver_1.NoSysDeviceDriver, { |
import { size } from '@vscode/sync-api-client'; | ||
import { u64 } from './baseTypes'; | ||
import { advise, fd, fdflags, fdstat, filedelta, filesize, filestat, filetype, fstflags, lookupflags, oflags, rights, timestamp, whence } from './wasiTypes'; | ||
export declare type DeviceId = bigint; | ||
export type DeviceId = bigint; | ||
export declare namespace DeviceIds { | ||
@@ -35,8 +35,26 @@ function next(): bigint; | ||
/** | ||
* Check if the base rights contain the given rights. | ||
* | ||
* @param rights The rights to check. | ||
*/ | ||
containsBaseRights(rights: rights): boolean; | ||
/** | ||
* Asserts the given base rights. | ||
* | ||
* @param right the rights to assert. | ||
*/ | ||
assertBaseRight(right: rights): void; | ||
assertBaseRights(right: rights): void; | ||
/** | ||
* Asserts the given fdflags. | ||
* | ||
* @param fdflags The fdflags to assert. | ||
*/ | ||
assertFdflags(fdflags: fdflags): void; | ||
/** | ||
* Asserts the given oflags. | ||
* | ||
* @param oflags The oflags to assert. | ||
*/ | ||
assertOflags(oflags: oflags): void; | ||
/** | ||
* Asserts that the file descriptor points to a directory. | ||
@@ -55,6 +73,9 @@ */ | ||
constructor(deviceId: bigint, fd: fd, fileType: filetype, rights_base: rights, rights_inheriting: rights, fdflags: fdflags, inode: bigint); | ||
assertBaseRight(right: rights): void; | ||
containsBaseRights(rights: rights): boolean; | ||
assertBaseRights(rights: rights): void; | ||
assertFdflags(fdflags: fdflags): void; | ||
assertOflags(oflags: oflags): void; | ||
assertIsDirectory(): void; | ||
} | ||
export declare type ReaddirEntry = { | ||
export type ReaddirEntry = { | ||
d_ino: bigint; | ||
@@ -97,3 +118,3 @@ d_type: filetype; | ||
export interface FileSystemDeviceDriver extends DeviceDriver { | ||
createStdioFileDescriptor(fd: 0 | 1 | 2, rights_base: rights, rights_inheriting: rights, fdflags: fdflags, path: string): FileDescriptor; | ||
createStdioFileDescriptor(fd: 0 | 1 | 2, fdflags: fdflags, path: string): FileDescriptor; | ||
} | ||
@@ -100,0 +121,0 @@ export interface CharacterDeviceDriver extends DeviceDriver { |
@@ -27,7 +27,21 @@ "use strict"; | ||
} | ||
assertBaseRight(right) { | ||
if ((this.rights_base & right) === 0n) { | ||
containsBaseRights(rights) { | ||
return (this.rights_base & rights) === rights; | ||
} | ||
assertBaseRights(rights) { | ||
if ((this.rights_base & rights) === rights) { | ||
return; | ||
} | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.perm); | ||
} | ||
assertFdflags(fdflags) { | ||
if (!wasiTypes_1.Rights.supportFdflags(this.rights_base, fdflags)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.perm); | ||
} | ||
} | ||
assertOflags(oflags) { | ||
if (!wasiTypes_1.Rights.supportOflags(this.rights_base, oflags)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.perm); | ||
} | ||
} | ||
assertIsDirectory() { | ||
@@ -34,0 +48,0 @@ if (this.fileType !== wasiTypes_1.Filetype.directory) { |
@@ -42,2 +42,3 @@ import { Disposable } from './disposable'; | ||
join(...paths: string[]): string; | ||
normalize(path: string): string; | ||
}; | ||
@@ -44,0 +45,0 @@ } |
import { URI } from 'vscode-uri'; | ||
import { ApiClient } from '@vscode/sync-api-client'; | ||
import { ApiShape } from '@vscode/sync-api-client'; | ||
import { CharacterDeviceDriver } from './deviceDriver'; | ||
export declare function create(apiClient: ApiClient, uri: URI): CharacterDeviceDriver; | ||
export declare function create(apiClient: ApiShape, uri: URI): CharacterDeviceDriver; |
@@ -10,2 +10,5 @@ "use strict"; | ||
const deviceDriver_1 = require("./deviceDriver"); | ||
const TerminalBaseRights = wasiTypes_1.Rights.fd_read | wasiTypes_1.Rights.fd_fdstat_set_flags | wasiTypes_1.Rights.fd_write | | ||
wasiTypes_1.Rights.fd_filestat_get | wasiTypes_1.Rights.poll_fd_readwrite; | ||
const TerminalInheritingRights = 0n; | ||
class TerminalFileDescriptor extends deviceDriver_1.BaseFileDescriptor { | ||
@@ -20,3 +23,3 @@ constructor(deviceId, fd, rights_base, rights_inheriting, fdflags, inode) { | ||
function createTerminalFileDescriptor(fd) { | ||
return new TerminalFileDescriptor(deviceId, fd, wasiTypes_1.Rights.CharacterDeviceBase, wasiTypes_1.Rights.CharacterDeviceInheriting, 0, inodeCounter++); | ||
return new TerminalFileDescriptor(deviceId, fd, TerminalBaseRights, TerminalInheritingRights, 0, inodeCounter++); | ||
} | ||
@@ -23,0 +26,0 @@ return Object.assign({}, deviceDriver_1.NoSysDeviceDriver, { |
import { URI } from 'vscode-uri'; | ||
import { ApiClient } from '@vscode/sync-api-client'; | ||
import { ApiShape } from '@vscode/sync-api-client'; | ||
import { FileSystemDeviceDriver } from './deviceDriver'; | ||
import { rights } from './wasiTypes'; | ||
import RAL from './ral'; | ||
export declare function create(apiClient: ApiClient, _textEncoder: RAL.TextEncoder, fileDescriptorId: { | ||
export declare const DirectoryBaseRights: rights; | ||
export declare const FileBaseRights: rights; | ||
export declare const DirectoryInheritingRights: rights; | ||
export declare const FileInheritingRights: rights; | ||
export declare function create(apiClient: ApiShape, _textEncoder: RAL.TextEncoder, fileDescriptorId: { | ||
next(): number; | ||
}, baseUri: URI, mountPoint: string): FileSystemDeviceDriver; |
@@ -10,3 +10,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.create = void 0; | ||
exports.create = exports.FileInheritingRights = exports.DirectoryInheritingRights = exports.FileBaseRights = exports.DirectoryBaseRights = void 0; | ||
const sync_api_client_1 = require("@vscode/sync-api-client"); | ||
const converter_1 = require("./converter"); | ||
@@ -16,8 +17,21 @@ const deviceDriver_1 = require("./deviceDriver"); | ||
const ral_1 = __importDefault(require("./ral")); | ||
const linkedMap_1 = require("./linkedMap"); | ||
const paths = (0, ral_1.default)().path; | ||
exports.DirectoryBaseRights = wasiTypes_1.Rights.fd_fdstat_set_flags | wasiTypes_1.Rights.path_create_directory | | ||
wasiTypes_1.Rights.path_create_file | wasiTypes_1.Rights.path_link_source | wasiTypes_1.Rights.path_link_target | wasiTypes_1.Rights.path_open | | ||
wasiTypes_1.Rights.fd_readdir | wasiTypes_1.Rights.path_readlink | wasiTypes_1.Rights.path_rename_source | wasiTypes_1.Rights.path_rename_target | | ||
wasiTypes_1.Rights.path_filestat_get | wasiTypes_1.Rights.path_filestat_set_size | wasiTypes_1.Rights.path_filestat_set_times | | ||
wasiTypes_1.Rights.fd_filestat_get | wasiTypes_1.Rights.fd_filestat_set_times | wasiTypes_1.Rights.path_remove_directory | wasiTypes_1.Rights.path_unlink_file | | ||
wasiTypes_1.Rights.path_symlink; | ||
exports.FileBaseRights = wasiTypes_1.Rights.fd_datasync | wasiTypes_1.Rights.fd_read | wasiTypes_1.Rights.fd_seek | wasiTypes_1.Rights.fd_fdstat_set_flags | | ||
wasiTypes_1.Rights.fd_sync | wasiTypes_1.Rights.fd_tell | wasiTypes_1.Rights.fd_write | wasiTypes_1.Rights.fd_advise | wasiTypes_1.Rights.fd_allocate | wasiTypes_1.Rights.fd_filestat_get | | ||
wasiTypes_1.Rights.fd_filestat_set_size | wasiTypes_1.Rights.fd_filestat_set_times | wasiTypes_1.Rights.poll_fd_readwrite; | ||
exports.DirectoryInheritingRights = exports.DirectoryBaseRights | exports.FileBaseRights; | ||
exports.FileInheritingRights = 0n; | ||
const DirectoryOnlyBaseRights = exports.DirectoryBaseRights & ~exports.FileBaseRights; | ||
const FileOnlyBaseRights = exports.FileBaseRights & ~exports.DirectoryBaseRights; | ||
class FileFileDescriptor extends deviceDriver_1.BaseFileDescriptor { | ||
constructor(deviceId, fd, rights_base, rights_inheriting, fdflags, inode, path) { | ||
super(deviceId, fd, wasiTypes_1.Filetype.regular_file, rights_base, rights_inheriting, fdflags, inode); | ||
constructor(deviceId, fd, rights_base, fdflags, inode) { | ||
super(deviceId, fd, wasiTypes_1.Filetype.regular_file, rights_base, 0n, fdflags, inode); | ||
this._cursor = 0; | ||
this.path = path; | ||
} | ||
@@ -35,117 +49,308 @@ get cursor() { | ||
class DirectoryFileDescriptor extends deviceDriver_1.BaseFileDescriptor { | ||
constructor(deviceId, fd, rights_base, rights_inheriting, fdflags, inode, path) { | ||
constructor(deviceId, fd, rights_base, rights_inheriting, fdflags, inode) { | ||
super(deviceId, fd, wasiTypes_1.Filetype.directory, rights_base, rights_inheriting, fdflags, inode); | ||
this.path = path; | ||
} | ||
childDirectoryRights(requested_rights) { | ||
return (this.rights_inheriting & requested_rights) & ~FileOnlyBaseRights; | ||
} | ||
childFileRights(requested_rights) { | ||
return (this.rights_inheriting & requested_rights) & ~DirectoryOnlyBaseRights; | ||
} | ||
} | ||
var INode; | ||
(function (INode) { | ||
function hasContent(inode) { | ||
return inode.content !== undefined; | ||
var NodeKind; | ||
(function (NodeKind) { | ||
NodeKind[NodeKind["File"] = 0] = "File"; | ||
NodeKind[NodeKind["Directory"] = 1] = "Directory"; | ||
})(NodeKind || (NodeKind = {})); | ||
var FileNode; | ||
(function (FileNode) { | ||
function create(id, parent) { | ||
return { | ||
kind: NodeKind.File, | ||
inode: id, | ||
refs: 0, | ||
parent, | ||
name: undefined | ||
}; | ||
} | ||
INode.hasContent = hasContent; | ||
})(INode || (INode = {})); | ||
function create(apiClient, _textEncoder, fileDescriptorId, baseUri, mountPoint) { | ||
const deviceId = deviceDriver_1.DeviceIds.next(); | ||
const vscode_fs = apiClient.vscode.workspace.fileSystem; | ||
let inodeCounter = 1n; | ||
const path2INode = new Map(); | ||
const inodes = new Map(); | ||
const deletedINode = new Map(); | ||
const preOpenDirectories = [mountPoint]; | ||
function createFileDescriptor(parentDescriptor, rights_base, rights_inheriting, fdflags, path) { | ||
const parentINode = getINode(parentDescriptor.inode); | ||
const filePath = paths.join(parentDescriptor.path, path); | ||
const fileUri = uriJoin(parentINode.uri, path); | ||
return new FileFileDescriptor(deviceId, fileDescriptorId.next(), rights_base, rights_inheriting, fdflags, getOrCreateINode(filePath, fileUri, true).id, filePath); | ||
FileNode.create = create; | ||
})(FileNode || (FileNode = {})); | ||
var DirectoryNode; | ||
(function (DirectoryNode) { | ||
function create(id, parent) { | ||
return { | ||
kind: NodeKind.Directory, | ||
inode: id, | ||
refs: 0, | ||
parent, | ||
name: undefined, | ||
entries: new Map() | ||
}; | ||
} | ||
function assertFileDescriptor(fileDescriptor) { | ||
if (!(fileDescriptor instanceof FileFileDescriptor)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
} | ||
DirectoryNode.create = create; | ||
})(DirectoryNode || (DirectoryNode = {})); | ||
class FileSystem { | ||
constructor(vscfs) { | ||
this.vscfs = vscfs; | ||
this.root = { | ||
kind: NodeKind.Directory, | ||
inode: FileSystem.inodeCounter++, | ||
parent: undefined, | ||
refs: 1, | ||
name: '/', | ||
entries: new Map() | ||
}; | ||
this.inodes = new Map(); | ||
this.inodes.set(this.root.inode, this.root); | ||
this.contents = new Map(); | ||
this.stats = new Map(); | ||
this.deletedNodes = new Map(); | ||
this.pathCache = new linkedMap_1.LRUCache(256); | ||
} | ||
function createDirectoryDescriptor(parentDescriptor, rights_base, rights_inheriting, fdflags, path) { | ||
const parentINode = getINode(parentDescriptor.inode); | ||
const filePath = paths.join(parentDescriptor.path, path); | ||
const fileUri = uriJoin(parentINode.uri, path); | ||
return new DirectoryFileDescriptor(deviceId, fileDescriptorId.next(), rights_base, rights_inheriting, fdflags, getOrCreateINode(filePath, fileUri, true).id, filePath); | ||
getRoot() { | ||
return this.root; | ||
} | ||
function assertDirectoryDescriptor(fileDescriptor) { | ||
if (!(fileDescriptor instanceof DirectoryFileDescriptor)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
getUri(node, fsPath) { | ||
const finalPath = fsPath === undefined || fsPath === '.' ? this.getPath(node) : paths.join(this.getPath(node), fsPath); | ||
return this.vscfs.with({ path: paths.join(this.vscfs.path, finalPath) }); | ||
} | ||
getNode(id, kind) { | ||
const node = this.inodes.get(id) ?? this.deletedNodes.get(id); | ||
if (node === undefined) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.noent); | ||
} | ||
this.assertNodeKind(node, kind); | ||
return node; | ||
} | ||
function assertFileOrDirectoryDescriptor(fileDescriptor) { | ||
if (!(fileDescriptor instanceof FileFileDescriptor) && !(fileDescriptor instanceof DirectoryFileDescriptor)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
getOrCreateNode(parent, path, kind, ref) { | ||
const parts = this.getPathSegments(path); | ||
if (parts.length === 1) { | ||
if (parts[0] === '.') { | ||
return parent; | ||
} | ||
else if (parts[0] === '..') { | ||
if (parent.parent !== undefined) { | ||
return parent.parent; | ||
} | ||
else { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.noent); | ||
} | ||
} | ||
} | ||
let current = parent; | ||
for (let i = 0; i < parts.length; i++) { | ||
switch (current.kind) { | ||
case NodeKind.File: | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.notdir); | ||
case NodeKind.Directory: | ||
let entry = current.entries.get(parts[i]); | ||
if (entry === undefined) { | ||
if (i === parts.length - 1) { | ||
entry = kind === NodeKind.File | ||
? FileNode.create(FileSystem.inodeCounter++, current) | ||
: DirectoryNode.create(FileSystem.inodeCounter++, current); | ||
if (ref) { | ||
entry.refs++; | ||
} | ||
} | ||
else { | ||
entry = DirectoryNode.create(FileSystem.inodeCounter++, current); | ||
} | ||
current.entries.set(parts[i], entry); | ||
// Cache the name for faster lookup. | ||
entry.name = parts[i]; | ||
this.inodes.set(entry.inode, entry); | ||
} | ||
else { | ||
if (i === parts.length - 1 && ref) { | ||
entry.refs++; | ||
} | ||
} | ||
current = entry; | ||
break; | ||
} | ||
} | ||
return current; | ||
} | ||
function getOrCreateINode(filepath, uri, ref) { | ||
let result = path2INode.get(filepath); | ||
if (result !== undefined) { | ||
if (ref) { | ||
result.refs++; | ||
getNodeByPath(parent, path, kind) { | ||
const parts = this.getPathSegments(path); | ||
if (parts.length === 1) { | ||
if (parts[0] === '.') { | ||
return parent; | ||
} | ||
return result; | ||
else if (parts[0] === '..') { | ||
return parent.parent; | ||
} | ||
} | ||
result = { id: inodeCounter++, uri, refs: 0, content: undefined }; | ||
if (ref) { | ||
result.refs++; | ||
let current = parent; | ||
for (let i = 0; i < parts.length; i++) { | ||
switch (current.kind) { | ||
case NodeKind.File: | ||
return undefined; | ||
case NodeKind.Directory: | ||
current = current.entries.get(parts[i]); | ||
if (current === undefined) { | ||
return undefined; | ||
} | ||
break; | ||
} | ||
} | ||
path2INode.set(filepath, result); | ||
inodes.set(result.id, result); | ||
if (current !== undefined) { | ||
this.assertNodeKind(current, kind); | ||
} | ||
return current; | ||
} | ||
existsNode(parent, path) { | ||
return this.getNodeByPath(parent, path) !== undefined; | ||
} | ||
setContent(inode, content) { | ||
this.contents.set(inode.inode, content); | ||
} | ||
getContent(inode, contentProvider) { | ||
let content = this.contents.get(inode.inode); | ||
if (content === undefined) { | ||
content = contentProvider.readFile(this.getUri(inode)); | ||
this.contents.set(inode.inode, content); | ||
} | ||
return content; | ||
} | ||
getStat(inode) { | ||
const result = this.stats.get(inode); | ||
if (result === undefined) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.noent); | ||
} | ||
return result; | ||
} | ||
function getINode(id) { | ||
const inode = inodes.get(id); | ||
if (inode === undefined) { | ||
deleteNode(node, stat, content) { | ||
if (node.parent === undefined) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
} | ||
return inode; | ||
if (node.refs > 0 && (stat === undefined || (node.kind === NodeKind.File && content === undefined))) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.inval); | ||
} | ||
const name = this.getName(node); | ||
node.parent.entries.delete(name); | ||
if (content !== undefined) { | ||
this.contents.set(node.inode, content); | ||
} | ||
if (stat !== undefined) { | ||
this.stats.set(node.inode, stat); | ||
} | ||
this.freeNode(node); | ||
} | ||
function getResolvedINode(id) { | ||
const inode = inodes.get(id); | ||
if (inode === undefined) { | ||
isNodeDeleted(inode) { | ||
return this.deletedNodes.has(inode); | ||
} | ||
renameNode(oldNode, stat, content, newParent, newPath) { | ||
this.deleteNode(oldNode, stat, content); | ||
this.getOrCreateNode(newParent, newPath, oldNode.kind, false); | ||
} | ||
closeNode(id) { | ||
const node = this.getNode(id); | ||
if (node.refs <= 0) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
} | ||
if (inode.content === undefined) { | ||
inode.content = vscode_fs.readFile(inode.uri); | ||
node.refs--; | ||
if (node.refs === 0) { | ||
if (node.kind === NodeKind.File) { | ||
this.contents.delete(node.inode); | ||
this.stats.delete(node.inode); | ||
} | ||
this.deletedNodes.delete(node.inode); | ||
} | ||
return inode; | ||
} | ||
function unrefINode(id) { | ||
let inode = inodes.get(id); | ||
if (inode === undefined) { | ||
inode = deletedINode.get(id); | ||
assertNodeKind(node, kind) { | ||
if (kind === undefined) { | ||
return; | ||
} | ||
if (inode === undefined) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
if (kind === NodeKind.File && node.kind !== NodeKind.File) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.isdir); | ||
} | ||
inode.refs--; | ||
if (inode.refs === 0) { | ||
inode.content = undefined; | ||
deletedINode.delete(id); | ||
else if (kind === NodeKind.Directory && node.kind !== NodeKind.Directory) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.notdir); | ||
} | ||
} | ||
function markINodeAsDeleted(filepath) { | ||
const inode = path2INode.get(filepath); | ||
if (inode === undefined) { | ||
return; | ||
freeNode(inode) { | ||
this.inodes.delete(inode.inode); | ||
this.pathCache.delete(inode); | ||
inode.name = undefined; | ||
if (inode.refs > 0) { | ||
// We still have a reference to the node. So make sure we can still | ||
// access it with its inode id | ||
this.deletedNodes.set(inode.inode, inode); | ||
} | ||
path2INode.delete(filepath); | ||
if (!deletedINode.has(inode.id)) { | ||
deletedINode.set(inode.id, inode); | ||
if (inode.kind === NodeKind.Directory) { | ||
for (const child of inode.entries.values()) { | ||
this.freeNode(child); | ||
} | ||
} | ||
} | ||
function uriJoin(uri, name) { | ||
if (name === '.') { | ||
return uri; | ||
getPathSegments(path) { | ||
if (path.charAt(0) === '/') { | ||
path = path.substring(1); | ||
} | ||
return uri.with({ path: paths.join(uri.path, name) }); | ||
if (path.charAt(path.length - 1) === '/') { | ||
path = path.substring(0, path.length - 1); | ||
} | ||
return path.normalize().split('/'); | ||
} | ||
getPath(inode) { | ||
let result = this.pathCache.get(inode); | ||
if (result === undefined) { | ||
const parts = []; | ||
let current = inode; | ||
do { | ||
parts.push(this.getName(current)); | ||
current = current.parent; | ||
} while (current !== undefined); | ||
result = parts.reverse().join('/'); | ||
this.pathCache.set(inode, result); | ||
} | ||
return result; | ||
} | ||
getName(inode) { | ||
if (inode.name !== undefined) { | ||
return inode.name; | ||
} | ||
const parent = inode.parent; | ||
if (parent === undefined) { | ||
throw new Error('The root node must always have a name'); | ||
} | ||
for (const [name, child] of parent.entries) { | ||
if (child === inode) { | ||
inode.name = name; | ||
return name; | ||
} | ||
} | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.noent); | ||
} | ||
} | ||
FileSystem.inodeCounter = 1n; | ||
function create(apiClient, _textEncoder, fileDescriptorId, baseUri, mountPoint) { | ||
const deviceId = deviceDriver_1.DeviceIds.next(); | ||
const vscode_fs = apiClient.vscode.workspace.fileSystem; | ||
const fs = new FileSystem(baseUri); | ||
const preOpenDirectories = [mountPoint]; | ||
function createFileDescriptor(parentDescriptor, rights_base, fdflags, path) { | ||
const parentNode = fs.getNode(parentDescriptor.inode, NodeKind.Directory); | ||
return new FileFileDescriptor(deviceId, fileDescriptorId.next(), rights_base, fdflags, fs.getOrCreateNode(parentNode, path, NodeKind.File, true).inode); | ||
} | ||
function assertFileDescriptor(fileDescriptor) { | ||
if (!(fileDescriptor instanceof FileFileDescriptor)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
} | ||
} | ||
function createDirectoryDescriptor(parentDescriptor, rights_base, rights_inheriting, fdflags, path) { | ||
const parentNode = fs.getNode(parentDescriptor.inode, NodeKind.Directory); | ||
return new DirectoryFileDescriptor(deviceId, fileDescriptorId.next(), rights_base, rights_inheriting, fdflags, fs.getOrCreateNode(parentNode, path, NodeKind.Directory, true).inode); | ||
} | ||
function assertDirectoryDescriptor(fileDescriptor) { | ||
if (!(fileDescriptor instanceof DirectoryFileDescriptor)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
} | ||
} | ||
function doGetFiletype(fileDescriptor, path) { | ||
const inode = getINode(fileDescriptor.inode); | ||
const fileUri = uriJoin(inode.uri, path); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.Directory); | ||
try { | ||
const stat = vscode_fs.stat(fileUri); | ||
const stat = vscode_fs.stat(fs.getUri(inode, path)); | ||
return converter_1.code2Wasi.asFileType(stat.type); | ||
@@ -157,13 +362,18 @@ } | ||
} | ||
function doStat(inode, result) { | ||
const vStat = vscode_fs.stat(inode.uri); | ||
function assignStat(result, inode, vStat) { | ||
result.dev = deviceId; | ||
result.ino = inode.id; | ||
result.ino = inode; | ||
result.filetype = converter_1.code2Wasi.asFileType(vStat.type); | ||
result.nlink = 0n; | ||
// nlink denotes the number of hard links (not soft links) | ||
// Since VS Code doesn't support hard links on files we | ||
// always return 1. | ||
result.nlink = 1n; | ||
result.size = BigInt(vStat.size); | ||
result.atim = BigInt(vStat.mtime); | ||
result.ctim = BigInt(vStat.ctime); | ||
result.mtim = BigInt(vStat.mtime); | ||
result.atim = timeInNanoseconds(vStat.mtime); | ||
result.ctim = timeInNanoseconds(vStat.ctime); | ||
result.mtim = timeInNanoseconds(vStat.mtime); | ||
} | ||
function timeInNanoseconds(timeInMilliseconds) { | ||
return BigInt(timeInMilliseconds) * 1000000n; | ||
} | ||
function read(content, offset, buffers) { | ||
@@ -200,13 +410,17 @@ let totalBytesRead = 0; | ||
function createOrTruncate(fileDescriptor) { | ||
const inode = getINode(fileDescriptor.inode); | ||
inode.content = new Uint8Array(0); | ||
const content = new Uint8Array(0); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
fileDescriptor.cursor = 0; | ||
writeContent(inode); | ||
writeContent(inode, content); | ||
} | ||
function writeContent(inode) { | ||
vscode_fs.writeFile(inode.uri, inode.content); | ||
function writeContent(node, content) { | ||
const toWrite = content ?? fs.getContent(node, vscode_fs); | ||
vscode_fs.writeFile(fs.getUri(node), toWrite); | ||
if (content !== undefined) { | ||
fs.setContent(node, content); | ||
} | ||
} | ||
return Object.assign({}, deviceDriver_1.NoSysDeviceDriver, { | ||
id: deviceId, | ||
createStdioFileDescriptor(fd, rights_base, rights_inheriting, fdflags, path) { | ||
createStdioFileDescriptor(fd, fdflags, path) { | ||
if (path.length === 0) { | ||
@@ -218,8 +432,7 @@ throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.inval); | ||
} | ||
const fileUri = uriJoin(baseUri, path); | ||
const inode = getOrCreateINode(path, fileUri, true); | ||
return new FileFileDescriptor(deviceId, fd, rights_base, rights_inheriting, fdflags, inode.id, path); | ||
const inode = fs.getOrCreateNode(fs.getRoot(), path, NodeKind.File, true); | ||
return new FileFileDescriptor(deviceId, fd, exports.FileBaseRights, fdflags, inode.inode); | ||
}, | ||
fd_advise(fileDescriptor, _offset, _length, _advise) { | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_advise); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_advise); | ||
// We don't have advisory in VS Code. So treat it as successful. | ||
@@ -232,4 +445,4 @@ return; | ||
const len = converter_1.BigInts.asNumber(_len); | ||
const inode = getResolvedINode(fileDescriptor.inode); | ||
const content = inode.content; | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
const content = fs.getContent(inode, vscode_fs); | ||
if (offset > content.byteLength) { | ||
@@ -241,15 +454,11 @@ throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.inval); | ||
newContent.set(content.subarray(offset), offset + len); | ||
inode.content = newContent; | ||
writeContent(inode); | ||
writeContent(inode, newContent); | ||
}, | ||
fd_close(fileDescriptor) { | ||
unrefINode(fileDescriptor.inode); | ||
fs.closeNode(fileDescriptor.inode); | ||
}, | ||
fd_datasync(fileDescriptor) { | ||
assertFileDescriptor(fileDescriptor); | ||
const inode = getINode(fileDescriptor.inode); | ||
if (!INode.hasContent(inode)) { | ||
return; | ||
} | ||
writeContent(inode); | ||
const node = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
writeContent(node); | ||
}, | ||
@@ -266,5 +475,9 @@ fd_fdstat_get(fileDescriptor, result) { | ||
fd_filestat_get(fileDescriptor, result) { | ||
assertFileDescriptor(fileDescriptor); | ||
const inode = getINode(fileDescriptor.inode); | ||
doStat(inode, result); | ||
if (fs.isNodeDeleted(fileDescriptor.inode)) { | ||
assignStat(result, fileDescriptor.inode, fs.getStat(fileDescriptor.inode)); | ||
return; | ||
} | ||
const inode = fs.getNode(fileDescriptor.inode); | ||
const vStat = vscode_fs.stat(fs.getUri(inode)); | ||
assignStat(result, inode.inode, vStat); | ||
}, | ||
@@ -274,4 +487,4 @@ fd_filestat_set_size(fileDescriptor, _size) { | ||
const size = converter_1.BigInts.asNumber(_size); | ||
const inode = getResolvedINode(fileDescriptor.inode); | ||
const content = inode.content; | ||
const node = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
const content = fs.getContent(node, vscode_fs); | ||
if (content.byteLength === size) { | ||
@@ -283,3 +496,3 @@ return; | ||
newContent.set(content); | ||
inode.content = newContent; | ||
writeContent(node, newContent); | ||
} | ||
@@ -289,5 +502,4 @@ else if (content.byteLength > size) { | ||
newContent.set(content.subarray(0, size)); | ||
inode.content = newContent; | ||
writeContent(node, newContent); | ||
} | ||
writeContent(inode); | ||
}, | ||
@@ -298,6 +510,7 @@ fd_filestat_set_times(_fileDescriptor, _atim, _mtim, _fst_flags) { | ||
// in local storage | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.nosys); | ||
}, | ||
fd_pread(fileDescriptor, _offset, buffers) { | ||
const offset = converter_1.BigInts.asNumber(_offset); | ||
const content = getResolvedINode(fileDescriptor.inode).content; | ||
const content = fs.getContent(fs.getNode(fileDescriptor.inode, NodeKind.File), vscode_fs); | ||
return read(content, offset, buffers); | ||
@@ -312,3 +525,3 @@ }, | ||
next, | ||
new DirectoryFileDescriptor(deviceId, fd, wasiTypes_1.Rights.DirectoryBase, wasiTypes_1.Rights.DirectoryInheriting, 0, getOrCreateINode('/', baseUri, true).id, '/') | ||
new DirectoryFileDescriptor(deviceId, fd, exports.DirectoryBaseRights, exports.DirectoryInheritingRights, 0, fs.getRoot().inode) | ||
]; | ||
@@ -318,6 +531,5 @@ }, | ||
const offset = converter_1.BigInts.asNumber(_offset); | ||
const inode = getResolvedINode(fileDescriptor.inode); | ||
const [newContent, bytesWritten] = write(inode.content, offset, buffers); | ||
inode.content = newContent; | ||
writeContent(inode); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
const [newContent, bytesWritten] = write(fs.getContent(inode, vscode_fs), offset, buffers); | ||
writeContent(inode, newContent); | ||
return bytesWritten; | ||
@@ -330,3 +542,3 @@ }, | ||
assertFileDescriptor(fileDescriptor); | ||
const content = getResolvedINode(fileDescriptor.inode).content; | ||
const content = fs.getContent(fs.getNode(fileDescriptor.inode, NodeKind.File), vscode_fs); | ||
const offset = fileDescriptor.cursor; | ||
@@ -341,10 +553,10 @@ const totalBytesRead = read(content, offset, buffers); | ||
// See also https://github.com/WebAssembly/wasi-filesystem/issues/3 | ||
const inode = getINode(fileDescriptor.inode); | ||
const entries = vscode_fs.readDirectory(inode.uri); | ||
const directoryNode = fs.getNode(fileDescriptor.inode, NodeKind.Directory); | ||
const entries = vscode_fs.readDirectory(fs.getUri(directoryNode)); | ||
const result = []; | ||
for (const entry of entries) { | ||
const name = entry[0]; | ||
const filePath = paths.join(fileDescriptor.path, name); | ||
const fileUri = uriJoin(inode.uri, name); | ||
result.push({ d_ino: getOrCreateINode(filePath, fileUri, false).id, d_type: converter_1.code2Wasi.asFileType(entry[1]), d_name: name }); | ||
const filetype = converter_1.code2Wasi.asFileType(entry[1]); | ||
const nodeKind = filetype === wasiTypes_1.Filetype.directory ? NodeKind.Directory : NodeKind.File; | ||
result.push({ d_ino: fs.getOrCreateNode(directoryNode, name, nodeKind, false).inode, d_type: filetype, d_name: name }); | ||
} | ||
@@ -364,4 +576,4 @@ return result; | ||
case wasiTypes_1.Whence.end: | ||
const inode = getResolvedINode(fileDescriptor.inode); | ||
fileDescriptor.cursor = Math.max(0, inode.content.byteLength - offset); | ||
const content = fs.getContent(fs.getNode(fileDescriptor.inode, NodeKind.File), vscode_fs); | ||
fileDescriptor.cursor = Math.max(0, content.byteLength - offset); | ||
break; | ||
@@ -372,7 +584,3 @@ } | ||
fd_sync(fileDescriptor) { | ||
const inode = getINode(fileDescriptor.inode); | ||
if (!INode.hasContent(inode)) { | ||
return; | ||
} | ||
writeContent(inode); | ||
writeContent(fs.getNode(fileDescriptor.inode, NodeKind.File)); | ||
}, | ||
@@ -388,6 +596,11 @@ fd_tell(fileDescriptor) { | ||
assertFileDescriptor(fileDescriptor); | ||
const inode = getResolvedINode(fileDescriptor.inode); | ||
const [newContent, bytesWritten] = write(inode.content, fileDescriptor.cursor, buffers); | ||
inode.content = newContent; | ||
writeContent(inode); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
const content = fs.getContent(inode, vscode_fs); | ||
// We have append mode on. According to POSIX we need to | ||
// move the cursor to the end of the file on every write | ||
if (wasiTypes_1.Fdflags.appendOn(fileDescriptor.fdflags)) { | ||
fileDescriptor.cursor = content.byteLength; | ||
} | ||
const [newContent, bytesWritten] = write(content, fileDescriptor.cursor, buffers); | ||
writeContent(inode, newContent); | ||
fileDescriptor.cursor = fileDescriptor.cursor + bytesWritten; | ||
@@ -397,11 +610,10 @@ return bytesWritten; | ||
path_create_directory(fileDescriptor, path) { | ||
const inode = getINode(fileDescriptor.inode); | ||
vscode_fs.createDirectory(uriJoin(inode.uri, path)); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.Directory); | ||
vscode_fs.createDirectory(fs.getUri(inode, path)); | ||
}, | ||
path_filestat_get(fileDescriptor, _flags, path, result) { | ||
assertFileOrDirectoryDescriptor(fileDescriptor); | ||
const inode = getINode(fileDescriptor.inode); | ||
const filePath = paths.join(fileDescriptor.path, path); | ||
const fileUri = uriJoin(inode.uri, path); | ||
doStat(getOrCreateINode(filePath, fileUri, false), result); | ||
assertDirectoryDescriptor(fileDescriptor); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.Directory); | ||
const vStat = vscode_fs.stat(fs.getUri(inode, path)); | ||
assignStat(result, fs.getOrCreateNode(inode, path, vStat.type === sync_api_client_1.FileType.Directory ? NodeKind.Directory : NodeKind.File, false).inode, vStat); | ||
}, | ||
@@ -412,2 +624,3 @@ path_filestat_set_times(_fileDescriptor, _flags, _path, _atim, _mtim, _fst_flags) { | ||
// in local storage | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.nosys); | ||
}, | ||
@@ -417,8 +630,9 @@ path_link(_oldFileDescriptor, _old_flags, _old_path, _newFileDescriptor, _new_path) { | ||
// support from the VS Code API. | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.nosys); | ||
}, | ||
path_open(parentDescriptor, _dirflags, path, oflags, fs_rights_base, fs_rights_inheriting, fdflags) { | ||
assertDirectoryDescriptor(parentDescriptor); | ||
if (path === '.') { | ||
path = parentDescriptor.path; | ||
} | ||
// We ignore lookup flags that request to follow symlinks. The POSIX FS | ||
// implementation we have right now doesn't support symlinks and VS Code | ||
// has no API to follow / resolve a symlink. | ||
let filetype = doGetFiletype(parentDescriptor, path); | ||
@@ -468,4 +682,4 @@ const entryExists = filetype !== undefined; | ||
const result = filetype === wasiTypes_1.Filetype.regular_file | ||
? createFileDescriptor(parentDescriptor, fs_rights_base | wasiTypes_1.Rights.FileBase, fs_rights_inheriting | wasiTypes_1.Rights.FileInheriting, fdflags, path) | ||
: createDirectoryDescriptor(parentDescriptor, fs_rights_base | wasiTypes_1.Rights.DirectoryBase, fs_rights_inheriting | wasiTypes_1.Rights.DirectoryInheriting, fdflags, path); | ||
? createFileDescriptor(parentDescriptor, parentDescriptor.childFileRights(fs_rights_base), fdflags, path) | ||
: createDirectoryDescriptor(parentDescriptor, parentDescriptor.childDirectoryRights(fs_rights_base), fs_rights_inheriting | exports.DirectoryInheritingRights, fdflags, path); | ||
if (result instanceof FileFileDescriptor && (createFile || wasiTypes_1.Oflags.truncOn(oflags))) { | ||
@@ -479,11 +693,27 @@ createOrTruncate(result); | ||
// support from the VS Code API. | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.noent); | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.nolink); | ||
}, | ||
path_remove_directory(fileDescriptor, path) { | ||
assertFileOrDirectoryDescriptor(fileDescriptor); | ||
const parentINode = getINode(fileDescriptor.inode); | ||
const fileUri = uriJoin(parentINode.uri, path); | ||
vscode_fs.delete(fileUri, { recursive: false, useTrash: true }); | ||
// todo@dirkb Need to think about whether we need to mark sub inodes as deleted as well. | ||
markINodeAsDeleted(paths.join(fileDescriptor.path, path)); | ||
assertDirectoryDescriptor(fileDescriptor); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.Directory); | ||
const targetNode = fs.getNodeByPath(inode, path, NodeKind.Directory); | ||
// We have a target node and there is an open file descriptor. | ||
let filestat; | ||
if (targetNode !== undefined && targetNode.refs > 0) { | ||
try { | ||
filestat = vscode_fs.stat(fs.getUri(targetNode)); | ||
} | ||
catch { | ||
filestat = { type: sync_api_client_1.FileType.Directory, ctime: Date.now(), mtime: Date.now(), size: 0 }; | ||
} | ||
} | ||
vscode_fs.delete(fs.getUri(inode, path), { recursive: false, useTrash: true }); | ||
if (targetNode !== undefined) { | ||
if (filestat !== undefined) { | ||
fs.deleteNode(targetNode, filestat); | ||
} | ||
else { | ||
fs.deleteNode(targetNode); | ||
} | ||
} | ||
}, | ||
@@ -493,19 +723,29 @@ path_rename(oldFileDescriptor, oldPath, newFileDescriptor, newPath) { | ||
assertDirectoryDescriptor(newFileDescriptor); | ||
const oldParentINode = getINode(oldFileDescriptor.inode); | ||
const newParentINode = getINode(newFileDescriptor.inode); | ||
const oldUri = uriJoin(oldParentINode.uri, oldPath); | ||
const newUri = uriJoin(newParentINode.uri, newPath); | ||
const newParentNode = fs.getNode(newFileDescriptor.inode, NodeKind.Directory); | ||
if (fs.existsNode(newParentNode, newPath)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.exist); | ||
} | ||
const oldParentNode = fs.getNode(oldFileDescriptor.inode, NodeKind.Directory); | ||
const oldNode = fs.getNodeByPath(oldParentNode, oldPath); | ||
let filestat; | ||
let content; | ||
if (oldNode !== undefined && oldNode.refs > 0) { | ||
try { | ||
const uri = fs.getUri(oldNode); | ||
filestat = vscode_fs.stat(uri); | ||
if (oldNode.kind === NodeKind.File) { | ||
content = vscode_fs.readFile(uri); | ||
} | ||
} | ||
catch { | ||
filestat = { type: sync_api_client_1.FileType.File, ctime: Date.now(), mtime: Date.now(), size: 0 }; | ||
content = new Uint8Array(0); | ||
} | ||
} | ||
const oldUri = fs.getUri(oldParentNode, oldPath); | ||
const newUri = fs.getUri(newParentNode, newPath); | ||
vscode_fs.rename(oldUri, newUri, { overwrite: false }); | ||
// todo@dirkb unclear what really happens in posix. We need to understand if | ||
// an old file descriptor could still read the directory under its new location. | ||
const oldINode = path2INode.get(paths.join(oldFileDescriptor.path, oldPath)); | ||
if (oldINode === undefined) { | ||
return; | ||
if (oldNode !== undefined) { | ||
fs.renameNode(oldNode, filestat, content, newParentNode, newPath); | ||
} | ||
const newFilePath = paths.join(newFileDescriptor.path, newPath); | ||
const newINode = path2INode.get(newFilePath); | ||
if (newINode !== undefined) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.badf); | ||
} | ||
path2INode.set(newFilePath, oldINode); | ||
}, | ||
@@ -517,13 +757,33 @@ path_symlink(_oldPath, _fileDescriptor, _newPath) { | ||
assertDirectoryDescriptor(fileDescriptor); | ||
const inode = getINode(fileDescriptor.inode); | ||
const filePath = paths.join(fileDescriptor.path, path); | ||
const fileUri = uriJoin(inode.uri, path); | ||
vscode_fs.delete(fileUri, { recursive: false, useTrash: true }); | ||
markINodeAsDeleted(filePath); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.Directory); | ||
const targetNode = fs.getNodeByPath(inode, path, NodeKind.File); | ||
let filestat; | ||
let content; | ||
if (targetNode !== undefined && targetNode.refs > 0) { | ||
try { | ||
const uri = fs.getUri(targetNode); | ||
filestat = vscode_fs.stat(uri); | ||
content = vscode_fs.readFile(uri); | ||
} | ||
catch { | ||
filestat = { type: sync_api_client_1.FileType.File, ctime: Date.now(), mtime: Date.now(), size: 0 }; | ||
content = new Uint8Array(0); | ||
} | ||
} | ||
vscode_fs.delete(fs.getUri(inode, path), { recursive: false, useTrash: true }); | ||
if (targetNode !== undefined) { | ||
if (filestat !== undefined && content !== undefined) { | ||
fs.deleteNode(targetNode, filestat, content); | ||
} | ||
else { | ||
fs.deleteNode(targetNode); | ||
} | ||
} | ||
}, | ||
bytesAvailable(fileDescriptor) { | ||
assertFileDescriptor(fileDescriptor); | ||
const inode = getResolvedINode(fileDescriptor.inode); | ||
const inode = fs.getNode(fileDescriptor.inode, NodeKind.File); | ||
const cursor = fileDescriptor.cursor; | ||
return BigInt(Math.max(0, inode.content.byteLength - cursor)); | ||
const content = fs.getContent(inode, vscode_fs); | ||
return BigInt(Math.max(0, content.byteLength - cursor)); | ||
} | ||
@@ -530,0 +790,0 @@ }); |
import { URI } from 'vscode-uri'; | ||
import { ApiClient } from '@vscode/sync-api-client'; | ||
import { ApiShape } from '@vscode/sync-api-client'; | ||
import RAL from './ral'; | ||
@@ -86,3 +86,3 @@ import { args_sizes_get, args_get, environ_sizes_get, environ_get, clock_res_get, clock_time_get, fd_advise, fd_allocate, fd_close, fd_datasync, fd_fdstat_get, fd_fdstat_set_flags, fd_filestat_get, fd_filestat_set_size, fd_filestat_set_times, fd_pread, fd_prestat_dir_name, fd_prestat_get, fd_pwrite, fd_read, fd_readdir, fd_seek, fd_sync, fd_tell, fd_write, path_create_directory, path_filestat_get, path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory, path_rename, path_symlink, path_unlink_file, poll_oneoff, proc_exit, random_get, sched_yield, sock_accept, sock_recv, sock_send, sock_shutdown } from './wasiTypes'; | ||
} | ||
export declare type DeviceDescription = { | ||
export type DeviceDescription = { | ||
kind: 'fileSystem'; | ||
@@ -100,7 +100,7 @@ uri: URI; | ||
uri: URI; | ||
factory: (apiClient: ApiClient, encoder: RAL.TextEncoder, decoder: RAL.TextDecoder, fileDescriptorId: { | ||
factory: (apiClient: ApiShape, encoder: RAL.TextEncoder, decoder: RAL.TextDecoder, fileDescriptorId: { | ||
next(): number; | ||
}) => DeviceDriver; | ||
}; | ||
export declare type FileDescriptorDescription = { | ||
export type FileDescriptorDescription = { | ||
kind: 'fileSystem'; | ||
@@ -116,3 +116,3 @@ uri: URI; | ||
}; | ||
export declare type Options = { | ||
export type Options = { | ||
/** | ||
@@ -143,3 +143,3 @@ * The encoding to use. | ||
*/ | ||
function create(programName: string, apiClient: ApiClient, exitHandler: (rval: number) => void, devices: DeviceDescription[], stdio: { | ||
function create(programName: string, apiClient: ApiShape, exitHandler: (rval: number) => void, devices: DeviceDescription[], stdio: { | ||
stdin: FileDescriptorDescription; | ||
@@ -146,0 +146,0 @@ stdout: FileDescriptorDescription; |
@@ -109,3 +109,3 @@ "use strict"; | ||
} | ||
result = driver.createStdioFileDescriptor(fd, wasiTypes_1.Rights.FileBase, wasiTypes_1.Rights.FileInheriting, 0, description.path); | ||
result = driver.createStdioFileDescriptor(fd, 0, description.path); | ||
} | ||
@@ -186,5 +186,5 @@ else if (description.kind === 'terminal') { | ||
case wasiTypes_1.Clockid.realtime: | ||
memory.setBigUint64(timestamp_ptr, 1n, true); | ||
return wasiTypes_1.Errno.success; | ||
case wasiTypes_1.Clockid.monotonic: | ||
case wasiTypes_1.Clockid.process_cputime_id: | ||
case wasiTypes_1.Clockid.thread_cputime_id: | ||
memory.setBigUint64(timestamp_ptr, 1n, true); | ||
@@ -232,3 +232,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_advise); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_advise); | ||
getDeviceDriver(fileDescriptor).fd_advise(fileDescriptor, offset, length, advise); | ||
@@ -244,3 +244,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_allocate); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_allocate); | ||
getDeviceDriver(fileDescriptor).fd_allocate(fileDescriptor, offset, len); | ||
@@ -267,3 +267,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_datasync); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_datasync); | ||
getDeviceDriver(fileDescriptor).fd_datasync(fileDescriptor); | ||
@@ -289,3 +289,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_fdstat_set_flags); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_fdstat_set_flags); | ||
getDeviceDriver(fileDescriptor).fd_fdstat_set_flags(fileDescriptor, fdflags); | ||
@@ -301,3 +301,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_filestat_get); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_filestat_get); | ||
getDeviceDriver(fileDescriptor).fd_filestat_get(fileDescriptor, wasiTypes_1.Filestat.create(filestat_ptr, memoryView())); | ||
@@ -313,3 +313,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_filestat_set_size); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_filestat_set_size); | ||
getDeviceDriver(fileDescriptor).fd_filestat_set_size(fileDescriptor, size); | ||
@@ -325,3 +325,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_filestat_set_times); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_filestat_set_times); | ||
getDeviceDriver(fileDescriptor).fd_filestat_set_times(fileDescriptor, atim, mtim, fst_flags); | ||
@@ -337,3 +337,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_read); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_read | wasiTypes_1.Rights.fd_seek); | ||
const buffers = read_iovs(iovs_ptr, iovs_len); | ||
@@ -399,3 +399,3 @@ const bytesRead = getDeviceDriver(fileDescriptor).fd_pread(fileDescriptor, offset, buffers); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_write); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_write | wasiTypes_1.Rights.fd_seek); | ||
const buffers = read_ciovs(ciovs_ptr, ciovs_len); | ||
@@ -413,3 +413,3 @@ const bytesWritten = getDeviceDriver(fileDescriptor).fd_pwrite(fileDescriptor, offset, buffers); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_read); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_read); | ||
const buffers = read_iovs(iovs_ptr, iovs_len); | ||
@@ -427,3 +427,3 @@ const bytesRead = getDeviceDriver(fileDescriptor).fd_read(fileDescriptor, buffers); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_readdir); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_readdir); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -487,3 +487,8 @@ const driver = getDeviceDriver(fileDescriptor); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_seek); | ||
if (whence === wasiTypes_1.Whence.cur && offset === 0n && !fileDescriptor.containsBaseRights(wasiTypes_1.Rights.fd_seek) && !fileDescriptor.containsBaseRights(wasiTypes_1.Rights.fd_tell)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.perm); | ||
} | ||
else { | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_seek); | ||
} | ||
const newOffset = getDeviceDriver(fileDescriptor).fd_seek(fileDescriptor, offset, whence); | ||
@@ -500,3 +505,3 @@ memoryView().setBigUint64(new_offset_ptr, BigInt(newOffset), true); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_sync); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_sync); | ||
getDeviceDriver(fileDescriptor).fd_sync(fileDescriptor); | ||
@@ -512,3 +517,3 @@ return wasiTypes_1.Errno.success; | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_tell); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_tell | wasiTypes_1.Rights.fd_seek); | ||
const offset = getDeviceDriver(fileDescriptor).fd_tell(fileDescriptor); | ||
@@ -525,3 +530,3 @@ memoryView().setBigUint64(offset_ptr, BigInt(offset), true); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_write); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.fd_write); | ||
const buffers = read_ciovs(ciovs_ptr, ciovs_len); | ||
@@ -539,3 +544,3 @@ const bytesWritten = getDeviceDriver(fileDescriptor).fd_write(fileDescriptor, buffers); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_create_directory); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_create_directory); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -553,3 +558,3 @@ const path = decoder.decode(new Uint8Array(memoryRaw(), path_ptr, path_len)); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_filestat_get); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_filestat_get); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -567,3 +572,3 @@ const path = decoder.decode(new Uint8Array(memoryRaw(), path_ptr, path_len)); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_filestat_set_times); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_filestat_set_times); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -581,6 +586,6 @@ const path = decoder.decode(new Uint8Array(memoryRaw(), path_ptr, path_len)); | ||
const oldFileDescriptor = getFileDescriptor(old_fd); | ||
oldFileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_link_source); | ||
oldFileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_link_source); | ||
oldFileDescriptor.assertIsDirectory(); | ||
const newFileDescriptor = getFileDescriptor(new_fd); | ||
newFileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_link_target); | ||
newFileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_link_target); | ||
newFileDescriptor.assertIsDirectory(); | ||
@@ -604,3 +609,5 @@ if (oldFileDescriptor.deviceId !== newFileDescriptor.deviceId) { | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_open); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_open); | ||
fileDescriptor.assertFdflags(fdflags); | ||
fileDescriptor.assertOflags(oflags); | ||
const path = decoder.decode(new Uint8Array(memoryRaw(), path_ptr, path_len)); | ||
@@ -617,15 +624,14 @@ const result = getDeviceDriver(fileDescriptor).path_open(fileDescriptor, dirflags, path, oflags, fs_rights_base, fs_rights_inheriting, fdflags); | ||
path_readlink: (fd, path_ptr, path_len, buf_ptr, buf_len, result_size_ptr) => { | ||
// VS Code has no support to follow a symlink. | ||
try { | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_readlink); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_readlink); | ||
fileDescriptor.assertIsDirectory(); | ||
const memory = memoryRaw(); | ||
const path = decoder.decode(new Uint8Array(memory, path_ptr, path_len)); | ||
const result = encoder.encode(getDeviceDriver(fileDescriptor).path_readlink(fileDescriptor, path)); | ||
if (result.byteLength > buf_len) { | ||
const target = encoder.encode(getDeviceDriver(fileDescriptor).path_readlink(fileDescriptor, path)); | ||
if (target.byteLength > buf_len) { | ||
return wasiTypes_1.Errno.inval; | ||
} | ||
new Uint8Array(memory, buf_ptr, buf_len).set(result); | ||
memoryView().setUint32(result_size_ptr, result.byteLength, true); | ||
new Uint8Array(memory, buf_ptr, buf_len).set(target); | ||
memoryView().setUint32(result_size_ptr, target.byteLength, true); | ||
return wasiTypes_1.Errno.success; | ||
@@ -640,3 +646,3 @@ } | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_remove_directory); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_remove_directory); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -654,6 +660,6 @@ const path = decoder.decode(new Uint8Array(memoryRaw(), path_ptr, path_len)); | ||
const oldFileDescriptor = getFileDescriptor(old_fd); | ||
oldFileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_rename_source); | ||
oldFileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_rename_source); | ||
oldFileDescriptor.assertIsDirectory(); | ||
const newFileDescriptor = getFileDescriptor(new_fd); | ||
newFileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_rename_target); | ||
newFileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_rename_target); | ||
newFileDescriptor.assertIsDirectory(); | ||
@@ -674,3 +680,3 @@ const memory = memoryRaw(); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_symlink); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_symlink); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -690,3 +696,3 @@ const memory = memoryRaw(); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.path_unlink_file); | ||
fileDescriptor.assertBaseRights(wasiTypes_1.Rights.path_unlink_file); | ||
fileDescriptor.assertIsDirectory(); | ||
@@ -836,3 +842,5 @@ const path = decoder.decode(new Uint8Array(memoryRaw(), path_ptr, path_len)); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
fileDescriptor.assertBaseRight(wasiTypes_1.Rights.fd_read); | ||
if (!fileDescriptor.containsBaseRights(wasiTypes_1.Rights.poll_fd_readwrite) && !fileDescriptor.containsBaseRights(wasiTypes_1.Rights.fd_read)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.perm); | ||
} | ||
const available = getDeviceDriver(fileDescriptor).fd_bytesAvailable(fileDescriptor); | ||
@@ -864,4 +872,6 @@ return { | ||
try { | ||
const fileHandle = getFileDescriptor(fd); | ||
fileHandle.assertBaseRight(wasiTypes_1.Rights.fd_write); | ||
const fileDescriptor = getFileDescriptor(fd); | ||
if (!fileDescriptor.containsBaseRights(wasiTypes_1.Rights.poll_fd_readwrite) && !fileDescriptor.containsBaseRights(wasiTypes_1.Rights.fd_write)) { | ||
throw new wasiTypes_1.WasiError(wasiTypes_1.Errno.perm); | ||
} | ||
return { | ||
@@ -868,0 +878,0 @@ userdata: subscription.userdata, |
@@ -1,5 +0,5 @@ | ||
import { ptr, size, u16, u32, u64, s64, u8 } from './baseTypes'; | ||
export declare type fd = u32; | ||
export declare type exitcode = u32; | ||
export declare type errno = u16; | ||
import { ptr, size, u16, u32, u64, s64, u8, cstring } from './baseTypes'; | ||
export type fd = u32; | ||
export type exitcode = u32; | ||
export type errno = u16; | ||
export declare namespace Errno { | ||
@@ -319,3 +319,3 @@ /** | ||
} | ||
export declare type rights = u64; | ||
export type rights = u64; | ||
export declare namespace Rights { | ||
@@ -456,62 +456,39 @@ /** | ||
/** | ||
* All rights | ||
* Check if the given rights contain the requested rights. | ||
* @param rights The granted rights. | ||
* @param check The rights to check. | ||
* @returns true if the granted rights contain the rights to check. | ||
*/ | ||
const All: bigint; | ||
function contains(rights: rights, check: rights): boolean; | ||
/** | ||
* Base rights for block devices. | ||
* | ||
* Note: we don't have block devices in VS Code. | ||
* Check if the given rights support the requested flags | ||
* @param rights The granted rights. | ||
* @param fdflags The requested flags. | ||
* @returns true if the granted rights support the given flags | ||
*/ | ||
const BlockDeviceBase = 0n; | ||
function supportFdflags(rights: rights, fdflags: fdflags): boolean; | ||
/** | ||
* Inheriting rights for block devices. | ||
* | ||
* Note: we don't have block devices in VS Code. | ||
* Check if the given rights support the requested flags | ||
* @param rights The granted rights. | ||
* @param fdflags The requested flags. | ||
* @returns true if the granted rights support the given flags | ||
*/ | ||
const BlockDeviceInheriting = 0n; | ||
function supportOflags(rights: rights, oflags: oflags): boolean; | ||
/** | ||
* Base rights for directories managed in VS Code. | ||
* No rights | ||
*/ | ||
const DirectoryBase: bigint; | ||
const None: rights; | ||
/** | ||
* Base rights for files managed in VS Code. | ||
* All rights | ||
*/ | ||
const FileBase: bigint; | ||
const All: bigint; | ||
} | ||
export type dircookie = u64; | ||
export type fdflags = u16; | ||
export declare namespace Fdflags { | ||
/** | ||
* Inheriting rights for directories | ||
* No flags. | ||
*/ | ||
const DirectoryInheriting: bigint; | ||
const none = 0; | ||
/** | ||
* Inheriting rights for files | ||
*/ | ||
const FileInheriting = 0n; | ||
/** | ||
* Base rights for character devices | ||
*/ | ||
const CharacterDeviceBase: bigint; | ||
/** | ||
* Inheriting rights for character devices | ||
*/ | ||
const CharacterDeviceInheriting = 0n; | ||
/** | ||
* Base rights for stdin | ||
*/ | ||
const StdinBase: bigint; | ||
/** | ||
* Inheriting rights for stdout / stderr | ||
*/ | ||
const StdinInheriting = 0n; | ||
/** | ||
* Base rights for stdout / stderr | ||
*/ | ||
const StdoutBase: bigint; | ||
/** | ||
* Inheriting rights for stdout / stderr | ||
*/ | ||
const StdoutInheriting = 0n; | ||
} | ||
export declare type dircookie = u64; | ||
export declare type fdflags = u16; | ||
export declare namespace Fdflags { | ||
/** | ||
* Append mode: Data written to the file is always appended to the file's | ||
@@ -521,2 +498,3 @@ * end. | ||
const append: number; | ||
function appendOn(value: fdflags): boolean; | ||
/** | ||
@@ -527,2 +505,3 @@ * Write according to synchronized I/O data integrity completion. Only the | ||
const dsync: number; | ||
function dsyncOn(value: fdflags): boolean; | ||
/** | ||
@@ -532,2 +511,3 @@ * Non-blocking mode. | ||
const nonblock: number; | ||
function nonblockOn(value: fdflags): boolean; | ||
/** | ||
@@ -537,2 +517,3 @@ * Synchronized read I/O operations. | ||
const rsync: number; | ||
function rsyncOn(value: fdflags): boolean; | ||
/** | ||
@@ -544,6 +525,11 @@ * Write according to synchronized I/O file integrity completion. In | ||
const sync: number; | ||
function syncOn(value: fdflags): boolean; | ||
} | ||
export declare type lookupflags = u32; | ||
export type lookupflags = u32; | ||
export declare namespace Lookupflags { | ||
/** | ||
* No flags. | ||
*/ | ||
const none = 0; | ||
/** | ||
* As long as the resolved path corresponds to a symbolic link, it is | ||
@@ -554,8 +540,14 @@ * expanded. | ||
} | ||
export declare type oflags = u16; | ||
export type oflags = u16; | ||
export declare namespace Oflags { | ||
/** | ||
* No flags. | ||
*/ | ||
const none = 0; | ||
/** | ||
* Create file if it does not exist. | ||
*/ | ||
const creat: number; | ||
function creatOn(value: oflags): boolean; | ||
function creatOff(value: oflags): boolean; | ||
/** | ||
@@ -565,2 +557,3 @@ * Fail if not a directory. | ||
const directory: number; | ||
function directoryOn(value: oflags): boolean; | ||
/** | ||
@@ -570,2 +563,3 @@ * Fail if file already exists. | ||
const excl: number; | ||
function exclOn(value: oflags): boolean; | ||
/** | ||
@@ -575,9 +569,5 @@ * Truncate file to size 0. | ||
const trunc: number; | ||
function creatOn(value: oflags): boolean; | ||
function creatOff(value: oflags): boolean; | ||
function directoryOn(value: oflags): boolean; | ||
function exclOn(value: oflags): boolean; | ||
function truncOn(value: oflags): boolean; | ||
} | ||
export declare type clockid = u32; | ||
export type clockid = u32; | ||
export declare namespace Clockid { | ||
@@ -605,3 +595,3 @@ /** | ||
} | ||
export declare type preopentype = u8; | ||
export type preopentype = u8; | ||
export declare namespace Preopentype { | ||
@@ -613,3 +603,3 @@ /** | ||
} | ||
export declare type filetype = u8; | ||
export type filetype = u8; | ||
export declare namespace Filetype { | ||
@@ -650,3 +640,3 @@ /** | ||
} | ||
export declare type advise = u8; | ||
export type advise = u8; | ||
/** | ||
@@ -680,3 +670,3 @@ * File or memory access pattern advisory information. | ||
/** | ||
* The application expects to access the specified data once and then not | ||
* The application expects to access the specified data once and then not | ||
* reuse it thereafter. | ||
@@ -686,11 +676,16 @@ */ | ||
} | ||
export declare type filesize = u64; | ||
export declare type device = u64; | ||
export declare type inode = u64; | ||
export declare type linkcount = u64; | ||
export declare type timestamp = u64; | ||
export declare type filestat = { | ||
export type filesize = u64; | ||
export type device = u64; | ||
export type inode = u64; | ||
export type linkcount = u64; | ||
export type timestamp = u64; | ||
export type filestat = { | ||
/** | ||
* The memory location of the allocated struct. | ||
*/ | ||
get $ptr(): ptr; | ||
/** | ||
* Device ID of device containing the file. | ||
*/ | ||
get dev(): device; | ||
set dev(value: device); | ||
@@ -700,2 +695,3 @@ /** | ||
*/ | ||
get ino(): inode; | ||
set ino(value: inode); | ||
@@ -705,2 +701,3 @@ /** | ||
*/ | ||
get filetype(): filetype; | ||
set filetype(value: filetype); | ||
@@ -710,2 +707,3 @@ /** | ||
*/ | ||
get nlink(): linkcount; | ||
set nlink(value: linkcount); | ||
@@ -716,2 +714,3 @@ /** | ||
*/ | ||
get size(): filesize; | ||
set size(value: filesize); | ||
@@ -721,2 +720,3 @@ /** | ||
*/ | ||
get atim(): timestamp; | ||
set atim(value: timestamp); | ||
@@ -726,2 +726,3 @@ /** | ||
*/ | ||
get mtim(): timestamp; | ||
set mtim(value: timestamp); | ||
@@ -731,2 +732,3 @@ /** | ||
*/ | ||
get ctim(): timestamp; | ||
set ctim(value: timestamp); | ||
@@ -744,7 +746,7 @@ }; | ||
*/ | ||
export declare type filedelta = s64; | ||
export type filedelta = s64; | ||
/** | ||
* The position relative to which to set the offset of the file descriptor. | ||
*/ | ||
export declare type whence = u8; | ||
export type whence = u8; | ||
export declare namespace Whence { | ||
@@ -764,6 +766,11 @@ /** | ||
} | ||
export declare type fdstat = { | ||
export type fdstat = { | ||
/** | ||
* The memory location. | ||
*/ | ||
get $ptr(): ptr<fdstat>; | ||
/** | ||
* File type. | ||
*/ | ||
get fs_filetype(): filetype; | ||
set fs_filetype(value: filetype); | ||
@@ -773,2 +780,3 @@ /** | ||
*/ | ||
get fs_flags(): fdflags; | ||
set fs_flags(value: fdflags); | ||
@@ -778,2 +786,3 @@ /** | ||
*/ | ||
get fs_rights_base(): rights; | ||
set fs_rights_base(value: rights); | ||
@@ -784,2 +793,3 @@ /** | ||
*/ | ||
get fs_rights_inheriting(): rights; | ||
set fs_rights_inheriting(value: rights); | ||
@@ -795,3 +805,3 @@ }; | ||
} | ||
export declare type fstflags = u16; | ||
export type fstflags = u16; | ||
export declare namespace Fstflags { | ||
@@ -822,4 +832,16 @@ /** | ||
*/ | ||
export declare type prestat = { | ||
export type prestat = { | ||
/** | ||
* The memory location. | ||
*/ | ||
get $ptr(): ptr; | ||
/** | ||
* Gets the pre-open type. | ||
*/ | ||
get preopentype(): preopentype; | ||
/** | ||
* Gets the length of the pre opened directory name. | ||
*/ | ||
get len(): size; | ||
/** | ||
* Sets the length of the pre opened directory name. | ||
@@ -830,2 +852,7 @@ */ | ||
export declare namespace Prestat { | ||
/** | ||
* The size in bytes. | ||
*/ | ||
const size: 8; | ||
const alignment: 4; | ||
function create(ptr: ptr, memory: DataView): prestat; | ||
@@ -836,7 +863,12 @@ } | ||
*/ | ||
export declare type iovec = { | ||
export type iovec = { | ||
/** | ||
* The memory location of the allocated struct. | ||
*/ | ||
get $ptr(): ptr; | ||
/** | ||
* The address of the buffer to be filled. | ||
*/ | ||
get buf(): ptr; | ||
set buf(value: ptr); | ||
/** | ||
@@ -846,2 +878,3 @@ * The length of the buffer to be filled. | ||
get buf_len(): u32; | ||
set buf_len(value: u32); | ||
}; | ||
@@ -853,13 +886,18 @@ export declare namespace Iovec { | ||
const size: 8; | ||
function create(ptr: ptr, memory: DataView): ciovec; | ||
function create(ptr: ptr, memory: DataView): iovec; | ||
} | ||
export declare type iovec_array = iovec[]; | ||
export type iovec_array = iovec[]; | ||
/** | ||
* A region of memory for scatter/gather writes. | ||
*/ | ||
export declare type ciovec = { | ||
export type ciovec = { | ||
/** | ||
* The memory location of the allocated struct. | ||
*/ | ||
get $ptr(): ptr<ciovec>; | ||
/** | ||
* The address of the buffer to be written. | ||
*/ | ||
get buf(): ptr; | ||
set buf(value: ptr); | ||
/** | ||
@@ -869,2 +907,3 @@ * The length of the buffer to be written. | ||
get buf_len(): u32; | ||
set buf_len(value: u32); | ||
}; | ||
@@ -878,8 +917,13 @@ export declare namespace Ciovec { | ||
} | ||
export declare type ciovec_array = iovec[]; | ||
export declare type dirnamlen = u32; | ||
export declare type dirent = { | ||
export type ciovec_array = iovec[]; | ||
export type dirnamlen = u32; | ||
export type dirent = { | ||
/** | ||
* The memory location of the allocated struct. | ||
*/ | ||
get $ptr(): ptr; | ||
/** | ||
* The offset of the next directory entry stored in this directory. | ||
*/ | ||
get d_next(): dircookie; | ||
set d_next(value: dircookie); | ||
@@ -889,2 +933,3 @@ /** | ||
*/ | ||
get d_ino(): inode; | ||
set d_ino(value: inode); | ||
@@ -894,2 +939,3 @@ /** | ||
*/ | ||
get d_namlen(): dirnamlen; | ||
set d_namlen(value: dirnamlen); | ||
@@ -899,2 +945,3 @@ /** | ||
*/ | ||
get d_type(): filetype; | ||
set d_type(value: filetype); | ||
@@ -909,3 +956,3 @@ }; | ||
*/ | ||
export declare type eventtype = u8; | ||
export type eventtype = u8; | ||
export declare namespace Eventtype { | ||
@@ -932,3 +979,3 @@ /** | ||
*/ | ||
export declare type eventrwflags = u16; | ||
export type eventrwflags = u16; | ||
export declare namespace Eventrwflags { | ||
@@ -944,3 +991,3 @@ /** | ||
*/ | ||
export declare type event_fd_readwrite = { | ||
export type event_fd_readwrite = { | ||
/** | ||
@@ -964,7 +1011,7 @@ * The number of bytes available for reading or writing. | ||
*/ | ||
export declare type userdata = u64; | ||
export type userdata = u64; | ||
/** | ||
* An event that occurred. | ||
*/ | ||
export declare type event = { | ||
export type event = { | ||
/** | ||
@@ -994,3 +1041,3 @@ * User-provided value that got attached to subscription::userdata. | ||
} | ||
export declare type subclockflags = u16; | ||
export type subclockflags = u16; | ||
export declare namespace Subclockflags { | ||
@@ -1008,3 +1055,3 @@ /** | ||
*/ | ||
export declare type subscription_clock = { | ||
export type subscription_clock = { | ||
/** | ||
@@ -1037,3 +1084,3 @@ * The clock against which to compare the timestamp. | ||
*/ | ||
export declare type subscription_fd_readwrite = { | ||
export type subscription_fd_readwrite = { | ||
/** | ||
@@ -1050,3 +1097,3 @@ * The file descriptor on which to wait for it to become ready for | ||
} | ||
export declare type subscription_u = { | ||
export type subscription_u = { | ||
get type(): eventtype; | ||
@@ -1066,3 +1113,3 @@ get clock(): subscription_clock; | ||
*/ | ||
export declare type subscription = { | ||
export type subscription = { | ||
/** | ||
@@ -1083,3 +1130,3 @@ * User-provided value that is attached to the subscription in the | ||
} | ||
export declare type Literal<T> = { | ||
export type Literal<T> = { | ||
[P in keyof T]: T[P]; | ||
@@ -1090,3 +1137,3 @@ }; | ||
*/ | ||
export declare type riflags = u16; | ||
export type riflags = u16; | ||
/** | ||
@@ -1108,3 +1155,3 @@ * Flags provided to sock_recv. | ||
*/ | ||
export declare type roflags = u16; | ||
export type roflags = u16; | ||
export declare namespace Roflags { | ||
@@ -1120,3 +1167,3 @@ /** | ||
*/ | ||
export declare type siflags = u16; | ||
export type siflags = u16; | ||
export declare namespace Siflags { | ||
@@ -1127,3 +1174,3 @@ } | ||
*/ | ||
export declare type sdflags = u8; | ||
export type sdflags = u8; | ||
export declare namespace Sdflags { | ||
@@ -1145,3 +1192,3 @@ /** | ||
*/ | ||
export declare type args_sizes_get = (argvCount_ptr: ptr, argvBufSize_ptr: ptr) => errno; | ||
export type args_sizes_get = (argvCount_ptr: ptr<u32>, argvBufSize_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1154,20 +1201,4 @@ * Read command-line argument data. The size of the array should match that | ||
*/ | ||
export declare type args_get = (argv_ptr: ptr, argvBuf_ptr: ptr) => errno; | ||
export type args_get = (argv_ptr: ptr<u32[]>, argvBuf_ptr: ptr<cstring>) => errno; | ||
/** | ||
* Return environment variable data sizes. | ||
* | ||
* @param environCount_ptr A memory location to store the number of vars. | ||
* @param environBufSize_ptr A memory location to store the needed buffer size. | ||
*/ | ||
export declare type environ_sizes_get = (environCount_ptr: ptr, environBufSize_ptr: ptr) => errno; | ||
/** | ||
* Read environment variable data. The sizes of the buffers should match | ||
* that returned by environ_sizes_get. Key/value pairs are expected to | ||
* be joined with =s, and terminated with \0s. | ||
* | ||
* @params environ_ptr A memory location to store the env value offsets | ||
* @params environBuf_ptr A memory location to store the actual env value. | ||
*/ | ||
export declare type environ_get = (environ_ptr: ptr, environBuf_ptr: ptr) => errno; | ||
/** | ||
* Return the resolution of a clock. Implementations are required to provide | ||
@@ -1180,3 +1211,3 @@ * a non-zero value for supported clocks. For unsupported clocks, return | ||
*/ | ||
export declare type clock_res_get = (id: clockid, timestamp_ptr: ptr) => errno; | ||
export type clock_res_get = (id: clockid, timestamp_ptr: ptr) => errno; | ||
/** | ||
@@ -1191,4 +1222,20 @@ * Return the time value of a clock. Note: This is similar to clock_gettime | ||
*/ | ||
export declare type clock_time_get = (id: clockid, precision: timestamp, timestamp_ptr: ptr) => errno; | ||
export type clock_time_get = (id: clockid, precision: timestamp, timestamp_ptr: ptr<u64>) => errno; | ||
/** | ||
* Return environment variable data sizes. | ||
* | ||
* @param environCount_ptr A memory location to store the number of vars. | ||
* @param environBufSize_ptr A memory location to store the needed buffer size. | ||
*/ | ||
export type environ_sizes_get = (environCount_ptr: ptr<u32>, environBufSize_ptr: ptr<u32>) => errno; | ||
/** | ||
* Read environment variable data. The sizes of the buffers should match | ||
* that returned by environ_sizes_get. Key/value pairs are expected to | ||
* be joined with =s, and terminated with \0s. | ||
* | ||
* @params environ_ptr A memory location to store the env value offsets | ||
* @params environBuf_ptr A memory location to store the actual env value. | ||
*/ | ||
export type environ_get = (environ_ptr: ptr<u32>, environBuf_ptr: ptr<cstring>) => errno; | ||
/** | ||
* Provide file advisory information on a file descriptor. Note: This is | ||
@@ -1202,3 +1249,3 @@ * similar to posix_fadvise in POSIX. | ||
*/ | ||
export declare type fd_advise = (fd: fd, offset: filesize, length: filesize, advise: advise) => errno; | ||
export type fd_advise = (fd: fd, offset: filesize, length: filesize, advise: advise) => errno; | ||
/** | ||
@@ -1212,3 +1259,3 @@ * Force the allocation of space in a file. Note: This is similar to | ||
*/ | ||
export declare type fd_allocate = (fd: fd, offset: filesize, len: filesize) => errno; | ||
export type fd_allocate = (fd: fd, offset: filesize, len: filesize) => errno; | ||
/** | ||
@@ -1219,3 +1266,3 @@ * Close a file descriptor. Note: This is similar to close in POSIX. | ||
*/ | ||
export declare type fd_close = (fd: fd) => errno; | ||
export type fd_close = (fd: fd) => errno; | ||
/** | ||
@@ -1227,3 +1274,3 @@ * Synchronize the data of a file to disk. Note: This is similar to | ||
*/ | ||
export declare type fd_datasync = (fd: fd) => errno; | ||
export type fd_datasync = (fd: fd) => errno; | ||
/** | ||
@@ -1236,3 +1283,3 @@ * Get the attributes of a file descriptor. Note: This returns similar | ||
*/ | ||
export declare type fd_fdstat_get = (fd: fd, fdstat_ptr: ptr) => errno; | ||
export type fd_fdstat_get = (fd: fd, fdstat_ptr: ptr<fdstat>) => errno; | ||
/** | ||
@@ -1245,3 +1292,3 @@ * Adjust the flags associated with a file descriptor. Note: This is similar | ||
*/ | ||
export declare type fd_fdstat_set_flags = (fd: fd, fdflags: fdflags) => errno; | ||
export type fd_fdstat_set_flags = (fd: fd, fdflags: fdflags) => errno; | ||
/** | ||
@@ -1253,3 +1300,3 @@ * Return the attributes of an open file. | ||
*/ | ||
export declare type fd_filestat_get = (fd: fd, filestat_ptr: ptr) => errno; | ||
export type fd_filestat_get = (fd: fd, filestat_ptr: ptr<filestat>) => errno; | ||
/** | ||
@@ -1263,3 +1310,3 @@ * Adjust the size of an open file. If this increases the file's size, the | ||
*/ | ||
export declare type fd_filestat_set_size = (fd: fd, size: filesize) => errno; | ||
export type fd_filestat_set_size = (fd: fd, size: filesize) => errno; | ||
/** | ||
@@ -1274,3 +1321,3 @@ * Adjust the timestamps of an open file or directory. Note: This is similar | ||
*/ | ||
export declare type fd_filestat_set_times = (fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) => errno; | ||
export type fd_filestat_set_times = (fd: fd, atim: timestamp, mtim: timestamp, fst_flags: fstflags) => errno; | ||
/** | ||
@@ -1286,3 +1333,3 @@ * Read from a file descriptor, without using and updating the file | ||
*/ | ||
export declare type fd_pread = (fd: fd, iovs_ptr: ptr, iovs_len: u32, offset: filesize, bytesRead_ptr: ptr) => errno; | ||
export type fd_pread = (fd: fd, iovs_ptr: ptr<iovec>, iovs_len: u32, offset: filesize, bytesRead_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1294,3 +1341,3 @@ * Return a description of the given preopened file descriptor. | ||
*/ | ||
export declare type fd_prestat_get = (fd: fd, bufPtr: ptr) => errno; | ||
export type fd_prestat_get = (fd: fd, bufPtr: ptr<prestat>) => errno; | ||
/** | ||
@@ -1303,3 +1350,3 @@ * Return a description of the given preopened file descriptor. | ||
*/ | ||
export declare type fd_prestat_dir_name = (fd: fd, pathPtr: ptr, pathLen: size) => errno; | ||
export type fd_prestat_dir_name = (fd: fd, pathPtr: ptr<u8[]>, pathLen: size) => errno; | ||
/** | ||
@@ -1315,3 +1362,3 @@ * Write to a file descriptor, without using and updating the file | ||
*/ | ||
export declare type fd_pwrite = (fd: fd, ciovs_ptr: ptr, ciovs_len: u32, offset: filesize, bytesWritten_ptr: ptr) => errno; | ||
export type fd_pwrite = (fd: fd, ciovs_ptr: ptr<ciovec>, ciovs_len: u32, offset: filesize, bytesWritten_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1325,3 +1372,3 @@ * Read from a file descriptor. Note: This is similar to readv in POSIX. | ||
*/ | ||
export declare type fd_read = (fd: fd, iovs_ptr: ptr, iovs_len: u32, bytesRead_ptr: ptr) => errno; | ||
export type fd_read = (fd: fd, iovs_ptr: ptr<iovec>, iovs_len: u32, bytesRead_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1345,3 +1392,3 @@ * Read directory entries from a directory. When successful, the contents of | ||
*/ | ||
export declare type fd_readdir = (fd: fd, buf_ptr: ptr, buf_len: size, cookie: dircookie, buf_used_ptr: ptr) => errno; | ||
export type fd_readdir = (fd: fd, buf_ptr: ptr<dirent>, buf_len: size, cookie: dircookie, buf_used_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1356,3 +1403,3 @@ * Move the offset of a file descriptor. Note: This is similar to lseek in | ||
*/ | ||
export declare type fd_seek = (fd: fd, offset: filedelta, whence: whence, new_offset_ptr: ptr) => errno; | ||
export type fd_seek = (fd: fd, offset: filedelta, whence: whence, new_offset_ptr: ptr<u64>) => errno; | ||
/** | ||
@@ -1364,3 +1411,3 @@ * Synchronize the data and metadata of a file to disk. Note: This is | ||
*/ | ||
export declare type fd_sync = (fd: fd) => errno; | ||
export type fd_sync = (fd: fd) => errno; | ||
/** | ||
@@ -1374,3 +1421,3 @@ * Return the current offset of a file descriptor. Note: This is similar | ||
*/ | ||
export declare type fd_tell = (fd: fd, offset_ptr: ptr) => errno; | ||
export type fd_tell = (fd: fd, offset_ptr: ptr<u64>) => errno; | ||
/** | ||
@@ -1384,3 +1431,3 @@ * Write to a file descriptor. Note: This is similar to writev in POSIX. | ||
*/ | ||
export declare type fd_write = (fd: fd, ciovs_ptr: ptr, ciovs_len: u32, bytesWritten_ptr: ptr) => errno; | ||
export type fd_write = (fd: fd, ciovs_ptr: ptr<ciovec>, ciovs_len: u32, bytesWritten_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1393,3 +1440,3 @@ * Create a directory. Note: This is similar to mkdirat in POSIX. | ||
*/ | ||
export declare type path_create_directory = (fd: fd, path_ptr: ptr, path_len: size) => errno; | ||
export type path_create_directory = (fd: fd, path_ptr: ptr<u8[]>, path_len: size) => errno; | ||
/** | ||
@@ -1405,3 +1452,3 @@ * Return the attributes of a file or directory. Note: This is similar to | ||
*/ | ||
export declare type path_filestat_get = (fd: fd, flags: lookupflags, path_ptr: ptr, path_len: size, filestat_ptr: ptr) => errno; | ||
export type path_filestat_get = (fd: fd, flags: lookupflags, path_ptr: ptr<u8[]>, path_len: size, filestat_ptr: ptr) => errno; | ||
/** | ||
@@ -1419,3 +1466,3 @@ * Adjust the timestamps of a file or directory. Note: This is similar to | ||
*/ | ||
export declare type path_filestat_set_times = (fd: fd, flags: lookupflags, path_ptr: ptr, path_len: size, atim: timestamp, mtim: timestamp, fst_flags: fstflags) => errno; | ||
export type path_filestat_set_times = (fd: fd, flags: lookupflags, path_ptr: ptr<u8[]>, path_len: size, atim: timestamp, mtim: timestamp, fst_flags: fstflags) => errno; | ||
/** | ||
@@ -1435,3 +1482,3 @@ * Create a hard link. Note: This is similar to linkat in POSIX. | ||
*/ | ||
export declare type path_link = (old_fd: fd, old_flags: lookupflags, old_path_ptr: ptr, old_path_len: size, new_fd: fd, new_path_ptr: ptr, new_path_len: size) => errno; | ||
export type path_link = (old_fd: fd, old_flags: lookupflags, old_path_ptr: ptr<u8[]>, old_path_len: size, new_fd: fd, new_path_ptr: ptr<u8[]>, new_path_len: size) => errno; | ||
/** | ||
@@ -1462,3 +1509,3 @@ * Open a file or directory. The returned file descriptor is not guaranteed | ||
*/ | ||
export declare type path_open = (fd: fd, dirflags: lookupflags, path: ptr, pathLen: size, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, fd_ptr: ptr) => errno; | ||
export type path_open = (fd: fd, dirflags: lookupflags, path: ptr<u8[]>, pathLen: size, oflags: oflags, fs_rights_base: rights, fs_rights_inheriting: rights, fdflags: fdflags, fd_ptr: ptr<fd>) => errno; | ||
/** | ||
@@ -1476,3 +1523,3 @@ * Read the contents of a symbolic link. Note: This is similar to readlinkat | ||
*/ | ||
export declare type path_readlink = (fd: fd, path_ptr: ptr, path_len: size, buf: ptr, buf_len: size, result_size_ptr: ptr) => errno; | ||
export type path_readlink = (fd: fd, path_ptr: ptr<u8[]>, path_len: size, buf: ptr<u8[]>, buf_len: size, result_size_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1486,3 +1533,3 @@ * Remove a directory. Return errno::notempty if the directory is not empty. | ||
*/ | ||
export declare type path_remove_directory = (fd: fd, path_ptr: ptr, path_len: size) => errno; | ||
export type path_remove_directory = (fd: fd, path_ptr: ptr<u8[]>, path_len: size) => errno; | ||
/** | ||
@@ -1501,3 +1548,3 @@ * Rename a file or directory. Note: This is similar to renameat in POSIX. | ||
*/ | ||
export declare type path_rename = (fd: fd, old_path_ptr: ptr, old_path_len: size, new_fd: fd, new_path_ptr: ptr, new_path_len: size) => errno; | ||
export type path_rename = (fd: fd, old_path_ptr: ptr<u8[]>, old_path_len: size, new_fd: fd, new_path_ptr: ptr<u8[]>, new_path_len: size) => errno; | ||
/** | ||
@@ -1514,3 +1561,3 @@ * Create a symbolic link. Note: This is similar to symlinkat in POSIX. | ||
*/ | ||
export declare type path_symlink = (old_path_ptr: ptr, old_path_len: size, fd: fd, new_path_ptr: ptr, new_path_len: size) => errno; | ||
export type path_symlink = (old_path_ptr: ptr<u8[]>, old_path_len: size, fd: fd, new_path_ptr: ptr<u8[]>, new_path_len: size) => errno; | ||
/** | ||
@@ -1524,3 +1571,3 @@ * Unlink a file. Return errno::isdir if the path refers to a directory. | ||
*/ | ||
export declare type path_unlink_file = (fd: fd, path_ptr: ptr, path_len: size) => errno; | ||
export type path_unlink_file = (fd: fd, path_ptr: ptr<u8[]>, path_len: size) => errno; | ||
/** | ||
@@ -1534,3 +1581,3 @@ * Concurrently poll for the occurrence of a set of events. | ||
*/ | ||
export declare type poll_oneoff = (input: ptr, output: ptr, subscriptions: size, result_size_ptr: ptr) => errno; | ||
export type poll_oneoff = (input: ptr<subscription[]>, output: ptr<event[]>, subscriptions: size, result_size_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1543,3 +1590,3 @@ * Terminate the process normally. An exit code of 0 indicates successful | ||
*/ | ||
export declare type proc_exit = (rval: exitcode) => void; | ||
export type proc_exit = (rval: exitcode) => void; | ||
/** | ||
@@ -1549,3 +1596,3 @@ * Temporarily yield execution of the calling thread. Note: This is similar | ||
*/ | ||
export declare type sched_yield = () => errno; | ||
export type sched_yield = () => errno; | ||
/** | ||
@@ -1562,3 +1609,3 @@ * Write high-quality random data into a buffer. This function blocks when | ||
*/ | ||
export declare type random_get = (buf: ptr, buf_len: size) => errno; | ||
export type random_get = (buf: ptr<u8[]>, buf_len: size) => errno; | ||
/** | ||
@@ -1572,3 +1619,3 @@ * Accept a new incoming connection. Note: This is similar to accept in | ||
*/ | ||
export declare type sock_accept = (fd: fd, flags: fdflags, result_fd_ptr: ptr) => errno; | ||
export type sock_accept = (fd: fd, flags: fdflags, result_fd_ptr: ptr<u32>) => errno; | ||
/** | ||
@@ -1587,3 +1634,3 @@ * Receive a message from a socket. Note: This is similar to recv in POSIX, | ||
*/ | ||
export declare type sock_recv = (fd: fd, ri_data_ptr: ptr, ri_data_len: u32, ri_flags: riflags, ro_datalen_ptr: ptr, roflags_ptr: ptr) => errno; | ||
export type sock_recv = (fd: fd, ri_data_ptr: ptr, ri_data_len: u32, ri_flags: riflags, ro_datalen_ptr: ptr, roflags_ptr: ptr) => errno; | ||
/** | ||
@@ -1601,3 +1648,3 @@ * Send a message on a socket. Note: This is similar to send in POSIX, | ||
*/ | ||
export declare type sock_send = (fd: fd, si_data_ptr: ptr, si_data_len: u32, si_flags: siflags, si_datalen_ptr: ptr) => errno; | ||
export type sock_send = (fd: fd, si_data_ptr: ptr, si_data_len: u32, si_flags: siflags, si_datalen_ptr: ptr) => errno; | ||
/** | ||
@@ -1610,2 +1657,2 @@ * Shut down socket send and receive channels. Note: This is similar to shutdown | ||
*/ | ||
export declare type sock_shutdown = (fd: fd, sdflags: sdflags) => errno; | ||
export type sock_shutdown = (fd: fd, sdflags: sdflags) => errno; |
@@ -467,71 +467,63 @@ "use strict"; | ||
/** | ||
* All rights | ||
* Check if the given rights contain the requested rights. | ||
* @param rights The granted rights. | ||
* @param check The rights to check. | ||
* @returns true if the granted rights contain the rights to check. | ||
*/ | ||
Rights.All = Rights.fd_advise | Rights.fd_allocate | Rights.fd_datasync | Rights.fd_fdstat_set_flags | | ||
Rights.fd_filestat_get | Rights.fd_filestat_set_size | Rights.fd_filestat_set_times | Rights.fd_read | | ||
Rights.fd_readdir | Rights.fd_seek | Rights.fd_sync | Rights.fd_tell | Rights.fd_write | Rights.path_create_directory | | ||
Rights.path_create_file | Rights.path_filestat_get | Rights.path_filestat_set_size | Rights.path_filestat_set_times | | ||
Rights.path_link_source | Rights.path_link_target | Rights.path_open | Rights.path_readlink | Rights.path_remove_directory | | ||
Rights.path_rename_source | Rights.path_rename_target | Rights.path_symlink | Rights.path_unlink_file | Rights.poll_fd_readwrite | | ||
Rights.sock_accept | Rights.sock_shutdown; | ||
function contains(rights, check) { | ||
return (rights & check) === check; | ||
} | ||
Rights.contains = contains; | ||
/** | ||
* Base rights for block devices. | ||
* | ||
* Note: we don't have block devices in VS Code. | ||
* Check if the given rights support the requested flags | ||
* @param rights The granted rights. | ||
* @param fdflags The requested flags. | ||
* @returns true if the granted rights support the given flags | ||
*/ | ||
Rights.BlockDeviceBase = 0n; | ||
function supportFdflags(rights, fdflags) { | ||
if (fdflags === Fdflags.none) { | ||
return true; | ||
} | ||
if (Fdflags.dsyncOn(fdflags)) { | ||
return contains(rights, Rights.fd_datasync | Rights.fd_sync); | ||
} | ||
if (Fdflags.rsyncOn(fdflags)) { | ||
return contains(rights, Rights.fd_sync); | ||
} | ||
return true; | ||
} | ||
Rights.supportFdflags = supportFdflags; | ||
/** | ||
* Inheriting rights for block devices. | ||
* | ||
* Note: we don't have block devices in VS Code. | ||
* Check if the given rights support the requested flags | ||
* @param rights The granted rights. | ||
* @param fdflags The requested flags. | ||
* @returns true if the granted rights support the given flags | ||
*/ | ||
Rights.BlockDeviceInheriting = 0n; | ||
function supportOflags(rights, oflags) { | ||
if (oflags === Oflags.none) { | ||
return true; | ||
} | ||
if (Oflags.creatOn(oflags)) { | ||
return contains(rights, Rights.path_create_file); | ||
} | ||
if (Oflags.truncOn(oflags)) { | ||
return contains(rights, Rights.path_filestat_set_size); | ||
} | ||
return true; | ||
} | ||
Rights.supportOflags = supportOflags; | ||
/** | ||
* Base rights for directories managed in VS Code. | ||
* No rights | ||
*/ | ||
Rights.DirectoryBase = Rights.path_create_directory | Rights.path_create_file | | ||
Rights.path_filestat_get | Rights.path_filestat_set_size | Rights.path_filestat_set_times | | ||
Rights.path_link_source | Rights.path_link_target | Rights.path_open | Rights.path_readlink | | ||
Rights.path_remove_directory | Rights.path_rename_source | Rights.path_rename_target | | ||
Rights.path_symlink | Rights.path_unlink_file | Rights.fd_readdir; | ||
Rights.None = 0n; | ||
/** | ||
* Base rights for files managed in VS Code. | ||
* All rights | ||
*/ | ||
Rights.FileBase = Rights.fd_read | Rights.fd_seek | Rights.fd_write | Rights.fd_filestat_get | | ||
Rights.fd_advise | Rights.fd_allocate | Rights.fd_datasync | Rights.fd_fdstat_set_flags | | ||
Rights.fd_filestat_set_size | Rights.fd_filestat_set_times | Rights.fd_sync | Rights.fd_tell; | ||
/** | ||
* Inheriting rights for directories | ||
*/ | ||
Rights.DirectoryInheriting = Rights.DirectoryBase | Rights.FileBase; | ||
/** | ||
* Inheriting rights for files | ||
*/ | ||
Rights.FileInheriting = 0n; | ||
/** | ||
* Base rights for character devices | ||
*/ | ||
Rights.CharacterDeviceBase = Rights.fd_read | Rights.fd_fdstat_set_flags | Rights.fd_write | | ||
Rights.fd_filestat_get | Rights.poll_fd_readwrite; | ||
/** | ||
* Inheriting rights for character devices | ||
*/ | ||
Rights.CharacterDeviceInheriting = 0n; | ||
/** | ||
* Base rights for stdin | ||
*/ | ||
Rights.StdinBase = Rights.fd_read | Rights.fd_filestat_get | Rights.poll_fd_readwrite; | ||
/** | ||
* Inheriting rights for stdout / stderr | ||
*/ | ||
Rights.StdinInheriting = 0n; | ||
/** | ||
* Base rights for stdout / stderr | ||
*/ | ||
Rights.StdoutBase = Rights.fd_fdstat_set_flags | Rights.fd_write | | ||
Rights.fd_filestat_get | Rights.poll_fd_readwrite; | ||
/** | ||
* Inheriting rights for stdout / stderr | ||
*/ | ||
Rights.StdoutInheriting = 0n; | ||
Rights.All = Rights.fd_datasync | Rights.fd_read | Rights.fd_seek | Rights.fd_fdstat_set_flags | | ||
Rights.fd_sync | Rights.fd_tell | Rights.fd_write | Rights.fd_advise | Rights.fd_allocate | Rights.path_create_directory | | ||
Rights.path_create_file | Rights.path_link_source | Rights.path_link_target | Rights.path_open | Rights.fd_readdir | | ||
Rights.path_readlink | Rights.path_rename_source | Rights.path_rename_target | Rights.path_filestat_get | | ||
Rights.path_filestat_set_size | Rights.path_filestat_set_times | Rights.fd_filestat_get | | ||
Rights.fd_filestat_set_size | Rights.fd_filestat_set_times | Rights.path_symlink | Rights.path_remove_directory | | ||
Rights.path_unlink_file | Rights.poll_fd_readwrite | Rights.sock_shutdown | Rights.sock_accept; | ||
})(Rights = exports.Rights || (exports.Rights = {})); | ||
@@ -541,2 +533,6 @@ var Fdflags; | ||
/** | ||
* No flags. | ||
*/ | ||
Fdflags.none = 0; | ||
/** | ||
* Append mode: Data written to the file is always appended to the file's | ||
@@ -546,2 +542,6 @@ * end. | ||
Fdflags.append = 1 << 0; | ||
function appendOn(value) { | ||
return (value & Fdflags.append) !== 0; | ||
} | ||
Fdflags.appendOn = appendOn; | ||
/** | ||
@@ -552,2 +552,6 @@ * Write according to synchronized I/O data integrity completion. Only the | ||
Fdflags.dsync = 1 << 1; | ||
function dsyncOn(value) { | ||
return (value & Fdflags.dsync) !== 0; | ||
} | ||
Fdflags.dsyncOn = dsyncOn; | ||
/** | ||
@@ -557,2 +561,6 @@ * Non-blocking mode. | ||
Fdflags.nonblock = 1 << 2; | ||
function nonblockOn(value) { | ||
return (value & Fdflags.nonblock) !== 0; | ||
} | ||
Fdflags.nonblockOn = nonblockOn; | ||
/** | ||
@@ -562,2 +570,6 @@ * Synchronized read I/O operations. | ||
Fdflags.rsync = 1 << 3; | ||
function rsyncOn(value) { | ||
return (value & Fdflags.rsync) !== 0; | ||
} | ||
Fdflags.rsyncOn = rsyncOn; | ||
/** | ||
@@ -569,2 +581,6 @@ * Write according to synchronized I/O file integrity completion. In | ||
Fdflags.sync = 1 << 4; | ||
function syncOn(value) { | ||
return (value & Fdflags.sync) !== 0; | ||
} | ||
Fdflags.syncOn = syncOn; | ||
})(Fdflags = exports.Fdflags || (exports.Fdflags = {})); | ||
@@ -574,2 +590,6 @@ var Lookupflags; | ||
/** | ||
* No flags. | ||
*/ | ||
Lookupflags.none = 0; | ||
/** | ||
* As long as the resolved path corresponds to a symbolic link, it is | ||
@@ -583,17 +603,9 @@ * expanded. | ||
/** | ||
* No flags. | ||
*/ | ||
Oflags.none = 0; | ||
/** | ||
* Create file if it does not exist. | ||
*/ | ||
Oflags.creat = 1 << 0; | ||
/** | ||
* Fail if not a directory. | ||
*/ | ||
Oflags.directory = 1 << 1; | ||
/** | ||
* Fail if file already exists. | ||
*/ | ||
Oflags.excl = 1 << 2; | ||
/** | ||
* Truncate file to size 0. | ||
*/ | ||
Oflags.trunc = 1 << 3; | ||
function creatOn(value) { | ||
@@ -607,2 +619,6 @@ return (value & Oflags.creat) !== 0; | ||
Oflags.creatOff = creatOff; | ||
/** | ||
* Fail if not a directory. | ||
*/ | ||
Oflags.directory = 1 << 1; | ||
function directoryOn(value) { | ||
@@ -612,2 +628,6 @@ return (value & Oflags.directory) !== 0; | ||
Oflags.directoryOn = directoryOn; | ||
/** | ||
* Fail if file already exists. | ||
*/ | ||
Oflags.excl = 1 << 2; | ||
function exclOn(value) { | ||
@@ -617,2 +637,6 @@ return (value & Oflags.excl) !== 0; | ||
Oflags.exclOn = exclOn; | ||
/** | ||
* Truncate file to size 0. | ||
*/ | ||
Oflags.trunc = 1 << 3; | ||
function truncOn(value) { | ||
@@ -718,3 +742,3 @@ return (value & Oflags.trunc) !== 0; | ||
/** | ||
* The application expects to access the specified data once and then not | ||
* The application expects to access the specified data once and then not | ||
* reuse it thereafter. | ||
@@ -742,9 +766,18 @@ */ | ||
return { | ||
get $ptr() { return ptr; }, | ||
get dev() { return memory.getBigUint64(ptr + offsets.dev, true); }, | ||
set dev(value) { memory.setBigUint64(ptr + offsets.dev, value, true); }, | ||
get ino() { return memory.getBigUint64(ptr + offsets.ino, true); }, | ||
set ino(value) { memory.setBigUint64(ptr + offsets.ino, value, true); }, | ||
get filetype() { return memory.getUint8(ptr + offsets.filetype); }, | ||
set filetype(value) { memory.setUint8(ptr + offsets.filetype, value); }, | ||
get nlink() { return memory.getBigUint64(ptr + offsets.nlink, true); }, | ||
set nlink(value) { memory.setBigUint64(ptr + offsets.nlink, value, true); }, | ||
get size() { return memory.getBigUint64(ptr + offsets.size, true); }, | ||
set size(value) { memory.setBigUint64(ptr + offsets.size, value, true); }, | ||
get atim() { return memory.getBigUint64(ptr + offsets.atim, true); }, | ||
set atim(value) { memory.setBigUint64(ptr + offsets.atim, value, true); }, | ||
get mtim() { return memory.getBigUint64(ptr + offsets.mtim, true); }, | ||
set mtim(value) { memory.setBigUint64(ptr + offsets.mtim, value, true); }, | ||
get ctim() { return memory.getBigUint64(ptr + offsets.ctim, true); }, | ||
set ctim(value) { memory.setBigUint64(ptr + offsets.ctim, value, true); } | ||
@@ -785,5 +818,10 @@ }; | ||
return { | ||
get $ptr() { return ptr; }, | ||
get fs_filetype() { return memory.getUint8(ptr + offsets.fs_filetype); }, | ||
set fs_filetype(value) { memory.setUint8(ptr + offsets.fs_filetype, value); }, | ||
get fs_flags() { return memory.getUint16(ptr + offsets.fs_flags, true); }, | ||
set fs_flags(value) { memory.setUint16(ptr + offsets.fs_flags, value, true); }, | ||
get fs_rights_base() { return memory.getBigUint64(ptr + offsets.fs_rights_base, true); }, | ||
set fs_rights_base(value) { memory.setBigUint64(ptr + offsets.fs_rights_base, value, true); }, | ||
get fs_rights_inheriting() { return memory.getBigUint64(ptr + offsets.fs_rights_inheriting, true); }, | ||
set fs_rights_inheriting(value) { memory.setBigUint64(ptr + offsets.fs_rights_inheriting, value, true); } | ||
@@ -819,7 +857,23 @@ }; | ||
(function (Prestat) { | ||
/** | ||
* The size in bytes. | ||
*/ | ||
Prestat.size = 8; | ||
Prestat.alignment = 4; | ||
const offsets = { | ||
tag: 0, | ||
len: 4 | ||
}; | ||
function create(ptr, memory) { | ||
memory.setUint8(ptr, Preopentype.dir); | ||
return { | ||
get $ptr() { return ptr; }, | ||
get preopentype() { | ||
return memory.getUint8(ptr + offsets.tag); | ||
}, | ||
get len() { | ||
return memory.getUint32(ptr + offsets.len, true); | ||
}, | ||
set len(value) { | ||
memory.setUint32(ptr + 4, value, true); | ||
memory.setUint32(ptr + offsets.len, value, true); | ||
} | ||
@@ -842,8 +896,7 @@ }; | ||
return { | ||
get buf() { | ||
return memory.getUint32(ptr + offsets.buf, true); | ||
}, | ||
get buf_len() { | ||
return memory.getUint32(ptr + offsets.buf_len, true); | ||
} | ||
get $ptr() { return ptr; }, | ||
get buf() { return memory.getUint32(ptr + offsets.buf, true); }, | ||
set buf(value) { memory.setUint32(ptr + offsets.buf, value, true); }, | ||
get buf_len() { return memory.getUint32(ptr + offsets.buf_len, true); }, | ||
set buf_len(value) { memory.setUint32(ptr + offsets.buf_len, value, true); } | ||
}; | ||
@@ -865,8 +918,7 @@ } | ||
return { | ||
get buf() { | ||
return memory.getUint32(ptr + offsets.buf, true); | ||
}, | ||
get buf_len() { | ||
return memory.getUint32(ptr + offsets.buf_len, true); | ||
} | ||
get $ptr() { return ptr; }, | ||
get buf() { return memory.getUint32(ptr + offsets.buf, true); }, | ||
set buf(value) { memory.setUint32(ptr + offsets.buf, value, true); }, | ||
get buf_len() { return memory.getUint32(ptr + offsets.buf_len, true); }, | ||
set buf_len(value) { memory.setUint32(ptr + offsets.buf_len, value, true); } | ||
}; | ||
@@ -887,5 +939,10 @@ } | ||
return { | ||
get $ptr() { return ptr; }, | ||
get d_next() { return memory.getBigUint64(ptr + offsets.d_next, true); }, | ||
set d_next(value) { memory.setBigUint64(ptr + offsets.d_next, value, true); }, | ||
get d_ino() { return memory.getBigUint64(ptr + offsets.d_ino, true); }, | ||
set d_ino(value) { memory.setBigUint64(ptr + offsets.d_ino, value, true); }, | ||
get d_namlen() { return memory.getUint32(ptr + offsets.d_namlen, true); }, | ||
set d_namlen(value) { memory.setUint32(ptr + offsets.d_namlen, value, true); }, | ||
get d_type() { return memory.getUint8(ptr + offsets.d_type); }, | ||
set d_type(value) { memory.setUint8(ptr + offsets.d_type, value); } | ||
@@ -892,0 +949,0 @@ }; |
@@ -90,2 +90,5 @@ "use strict"; | ||
return path.posix.join(...paths); | ||
}, | ||
normalize(value) { | ||
return path.posix.normalize(value); | ||
} | ||
@@ -92,0 +95,0 @@ }) |
{ | ||
"name": "@vscode/wasm-wasi", | ||
"version": "0.8.2", | ||
"version": "0.9.0", | ||
"description": "A WASI implementation that uses VS Code's extension host as the implementing API", | ||
@@ -29,4 +29,4 @@ "engines": { | ||
"dependencies": { | ||
"vscode-uri": "^3.0.6", | ||
"@vscode/sync-api-client": "0.8.1" | ||
"vscode-uri": "^3.0.7", | ||
"@vscode/sync-api-client": "0.9.0" | ||
}, | ||
@@ -43,4 +43,4 @@ "devDependencies": {}, | ||
"all": "npm run clean && npm run compile && npm run lint", | ||
"all:publish": "git clean -xfd . && npm install && npm run compile:publish && npm run lint" | ||
"all:publish": "git clean -xfd . && npm install && npm run compile:publish && npm run lint && cd ../wasm-wasi-tests && npm run all:publish && cd .." | ||
} | ||
} |
242649
43
6349
+ Added@vscode/sync-api-client@0.9.0(transitive)
+ Added@vscode/sync-api-common@0.9.0(transitive)
- Removed@vscode/sync-api-client@0.8.1(transitive)
- Removed@vscode/sync-api-common@0.8.1(transitive)
Updatedvscode-uri@^3.0.7