@zenfs/core 1.7.2 → 1.8.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/backend.js +3 -4
- package/dist/backends/fetch.d.ts +17 -18
- package/dist/backends/fetch.js +95 -58
- package/dist/backends/index.d.ts +2 -1
- package/dist/backends/index.js +2 -1
- package/dist/backends/memory.d.ts +1 -1
- package/dist/backends/overlay.d.ts +8 -14
- package/dist/backends/overlay.js +38 -31
- package/dist/backends/passthrough.d.ts +8 -3
- package/dist/backends/passthrough.js +148 -4
- package/dist/backends/port/fs.d.ts +15 -49
- package/dist/backends/port/fs.js +28 -116
- package/dist/backends/port/rpc.d.ts +13 -6
- package/dist/backends/port/rpc.js +9 -7
- package/dist/backends/store/file_index.d.ts +38 -0
- package/dist/backends/store/file_index.js +76 -0
- package/dist/backends/store/fs.d.ts +39 -34
- package/dist/backends/store/fs.js +407 -238
- package/dist/backends/store/index_fs.d.ts +34 -0
- package/dist/backends/store/index_fs.js +67 -0
- package/dist/backends/store/inode.d.ts +26 -8
- package/dist/backends/store/inode.js +92 -91
- package/dist/backends/store/simple.d.ts +20 -20
- package/dist/backends/store/simple.js +3 -4
- package/dist/backends/store/store.d.ts +12 -12
- package/dist/backends/store/store.js +4 -6
- package/dist/devices.d.ts +44 -21
- package/dist/devices.js +110 -55
- package/dist/file.d.ts +111 -7
- package/dist/file.js +324 -92
- package/dist/filesystem.d.ts +44 -4
- package/dist/mixins/async.js +12 -6
- package/dist/mixins/mutexed.d.ts +8 -3
- package/dist/mixins/mutexed.js +57 -1
- package/dist/mixins/readonly.d.ts +17 -16
- package/dist/mixins/readonly.js +6 -0
- package/dist/mixins/sync.d.ts +1 -1
- package/dist/stats.d.ts +12 -6
- package/dist/stats.js +14 -6
- package/dist/utils.d.ts +23 -3
- package/dist/utils.js +58 -10
- package/dist/vfs/async.js +1 -1
- package/dist/vfs/constants.d.ts +2 -2
- package/dist/vfs/constants.js +2 -2
- package/dist/vfs/dir.js +3 -1
- package/dist/vfs/index.js +4 -1
- package/dist/vfs/promises.js +33 -13
- package/dist/vfs/shared.js +2 -0
- package/dist/vfs/sync.js +25 -13
- package/dist/vfs/types.d.ts +15 -0
- package/eslint.shared.js +1 -0
- package/package.json +2 -3
- package/readme.md +2 -2
- package/scripts/test.js +73 -11
- package/tests/common/mutex.test.ts +1 -1
- package/tests/fetch/run.sh +16 -0
- package/tests/fetch/server.ts +49 -0
- package/tests/fetch/setup.ts +13 -0
- package/tests/fs/read.test.ts +10 -10
- package/tests/fs/times.test.ts +2 -2
- package/tests/fs/write.test.ts +6 -11
- package/tests/setup/index.ts +38 -0
- package/tests/setup/port.ts +15 -0
- package/dist/backends/file_index.d.ts +0 -63
- package/dist/backends/file_index.js +0 -163
- package/tests/common/async.test.ts +0 -31
- package/tests/setup/cow+fetch.ts +0 -45
- /package/tests/fs/{appendFile.test.ts → append.test.ts} +0 -0
|
@@ -50,22 +50,23 @@ 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
|
-
import {
|
|
54
|
-
import { S_IFDIR, S_IFREG, S_ISGID, S_ISUID } from '../../vfs/constants.js';
|
|
55
|
-
import { basename, dirname, parse, resolve } from '../../vfs/path.js';
|
|
53
|
+
import { randomInt, serialize } from 'utilium';
|
|
56
54
|
import { Errno, ErrnoError } from '../../error.js';
|
|
57
|
-
import {
|
|
55
|
+
import { LazyFile } from '../../file.js';
|
|
58
56
|
import { FileSystem } from '../../filesystem.js';
|
|
57
|
+
import { _throw, canary, decodeDirListing, encodeDirListing, encodeUTF8, growBuffer } from '../../utils.js';
|
|
58
|
+
import { S_IFDIR, S_IFREG, S_ISGID, S_ISUID, size_max } from '../../vfs/constants.js';
|
|
59
|
+
import { basename, dirname, join, parse, resolve } from '../../vfs/path.js';
|
|
60
|
+
import { Index } from './file_index.js';
|
|
59
61
|
import { Inode, rootIno } from './inode.js';
|
|
60
|
-
import { decodeDirListing, encodeDirListing, encodeUTF8, randomBigInt } from '../../utils.js';
|
|
61
|
-
import { serialize } from 'utilium';
|
|
62
62
|
const maxInodeAllocTries = 5;
|
|
63
63
|
/**
|
|
64
64
|
* A file system which uses a key-value store.
|
|
65
65
|
*
|
|
66
66
|
* We use a unique ID for each node in the file system. The root node has a fixed ID.
|
|
67
|
-
*
|
|
68
|
-
* @todo
|
|
67
|
+
*
|
|
68
|
+
* @todo Introduce Node ID caching?
|
|
69
|
+
* @todo Check modes?
|
|
69
70
|
* @internal
|
|
70
71
|
*/
|
|
71
72
|
export class StoreFS extends FileSystem {
|
|
@@ -88,6 +89,7 @@ export class StoreFS extends FileSystem {
|
|
|
88
89
|
features: ['setid'],
|
|
89
90
|
};
|
|
90
91
|
}
|
|
92
|
+
/* node:coverage disable */
|
|
91
93
|
/**
|
|
92
94
|
* Delete all contents stored in the file system.
|
|
93
95
|
* @deprecated
|
|
@@ -106,16 +108,128 @@ export class StoreFS extends FileSystem {
|
|
|
106
108
|
// Root always exists.
|
|
107
109
|
this.checkRootSync();
|
|
108
110
|
}
|
|
111
|
+
/* node:coverage enable */
|
|
109
112
|
/**
|
|
110
|
-
*
|
|
113
|
+
* Load an index into the StoreFS.
|
|
114
|
+
* You *must* manually add non-directory files
|
|
111
115
|
*/
|
|
112
|
-
async
|
|
116
|
+
async loadIndex(index) {
|
|
113
117
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
114
118
|
try {
|
|
115
119
|
const tx = __addDisposableResource(env_1, this.store.transaction(), true);
|
|
120
|
+
const dirs = index.directories();
|
|
121
|
+
for (const [path, inode] of index) {
|
|
122
|
+
await tx.set(inode.ino, serialize(inode));
|
|
123
|
+
if (dirs.has(path))
|
|
124
|
+
await tx.set(inode.data, encodeDirListing(dirs.get(path)));
|
|
125
|
+
}
|
|
126
|
+
await tx.commit();
|
|
127
|
+
}
|
|
128
|
+
catch (e_1) {
|
|
129
|
+
env_1.error = e_1;
|
|
130
|
+
env_1.hasError = true;
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
const result_1 = __disposeResources(env_1);
|
|
134
|
+
if (result_1)
|
|
135
|
+
await result_1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Load an index into the StoreFS.
|
|
140
|
+
* You *must* manually add non-directory files
|
|
141
|
+
*/
|
|
142
|
+
loadIndexSync(index) {
|
|
143
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
144
|
+
try {
|
|
145
|
+
const tx = __addDisposableResource(env_2, this.store.transaction(), false);
|
|
146
|
+
const dirs = index.directories();
|
|
147
|
+
for (const [path, inode] of index) {
|
|
148
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
149
|
+
if (dirs.has(path))
|
|
150
|
+
tx.setSync(inode.data, encodeDirListing(dirs.get(path)));
|
|
151
|
+
}
|
|
152
|
+
tx.commitSync();
|
|
153
|
+
}
|
|
154
|
+
catch (e_2) {
|
|
155
|
+
env_2.error = e_2;
|
|
156
|
+
env_2.hasError = true;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
__disposeResources(env_2);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async createIndex() {
|
|
163
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
164
|
+
try {
|
|
165
|
+
const index = new Index();
|
|
166
|
+
const tx = __addDisposableResource(env_3, this.store.transaction(), true);
|
|
167
|
+
const queue = [['/', 0]];
|
|
168
|
+
const silence = canary();
|
|
169
|
+
while (queue.length) {
|
|
170
|
+
const [path, ino] = queue.shift();
|
|
171
|
+
const inode = new Inode(await tx.get(ino));
|
|
172
|
+
index.set(path, inode);
|
|
173
|
+
if (inode.mode & S_IFDIR) {
|
|
174
|
+
const dir = decodeDirListing(await tx.get(inode.data));
|
|
175
|
+
for (const [name, id] of Object.entries(dir)) {
|
|
176
|
+
queue.push([join(path, name), id]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
silence();
|
|
181
|
+
return index;
|
|
182
|
+
}
|
|
183
|
+
catch (e_3) {
|
|
184
|
+
env_3.error = e_3;
|
|
185
|
+
env_3.hasError = true;
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
const result_2 = __disposeResources(env_3);
|
|
189
|
+
if (result_2)
|
|
190
|
+
await result_2;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
createIndexSync() {
|
|
194
|
+
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
195
|
+
try {
|
|
196
|
+
const index = new Index();
|
|
197
|
+
const tx = __addDisposableResource(env_4, this.store.transaction(), false);
|
|
198
|
+
const queue = [['/', 0]];
|
|
199
|
+
const silence = canary();
|
|
200
|
+
while (queue.length) {
|
|
201
|
+
const [path, ino] = queue.shift();
|
|
202
|
+
const inode = new Inode(tx.getSync(ino));
|
|
203
|
+
index.set(path, inode);
|
|
204
|
+
if (inode.mode & S_IFDIR) {
|
|
205
|
+
const dir = decodeDirListing(tx.getSync(inode.data));
|
|
206
|
+
for (const [name, id] of Object.entries(dir)) {
|
|
207
|
+
queue.push([join(path, name), id]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
silence();
|
|
212
|
+
return index;
|
|
213
|
+
}
|
|
214
|
+
catch (e_4) {
|
|
215
|
+
env_4.error = e_4;
|
|
216
|
+
env_4.hasError = true;
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
__disposeResources(env_4);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* @todo Make rename compatible with the cache.
|
|
224
|
+
*/
|
|
225
|
+
async rename(oldPath, newPath) {
|
|
226
|
+
var _a, _b, _c;
|
|
227
|
+
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
228
|
+
try {
|
|
229
|
+
const tx = __addDisposableResource(env_5, this.store.transaction(), true);
|
|
116
230
|
const _old = parse(oldPath), _new = parse(newPath),
|
|
117
231
|
// Remove oldPath from parent's directory listing.
|
|
118
|
-
oldDirNode = await this.findInode(tx, _old.dir, 'rename'), oldDirList = decodeDirListing(await
|
|
232
|
+
oldDirNode = await this.findInode(tx, _old.dir, 'rename'), oldDirList = decodeDirListing((_a = (await tx.get(oldDirNode.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', _old.dir, 'rename')));
|
|
119
233
|
if (!oldDirList[_old.base]) {
|
|
120
234
|
throw ErrnoError.With('ENOENT', oldPath, 'rename');
|
|
121
235
|
}
|
|
@@ -133,10 +247,10 @@ export class StoreFS extends FileSystem {
|
|
|
133
247
|
const sameParent = _new.dir == _old.dir;
|
|
134
248
|
// Prevent us from re-grabbing the same directory listing, which still contains `old_path.base.`
|
|
135
249
|
const newDirNode = sameParent ? oldDirNode : await this.findInode(tx, _new.dir, 'rename');
|
|
136
|
-
const newDirList = sameParent ? oldDirList : decodeDirListing(await
|
|
250
|
+
const newDirList = sameParent ? oldDirList : decodeDirListing((_b = (await tx.get(newDirNode.data))) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', _new.dir, 'rename')));
|
|
137
251
|
if (newDirList[_new.base]) {
|
|
138
252
|
// If it's a file, delete it, if it's a directory, throw a permissions error.
|
|
139
|
-
const existing = new Inode(await
|
|
253
|
+
const existing = new Inode((_c = (await tx.get(newDirList[_new.base]))) !== null && _c !== void 0 ? _c : _throw(ErrnoError.With('ENOENT', newPath, 'rename')));
|
|
140
254
|
if (!existing.toStats().isFile()) {
|
|
141
255
|
throw ErrnoError.With('EPERM', newPath, 'rename');
|
|
142
256
|
}
|
|
@@ -149,23 +263,24 @@ export class StoreFS extends FileSystem {
|
|
|
149
263
|
await tx.set(newDirNode.data, encodeDirListing(newDirList));
|
|
150
264
|
await tx.commit();
|
|
151
265
|
}
|
|
152
|
-
catch (
|
|
153
|
-
|
|
154
|
-
|
|
266
|
+
catch (e_5) {
|
|
267
|
+
env_5.error = e_5;
|
|
268
|
+
env_5.hasError = true;
|
|
155
269
|
}
|
|
156
270
|
finally {
|
|
157
|
-
const
|
|
158
|
-
if (
|
|
159
|
-
await
|
|
271
|
+
const result_3 = __disposeResources(env_5);
|
|
272
|
+
if (result_3)
|
|
273
|
+
await result_3;
|
|
160
274
|
}
|
|
161
275
|
}
|
|
162
276
|
renameSync(oldPath, newPath) {
|
|
163
|
-
|
|
277
|
+
var _a, _b, _c;
|
|
278
|
+
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
164
279
|
try {
|
|
165
|
-
const tx = __addDisposableResource(
|
|
280
|
+
const tx = __addDisposableResource(env_6, this.store.transaction(), false);
|
|
166
281
|
const _old = parse(oldPath), _new = parse(newPath),
|
|
167
282
|
// Remove oldPath from parent's directory listing.
|
|
168
|
-
oldDirNode = this.findInodeSync(tx, _old.dir, 'rename'), oldDirList = decodeDirListing(
|
|
283
|
+
oldDirNode = this.findInodeSync(tx, _old.dir, 'rename'), oldDirList = decodeDirListing((_a = tx.getSync(oldDirNode.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', _old.dir, 'rename')));
|
|
169
284
|
if (!oldDirList[_old.base]) {
|
|
170
285
|
throw ErrnoError.With('ENOENT', oldPath, 'rename');
|
|
171
286
|
}
|
|
@@ -183,10 +298,10 @@ export class StoreFS extends FileSystem {
|
|
|
183
298
|
const sameParent = _new.dir === _old.dir;
|
|
184
299
|
// Prevent us from re-grabbing the same directory listing, which still contains `old_path.base.`
|
|
185
300
|
const newDirNode = sameParent ? oldDirNode : this.findInodeSync(tx, _new.dir, 'rename');
|
|
186
|
-
const newDirList = sameParent ? oldDirList : decodeDirListing(
|
|
301
|
+
const newDirList = sameParent ? oldDirList : decodeDirListing((_b = tx.getSync(newDirNode.data)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', _new.dir, 'rename')));
|
|
187
302
|
if (newDirList[_new.base]) {
|
|
188
303
|
// If it's a file, delete it, if it's a directory, throw a permissions error.
|
|
189
|
-
const existing = new Inode(
|
|
304
|
+
const existing = new Inode((_c = tx.getSync(newDirList[_new.base])) !== null && _c !== void 0 ? _c : _throw(ErrnoError.With('ENOENT', newPath, 'rename')));
|
|
190
305
|
if (!existing.toStats().isFile()) {
|
|
191
306
|
throw ErrnoError.With('EPERM', newPath, 'rename');
|
|
192
307
|
}
|
|
@@ -199,84 +314,84 @@ export class StoreFS extends FileSystem {
|
|
|
199
314
|
tx.setSync(newDirNode.data, encodeDirListing(newDirList));
|
|
200
315
|
tx.commitSync();
|
|
201
316
|
}
|
|
202
|
-
catch (
|
|
203
|
-
|
|
204
|
-
|
|
317
|
+
catch (e_6) {
|
|
318
|
+
env_6.error = e_6;
|
|
319
|
+
env_6.hasError = true;
|
|
205
320
|
}
|
|
206
321
|
finally {
|
|
207
|
-
__disposeResources(
|
|
322
|
+
__disposeResources(env_6);
|
|
208
323
|
}
|
|
209
324
|
}
|
|
210
325
|
async stat(path) {
|
|
211
|
-
const
|
|
326
|
+
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
212
327
|
try {
|
|
213
|
-
const tx = __addDisposableResource(
|
|
328
|
+
const tx = __addDisposableResource(env_7, this.store.transaction(), true);
|
|
214
329
|
return (await this.findInode(tx, path, 'stat')).toStats();
|
|
215
330
|
}
|
|
216
|
-
catch (
|
|
217
|
-
|
|
218
|
-
|
|
331
|
+
catch (e_7) {
|
|
332
|
+
env_7.error = e_7;
|
|
333
|
+
env_7.hasError = true;
|
|
219
334
|
}
|
|
220
335
|
finally {
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
223
|
-
await
|
|
336
|
+
const result_4 = __disposeResources(env_7);
|
|
337
|
+
if (result_4)
|
|
338
|
+
await result_4;
|
|
224
339
|
}
|
|
225
340
|
}
|
|
226
341
|
statSync(path) {
|
|
227
|
-
const
|
|
342
|
+
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
228
343
|
try {
|
|
229
|
-
const tx = __addDisposableResource(
|
|
344
|
+
const tx = __addDisposableResource(env_8, this.store.transaction(), false);
|
|
230
345
|
return this.findInodeSync(tx, path, 'stat').toStats();
|
|
231
346
|
}
|
|
232
|
-
catch (
|
|
233
|
-
|
|
234
|
-
|
|
347
|
+
catch (e_8) {
|
|
348
|
+
env_8.error = e_8;
|
|
349
|
+
env_8.hasError = true;
|
|
235
350
|
}
|
|
236
351
|
finally {
|
|
237
|
-
__disposeResources(
|
|
352
|
+
__disposeResources(env_8);
|
|
238
353
|
}
|
|
239
354
|
}
|
|
240
|
-
async createFile(path, flag, mode) {
|
|
241
|
-
const node = await this.commitNew(path, S_IFREG, mode, new Uint8Array(), 'createFile');
|
|
242
|
-
return new
|
|
355
|
+
async createFile(path, flag, mode, options) {
|
|
356
|
+
const node = await this.commitNew(path, S_IFREG, { mode, ...options }, new Uint8Array(), 'createFile');
|
|
357
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
243
358
|
}
|
|
244
|
-
createFileSync(path, flag, mode) {
|
|
245
|
-
const node = this.commitNewSync(path, S_IFREG, mode, new Uint8Array(), 'createFile');
|
|
246
|
-
return new
|
|
359
|
+
createFileSync(path, flag, mode, options) {
|
|
360
|
+
const node = this.commitNewSync(path, S_IFREG, { mode, ...options }, new Uint8Array(), 'createFile');
|
|
361
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
247
362
|
}
|
|
248
363
|
async openFile(path, flag) {
|
|
249
|
-
const
|
|
364
|
+
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
250
365
|
try {
|
|
251
|
-
const tx = __addDisposableResource(
|
|
366
|
+
const tx = __addDisposableResource(env_9, this.store.transaction(), true);
|
|
252
367
|
const node = await this.findInode(tx, path, 'openFile');
|
|
253
|
-
const data = await
|
|
254
|
-
return new
|
|
368
|
+
//const data = (await tx.get(node.data)) ?? _throw(ErrnoError.With('ENODATA', path, 'openFile'));
|
|
369
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
255
370
|
}
|
|
256
|
-
catch (
|
|
257
|
-
|
|
258
|
-
|
|
371
|
+
catch (e_9) {
|
|
372
|
+
env_9.error = e_9;
|
|
373
|
+
env_9.hasError = true;
|
|
259
374
|
}
|
|
260
375
|
finally {
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
263
|
-
await
|
|
376
|
+
const result_5 = __disposeResources(env_9);
|
|
377
|
+
if (result_5)
|
|
378
|
+
await result_5;
|
|
264
379
|
}
|
|
265
380
|
}
|
|
266
381
|
openFileSync(path, flag) {
|
|
267
|
-
const
|
|
382
|
+
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
268
383
|
try {
|
|
269
|
-
const tx = __addDisposableResource(
|
|
384
|
+
const tx = __addDisposableResource(env_10, this.store.transaction(), false);
|
|
270
385
|
const node = this.findInodeSync(tx, path, 'openFile');
|
|
271
|
-
const data =
|
|
272
|
-
return new
|
|
386
|
+
//const data = tx.getSync(node.data) ?? _throw(ErrnoError.With('ENODATA', path, 'openFile'));
|
|
387
|
+
return new LazyFile(this, path, flag, node.toStats());
|
|
273
388
|
}
|
|
274
|
-
catch (
|
|
275
|
-
|
|
276
|
-
|
|
389
|
+
catch (e_10) {
|
|
390
|
+
env_10.error = e_10;
|
|
391
|
+
env_10.hasError = true;
|
|
277
392
|
}
|
|
278
393
|
finally {
|
|
279
|
-
__disposeResources(
|
|
394
|
+
__disposeResources(env_10);
|
|
280
395
|
}
|
|
281
396
|
}
|
|
282
397
|
async unlink(path) {
|
|
@@ -297,152 +412,225 @@ export class StoreFS extends FileSystem {
|
|
|
297
412
|
}
|
|
298
413
|
this.removeSync(path, true, 'rmdir');
|
|
299
414
|
}
|
|
300
|
-
async mkdir(path, mode) {
|
|
301
|
-
await this.commitNew(path, S_IFDIR, mode, encodeUTF8('{}'), 'mkdir');
|
|
415
|
+
async mkdir(path, mode, options) {
|
|
416
|
+
await this.commitNew(path, S_IFDIR, { mode, ...options }, encodeUTF8('{}'), 'mkdir');
|
|
302
417
|
}
|
|
303
|
-
mkdirSync(path, mode) {
|
|
304
|
-
this.commitNewSync(path, S_IFDIR, mode, encodeUTF8('{}'), 'mkdir');
|
|
418
|
+
mkdirSync(path, mode, options) {
|
|
419
|
+
this.commitNewSync(path, S_IFDIR, { mode, ...options }, encodeUTF8('{}'), 'mkdir');
|
|
305
420
|
}
|
|
306
421
|
async readdir(path) {
|
|
307
|
-
|
|
422
|
+
var _a;
|
|
423
|
+
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
308
424
|
try {
|
|
309
|
-
const tx = __addDisposableResource(
|
|
425
|
+
const tx = __addDisposableResource(env_11, this.store.transaction(), true);
|
|
310
426
|
const node = await this.findInode(tx, path, 'readdir');
|
|
311
|
-
return Object.keys(decodeDirListing(await
|
|
427
|
+
return Object.keys(decodeDirListing((_a = (await tx.get(node.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, 'readdir'))));
|
|
312
428
|
}
|
|
313
|
-
catch (
|
|
314
|
-
|
|
315
|
-
|
|
429
|
+
catch (e_11) {
|
|
430
|
+
env_11.error = e_11;
|
|
431
|
+
env_11.hasError = true;
|
|
316
432
|
}
|
|
317
433
|
finally {
|
|
318
|
-
const
|
|
319
|
-
if (
|
|
320
|
-
await
|
|
434
|
+
const result_6 = __disposeResources(env_11);
|
|
435
|
+
if (result_6)
|
|
436
|
+
await result_6;
|
|
321
437
|
}
|
|
322
438
|
}
|
|
323
439
|
readdirSync(path) {
|
|
324
|
-
|
|
440
|
+
var _a;
|
|
441
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
325
442
|
try {
|
|
326
|
-
const tx = __addDisposableResource(
|
|
443
|
+
const tx = __addDisposableResource(env_12, this.store.transaction(), false);
|
|
327
444
|
const node = this.findInodeSync(tx, path, 'readdir');
|
|
328
|
-
return Object.keys(decodeDirListing(
|
|
445
|
+
return Object.keys(decodeDirListing((_a = tx.getSync(node.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, 'readdir'))));
|
|
329
446
|
}
|
|
330
|
-
catch (
|
|
331
|
-
|
|
332
|
-
|
|
447
|
+
catch (e_12) {
|
|
448
|
+
env_12.error = e_12;
|
|
449
|
+
env_12.hasError = true;
|
|
333
450
|
}
|
|
334
451
|
finally {
|
|
335
|
-
__disposeResources(
|
|
452
|
+
__disposeResources(env_12);
|
|
336
453
|
}
|
|
337
454
|
}
|
|
338
455
|
/**
|
|
339
456
|
* Updated the inode and data node at `path`
|
|
340
457
|
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
341
458
|
*/
|
|
342
|
-
async sync(path, data,
|
|
343
|
-
const
|
|
459
|
+
async sync(path, data, metadata) {
|
|
460
|
+
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
344
461
|
try {
|
|
345
|
-
const tx = __addDisposableResource(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (inodeChanged) {
|
|
352
|
-
await tx.set(fileInodeId, serialize(fileInode));
|
|
353
|
-
}
|
|
462
|
+
const tx = __addDisposableResource(env_13, this.store.transaction(), true);
|
|
463
|
+
const inode = await this.findInode(tx, path, 'sync');
|
|
464
|
+
if (data)
|
|
465
|
+
await tx.set(inode.data, data);
|
|
466
|
+
if (inode.update(metadata))
|
|
467
|
+
await tx.set(inode.ino, serialize(inode));
|
|
354
468
|
await tx.commit();
|
|
355
469
|
}
|
|
356
|
-
catch (
|
|
357
|
-
|
|
358
|
-
|
|
470
|
+
catch (e_13) {
|
|
471
|
+
env_13.error = e_13;
|
|
472
|
+
env_13.hasError = true;
|
|
359
473
|
}
|
|
360
474
|
finally {
|
|
361
|
-
const
|
|
362
|
-
if (
|
|
363
|
-
await
|
|
475
|
+
const result_7 = __disposeResources(env_13);
|
|
476
|
+
if (result_7)
|
|
477
|
+
await result_7;
|
|
364
478
|
}
|
|
365
479
|
}
|
|
366
480
|
/**
|
|
367
481
|
* Updated the inode and data node at `path`
|
|
368
482
|
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
369
483
|
*/
|
|
370
|
-
syncSync(path, data,
|
|
371
|
-
const
|
|
484
|
+
syncSync(path, data, metadata) {
|
|
485
|
+
const env_14 = { stack: [], error: void 0, hasError: false };
|
|
372
486
|
try {
|
|
373
|
-
const tx = __addDisposableResource(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (inodeChanged) {
|
|
380
|
-
tx.setSync(fileInodeId, serialize(fileInode));
|
|
381
|
-
}
|
|
487
|
+
const tx = __addDisposableResource(env_14, this.store.transaction(), false);
|
|
488
|
+
const inode = this.findInodeSync(tx, path, 'sync');
|
|
489
|
+
if (data)
|
|
490
|
+
tx.setSync(inode.data, data);
|
|
491
|
+
if (inode.update(metadata))
|
|
492
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
382
493
|
tx.commitSync();
|
|
383
494
|
}
|
|
384
|
-
catch (
|
|
385
|
-
|
|
386
|
-
|
|
495
|
+
catch (e_14) {
|
|
496
|
+
env_14.error = e_14;
|
|
497
|
+
env_14.hasError = true;
|
|
387
498
|
}
|
|
388
499
|
finally {
|
|
389
|
-
__disposeResources(
|
|
500
|
+
__disposeResources(env_14);
|
|
390
501
|
}
|
|
391
502
|
}
|
|
392
503
|
async link(target, link) {
|
|
393
|
-
|
|
504
|
+
var _a;
|
|
505
|
+
const env_15 = { stack: [], error: void 0, hasError: false };
|
|
394
506
|
try {
|
|
395
|
-
const tx = __addDisposableResource(
|
|
396
|
-
const newDir = dirname(link), newDirNode = await this.findInode(tx, newDir, 'link'), listing = decodeDirListing(await
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
tx.setSync(ino, serialize(node));
|
|
507
|
+
const tx = __addDisposableResource(env_15, this.store.transaction(), true);
|
|
508
|
+
const newDir = dirname(link), newDirNode = await this.findInode(tx, newDir, 'link'), listing = decodeDirListing((_a = (await tx.get(newDirNode.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', newDir, 'link')));
|
|
509
|
+
const inode = await this.findInode(tx, target, 'link');
|
|
510
|
+
inode.nlink++;
|
|
511
|
+
listing[basename(link)] = inode.ino;
|
|
512
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
402
513
|
tx.setSync(newDirNode.data, encodeDirListing(listing));
|
|
403
514
|
tx.commitSync();
|
|
404
515
|
}
|
|
405
|
-
catch (
|
|
406
|
-
|
|
407
|
-
|
|
516
|
+
catch (e_15) {
|
|
517
|
+
env_15.error = e_15;
|
|
518
|
+
env_15.hasError = true;
|
|
408
519
|
}
|
|
409
520
|
finally {
|
|
410
|
-
const
|
|
411
|
-
if (
|
|
412
|
-
await
|
|
521
|
+
const result_8 = __disposeResources(env_15);
|
|
522
|
+
if (result_8)
|
|
523
|
+
await result_8;
|
|
413
524
|
}
|
|
414
525
|
}
|
|
415
526
|
linkSync(target, link) {
|
|
416
|
-
|
|
527
|
+
var _a;
|
|
528
|
+
const env_16 = { stack: [], error: void 0, hasError: false };
|
|
417
529
|
try {
|
|
418
|
-
const tx = __addDisposableResource(
|
|
419
|
-
const newDir = dirname(link), newDirNode = this.findInodeSync(tx, newDir, 'link'), listing = decodeDirListing(
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
tx.setSync(ino, serialize(node));
|
|
530
|
+
const tx = __addDisposableResource(env_16, this.store.transaction(), false);
|
|
531
|
+
const newDir = dirname(link), newDirNode = this.findInodeSync(tx, newDir, 'link'), listing = decodeDirListing((_a = tx.getSync(newDirNode.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', newDir, 'link')));
|
|
532
|
+
const inode = this.findInodeSync(tx, target, 'link');
|
|
533
|
+
inode.nlink++;
|
|
534
|
+
listing[basename(link)] = inode.ino;
|
|
535
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
425
536
|
tx.setSync(newDirNode.data, encodeDirListing(listing));
|
|
426
537
|
tx.commitSync();
|
|
427
538
|
}
|
|
428
|
-
catch (
|
|
429
|
-
|
|
430
|
-
|
|
539
|
+
catch (e_16) {
|
|
540
|
+
env_16.error = e_16;
|
|
541
|
+
env_16.hasError = true;
|
|
431
542
|
}
|
|
432
543
|
finally {
|
|
433
|
-
__disposeResources(
|
|
544
|
+
__disposeResources(env_16);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
async read(path, buffer, offset, end) {
|
|
548
|
+
var _a;
|
|
549
|
+
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
550
|
+
try {
|
|
551
|
+
const tx = __addDisposableResource(env_17, this.store.transaction(), true);
|
|
552
|
+
const inode = await this.findInode(tx, path, 'read');
|
|
553
|
+
const data = (_a = (await tx.get(inode.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
554
|
+
buffer.set(data.subarray(offset, end));
|
|
555
|
+
}
|
|
556
|
+
catch (e_17) {
|
|
557
|
+
env_17.error = e_17;
|
|
558
|
+
env_17.hasError = true;
|
|
559
|
+
}
|
|
560
|
+
finally {
|
|
561
|
+
const result_9 = __disposeResources(env_17);
|
|
562
|
+
if (result_9)
|
|
563
|
+
await result_9;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
readSync(path, buffer, offset, end) {
|
|
567
|
+
var _a;
|
|
568
|
+
const env_18 = { stack: [], error: void 0, hasError: false };
|
|
569
|
+
try {
|
|
570
|
+
const tx = __addDisposableResource(env_18, this.store.transaction(), false);
|
|
571
|
+
const inode = this.findInodeSync(tx, path, 'read');
|
|
572
|
+
const data = (_a = tx.getSync(inode.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
573
|
+
buffer.set(data.subarray(offset, end));
|
|
574
|
+
}
|
|
575
|
+
catch (e_18) {
|
|
576
|
+
env_18.error = e_18;
|
|
577
|
+
env_18.hasError = true;
|
|
578
|
+
}
|
|
579
|
+
finally {
|
|
580
|
+
__disposeResources(env_18);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
async write(path, data, offset) {
|
|
584
|
+
const env_19 = { stack: [], error: void 0, hasError: false };
|
|
585
|
+
try {
|
|
586
|
+
const tx = __addDisposableResource(env_19, this.store.transaction(), true);
|
|
587
|
+
const inode = await this.findInode(tx, path, 'write');
|
|
588
|
+
const buffer = growBuffer(await tx.get(inode.data), offset + data.byteLength);
|
|
589
|
+
buffer.set(data, offset);
|
|
590
|
+
inode.update({ mtimeMs: Date.now(), size: buffer.byteLength });
|
|
591
|
+
await tx.set(inode.ino, serialize(inode));
|
|
592
|
+
await tx.set(inode.data, buffer);
|
|
593
|
+
await tx.commit();
|
|
594
|
+
}
|
|
595
|
+
catch (e_19) {
|
|
596
|
+
env_19.error = e_19;
|
|
597
|
+
env_19.hasError = true;
|
|
598
|
+
}
|
|
599
|
+
finally {
|
|
600
|
+
const result_10 = __disposeResources(env_19);
|
|
601
|
+
if (result_10)
|
|
602
|
+
await result_10;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
writeSync(path, data, offset) {
|
|
606
|
+
const env_20 = { stack: [], error: void 0, hasError: false };
|
|
607
|
+
try {
|
|
608
|
+
const tx = __addDisposableResource(env_20, this.store.transaction(), false);
|
|
609
|
+
const inode = this.findInodeSync(tx, path, 'write');
|
|
610
|
+
const buffer = growBuffer(tx.getSync(inode.data), offset + data.byteLength);
|
|
611
|
+
buffer.set(data, offset);
|
|
612
|
+
inode.update({ mtimeMs: Date.now(), size: buffer.byteLength });
|
|
613
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
614
|
+
tx.setSync(inode.data, buffer);
|
|
615
|
+
tx.commitSync();
|
|
616
|
+
}
|
|
617
|
+
catch (e_20) {
|
|
618
|
+
env_20.error = e_20;
|
|
619
|
+
env_20.hasError = true;
|
|
620
|
+
}
|
|
621
|
+
finally {
|
|
622
|
+
__disposeResources(env_20);
|
|
434
623
|
}
|
|
435
624
|
}
|
|
436
625
|
/**
|
|
437
626
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
438
627
|
*/
|
|
439
628
|
async checkRoot() {
|
|
440
|
-
const
|
|
629
|
+
const env_21 = { stack: [], error: void 0, hasError: false };
|
|
441
630
|
try {
|
|
442
|
-
const tx = __addDisposableResource(
|
|
443
|
-
if (await tx.get(rootIno))
|
|
631
|
+
const tx = __addDisposableResource(env_21, this.store.transaction(), true);
|
|
632
|
+
if (await tx.get(rootIno))
|
|
444
633
|
return;
|
|
445
|
-
}
|
|
446
634
|
// Create new inode. o777, owned by root:root
|
|
447
635
|
const inode = new Inode();
|
|
448
636
|
inode.ino = rootIno;
|
|
@@ -452,26 +640,25 @@ export class StoreFS extends FileSystem {
|
|
|
452
640
|
await tx.set(rootIno, serialize(inode));
|
|
453
641
|
await tx.commit();
|
|
454
642
|
}
|
|
455
|
-
catch (
|
|
456
|
-
|
|
457
|
-
|
|
643
|
+
catch (e_21) {
|
|
644
|
+
env_21.error = e_21;
|
|
645
|
+
env_21.hasError = true;
|
|
458
646
|
}
|
|
459
647
|
finally {
|
|
460
|
-
const
|
|
461
|
-
if (
|
|
462
|
-
await
|
|
648
|
+
const result_11 = __disposeResources(env_21);
|
|
649
|
+
if (result_11)
|
|
650
|
+
await result_11;
|
|
463
651
|
}
|
|
464
652
|
}
|
|
465
653
|
/**
|
|
466
654
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
467
655
|
*/
|
|
468
656
|
checkRootSync() {
|
|
469
|
-
const
|
|
657
|
+
const env_22 = { stack: [], error: void 0, hasError: false };
|
|
470
658
|
try {
|
|
471
|
-
const tx = __addDisposableResource(
|
|
472
|
-
if (tx.getSync(rootIno))
|
|
659
|
+
const tx = __addDisposableResource(env_22, this.store.transaction(), false);
|
|
660
|
+
if (tx.getSync(rootIno))
|
|
473
661
|
return;
|
|
474
|
-
}
|
|
475
662
|
// Create new inode, mode o777, owned by root:root
|
|
476
663
|
const inode = new Inode();
|
|
477
664
|
inode.ino = rootIno;
|
|
@@ -481,12 +668,12 @@ export class StoreFS extends FileSystem {
|
|
|
481
668
|
tx.setSync(rootIno, serialize(inode));
|
|
482
669
|
tx.commitSync();
|
|
483
670
|
}
|
|
484
|
-
catch (
|
|
485
|
-
|
|
486
|
-
|
|
671
|
+
catch (e_22) {
|
|
672
|
+
env_22.error = e_22;
|
|
673
|
+
env_22.hasError = true;
|
|
487
674
|
}
|
|
488
675
|
finally {
|
|
489
|
-
__disposeResources(
|
|
676
|
+
__disposeResources(env_22);
|
|
490
677
|
}
|
|
491
678
|
}
|
|
492
679
|
/**
|
|
@@ -496,6 +683,7 @@ export class StoreFS extends FileSystem {
|
|
|
496
683
|
* the parent.
|
|
497
684
|
*/
|
|
498
685
|
async _findInode(tx, path, syscall, visited = new Set()) {
|
|
686
|
+
var _a, _b;
|
|
499
687
|
if (visited.has(path)) {
|
|
500
688
|
throw new ErrnoError(Errno.EIO, 'Infinite loop detected while finding inode', path);
|
|
501
689
|
}
|
|
@@ -504,8 +692,8 @@ export class StoreFS extends FileSystem {
|
|
|
504
692
|
return rootIno;
|
|
505
693
|
}
|
|
506
694
|
const { dir: parent, base: filename } = parse(path);
|
|
507
|
-
const inode = parent == '/' ? new Inode(await
|
|
508
|
-
const dirList = decodeDirListing(await
|
|
695
|
+
const inode = parent == '/' ? new Inode((_a = (await tx.get(rootIno))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parent, syscall))) : await this.findInode(tx, parent, syscall, visited);
|
|
696
|
+
const dirList = decodeDirListing((_b = (await tx.get(inode.data))) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENODATA', parent, syscall)));
|
|
509
697
|
if (!(filename in dirList)) {
|
|
510
698
|
throw ErrnoError.With('ENOENT', resolve(parent, filename), syscall);
|
|
511
699
|
}
|
|
@@ -519,6 +707,7 @@ export class StoreFS extends FileSystem {
|
|
|
519
707
|
* @return string The ID of the file's inode in the file system.
|
|
520
708
|
*/
|
|
521
709
|
_findInodeSync(tx, path, syscall, visited = new Set()) {
|
|
710
|
+
var _a, _b;
|
|
522
711
|
if (visited.has(path)) {
|
|
523
712
|
throw new ErrnoError(Errno.EIO, 'Infinite loop detected while finding inode', path);
|
|
524
713
|
}
|
|
@@ -527,8 +716,8 @@ export class StoreFS extends FileSystem {
|
|
|
527
716
|
return rootIno;
|
|
528
717
|
}
|
|
529
718
|
const { dir: parent, base: filename } = parse(path);
|
|
530
|
-
const inode = parent == '/' ? new Inode(
|
|
531
|
-
const dir = decodeDirListing(
|
|
719
|
+
const inode = parent == '/' ? new Inode((_a = tx.getSync(rootIno)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parent, syscall))) : this.findInodeSync(tx, parent, syscall, visited);
|
|
720
|
+
const dir = decodeDirListing((_b = tx.getSync(inode.data)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENODATA', parent, syscall)));
|
|
532
721
|
if (!(filename in dir)) {
|
|
533
722
|
throw ErrnoError.With('ENOENT', resolve(parent, filename), syscall);
|
|
534
723
|
}
|
|
@@ -540,8 +729,9 @@ export class StoreFS extends FileSystem {
|
|
|
540
729
|
* @todo memoize/cache
|
|
541
730
|
*/
|
|
542
731
|
async findInode(tx, path, syscall, visited = new Set()) {
|
|
732
|
+
var _a;
|
|
543
733
|
const ino = await this._findInode(tx, path, syscall, visited);
|
|
544
|
-
return new Inode(await
|
|
734
|
+
return new Inode((_a = (await tx.get(ino))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
545
735
|
}
|
|
546
736
|
/**
|
|
547
737
|
* Finds the Inode of `path`.
|
|
@@ -550,34 +740,9 @@ export class StoreFS extends FileSystem {
|
|
|
550
740
|
* @todo memoize/cache
|
|
551
741
|
*/
|
|
552
742
|
findInodeSync(tx, path, syscall, visited = new Set()) {
|
|
743
|
+
var _a;
|
|
553
744
|
const ino = this._findInodeSync(tx, path, syscall, visited);
|
|
554
|
-
return new Inode(
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Given an ID, retrieves the corresponding data.
|
|
558
|
-
* @param tx The transaction to use.
|
|
559
|
-
* @param path The corresponding path to the file (used for error messages).
|
|
560
|
-
* @param id The ID to look up.
|
|
561
|
-
*/
|
|
562
|
-
async get(tx, id, path, syscall) {
|
|
563
|
-
const data = await tx.get(id);
|
|
564
|
-
if (!data) {
|
|
565
|
-
throw ErrnoError.With('ENOENT', path, syscall);
|
|
566
|
-
}
|
|
567
|
-
return data;
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* Given an ID, retrieves the corresponding data.
|
|
571
|
-
* @param tx The transaction to use.
|
|
572
|
-
* @param path The corresponding path to the file (used for error messages).
|
|
573
|
-
* @param id The ID to look up.
|
|
574
|
-
*/
|
|
575
|
-
getSync(tx, id, path, syscall) {
|
|
576
|
-
const data = tx.getSync(id);
|
|
577
|
-
if (!data) {
|
|
578
|
-
throw ErrnoError.With('ENOENT', path, syscall);
|
|
579
|
-
}
|
|
580
|
-
return data;
|
|
745
|
+
return new Inode((_a = tx.getSync(ino)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
581
746
|
}
|
|
582
747
|
/**
|
|
583
748
|
* Adds a new node under a random ID. Retries before giving up in
|
|
@@ -585,7 +750,7 @@ export class StoreFS extends FileSystem {
|
|
|
585
750
|
*/
|
|
586
751
|
async allocNew(tx, path, syscall) {
|
|
587
752
|
for (let i = 0; i < maxInodeAllocTries; i++) {
|
|
588
|
-
const ino =
|
|
753
|
+
const ino = randomInt(0, size_max);
|
|
589
754
|
if (await tx.get(ino)) {
|
|
590
755
|
continue;
|
|
591
756
|
}
|
|
@@ -600,7 +765,7 @@ export class StoreFS extends FileSystem {
|
|
|
600
765
|
*/
|
|
601
766
|
allocNewSync(tx, path, syscall) {
|
|
602
767
|
for (let i = 0; i < maxInodeAllocTries; i++) {
|
|
603
|
-
const ino =
|
|
768
|
+
const ino = randomInt(0, size_max);
|
|
604
769
|
if (tx.getSync(ino)) {
|
|
605
770
|
continue;
|
|
606
771
|
}
|
|
@@ -616,8 +781,9 @@ export class StoreFS extends FileSystem {
|
|
|
616
781
|
* @param mode The mode to create the new file with.
|
|
617
782
|
* @param data The data to store at the file's data node.
|
|
618
783
|
*/
|
|
619
|
-
async commitNew(path, type,
|
|
620
|
-
|
|
784
|
+
async commitNew(path, type, options, data, syscall) {
|
|
785
|
+
var _a;
|
|
786
|
+
const env_23 = { stack: [], error: void 0, hasError: false };
|
|
621
787
|
try {
|
|
622
788
|
/*
|
|
623
789
|
The root always exists.
|
|
@@ -627,10 +793,10 @@ export class StoreFS extends FileSystem {
|
|
|
627
793
|
if (path == '/') {
|
|
628
794
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
629
795
|
}
|
|
630
|
-
const tx = __addDisposableResource(
|
|
796
|
+
const tx = __addDisposableResource(env_23, this.store.transaction(), true);
|
|
631
797
|
const { dir: parentPath, base: fname } = parse(path);
|
|
632
798
|
const parent = await this.findInode(tx, parentPath, syscall);
|
|
633
|
-
const listing = decodeDirListing(await
|
|
799
|
+
const listing = decodeDirListing((_a = (await tx.get(parent.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parentPath, syscall)));
|
|
634
800
|
// Check if file already exists.
|
|
635
801
|
if (listing[fname]) {
|
|
636
802
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
@@ -639,9 +805,9 @@ export class StoreFS extends FileSystem {
|
|
|
639
805
|
const inode = new Inode();
|
|
640
806
|
inode.ino = await this.allocNew(tx, path, syscall);
|
|
641
807
|
inode.data = await this.allocNew(tx, path, syscall);
|
|
642
|
-
inode.mode = mode | type;
|
|
643
|
-
inode.uid = parent.mode & S_ISUID ? parent.uid :
|
|
644
|
-
inode.gid = parent.mode & S_ISGID ? parent.gid :
|
|
808
|
+
inode.mode = options.mode | type;
|
|
809
|
+
inode.uid = parent.mode & S_ISUID ? parent.uid : options.uid;
|
|
810
|
+
inode.gid = parent.mode & S_ISGID ? parent.gid : options.gid;
|
|
645
811
|
inode.size = data.length;
|
|
646
812
|
await tx.set(inode.ino, serialize(inode));
|
|
647
813
|
await tx.set(inode.data, data);
|
|
@@ -651,14 +817,14 @@ export class StoreFS extends FileSystem {
|
|
|
651
817
|
await tx.commit();
|
|
652
818
|
return inode;
|
|
653
819
|
}
|
|
654
|
-
catch (
|
|
655
|
-
|
|
656
|
-
|
|
820
|
+
catch (e_23) {
|
|
821
|
+
env_23.error = e_23;
|
|
822
|
+
env_23.hasError = true;
|
|
657
823
|
}
|
|
658
824
|
finally {
|
|
659
|
-
const
|
|
660
|
-
if (
|
|
661
|
-
await
|
|
825
|
+
const result_12 = __disposeResources(env_23);
|
|
826
|
+
if (result_12)
|
|
827
|
+
await result_12;
|
|
662
828
|
}
|
|
663
829
|
}
|
|
664
830
|
/**
|
|
@@ -670,8 +836,9 @@ export class StoreFS extends FileSystem {
|
|
|
670
836
|
* @param data The data to store at the file's data node.
|
|
671
837
|
* @return The Inode for the new file.
|
|
672
838
|
*/
|
|
673
|
-
commitNewSync(path, type,
|
|
674
|
-
|
|
839
|
+
commitNewSync(path, type, options, data, syscall) {
|
|
840
|
+
var _a;
|
|
841
|
+
const env_24 = { stack: [], error: void 0, hasError: false };
|
|
675
842
|
try {
|
|
676
843
|
/*
|
|
677
844
|
The root always exists.
|
|
@@ -681,10 +848,10 @@ export class StoreFS extends FileSystem {
|
|
|
681
848
|
if (path == '/') {
|
|
682
849
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
683
850
|
}
|
|
684
|
-
const tx = __addDisposableResource(
|
|
851
|
+
const tx = __addDisposableResource(env_24, this.store.transaction(), false);
|
|
685
852
|
const { dir: parentPath, base: fname } = parse(path);
|
|
686
853
|
const parent = this.findInodeSync(tx, parentPath, syscall);
|
|
687
|
-
const listing = decodeDirListing(
|
|
854
|
+
const listing = decodeDirListing((_a = tx.getSync(parent.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parentPath, syscall)));
|
|
688
855
|
// Check if file already exists.
|
|
689
856
|
if (listing[fname]) {
|
|
690
857
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
@@ -694,9 +861,9 @@ export class StoreFS extends FileSystem {
|
|
|
694
861
|
inode.ino = this.allocNewSync(tx, path, syscall);
|
|
695
862
|
inode.data = this.allocNewSync(tx, path, syscall);
|
|
696
863
|
inode.size = data.length;
|
|
697
|
-
inode.mode = mode | type;
|
|
698
|
-
inode.uid = parent.mode & S_ISUID ? parent.uid :
|
|
699
|
-
inode.gid = parent.mode & S_ISGID ? parent.gid :
|
|
864
|
+
inode.mode = options.mode | type;
|
|
865
|
+
inode.uid = parent.mode & S_ISUID ? parent.uid : options.uid;
|
|
866
|
+
inode.gid = parent.mode & S_ISGID ? parent.gid : options.gid;
|
|
700
867
|
// Update and commit parent directory listing.
|
|
701
868
|
tx.setSync(inode.ino, serialize(inode));
|
|
702
869
|
tx.setSync(inode.data, data);
|
|
@@ -705,12 +872,12 @@ export class StoreFS extends FileSystem {
|
|
|
705
872
|
tx.commitSync();
|
|
706
873
|
return inode;
|
|
707
874
|
}
|
|
708
|
-
catch (
|
|
709
|
-
|
|
710
|
-
|
|
875
|
+
catch (e_24) {
|
|
876
|
+
env_24.error = e_24;
|
|
877
|
+
env_24.hasError = true;
|
|
711
878
|
}
|
|
712
879
|
finally {
|
|
713
|
-
__disposeResources(
|
|
880
|
+
__disposeResources(env_24);
|
|
714
881
|
}
|
|
715
882
|
}
|
|
716
883
|
/**
|
|
@@ -720,16 +887,17 @@ export class StoreFS extends FileSystem {
|
|
|
720
887
|
* @todo Update mtime.
|
|
721
888
|
*/
|
|
722
889
|
async remove(path, isDir, syscall) {
|
|
723
|
-
|
|
890
|
+
var _a, _b;
|
|
891
|
+
const env_25 = { stack: [], error: void 0, hasError: false };
|
|
724
892
|
try {
|
|
725
|
-
const tx = __addDisposableResource(
|
|
726
|
-
const { dir: parent, base: fileName } = parse(path), parentNode = await this.findInode(tx, parent, syscall), listing = decodeDirListing(await
|
|
893
|
+
const tx = __addDisposableResource(env_25, this.store.transaction(), true);
|
|
894
|
+
const { dir: parent, base: fileName } = parse(path), parentNode = await this.findInode(tx, parent, syscall), listing = decodeDirListing((_a = (await tx.get(parentNode.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parent, syscall)));
|
|
727
895
|
if (!listing[fileName]) {
|
|
728
896
|
throw ErrnoError.With('ENOENT', path, 'remove');
|
|
729
897
|
}
|
|
730
898
|
const fileIno = listing[fileName];
|
|
731
899
|
// Get file inode.
|
|
732
|
-
const fileNode = new Inode(await
|
|
900
|
+
const fileNode = new Inode((_b = (await tx.get(fileIno))) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
733
901
|
// Remove from directory listing of parent.
|
|
734
902
|
delete listing[fileName];
|
|
735
903
|
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
@@ -744,14 +912,14 @@ export class StoreFS extends FileSystem {
|
|
|
744
912
|
// Success.
|
|
745
913
|
await tx.commit();
|
|
746
914
|
}
|
|
747
|
-
catch (
|
|
748
|
-
|
|
749
|
-
|
|
915
|
+
catch (e_25) {
|
|
916
|
+
env_25.error = e_25;
|
|
917
|
+
env_25.hasError = true;
|
|
750
918
|
}
|
|
751
919
|
finally {
|
|
752
|
-
const
|
|
753
|
-
if (
|
|
754
|
-
await
|
|
920
|
+
const result_13 = __disposeResources(env_25);
|
|
921
|
+
if (result_13)
|
|
922
|
+
await result_13;
|
|
755
923
|
}
|
|
756
924
|
}
|
|
757
925
|
/**
|
|
@@ -761,15 +929,16 @@ export class StoreFS extends FileSystem {
|
|
|
761
929
|
* @todo Update mtime.
|
|
762
930
|
*/
|
|
763
931
|
removeSync(path, isDir, syscall) {
|
|
764
|
-
|
|
932
|
+
var _a, _b;
|
|
933
|
+
const env_26 = { stack: [], error: void 0, hasError: false };
|
|
765
934
|
try {
|
|
766
|
-
const tx = __addDisposableResource(
|
|
767
|
-
const { dir: parent, base: fileName } = parse(path), parentNode = this.findInodeSync(tx, parent, syscall), listing = decodeDirListing(
|
|
935
|
+
const tx = __addDisposableResource(env_26, this.store.transaction(), false);
|
|
936
|
+
const { dir: parent, base: fileName } = parse(path), parentNode = this.findInodeSync(tx, parent, syscall), listing = decodeDirListing((_a = tx.getSync(parentNode.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parent, syscall))), fileIno = listing[fileName];
|
|
768
937
|
if (!fileIno) {
|
|
769
938
|
throw ErrnoError.With('ENOENT', path, 'remove');
|
|
770
939
|
}
|
|
771
940
|
// Get file inode.
|
|
772
|
-
const fileNode = new Inode(
|
|
941
|
+
const fileNode = new Inode((_b = tx.getSync(fileIno)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
773
942
|
// Remove from directory listing of parent.
|
|
774
943
|
delete listing[fileName];
|
|
775
944
|
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
@@ -785,12 +954,12 @@ export class StoreFS extends FileSystem {
|
|
|
785
954
|
// Success.
|
|
786
955
|
tx.commitSync();
|
|
787
956
|
}
|
|
788
|
-
catch (
|
|
789
|
-
|
|
790
|
-
|
|
957
|
+
catch (e_26) {
|
|
958
|
+
env_26.error = e_26;
|
|
959
|
+
env_26.hasError = true;
|
|
791
960
|
}
|
|
792
961
|
finally {
|
|
793
|
-
__disposeResources(
|
|
962
|
+
__disposeResources(env_26);
|
|
794
963
|
}
|
|
795
964
|
}
|
|
796
965
|
}
|