@zenfs/core
Version:
A filesystem, anywhere
675 lines (674 loc) • 35.9 kB
JavaScript
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;
}