@zenfs/core 2.6.6 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/memory.d.ts +1 -1
- package/dist/backends/store/fs.js +4 -4
- package/dist/config.js +7 -7
- package/dist/internal/contexts.d.ts +4 -0
- package/dist/internal/contexts.js +10 -6
- package/dist/internal/filesystem.d.ts +5 -0
- package/dist/internal/filesystem.js +18 -0
- package/dist/internal/inode.d.ts +6 -1
- package/dist/internal/inode.js +15 -4
- package/dist/internal/ioctl.d.ts +148 -0
- package/dist/internal/ioctl.js +368 -0
- package/dist/mixins/async.js +6 -1
- package/dist/mixins/mutexed.d.ts +3 -0
- package/dist/mixins/mutexed.js +29 -1
- package/dist/mixins/shared.d.ts +1 -1
- package/dist/mixins/shared.js +1 -0
- package/dist/mixins/sync.js +3 -0
- package/dist/node/async.js +3 -3
- package/dist/node/promises.js +16 -16
- package/dist/node/sync.js +23 -23
- package/dist/vfs/async.js +10 -10
- package/dist/vfs/file.d.ts +11 -1
- package/dist/vfs/file.js +26 -4
- package/dist/vfs/ioctl.d.ts +8 -85
- package/dist/vfs/ioctl.js +67 -369
- package/dist/vfs/shared.d.ts +2 -0
- package/dist/vfs/shared.js +12 -8
- package/dist/vfs/sync.d.ts +1 -1
- package/dist/vfs/sync.js +19 -19
- package/dist/vfs/watchers.js +1 -1
- package/dist/vfs/xattr.js +8 -8
- package/package.json +10 -1
- package/tests/common/utf8stream.test.ts +1 -1
- package/tests/fs/permissions.test.ts +1 -1
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { Errno, Exception, withErrno } from 'kerium';
|
|
36
|
+
import { sizeof } from 'memium';
|
|
37
|
+
import { $from, struct, types as t } from 'memium/decorators';
|
|
38
|
+
import { _throw } from 'utilium';
|
|
39
|
+
import { BufferView } from 'utilium/buffer';
|
|
40
|
+
import { InodeFlags } from './inode.js';
|
|
41
|
+
/*
|
|
42
|
+
* Flags for the fsxattr.xflags field
|
|
43
|
+
*/
|
|
44
|
+
var XFlag;
|
|
45
|
+
(function (XFlag) {
|
|
46
|
+
/** data in realtime volume */
|
|
47
|
+
XFlag[XFlag["RealTime"] = 1] = "RealTime";
|
|
48
|
+
/** preallocated file extents */
|
|
49
|
+
XFlag[XFlag["PreAlloc"] = 2] = "PreAlloc";
|
|
50
|
+
/** file cannot be modified */
|
|
51
|
+
XFlag[XFlag["Immutable"] = 8] = "Immutable";
|
|
52
|
+
/** all writes append */
|
|
53
|
+
XFlag[XFlag["Append"] = 16] = "Append";
|
|
54
|
+
/** all writes synchronous */
|
|
55
|
+
XFlag[XFlag["Sync"] = 32] = "Sync";
|
|
56
|
+
/** do not update access time */
|
|
57
|
+
XFlag[XFlag["NoAtime"] = 64] = "NoAtime";
|
|
58
|
+
/** do not include in backups */
|
|
59
|
+
XFlag[XFlag["NoDump"] = 128] = "NoDump";
|
|
60
|
+
/** create with rt bit set */
|
|
61
|
+
XFlag[XFlag["RtInherit"] = 256] = "RtInherit";
|
|
62
|
+
/** create with parents projid */
|
|
63
|
+
XFlag[XFlag["ProjInherit"] = 512] = "ProjInherit";
|
|
64
|
+
/** disallow symlink creation */
|
|
65
|
+
XFlag[XFlag["NoSymlinks"] = 1024] = "NoSymlinks";
|
|
66
|
+
/** extent size allocator hint */
|
|
67
|
+
XFlag[XFlag["ExtSize"] = 2048] = "ExtSize";
|
|
68
|
+
/** inherit inode extent size */
|
|
69
|
+
XFlag[XFlag["ExtSzInherit"] = 4096] = "ExtSzInherit";
|
|
70
|
+
/** do not defragment */
|
|
71
|
+
XFlag[XFlag["NoDefrag"] = 8192] = "NoDefrag";
|
|
72
|
+
/** use filestream allocator */
|
|
73
|
+
XFlag[XFlag["FileStream"] = 16384] = "FileStream";
|
|
74
|
+
/** use DAX for IO */
|
|
75
|
+
XFlag[XFlag["Dax"] = 32768] = "Dax";
|
|
76
|
+
/** CoW extent size allocator hint */
|
|
77
|
+
XFlag[XFlag["CowExtSize"] = 65536] = "CowExtSize";
|
|
78
|
+
/** no DIFLAG for this */
|
|
79
|
+
XFlag[XFlag["HasAttr"] = 2147483648] = "HasAttr";
|
|
80
|
+
})(XFlag || (XFlag = {}));
|
|
81
|
+
let fsxattr = (() => {
|
|
82
|
+
var _a, _b, _c, _d, _e;
|
|
83
|
+
let _classDecorators = [struct()];
|
|
84
|
+
let _classDescriptor;
|
|
85
|
+
let _classExtraInitializers = [];
|
|
86
|
+
let _classThis;
|
|
87
|
+
let _classSuper = $from(BufferView);
|
|
88
|
+
let _xflags_decorators;
|
|
89
|
+
let _xflags_initializers = [];
|
|
90
|
+
let _xflags_extraInitializers = [];
|
|
91
|
+
let _extsize_decorators;
|
|
92
|
+
let _extsize_initializers = [];
|
|
93
|
+
let _extsize_extraInitializers = [];
|
|
94
|
+
let _nextents_decorators;
|
|
95
|
+
let _nextents_initializers = [];
|
|
96
|
+
let _nextents_extraInitializers = [];
|
|
97
|
+
let _projid_decorators;
|
|
98
|
+
let _projid_initializers = [];
|
|
99
|
+
let _projid_extraInitializers = [];
|
|
100
|
+
let _cowextsize_decorators;
|
|
101
|
+
let _cowextsize_initializers = [];
|
|
102
|
+
let _cowextsize_extraInitializers = [];
|
|
103
|
+
let _pad_decorators;
|
|
104
|
+
let _pad_initializers = [];
|
|
105
|
+
let _pad_extraInitializers = [];
|
|
106
|
+
var fsxattr = class extends _classSuper {
|
|
107
|
+
static { _classThis = this; }
|
|
108
|
+
static {
|
|
109
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
110
|
+
_xflags_decorators = [(_a = t).uint32.bind(_a)];
|
|
111
|
+
_extsize_decorators = [(_b = t).uint32.bind(_b)];
|
|
112
|
+
_nextents_decorators = [(_c = t).uint32.bind(_c)];
|
|
113
|
+
_projid_decorators = [(_d = t).uint32.bind(_d)];
|
|
114
|
+
_cowextsize_decorators = [(_e = t).uint32.bind(_e)];
|
|
115
|
+
_pad_decorators = [t.char(8)];
|
|
116
|
+
__esDecorate(this, null, _xflags_decorators, { kind: "accessor", name: "xflags", static: false, private: false, access: { has: obj => "xflags" in obj, get: obj => obj.xflags, set: (obj, value) => { obj.xflags = value; } }, metadata: _metadata }, _xflags_initializers, _xflags_extraInitializers);
|
|
117
|
+
__esDecorate(this, null, _extsize_decorators, { kind: "accessor", name: "extsize", static: false, private: false, access: { has: obj => "extsize" in obj, get: obj => obj.extsize, set: (obj, value) => { obj.extsize = value; } }, metadata: _metadata }, _extsize_initializers, _extsize_extraInitializers);
|
|
118
|
+
__esDecorate(this, null, _nextents_decorators, { kind: "accessor", name: "nextents", static: false, private: false, access: { has: obj => "nextents" in obj, get: obj => obj.nextents, set: (obj, value) => { obj.nextents = value; } }, metadata: _metadata }, _nextents_initializers, _nextents_extraInitializers);
|
|
119
|
+
__esDecorate(this, null, _projid_decorators, { kind: "accessor", name: "projid", static: false, private: false, access: { has: obj => "projid" in obj, get: obj => obj.projid, set: (obj, value) => { obj.projid = value; } }, metadata: _metadata }, _projid_initializers, _projid_extraInitializers);
|
|
120
|
+
__esDecorate(this, null, _cowextsize_decorators, { kind: "accessor", name: "cowextsize", static: false, private: false, access: { has: obj => "cowextsize" in obj, get: obj => obj.cowextsize, set: (obj, value) => { obj.cowextsize = value; } }, metadata: _metadata }, _cowextsize_initializers, _cowextsize_extraInitializers);
|
|
121
|
+
__esDecorate(this, null, _pad_decorators, { kind: "accessor", name: "pad", static: false, private: false, access: { has: obj => "pad" in obj, get: obj => obj.pad, set: (obj, value) => { obj.pad = value; } }, metadata: _metadata }, _pad_initializers, _pad_extraInitializers);
|
|
122
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
123
|
+
fsxattr = _classThis = _classDescriptor.value;
|
|
124
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
125
|
+
}
|
|
126
|
+
static name = 'fsxattr';
|
|
127
|
+
#xflags_accessor_storage = __runInitializers(this, _xflags_initializers, void 0);
|
|
128
|
+
/** xflags field value */
|
|
129
|
+
get xflags() { return this.#xflags_accessor_storage; }
|
|
130
|
+
set xflags(value) { this.#xflags_accessor_storage = value; }
|
|
131
|
+
#extsize_accessor_storage = (__runInitializers(this, _xflags_extraInitializers), __runInitializers(this, _extsize_initializers, void 0));
|
|
132
|
+
/** extsize field value */
|
|
133
|
+
get extsize() { return this.#extsize_accessor_storage; }
|
|
134
|
+
set extsize(value) { this.#extsize_accessor_storage = value; }
|
|
135
|
+
#nextents_accessor_storage = (__runInitializers(this, _extsize_extraInitializers), __runInitializers(this, _nextents_initializers, void 0));
|
|
136
|
+
/** nextents field value */
|
|
137
|
+
get nextents() { return this.#nextents_accessor_storage; }
|
|
138
|
+
set nextents(value) { this.#nextents_accessor_storage = value; }
|
|
139
|
+
#projid_accessor_storage = (__runInitializers(this, _nextents_extraInitializers), __runInitializers(this, _projid_initializers, void 0));
|
|
140
|
+
/** project identifier */
|
|
141
|
+
get projid() { return this.#projid_accessor_storage; }
|
|
142
|
+
set projid(value) { this.#projid_accessor_storage = value; }
|
|
143
|
+
#cowextsize_accessor_storage = (__runInitializers(this, _projid_extraInitializers), __runInitializers(this, _cowextsize_initializers, void 0));
|
|
144
|
+
/** CoW extsize field value */
|
|
145
|
+
get cowextsize() { return this.#cowextsize_accessor_storage; }
|
|
146
|
+
set cowextsize(value) { this.#cowextsize_accessor_storage = value; }
|
|
147
|
+
#pad_accessor_storage = (__runInitializers(this, _cowextsize_extraInitializers), __runInitializers(this, _pad_initializers, []));
|
|
148
|
+
get pad() { return this.#pad_accessor_storage; }
|
|
149
|
+
set pad(value) { this.#pad_accessor_storage = value; }
|
|
150
|
+
constructor(inode = _throw(new Exception(Errno.EINVAL, 'fsxattr must be initialized with an inode'))) {
|
|
151
|
+
super(new ArrayBuffer(sizeof(fsxattr)));
|
|
152
|
+
__runInitializers(this, _pad_extraInitializers);
|
|
153
|
+
this.extsize = inode.size;
|
|
154
|
+
this.nextents = 1;
|
|
155
|
+
this.projid = inode.uid;
|
|
156
|
+
this.cowextsize = inode.size;
|
|
157
|
+
for (const name of Object.keys(InodeFlags)) {
|
|
158
|
+
if (!((inode.flags || 0) & InodeFlags[name]))
|
|
159
|
+
continue;
|
|
160
|
+
if (name in XFlag)
|
|
161
|
+
this.xflags |= XFlag[name];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
static {
|
|
165
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
return fsxattr = _classThis;
|
|
169
|
+
})();
|
|
170
|
+
/**
|
|
171
|
+
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
|
|
172
|
+
* @see `FS_*_FL` in `include/uapi/linux/fs.h` (around L250)
|
|
173
|
+
* @experimental
|
|
174
|
+
*/
|
|
175
|
+
var FileFlag;
|
|
176
|
+
(function (FileFlag) {
|
|
177
|
+
/** Secure deletion */
|
|
178
|
+
FileFlag[FileFlag["SecureRm"] = 1] = "SecureRm";
|
|
179
|
+
/** Undelete */
|
|
180
|
+
FileFlag[FileFlag["Undelete"] = 2] = "Undelete";
|
|
181
|
+
/** Compress file */
|
|
182
|
+
FileFlag[FileFlag["Compress"] = 4] = "Compress";
|
|
183
|
+
/** Synchronous updates */
|
|
184
|
+
FileFlag[FileFlag["Sync"] = 8] = "Sync";
|
|
185
|
+
/** Immutable file */
|
|
186
|
+
FileFlag[FileFlag["Immutable"] = 16] = "Immutable";
|
|
187
|
+
/** Writes to file may only append */
|
|
188
|
+
FileFlag[FileFlag["Append"] = 32] = "Append";
|
|
189
|
+
/** do not dump file */
|
|
190
|
+
FileFlag[FileFlag["NoDump"] = 64] = "NoDump";
|
|
191
|
+
/** do not update atime */
|
|
192
|
+
FileFlag[FileFlag["NoAtime"] = 128] = "NoAtime";
|
|
193
|
+
// Reserved for compression usage...
|
|
194
|
+
FileFlag[FileFlag["Dirty"] = 256] = "Dirty";
|
|
195
|
+
/** One or more compressed clusters */
|
|
196
|
+
FileFlag[FileFlag["CompressBlk"] = 512] = "CompressBlk";
|
|
197
|
+
/** Don't compress */
|
|
198
|
+
FileFlag[FileFlag["NoCompress"] = 1024] = "NoCompress";
|
|
199
|
+
// End compression flags --- maybe not all used
|
|
200
|
+
/** Encrypted file */
|
|
201
|
+
FileFlag[FileFlag["Encrypt"] = 2048] = "Encrypt";
|
|
202
|
+
/** btree format dir */
|
|
203
|
+
FileFlag[FileFlag["Btree"] = 4096] = "Btree";
|
|
204
|
+
/** hash-indexed directory */
|
|
205
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
206
|
+
FileFlag[FileFlag["Index"] = 4096] = "Index";
|
|
207
|
+
/** AFS directory */
|
|
208
|
+
FileFlag[FileFlag["IMagic"] = 8192] = "IMagic";
|
|
209
|
+
/** Reserved for ext3 */
|
|
210
|
+
FileFlag[FileFlag["JournalData"] = 16384] = "JournalData";
|
|
211
|
+
/** file tail should not be merged */
|
|
212
|
+
FileFlag[FileFlag["NoTail"] = 32768] = "NoTail";
|
|
213
|
+
/** dirsync behaviour (directories only) */
|
|
214
|
+
FileFlag[FileFlag["DirSync"] = 65536] = "DirSync";
|
|
215
|
+
/** Top of directory hierarchies*/
|
|
216
|
+
FileFlag[FileFlag["TopDir"] = 131072] = "TopDir";
|
|
217
|
+
/** Reserved for ext4 */
|
|
218
|
+
FileFlag[FileFlag["HugeFile"] = 262144] = "HugeFile";
|
|
219
|
+
/** Extents */
|
|
220
|
+
FileFlag[FileFlag["Extent"] = 524288] = "Extent";
|
|
221
|
+
/** Verity protected inode */
|
|
222
|
+
FileFlag[FileFlag["Verity"] = 1048576] = "Verity";
|
|
223
|
+
/** Inode used for large EA */
|
|
224
|
+
FileFlag[FileFlag["EaInode"] = 2097152] = "EaInode";
|
|
225
|
+
/** Reserved for ext4 */
|
|
226
|
+
FileFlag[FileFlag["EofBlocks"] = 4194304] = "EofBlocks";
|
|
227
|
+
/** Do not cow file */
|
|
228
|
+
FileFlag[FileFlag["NoCow"] = 8388608] = "NoCow";
|
|
229
|
+
/** Inode is DAX */
|
|
230
|
+
FileFlag[FileFlag["Dax"] = 33554432] = "Dax";
|
|
231
|
+
/** Reserved for ext4 */
|
|
232
|
+
FileFlag[FileFlag["InlineData"] = 268435456] = "InlineData";
|
|
233
|
+
/** Create with parents projid */
|
|
234
|
+
FileFlag[FileFlag["ProjInherit"] = 536870912] = "ProjInherit";
|
|
235
|
+
/** Folder is case insensitive */
|
|
236
|
+
FileFlag[FileFlag["CaseFold"] = 1073741824] = "CaseFold";
|
|
237
|
+
/** reserved for ext2 lib */
|
|
238
|
+
FileFlag[FileFlag["Reserved"] = 2147483648] = "Reserved";
|
|
239
|
+
})(FileFlag || (FileFlag = {}));
|
|
240
|
+
/**
|
|
241
|
+
* `FS_IOC_*` commands for {@link ioctl | `ioctl`}
|
|
242
|
+
* @remarks
|
|
243
|
+
* These are computed from a script since constant values are needed for enum member types
|
|
244
|
+
*/
|
|
245
|
+
export var IOC;
|
|
246
|
+
(function (IOC) {
|
|
247
|
+
IOC[IOC["GetFlags"] = 2148034049] = "GetFlags";
|
|
248
|
+
IOC[IOC["SetFlags"] = 1074292226] = "SetFlags";
|
|
249
|
+
IOC[IOC["GetVersion"] = 2148038145] = "GetVersion";
|
|
250
|
+
IOC[IOC["SetVersion"] = 1074296322] = "SetVersion";
|
|
251
|
+
IOC[IOC["Fiemap"] = 3223348747] = "Fiemap";
|
|
252
|
+
IOC[IOC["GetXattr"] = 2149341215] = "GetXattr";
|
|
253
|
+
IOC[IOC["SetXattr"] = 1075599392] = "SetXattr";
|
|
254
|
+
IOC[IOC["GetLabel"] = 2164298801] = "GetLabel";
|
|
255
|
+
IOC[IOC["SetLabel"] = 1090556978] = "SetLabel";
|
|
256
|
+
IOC[IOC["GetUUID"] = 2148603136] = "GetUUID";
|
|
257
|
+
IOC[IOC["GetSysfsPath"] = 2155943169] = "GetSysfsPath";
|
|
258
|
+
})(IOC || (IOC = {}));
|
|
259
|
+
/**
|
|
260
|
+
* `FS_IOC32_*` commands for {@link ioctl | `ioctl`}
|
|
261
|
+
* @remarks
|
|
262
|
+
* These are computed from a script since constant values are needed for enum member types
|
|
263
|
+
*/
|
|
264
|
+
export var IOC32;
|
|
265
|
+
(function (IOC32) {
|
|
266
|
+
IOC32[IOC32["GetFlags"] = 2147771905] = "GetFlags";
|
|
267
|
+
IOC32[IOC32["SetFlags"] = 1074030082] = "SetFlags";
|
|
268
|
+
IOC32[IOC32["GetVersion"] = 2147776001] = "GetVersion";
|
|
269
|
+
IOC32[IOC32["SetVersion"] = 1074034178] = "SetVersion";
|
|
270
|
+
})(IOC32 || (IOC32 = {}));
|
|
271
|
+
/**
|
|
272
|
+
* @internal
|
|
273
|
+
* @category ioctl
|
|
274
|
+
*/
|
|
275
|
+
export const ioctl_default_ops = {
|
|
276
|
+
[IOC.GetFlags]($) {
|
|
277
|
+
if (typeof $.inode.flags !== 'number')
|
|
278
|
+
throw withErrno('ENOTTY');
|
|
279
|
+
return $.inode.flags;
|
|
280
|
+
},
|
|
281
|
+
[IOC32.GetFlags]($) {
|
|
282
|
+
if (typeof $.inode.flags !== 'number')
|
|
283
|
+
throw withErrno('ENOTTY');
|
|
284
|
+
return $.inode.flags;
|
|
285
|
+
},
|
|
286
|
+
[IOC.GetVersion]($) {
|
|
287
|
+
if (typeof $.inode.version !== 'number')
|
|
288
|
+
throw withErrno('ENOTTY');
|
|
289
|
+
return $.inode.version;
|
|
290
|
+
},
|
|
291
|
+
[IOC32.GetVersion]($) {
|
|
292
|
+
if (typeof $.inode.version !== 'number')
|
|
293
|
+
throw withErrno('ENOTTY');
|
|
294
|
+
return $.inode.version;
|
|
295
|
+
},
|
|
296
|
+
[IOC.Fiemap]() {
|
|
297
|
+
throw withErrno('ENOTSUP');
|
|
298
|
+
},
|
|
299
|
+
[IOC.GetXattr]($, _name) {
|
|
300
|
+
return new fsxattr($.inode);
|
|
301
|
+
},
|
|
302
|
+
[IOC.SetXattr]($, _name, _value) {
|
|
303
|
+
throw withErrno('ENOTSUP');
|
|
304
|
+
},
|
|
305
|
+
[IOC.GetLabel]($) {
|
|
306
|
+
return $.fs.label;
|
|
307
|
+
},
|
|
308
|
+
[IOC.SetLabel]($, label) {
|
|
309
|
+
$.fs.label = label;
|
|
310
|
+
},
|
|
311
|
+
[IOC.GetUUID]($) {
|
|
312
|
+
return $.fs.uuid;
|
|
313
|
+
},
|
|
314
|
+
[IOC.GetSysfsPath]($) {
|
|
315
|
+
/**
|
|
316
|
+
* Returns the path component under /sys/fs/ that refers to this filesystem;
|
|
317
|
+
* also /sys/kernel/debug/ for filesystems with debugfs exports
|
|
318
|
+
* @todo Implement sysfs and have each FS implement the /sys/fs/<name> tree
|
|
319
|
+
*/
|
|
320
|
+
return `/sys/fs/${$.fs.name}/${$.fs.uuid}`;
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* @internal
|
|
325
|
+
* @category ioctl
|
|
326
|
+
*/
|
|
327
|
+
export const ioctl_default_ops_async = {
|
|
328
|
+
...ioctl_default_ops,
|
|
329
|
+
async [IOC.SetFlags]($, flags) {
|
|
330
|
+
$.inode.flags = flags;
|
|
331
|
+
await $.fs.touch($.path, $.inode);
|
|
332
|
+
},
|
|
333
|
+
async [IOC32.SetFlags]($, flags) {
|
|
334
|
+
$.inode.flags = flags;
|
|
335
|
+
await $.fs.touch($.path, $.inode);
|
|
336
|
+
},
|
|
337
|
+
async [IOC.SetVersion]($, version) {
|
|
338
|
+
$.inode.version = version;
|
|
339
|
+
await $.fs.touch($.path, $.inode);
|
|
340
|
+
},
|
|
341
|
+
async [IOC32.SetVersion]($, version) {
|
|
342
|
+
$.inode.version = version;
|
|
343
|
+
await $.fs.touch($.path, $.inode);
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* @internal
|
|
348
|
+
* @category ioctl
|
|
349
|
+
*/
|
|
350
|
+
export const ioctl_default_ops_sync = {
|
|
351
|
+
...ioctl_default_ops,
|
|
352
|
+
[IOC.SetFlags]($, flags) {
|
|
353
|
+
$.inode.flags = flags;
|
|
354
|
+
$.fs.touchSync($.path, $.inode);
|
|
355
|
+
},
|
|
356
|
+
[IOC32.SetFlags]($, flags) {
|
|
357
|
+
$.inode.flags = flags;
|
|
358
|
+
$.fs.touchSync($.path, $.inode);
|
|
359
|
+
},
|
|
360
|
+
[IOC.SetVersion]($, version) {
|
|
361
|
+
$.inode.version = version;
|
|
362
|
+
$.fs.touchSync($.path, $.inode);
|
|
363
|
+
},
|
|
364
|
+
[IOC32.SetVersion]($, version) {
|
|
365
|
+
$.inode.version = version;
|
|
366
|
+
$.fs.touchSync($.path, $.inode);
|
|
367
|
+
},
|
|
368
|
+
};
|
package/dist/mixins/async.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
2
|
import { withErrno } from 'kerium';
|
|
3
3
|
import { crit, debug, err } from 'kerium/log';
|
|
4
4
|
import { StoreFS } from '../backends/store/fs.js';
|
|
5
5
|
import { isDirectory } from '../internal/inode.js';
|
|
6
6
|
import { join } from '../path.js';
|
|
7
|
+
import { _asyncFSKeys } from './shared.js';
|
|
7
8
|
/**
|
|
8
9
|
* Async() implements synchronous methods on an asynchronous file system
|
|
9
10
|
*
|
|
@@ -143,6 +144,10 @@ export function Async(FS) {
|
|
|
143
144
|
this._sync.writeSync(path, buffer, offset);
|
|
144
145
|
this._async(() => this.write(path, buffer, offset));
|
|
145
146
|
}
|
|
147
|
+
ioctlSync(context, command, ...args) {
|
|
148
|
+
this.checkSync();
|
|
149
|
+
return this._sync.ioctlSync(context, command, ...args);
|
|
150
|
+
}
|
|
146
151
|
streamWrite(path, options) {
|
|
147
152
|
this.checkSync();
|
|
148
153
|
const sync = this._sync.streamWrite(path, options).getWriter();
|
package/dist/mixins/mutexed.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { UUID } from 'node:crypto';
|
|
|
2
2
|
import type { Concrete } from 'utilium';
|
|
3
3
|
import type { CreationOptions, FileSystem, StreamOptions, UsageInfo } from '../internal/filesystem.js';
|
|
4
4
|
import type { InodeLike } from '../internal/inode.js';
|
|
5
|
+
import type { IoctlContext } from '../internal/ioctl.js';
|
|
5
6
|
import '../polyfills.js';
|
|
6
7
|
/**
|
|
7
8
|
* @category Internals
|
|
@@ -90,6 +91,8 @@ export declare class _MutexedFS<T extends FileSystem> implements FileSystem {
|
|
|
90
91
|
writeSync(path: string, buffer: Uint8Array, offset: number): void;
|
|
91
92
|
streamRead(path: string, options: StreamOptions): ReadableStream;
|
|
92
93
|
streamWrite(path: string, options: StreamOptions): WritableStream;
|
|
94
|
+
ioctl(context: IoctlContext, command: number, ...args: any[]): Promise<any>;
|
|
95
|
+
ioctlSync(context: IoctlContext, command: number, ...args: any[]): any;
|
|
93
96
|
}
|
|
94
97
|
/**
|
|
95
98
|
* This serializes access to an underlying async filesystem.
|
package/dist/mixins/mutexed.js
CHANGED
|
@@ -50,6 +50,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
+
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
53
54
|
import { withErrno } from 'kerium';
|
|
54
55
|
import { err } from 'kerium/log';
|
|
55
56
|
import '../polyfills.js';
|
|
@@ -170,7 +171,6 @@ export class _MutexedFS {
|
|
|
170
171
|
get isLocked() {
|
|
171
172
|
return !!this.currentLock?.isLocked;
|
|
172
173
|
}
|
|
173
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
174
174
|
async rename(oldPath, newPath) {
|
|
175
175
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
176
176
|
try {
|
|
@@ -563,6 +563,34 @@ export class _MutexedFS {
|
|
|
563
563
|
__disposeResources(env_28);
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
|
+
async ioctl(context, command, ...args) {
|
|
567
|
+
const env_29 = { stack: [], error: void 0, hasError: false };
|
|
568
|
+
try {
|
|
569
|
+
const _ = __addDisposableResource(env_29, await this.lock(), false);
|
|
570
|
+
return await this._fs.ioctl({ ...context, fs: this._fs }, command, ...args);
|
|
571
|
+
}
|
|
572
|
+
catch (e_29) {
|
|
573
|
+
env_29.error = e_29;
|
|
574
|
+
env_29.hasError = true;
|
|
575
|
+
}
|
|
576
|
+
finally {
|
|
577
|
+
__disposeResources(env_29);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
ioctlSync(context, command, ...args) {
|
|
581
|
+
const env_30 = { stack: [], error: void 0, hasError: false };
|
|
582
|
+
try {
|
|
583
|
+
const _ = __addDisposableResource(env_30, this.lockSync(), false);
|
|
584
|
+
return this._fs.ioctlSync({ ...context, fs: this._fs }, command, ...args);
|
|
585
|
+
}
|
|
586
|
+
catch (e_30) {
|
|
587
|
+
env_30.error = e_30;
|
|
588
|
+
env_30.hasError = true;
|
|
589
|
+
}
|
|
590
|
+
finally {
|
|
591
|
+
__disposeResources(env_30);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
566
594
|
}
|
|
567
595
|
/**
|
|
568
596
|
* This serializes access to an underlying async filesystem.
|
package/dist/mixins/shared.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type _SyncFSKeys = Exclude<Extract<keyof FileSystem, `${string}Sync`>, '_
|
|
|
18
18
|
export type _AsyncFSKeys = {
|
|
19
19
|
[K in _SyncFSKeys]: K extends `${infer T}Sync` ? T : never;
|
|
20
20
|
}[_SyncFSKeys];
|
|
21
|
-
export declare const _asyncFSKeys: ["rename", "stat", "touch", "createFile", "unlink", "rmdir", "mkdir", "readdir", "exists", "link", "sync", "read", "write"];
|
|
21
|
+
export declare const _asyncFSKeys: ["rename", "stat", "touch", "createFile", "unlink", "rmdir", "mkdir", "readdir", "exists", "link", "sync", "read", "write", "ioctl"];
|
|
22
22
|
/**
|
|
23
23
|
* Asynchronous `FileSystem` methods. This is a convenience type for all of the async operations.
|
|
24
24
|
* @category Internals
|
package/dist/mixins/shared.js
CHANGED
package/dist/mixins/sync.js
CHANGED
package/dist/node/async.js
CHANGED
|
@@ -328,7 +328,7 @@ export function access(path, cbMode, cb = nop) {
|
|
|
328
328
|
access;
|
|
329
329
|
const statWatchers = new Map();
|
|
330
330
|
export function watchFile(path, options, listener) {
|
|
331
|
-
const normalizedPath = normalizePath(path);
|
|
331
|
+
const normalizedPath = normalizePath.call(this, path);
|
|
332
332
|
const opts = typeof options != 'function' ? options : {};
|
|
333
333
|
if (typeof options == 'function') {
|
|
334
334
|
listener = options;
|
|
@@ -365,7 +365,7 @@ watchFile;
|
|
|
365
365
|
* @param listener Optional listener to remove.
|
|
366
366
|
*/
|
|
367
367
|
export function unwatchFile(path, listener = nop) {
|
|
368
|
-
const normalizedPath = normalizePath(path);
|
|
368
|
+
const normalizedPath = normalizePath.call(this, path);
|
|
369
369
|
const entry = statWatchers.get(normalizedPath);
|
|
370
370
|
if (entry) {
|
|
371
371
|
if (listener && listener !== nop) {
|
|
@@ -384,7 +384,7 @@ export function unwatchFile(path, listener = nop) {
|
|
|
384
384
|
}
|
|
385
385
|
unwatchFile;
|
|
386
386
|
export function watch(path, options, listener) {
|
|
387
|
-
const watcher = new FSWatcher(this, normalizePath(path), typeof options == 'object' ? options : {});
|
|
387
|
+
const watcher = new FSWatcher(this, normalizePath.call(this, path), typeof options == 'object' ? options : {});
|
|
388
388
|
listener = typeof options == 'function' ? options : listener;
|
|
389
389
|
watcher.on('change', listener || nop);
|
|
390
390
|
return watcher;
|
package/dist/node/promises.js
CHANGED
|
@@ -529,7 +529,7 @@ rename;
|
|
|
529
529
|
* Test whether or not `path` exists by checking with the file system.
|
|
530
530
|
*/
|
|
531
531
|
export async function exists(path) {
|
|
532
|
-
path = normalizePath(path);
|
|
532
|
+
path = normalizePath.call(this, path);
|
|
533
533
|
try {
|
|
534
534
|
const { fs, path: resolved } = await _async.resolve(this, path);
|
|
535
535
|
return await fs.exists(resolved);
|
|
@@ -579,7 +579,7 @@ truncate;
|
|
|
579
579
|
export async function unlink(path) {
|
|
580
580
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
581
581
|
try {
|
|
582
|
-
path = normalizePath(path);
|
|
582
|
+
path = normalizePath.call(this, path);
|
|
583
583
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
584
584
|
const $ex = { syscall: 'unlink', path };
|
|
585
585
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
@@ -691,7 +691,7 @@ appendFile;
|
|
|
691
691
|
export async function rmdir(path) {
|
|
692
692
|
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
693
693
|
try {
|
|
694
|
-
path = normalizePath(path);
|
|
694
|
+
path = normalizePath.call(this, path);
|
|
695
695
|
const { fs, path: resolved } = await _async.resolve(this, path);
|
|
696
696
|
const $ex = { syscall: 'rmdir', path };
|
|
697
697
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
@@ -722,7 +722,7 @@ export async function mkdir(path, options) {
|
|
|
722
722
|
}
|
|
723
723
|
mkdir;
|
|
724
724
|
export async function readdir(path, options) {
|
|
725
|
-
path = normalizePath(path);
|
|
725
|
+
path = normalizePath.call(this, path);
|
|
726
726
|
const opt = typeof options === 'object' && options != null ? options : { encoding: options, withFileTypes: false, recursive: false };
|
|
727
727
|
const rawEntries = await _async.readdir.call(this, path, opt);
|
|
728
728
|
const values = [];
|
|
@@ -755,11 +755,11 @@ export async function symlink(dest, path, type = 'file') {
|
|
|
755
755
|
try {
|
|
756
756
|
if (!['file', 'dir', 'junction'].includes(type))
|
|
757
757
|
throw new TypeError('Invalid symlink type: ' + type);
|
|
758
|
-
path = normalizePath(path);
|
|
758
|
+
path = normalizePath.call(this, path);
|
|
759
759
|
if (await exists.call(this, path))
|
|
760
760
|
throw UV('EEXIST', 'symlink', path);
|
|
761
761
|
const handle = __addDisposableResource(env_7, await _async.open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
|
|
762
|
-
const encoded = encodeUTF8(normalizePath(dest, true));
|
|
762
|
+
const encoded = encodeUTF8(normalizePath.call(this, dest, true));
|
|
763
763
|
await handle.write(encoded, 0, encoded.length, 0);
|
|
764
764
|
await handle.chmod(constants.S_IFLNK);
|
|
765
765
|
}
|
|
@@ -775,7 +775,7 @@ export async function symlink(dest, path, type = 'file') {
|
|
|
775
775
|
}
|
|
776
776
|
symlink;
|
|
777
777
|
export async function readlink(path, options) {
|
|
778
|
-
path = normalizePath(path);
|
|
778
|
+
path = normalizePath.call(this, path);
|
|
779
779
|
const buf = Buffer.from(await _async.readlink.call(this, path), 'utf-8');
|
|
780
780
|
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
781
781
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
@@ -824,7 +824,7 @@ lchown;
|
|
|
824
824
|
export async function chmod(path, mode) {
|
|
825
825
|
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
826
826
|
try {
|
|
827
|
-
const handle = __addDisposableResource(env_10, await open.call(this, path, 'r+').catch(rethrow({ syscall: 'chmod', path: normalizePath(path) })), true);
|
|
827
|
+
const handle = __addDisposableResource(env_10, await open.call(this, path, 'r+').catch(rethrow({ syscall: 'chmod', path: normalizePath.call(this, path) })), true);
|
|
828
828
|
await handle.chmod(mode);
|
|
829
829
|
}
|
|
830
830
|
catch (e_10) {
|
|
@@ -911,7 +911,7 @@ export async function lutimes(path, atime, mtime) {
|
|
|
911
911
|
lutimes;
|
|
912
912
|
export async function realpath(path, options) {
|
|
913
913
|
const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
|
|
914
|
-
path = normalizePath(path);
|
|
914
|
+
path = normalizePath.call(this, path);
|
|
915
915
|
const { fullPath } = await _async.resolve(this, path);
|
|
916
916
|
if (encoding == 'utf8' || encoding == 'utf-8')
|
|
917
917
|
return fullPath;
|
|
@@ -976,7 +976,7 @@ access;
|
|
|
976
976
|
* @param path The path to the file or directory to remove.
|
|
977
977
|
*/
|
|
978
978
|
export async function rm(path, options) {
|
|
979
|
-
path = normalizePath(path);
|
|
979
|
+
path = normalizePath.call(this, path);
|
|
980
980
|
const stats = await lstat.call(this, path).catch((error) => {
|
|
981
981
|
if (error.code == 'ENOENT' && options?.force)
|
|
982
982
|
return undefined;
|
|
@@ -1034,8 +1034,8 @@ export async function mkdtempDisposable(prefix, options) {
|
|
|
1034
1034
|
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
|
|
1035
1035
|
*/
|
|
1036
1036
|
export async function copyFile(src, dest, mode) {
|
|
1037
|
-
src = normalizePath(src);
|
|
1038
|
-
dest = normalizePath(dest);
|
|
1037
|
+
src = normalizePath.call(this, src);
|
|
1038
|
+
dest = normalizePath.call(this, dest);
|
|
1039
1039
|
if (mode && mode & constants.COPYFILE_EXCL && (await exists.call(this, dest)))
|
|
1040
1040
|
throw UV('EEXIST', 'copyFile', dest);
|
|
1041
1041
|
await writeFile.call(this, dest, await readFile.call(this, src));
|
|
@@ -1050,7 +1050,7 @@ copyFile;
|
|
|
1050
1050
|
* @todo Use options
|
|
1051
1051
|
*/
|
|
1052
1052
|
export function opendir(path, options) {
|
|
1053
|
-
path = normalizePath(path);
|
|
1053
|
+
path = normalizePath.call(this, path);
|
|
1054
1054
|
return Promise.resolve(new Dir(path, this));
|
|
1055
1055
|
}
|
|
1056
1056
|
opendir;
|
|
@@ -1067,8 +1067,8 @@ opendir;
|
|
|
1067
1067
|
* * `recursive`: If `true`, copies directories recursively.
|
|
1068
1068
|
*/
|
|
1069
1069
|
export async function cp(source, destination, opts) {
|
|
1070
|
-
source = normalizePath(source);
|
|
1071
|
-
destination = normalizePath(destination);
|
|
1070
|
+
source = normalizePath.call(this, source);
|
|
1071
|
+
destination = normalizePath.call(this, destination);
|
|
1072
1072
|
const srcStats = await lstat.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
1073
1073
|
if (opts?.errorOnExist && (await exists.call(this, destination)))
|
|
1074
1074
|
throw UV('EEXIST', 'cp', destination);
|
|
@@ -1116,7 +1116,7 @@ export async function cp(source, destination, opts) {
|
|
|
1116
1116
|
}
|
|
1117
1117
|
cp;
|
|
1118
1118
|
export async function statfs(path, opts) {
|
|
1119
|
-
path = normalizePath(path);
|
|
1119
|
+
path = normalizePath.call(this, path);
|
|
1120
1120
|
const { fs } = resolveMount(path, this);
|
|
1121
1121
|
return Promise.resolve(_statfs(fs, opts?.bigint));
|
|
1122
1122
|
}
|