UNPKG

@zenfs/core

Version:

A filesystem, anywhere

675 lines (674 loc) 35.9 kB
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); var _, done = false; for (var i = decorators.length - 1; i >= 0; i--) { var context = {}; for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; for (var p in contextIn.access) context.access[p] = contextIn.access[p]; context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); if (kind === "accessor") { if (result === void 0) continue; if (result === null || typeof result !== "object") throw new TypeError("Object expected"); if (_ = accept(result.get)) descriptor.get = _; if (_ = accept(result.set)) descriptor.set = _; if (_ = accept(result.init)) initializers.unshift(_); } else if (_ = accept(result)) { if (kind === "field") initializers.unshift(_); else descriptor[key] = _; } } if (target) Object.defineProperty(target, contextIn.name, descriptor); done = true; }; var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { var useValue = arguments.length > 2; for (var i = 0; i < initializers.length; i++) { value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } return useValue ? value : void 0; }; // SPDX-License-Identifier: LGPL-3.0-or-later import { withErrno } from 'kerium'; import { crit, warn } from 'kerium/log'; import { sizeof } from 'memium'; import { $from, field, struct, types as t } from 'memium/decorators'; import { decodeUTF8, encodeUTF8, pick } from 'utilium'; import { BufferView } from 'utilium/buffer'; import * as c from '../constants.js'; import { Stats } from '../node/stats.js'; import { contextOf } from './contexts.js'; /** * Root inode * @hidden */ export const rootIno = 0; /** 4 KiB minus static inode data */ const maxDynamicData = 3968; let Attribute = (() => { var _a, _b; let _classDecorators = [struct.packed()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = $from.typed(Uint8Array); let _keySize_decorators; let _keySize_initializers = []; let _keySize_extraInitializers = []; let _valueSize_decorators; let _valueSize_initializers = []; let _valueSize_extraInitializers = []; var Attribute = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _keySize_decorators = [(_a = t).uint32.bind(_a)]; _valueSize_decorators = [(_b = t).uint32.bind(_b)]; __esDecorate(this, null, _keySize_decorators, { kind: "accessor", name: "keySize", static: false, private: false, access: { has: obj => "keySize" in obj, get: obj => obj.keySize, set: (obj, value) => { obj.keySize = value; } }, metadata: _metadata }, _keySize_initializers, _keySize_extraInitializers); __esDecorate(this, null, _valueSize_decorators, { kind: "accessor", name: "valueSize", static: false, private: false, access: { has: obj => "valueSize" in obj, get: obj => obj.valueSize, set: (obj, value) => { obj.valueSize = value; } }, metadata: _metadata }, _valueSize_initializers, _valueSize_extraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); Attribute = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); } static name = 'Attribute'; #keySize_accessor_storage = __runInitializers(this, _keySize_initializers, void 0); get keySize() { return this.#keySize_accessor_storage; } set keySize(value) { this.#keySize_accessor_storage = value; } #valueSize_accessor_storage = (__runInitializers(this, _keySize_extraInitializers), __runInitializers(this, _valueSize_initializers, void 0)); get valueSize() { return this.#valueSize_accessor_storage; } set valueSize(value) { this.#valueSize_accessor_storage = value; } get name() { return decodeUTF8(this.subarray(8, 8 + this.keySize)); } /** * Note that this does not handle moving the data. * Changing the name after setting the value is undefined behavior and will lead to corruption. * This should only be used when creating a new attribute. */ set name(value) { const buf = encodeUTF8(value); if (8 + buf.length + this.valueSize > maxDynamicData) throw withErrno('EOVERFLOW'); this.set(buf, 8); this.keySize = buf.length; } get value() { return this.subarray(8 + this.keySize, this.size); } set value(value) { if (8 + this.keySize + value.length > maxDynamicData) throw withErrno('EOVERFLOW'); this.valueSize = value.length; this.set(value, 8 + this.keySize); } get size() { return 8 + this.keySize + this.valueSize; } constructor() { super(...arguments); __runInitializers(this, _valueSize_extraInitializers); } static { __runInitializers(_classThis, _classExtraInitializers); } }; return Attribute = _classThis; })(); /** * Extended attributes * @category Internals * @internal */ let Attributes = (() => { var _a; let _classDecorators = [struct.packed()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = $from(BufferView); let _size_decorators; let _size_initializers = []; let _size_extraInitializers = []; var Attributes = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _size_decorators = [(_a = t).uint32.bind(_a)]; __esDecorate(this, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); Attributes = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); } static name = 'Attributes'; #size_accessor_storage = __runInitializers(this, _size_initializers, void 0); get size() { return this.#size_accessor_storage; } set size(value) { this.#size_accessor_storage = value; } get byteSize() { let offset = this.byteOffset + sizeof(this); for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); offset += entry.size; } return offset; } has(name) { let offset = this.byteOffset + sizeof(this); for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); if (entry.name == name) return true; offset += entry.size; } return false; } get(name) { let offset = this.byteOffset + sizeof(this); for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); if (entry.name == name) return entry.value; offset += entry.size; } } set(name, value) { let offset = this.byteOffset + sizeof(this); let remove; for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); if (entry.name == name) remove = [offset, entry.size]; offset += entry.size; } const buf = new Uint8Array(this.buffer); if (remove) { const [start, size] = remove; offset -= size; buf.copyWithin(start, start + size, offset + size); buf.fill(0, offset, offset + size); this.size--; } const attr = new Attribute(this.buffer, offset); attr.name = name; attr.value = value; this.size++; } remove(name) { let offset = this.byteOffset + sizeof(this); let remove; for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); if (entry.name == name) remove = [offset, entry.size]; offset += entry.size; } if (!remove) return false; const [start, size] = remove; const buf = new Uint8Array(this.buffer); buf.copyWithin(start, start + size, offset); buf.fill(0, offset - size, offset); this.size--; return true; } copyFrom(other) { const { byteSize } = other; new Uint8Array(this.buffer, this.byteOffset, byteSize).set(new Uint8Array(other.buffer, other.byteOffset, byteSize)); } *keys() { let offset = this.byteOffset + sizeof(this); for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); yield entry.name; offset += entry.size; } } *values() { let offset = this.byteOffset + sizeof(this); for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); yield entry.value; offset += entry.size; } } *entries() { let offset = this.byteOffset + sizeof(this); for (let i = 0; i < this.size; i++) { const entry = new Attribute(this.buffer, offset); yield [entry.name, entry.value]; offset += entry.size; } } constructor() { super(...arguments); __runInitializers(this, _size_extraInitializers); } static { __runInitializers(_classThis, _classExtraInitializers); } }; return Attributes = _classThis; })(); export { Attributes }; /** * @internal @hidden */ export const _inode_fields = [ 'ino', 'data', 'size', 'mode', 'flags', 'nlink', 'uid', 'gid', 'atimeMs', 'birthtimeMs', 'mtimeMs', 'ctimeMs', 'version', ]; /** * Represents which version of the `Inode` format we are on. * 1. 58 bytes. The first member was called `ino` but used as the ID for data. * 2. 66 bytes. Renamed the first member from `ino` to `data` and added a separate `ino` field * 3. 72 bytes. Changed the ID fields from 64 to 32 bits and added `flags`. * 4. >= 128 bytes. Added extended attributes. * 5. (current) 4 KiB. Changed flags * @internal @hidden */ export const _inode_version = 5; /** * Inode flags * @see `S_*` in `include/linux/fs.h` (around L2325) * @experimental */ export var InodeFlags; (function (InodeFlags) { /** Writes are synced at once */ InodeFlags[InodeFlags["Sync"] = 1] = "Sync"; /** Do not update access times */ InodeFlags[InodeFlags["NoAtime"] = 2] = "NoAtime"; /** Append-only file */ InodeFlags[InodeFlags["Append"] = 4] = "Append"; /** Immutable file */ InodeFlags[InodeFlags["Immutable"] = 8] = "Immutable"; /** removed, but still open directory */ InodeFlags[InodeFlags["Dead"] = 16] = "Dead"; /** Inode is not counted to quota */ InodeFlags[InodeFlags["NoQuota"] = 32] = "NoQuota"; /** Directory modifications are synchronous */ InodeFlags[InodeFlags["Dirsync"] = 64] = "Dirsync"; /** Do not update file c/mtime */ InodeFlags[InodeFlags["NoCMtime"] = 128] = "NoCMtime"; /** Do not truncate: swapon got its bmaps */ InodeFlags[InodeFlags["SwapFile"] = 256] = "SwapFile"; /** Inode is fs-internal */ InodeFlags[InodeFlags["Private"] = 512] = "Private"; /** Inode has an associated IMA struct */ InodeFlags[InodeFlags["IMA"] = 1024] = "IMA"; /** Automount/referral quasi-directory */ InodeFlags[InodeFlags["AutoMount"] = 2048] = "AutoMount"; /** no suid or xattr security attributes */ InodeFlags[InodeFlags["NoSec"] = 4096] = "NoSec"; /** Direct Access, avoiding the page cache */ InodeFlags[InodeFlags["DAX"] = 8192] = "DAX"; /** Encrypted file (using fs/crypto/) */ InodeFlags[InodeFlags["Encrypted"] = 16384] = "Encrypted"; /** Casefolded file */ InodeFlags[InodeFlags["CaseFold"] = 32768] = "CaseFold"; /** Verity file (using fs/verity/) */ InodeFlags[InodeFlags["Verity"] = 65536] = "Verity"; /** File is in use by the kernel (eg. fs/cachefiles) */ InodeFlags[InodeFlags["KernelFile"] = 131072] = "KernelFile"; })(InodeFlags || (InodeFlags = {})); /** User visible flags */ export const userVisibleFlags = 0x0003dfff; /** User modifiable flags */ export const userModifiableFlags = 0x000380ff; /** * Generic inode definition that can easily be serialized. * @category Internals * @internal */ let Inode = (() => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r; let _classDecorators = [struct.packed()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _classSuper = $from(BufferView); let _data_decorators; let _data_initializers = []; let _data_extraInitializers = []; let ___data_old_decorators; let ___data_old_initializers = []; let ___data_old_extraInitializers = []; let _size_decorators; let _size_initializers = []; let _size_extraInitializers = []; let _mode_decorators; let _mode_initializers = []; let _mode_extraInitializers = []; let _nlink_decorators; let _nlink_initializers = []; let _nlink_extraInitializers = []; let _uid_decorators; let _uid_initializers = []; let _uid_extraInitializers = []; let _gid_decorators; let _gid_initializers = []; let _gid_extraInitializers = []; let _atimeMs_decorators; let _atimeMs_initializers = []; let _atimeMs_extraInitializers = []; let _birthtimeMs_decorators; let _birthtimeMs_initializers = []; let _birthtimeMs_extraInitializers = []; let _mtimeMs_decorators; let _mtimeMs_initializers = []; let _mtimeMs_extraInitializers = []; let _ctimeMs_decorators; let _ctimeMs_initializers = []; let _ctimeMs_extraInitializers = []; let _ino_decorators; let _ino_initializers = []; let _ino_extraInitializers = []; let ___ino_old_decorators; let ___ino_old_initializers = []; let ___ino_old_extraInitializers = []; let _flags_decorators; let _flags_initializers = []; let _flags_extraInitializers = []; let ___after_flags_decorators; let ___after_flags_initializers = []; let ___after_flags_extraInitializers = []; let _version_decorators; let _version_initializers = []; let _version_extraInitializers = []; let ___padding_decorators; let ___padding_initializers = []; let ___padding_extraInitializers = []; let _attributes_decorators; let _attributes_initializers = []; let _attributes_extraInitializers = []; let ___data_decorators; let ___data_initializers = []; let ___data_extraInitializers = []; var Inode = class extends _classSuper { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _data_decorators = [(_a = t).uint32.bind(_a)]; ___data_old_decorators = [(_b = t).uint32.bind(_b)]; _size_decorators = [(_c = t).uint32.bind(_c)]; _mode_decorators = [(_d = t).uint16.bind(_d)]; _nlink_decorators = [(_e = t).uint32.bind(_e)]; _uid_decorators = [(_f = t).uint32.bind(_f)]; _gid_decorators = [(_g = t).uint32.bind(_g)]; _atimeMs_decorators = [(_h = t).float64.bind(_h)]; _birthtimeMs_decorators = [(_j = t).float64.bind(_j)]; _mtimeMs_decorators = [(_k = t).float64.bind(_k)]; _ctimeMs_decorators = [(_l = t).float64.bind(_l)]; _ino_decorators = [(_m = t).uint32.bind(_m)]; ___ino_old_decorators = [(_o = t).uint32.bind(_o)]; _flags_decorators = [(_p = t).uint32.bind(_p)]; ___after_flags_decorators = [(_q = t).uint16.bind(_q)]; _version_decorators = [(_r = t).uint32.bind(_r)]; ___padding_decorators = [t.uint8(48)]; _attributes_decorators = [field(Attributes)]; ___data_decorators = [t.uint8(maxDynamicData)]; __esDecorate(this, null, _data_decorators, { kind: "accessor", name: "data", static: false, private: false, access: { has: obj => "data" in obj, get: obj => obj.data, set: (obj, value) => { obj.data = value; } }, metadata: _metadata }, _data_initializers, _data_extraInitializers); __esDecorate(this, null, ___data_old_decorators, { kind: "accessor", name: "__data_old", static: false, private: false, access: { has: obj => "__data_old" in obj, get: obj => obj.__data_old, set: (obj, value) => { obj.__data_old = value; } }, metadata: _metadata }, ___data_old_initializers, ___data_old_extraInitializers); __esDecorate(this, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers); __esDecorate(this, null, _mode_decorators, { kind: "accessor", name: "mode", static: false, private: false, access: { has: obj => "mode" in obj, get: obj => obj.mode, set: (obj, value) => { obj.mode = value; } }, metadata: _metadata }, _mode_initializers, _mode_extraInitializers); __esDecorate(this, null, _nlink_decorators, { kind: "accessor", name: "nlink", static: false, private: false, access: { has: obj => "nlink" in obj, get: obj => obj.nlink, set: (obj, value) => { obj.nlink = value; } }, metadata: _metadata }, _nlink_initializers, _nlink_extraInitializers); __esDecorate(this, null, _uid_decorators, { kind: "accessor", name: "uid", static: false, private: false, access: { has: obj => "uid" in obj, get: obj => obj.uid, set: (obj, value) => { obj.uid = value; } }, metadata: _metadata }, _uid_initializers, _uid_extraInitializers); __esDecorate(this, null, _gid_decorators, { kind: "accessor", name: "gid", static: false, private: false, access: { has: obj => "gid" in obj, get: obj => obj.gid, set: (obj, value) => { obj.gid = value; } }, metadata: _metadata }, _gid_initializers, _gid_extraInitializers); __esDecorate(this, null, _atimeMs_decorators, { kind: "accessor", name: "atimeMs", static: false, private: false, access: { has: obj => "atimeMs" in obj, get: obj => obj.atimeMs, set: (obj, value) => { obj.atimeMs = value; } }, metadata: _metadata }, _atimeMs_initializers, _atimeMs_extraInitializers); __esDecorate(this, null, _birthtimeMs_decorators, { kind: "accessor", name: "birthtimeMs", static: false, private: false, access: { has: obj => "birthtimeMs" in obj, get: obj => obj.birthtimeMs, set: (obj, value) => { obj.birthtimeMs = value; } }, metadata: _metadata }, _birthtimeMs_initializers, _birthtimeMs_extraInitializers); __esDecorate(this, null, _mtimeMs_decorators, { kind: "accessor", name: "mtimeMs", static: false, private: false, access: { has: obj => "mtimeMs" in obj, get: obj => obj.mtimeMs, set: (obj, value) => { obj.mtimeMs = value; } }, metadata: _metadata }, _mtimeMs_initializers, _mtimeMs_extraInitializers); __esDecorate(this, null, _ctimeMs_decorators, { kind: "accessor", name: "ctimeMs", static: false, private: false, access: { has: obj => "ctimeMs" in obj, get: obj => obj.ctimeMs, set: (obj, value) => { obj.ctimeMs = value; } }, metadata: _metadata }, _ctimeMs_initializers, _ctimeMs_extraInitializers); __esDecorate(this, null, _ino_decorators, { kind: "accessor", name: "ino", static: false, private: false, access: { has: obj => "ino" in obj, get: obj => obj.ino, set: (obj, value) => { obj.ino = value; } }, metadata: _metadata }, _ino_initializers, _ino_extraInitializers); __esDecorate(this, null, ___ino_old_decorators, { kind: "accessor", name: "__ino_old", static: false, private: false, access: { has: obj => "__ino_old" in obj, get: obj => obj.__ino_old, set: (obj, value) => { obj.__ino_old = value; } }, metadata: _metadata }, ___ino_old_initializers, ___ino_old_extraInitializers); __esDecorate(this, null, _flags_decorators, { kind: "accessor", name: "flags", static: false, private: false, access: { has: obj => "flags" in obj, get: obj => obj.flags, set: (obj, value) => { obj.flags = value; } }, metadata: _metadata }, _flags_initializers, _flags_extraInitializers); __esDecorate(this, null, ___after_flags_decorators, { kind: "accessor", name: "__after_flags", static: false, private: false, access: { has: obj => "__after_flags" in obj, get: obj => obj.__after_flags, set: (obj, value) => { obj.__after_flags = value; } }, metadata: _metadata }, ___after_flags_initializers, ___after_flags_extraInitializers); __esDecorate(this, null, _version_decorators, { kind: "accessor", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers); __esDecorate(this, null, ___padding_decorators, { kind: "accessor", name: "__padding", static: false, private: false, access: { has: obj => "__padding" in obj, get: obj => obj.__padding, set: (obj, value) => { obj.__padding = value; } }, metadata: _metadata }, ___padding_initializers, ___padding_extraInitializers); __esDecorate(this, null, _attributes_decorators, { kind: "accessor", name: "attributes", static: false, private: false, access: { has: obj => "attributes" in obj, get: obj => obj.attributes, set: (obj, value) => { obj.attributes = value; } }, metadata: _metadata }, _attributes_initializers, _attributes_extraInitializers); __esDecorate(this, null, ___data_decorators, { kind: "accessor", name: "__data", static: false, private: false, access: { has: obj => "__data" in obj, get: obj => obj.__data, set: (obj, value) => { obj.__data = value; } }, metadata: _metadata }, ___data_initializers, ___data_extraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); Inode = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); } static name = 'Inode'; constructor(...args) { let data = {}; if (typeof args[0] === 'object' && args[0] !== null && !ArrayBuffer.isView(args[0])) { data = args[0]; args = [sizeof(Inode)]; } super(...args); __runInitializers(this, ___data_extraInitializers); if (this.byteLength < sizeof(Inode)) { throw crit(withErrno('EIO', `Buffer is too small to create an inode (${this.byteLength} bytes)`)); } Object.assign(this, data); this.atimeMs ||= Date.now(); this.mtimeMs ||= Date.now(); this.ctimeMs ||= Date.now(); this.birthtimeMs ||= Date.now(); if (this.ino && !this.nlink) { warn(`Inode ${this.ino} has an nlink of 0`); } } #data_accessor_storage = __runInitializers(this, _data_initializers, void 0); get data() { return this.#data_accessor_storage; } set data(value) { this.#data_accessor_storage = value; } #__data_old_accessor_storage = (__runInitializers(this, _data_extraInitializers), __runInitializers(this, ___data_old_initializers, void 0)); /** For future use */ get __data_old() { return this.#__data_old_accessor_storage; } set __data_old(value) { this.#__data_old_accessor_storage = value; } #size_accessor_storage = (__runInitializers(this, ___data_old_extraInitializers), __runInitializers(this, _size_initializers, void 0)); get size() { return this.#size_accessor_storage; } set size(value) { this.#size_accessor_storage = value; } #mode_accessor_storage = (__runInitializers(this, _size_extraInitializers), __runInitializers(this, _mode_initializers, void 0)); get mode() { return this.#mode_accessor_storage; } set mode(value) { this.#mode_accessor_storage = value; } #nlink_accessor_storage = (__runInitializers(this, _mode_extraInitializers), __runInitializers(this, _nlink_initializers, void 0)); get nlink() { return this.#nlink_accessor_storage; } set nlink(value) { this.#nlink_accessor_storage = value; } #uid_accessor_storage = (__runInitializers(this, _nlink_extraInitializers), __runInitializers(this, _uid_initializers, void 0)); get uid() { return this.#uid_accessor_storage; } set uid(value) { this.#uid_accessor_storage = value; } #gid_accessor_storage = (__runInitializers(this, _uid_extraInitializers), __runInitializers(this, _gid_initializers, void 0)); get gid() { return this.#gid_accessor_storage; } set gid(value) { this.#gid_accessor_storage = value; } #atimeMs_accessor_storage = (__runInitializers(this, _gid_extraInitializers), __runInitializers(this, _atimeMs_initializers, void 0)); get atimeMs() { return this.#atimeMs_accessor_storage; } set atimeMs(value) { this.#atimeMs_accessor_storage = value; } #birthtimeMs_accessor_storage = (__runInitializers(this, _atimeMs_extraInitializers), __runInitializers(this, _birthtimeMs_initializers, void 0)); get birthtimeMs() { return this.#birthtimeMs_accessor_storage; } set birthtimeMs(value) { this.#birthtimeMs_accessor_storage = value; } #mtimeMs_accessor_storage = (__runInitializers(this, _birthtimeMs_extraInitializers), __runInitializers(this, _mtimeMs_initializers, void 0)); get mtimeMs() { return this.#mtimeMs_accessor_storage; } set mtimeMs(value) { this.#mtimeMs_accessor_storage = value; } #ctimeMs_accessor_storage = (__runInitializers(this, _mtimeMs_extraInitializers), __runInitializers(this, _ctimeMs_initializers, void 0)); /** * The time the inode was changed. * * This is automatically updated whenever changed are made using `update()`. */ get ctimeMs() { return this.#ctimeMs_accessor_storage; } set ctimeMs(value) { this.#ctimeMs_accessor_storage = value; } #ino_accessor_storage = (__runInitializers(this, _ctimeMs_extraInitializers), __runInitializers(this, _ino_initializers, void 0)); get ino() { return this.#ino_accessor_storage; } set ino(value) { this.#ino_accessor_storage = value; } #__ino_old_accessor_storage = (__runInitializers(this, _ino_extraInitializers), __runInitializers(this, ___ino_old_initializers, void 0)); /** For future use */ get __ino_old() { return this.#__ino_old_accessor_storage; } set __ino_old(value) { this.#__ino_old_accessor_storage = value; } #flags_accessor_storage = (__runInitializers(this, ___ino_old_extraInitializers), __runInitializers(this, _flags_initializers, void 0)); get flags() { return this.#flags_accessor_storage; } set flags(value) { this.#flags_accessor_storage = value; } #__after_flags_accessor_storage = (__runInitializers(this, _flags_extraInitializers), __runInitializers(this, ___after_flags_initializers, void 0)); /** For future use */ get __after_flags() { return this.#__after_flags_accessor_storage; } set __after_flags(value) { this.#__after_flags_accessor_storage = value; } #version_accessor_storage = (__runInitializers(this, ___after_flags_extraInitializers), __runInitializers(this, _version_initializers, void 0)); /** * The "version" of the inode/data. * Unrelated to the inode format! */ get version() { return this.#version_accessor_storage; } set version(value) { this.#version_accessor_storage = value; } #__padding_accessor_storage = (__runInitializers(this, _version_extraInitializers), __runInitializers(this, ___padding_initializers, void 0)); /** * Padding up to 128 bytes. * This ensures there is enough room for expansion without breaking the ABI. * @internal */ get __padding() { return this.#__padding_accessor_storage; } set __padding(value) { this.#__padding_accessor_storage = value; } #attributes_accessor_storage = (__runInitializers(this, ___padding_extraInitializers), __runInitializers(this, _attributes_initializers, void 0)); get attributes() { return this.#attributes_accessor_storage; } set attributes(value) { this.#attributes_accessor_storage = value; } #__data_accessor_storage = (__runInitializers(this, _attributes_extraInitializers), __runInitializers(this, ___data_initializers, void 0)); /** * Since the attribute data uses dynamic arrays, * it is necessary to add this so attributes can be added. * @internal @hidden */ get __data() { return this.#__data_accessor_storage; } set __data(value) { this.#__data_accessor_storage = value; } toString() { return `<Inode ${this.ino}>`; } toJSON() { return { ...pick(this, _inode_fields), attributes: this.attributes, }; } /** * Handy function that converts the Inode to a Node Stats object. * @deprecated Use `new Stats(inode)` instead. */ toStats() { return new Stats(this); } /** * Updates the Inode using information from the stats object. Used by file * systems at sync time, e.g.: * - Program opens file and gets a File object. * - Program mutates file. File object is responsible for maintaining * metadata changes locally -- typically in a Stats object. * - Program closes file. File object's metadata changes are synced with the * file system. * @returns whether any changes have occurred. */ update(data) { if (!data) return false; let hasChanged = false; for (const key of _inode_fields) { if (data[key] === undefined) continue; // When multiple StoreFSes are used in a single stack, the differing IDs end up here. if (key == 'ino' || key == 'data') continue; if (this[key] === data[key]) continue; if (key == 'atimeMs' && this.flags & InodeFlags.NoAtime) continue; this[key] = data[key]; hasChanged = true; } if (data.attributes) { this.attributes.copyFrom(data.attributes); hasChanged = true; } if (hasChanged) this.ctimeMs = Date.now(); return hasChanged; } static { __runInitializers(_classThis, _classExtraInitializers); } }; return Inode = _classThis; })(); export { Inode }; export function isFile(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFREG; } export function isDirectory(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFDIR; } export function isSymbolicLink(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFLNK; } export function isSocket(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFSOCK; } export function isBlockDevice(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFBLK; } export function isCharacterDevice(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFCHR; } export function isFIFO(metadata) { return (metadata.mode & c.S_IFMT) === c.S_IFIFO; } /** * Checks if a given user/group has access to this item * @param access The requested access, combination of `W_OK`, `R_OK`, and `X_OK` * @internal */ export function hasAccess($, inode, access) { const { credentials } = contextOf($); if (isSymbolicLink(inode) || credentials.euid === 0 || credentials.egid === 0) return true; let perm = 0; if (credentials.uid === inode.uid) { if (inode.mode & c.S_IRUSR) perm |= c.R_OK; if (inode.mode & c.S_IWUSR) perm |= c.W_OK; if (inode.mode & c.S_IXUSR) perm |= c.X_OK; } if (credentials.gid === inode.gid || credentials.groups.includes(Number(inode.gid))) { if (inode.mode & c.S_IRGRP) perm |= c.R_OK; if (inode.mode & c.S_IWGRP) perm |= c.W_OK; if (inode.mode & c.S_IXGRP) perm |= c.X_OK; } if (inode.mode & c.S_IROTH) perm |= c.R_OK; if (inode.mode & c.S_IWOTH) perm |= c.W_OK; if (inode.mode & c.S_IXOTH) perm |= c.X_OK; return (perm & access) === access; } /** * @hidden @internal */ export function _chown(stats, uid, gid) { let valid = true; if (!isNaN(uid) && uid >= 0 && uid < c.size_max) stats.uid = uid; else valid = false; if (!isNaN(gid) && gid >= 0 && gid < c.size_max) stats.gid = gid; else valid = false; return valid; }