@zenfs/core 1.7.2 → 1.8.0
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 +7 -2
- package/dist/backends/overlay.js +32 -9
- package/dist/backends/passthrough.d.ts +4 -0
- package/dist/backends/passthrough.js +128 -0
- package/dist/backends/port/fs.d.ts +9 -44
- package/dist/backends/port/fs.js +93 -116
- package/dist/backends/port/rpc.d.ts +8 -5
- 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 +55 -34
- package/dist/backends/store/fs.js +417 -233
- 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 +11 -10
- package/dist/devices.js +15 -11
- package/dist/file.d.ts +111 -7
- package/dist/file.js +319 -71
- package/dist/filesystem.d.ts +22 -4
- package/dist/mixins/mutexed.d.ts +7 -2
- package/dist/mixins/mutexed.js +56 -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 +17 -3
- package/dist/utils.js +32 -10
- 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 +31 -11
- package/dist/vfs/shared.js +2 -0
- package/dist/vfs/sync.js +25 -13
- package/dist/vfs/types.d.ts +15 -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/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
55
|
import { PreloadFile } from '../../file.js';
|
|
58
56
|
import { FileSystem } from '../../filesystem.js';
|
|
57
|
+
import { _throw, canary, decodeDirListing, encodeDirListing, encodeUTF8 } 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,86 @@ 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');
|
|
355
|
+
async createFile(path, flag, mode, options) {
|
|
356
|
+
const node = await this.commitNew(path, S_IFREG, { mode, ...options }, new Uint8Array(), 'createFile');
|
|
242
357
|
return new PreloadFile(this, path, flag, node.toStats(), new Uint8Array());
|
|
243
358
|
}
|
|
244
|
-
createFileSync(path, flag, mode) {
|
|
245
|
-
const node = this.commitNewSync(path, S_IFREG, mode, new Uint8Array(), 'createFile');
|
|
359
|
+
createFileSync(path, flag, mode, options) {
|
|
360
|
+
const node = this.commitNewSync(path, S_IFREG, { mode, ...options }, new Uint8Array(), 'createFile');
|
|
246
361
|
return new PreloadFile(this, path, flag, node.toStats(), new Uint8Array());
|
|
247
362
|
}
|
|
248
363
|
async openFile(path, flag) {
|
|
249
|
-
|
|
364
|
+
var _a;
|
|
365
|
+
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
250
366
|
try {
|
|
251
|
-
const tx = __addDisposableResource(
|
|
367
|
+
const tx = __addDisposableResource(env_9, this.store.transaction(), true);
|
|
252
368
|
const node = await this.findInode(tx, path, 'openFile');
|
|
253
|
-
const data = await
|
|
369
|
+
const data = (_a = (await tx.get(node.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'openFile'));
|
|
254
370
|
return new PreloadFile(this, path, flag, node.toStats(), data);
|
|
255
371
|
}
|
|
256
|
-
catch (
|
|
257
|
-
|
|
258
|
-
|
|
372
|
+
catch (e_9) {
|
|
373
|
+
env_9.error = e_9;
|
|
374
|
+
env_9.hasError = true;
|
|
259
375
|
}
|
|
260
376
|
finally {
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
263
|
-
await
|
|
377
|
+
const result_5 = __disposeResources(env_9);
|
|
378
|
+
if (result_5)
|
|
379
|
+
await result_5;
|
|
264
380
|
}
|
|
265
381
|
}
|
|
266
382
|
openFileSync(path, flag) {
|
|
267
|
-
|
|
383
|
+
var _a;
|
|
384
|
+
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
268
385
|
try {
|
|
269
|
-
const tx = __addDisposableResource(
|
|
386
|
+
const tx = __addDisposableResource(env_10, this.store.transaction(), false);
|
|
270
387
|
const node = this.findInodeSync(tx, path, 'openFile');
|
|
271
|
-
const data =
|
|
388
|
+
const data = (_a = tx.getSync(node.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, 'openFile'));
|
|
272
389
|
return new PreloadFile(this, path, flag, node.toStats(), data);
|
|
273
390
|
}
|
|
274
|
-
catch (
|
|
275
|
-
|
|
276
|
-
|
|
391
|
+
catch (e_10) {
|
|
392
|
+
env_10.error = e_10;
|
|
393
|
+
env_10.hasError = true;
|
|
277
394
|
}
|
|
278
395
|
finally {
|
|
279
|
-
__disposeResources(
|
|
396
|
+
__disposeResources(env_10);
|
|
280
397
|
}
|
|
281
398
|
}
|
|
282
399
|
async unlink(path) {
|
|
@@ -297,152 +414,238 @@ export class StoreFS extends FileSystem {
|
|
|
297
414
|
}
|
|
298
415
|
this.removeSync(path, true, 'rmdir');
|
|
299
416
|
}
|
|
300
|
-
async mkdir(path, mode) {
|
|
301
|
-
await this.commitNew(path, S_IFDIR, mode, encodeUTF8('{}'), 'mkdir');
|
|
417
|
+
async mkdir(path, mode, options) {
|
|
418
|
+
await this.commitNew(path, S_IFDIR, { mode, ...options }, encodeUTF8('{}'), 'mkdir');
|
|
302
419
|
}
|
|
303
|
-
mkdirSync(path, mode) {
|
|
304
|
-
this.commitNewSync(path, S_IFDIR, mode, encodeUTF8('{}'), 'mkdir');
|
|
420
|
+
mkdirSync(path, mode, options) {
|
|
421
|
+
this.commitNewSync(path, S_IFDIR, { mode, ...options }, encodeUTF8('{}'), 'mkdir');
|
|
305
422
|
}
|
|
306
423
|
async readdir(path) {
|
|
307
|
-
|
|
424
|
+
var _a;
|
|
425
|
+
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
308
426
|
try {
|
|
309
|
-
const tx = __addDisposableResource(
|
|
427
|
+
const tx = __addDisposableResource(env_11, this.store.transaction(), true);
|
|
310
428
|
const node = await this.findInode(tx, path, 'readdir');
|
|
311
|
-
return Object.keys(decodeDirListing(await
|
|
429
|
+
return Object.keys(decodeDirListing((_a = (await tx.get(node.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, 'readdir'))));
|
|
312
430
|
}
|
|
313
|
-
catch (
|
|
314
|
-
|
|
315
|
-
|
|
431
|
+
catch (e_11) {
|
|
432
|
+
env_11.error = e_11;
|
|
433
|
+
env_11.hasError = true;
|
|
316
434
|
}
|
|
317
435
|
finally {
|
|
318
|
-
const
|
|
319
|
-
if (
|
|
320
|
-
await
|
|
436
|
+
const result_6 = __disposeResources(env_11);
|
|
437
|
+
if (result_6)
|
|
438
|
+
await result_6;
|
|
321
439
|
}
|
|
322
440
|
}
|
|
323
441
|
readdirSync(path) {
|
|
324
|
-
|
|
442
|
+
var _a;
|
|
443
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
325
444
|
try {
|
|
326
|
-
const tx = __addDisposableResource(
|
|
445
|
+
const tx = __addDisposableResource(env_12, this.store.transaction(), false);
|
|
327
446
|
const node = this.findInodeSync(tx, path, 'readdir');
|
|
328
|
-
return Object.keys(decodeDirListing(
|
|
447
|
+
return Object.keys(decodeDirListing((_a = tx.getSync(node.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, 'readdir'))));
|
|
329
448
|
}
|
|
330
|
-
catch (
|
|
331
|
-
|
|
332
|
-
|
|
449
|
+
catch (e_12) {
|
|
450
|
+
env_12.error = e_12;
|
|
451
|
+
env_12.hasError = true;
|
|
333
452
|
}
|
|
334
453
|
finally {
|
|
335
|
-
__disposeResources(
|
|
454
|
+
__disposeResources(env_12);
|
|
336
455
|
}
|
|
337
456
|
}
|
|
338
457
|
/**
|
|
339
458
|
* Updated the inode and data node at `path`
|
|
340
459
|
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
341
460
|
*/
|
|
342
|
-
async sync(path, data,
|
|
343
|
-
const
|
|
461
|
+
async sync(path, data, metadata) {
|
|
462
|
+
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
344
463
|
try {
|
|
345
|
-
const tx = __addDisposableResource(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (inodeChanged) {
|
|
352
|
-
await tx.set(fileInodeId, serialize(fileInode));
|
|
353
|
-
}
|
|
464
|
+
const tx = __addDisposableResource(env_13, this.store.transaction(), true);
|
|
465
|
+
const inode = await this.findInode(tx, path, 'sync');
|
|
466
|
+
if (data)
|
|
467
|
+
await tx.set(inode.data, data);
|
|
468
|
+
if (inode.update(metadata))
|
|
469
|
+
await tx.set(inode.ino, serialize(inode));
|
|
354
470
|
await tx.commit();
|
|
355
471
|
}
|
|
356
|
-
catch (
|
|
357
|
-
|
|
358
|
-
|
|
472
|
+
catch (e_13) {
|
|
473
|
+
env_13.error = e_13;
|
|
474
|
+
env_13.hasError = true;
|
|
359
475
|
}
|
|
360
476
|
finally {
|
|
361
|
-
const
|
|
362
|
-
if (
|
|
363
|
-
await
|
|
477
|
+
const result_7 = __disposeResources(env_13);
|
|
478
|
+
if (result_7)
|
|
479
|
+
await result_7;
|
|
364
480
|
}
|
|
365
481
|
}
|
|
366
482
|
/**
|
|
367
483
|
* Updated the inode and data node at `path`
|
|
368
484
|
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
369
485
|
*/
|
|
370
|
-
syncSync(path, data,
|
|
371
|
-
const
|
|
486
|
+
syncSync(path, data, metadata) {
|
|
487
|
+
const env_14 = { stack: [], error: void 0, hasError: false };
|
|
372
488
|
try {
|
|
373
|
-
const tx = __addDisposableResource(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (inodeChanged) {
|
|
380
|
-
tx.setSync(fileInodeId, serialize(fileInode));
|
|
381
|
-
}
|
|
489
|
+
const tx = __addDisposableResource(env_14, this.store.transaction(), false);
|
|
490
|
+
const inode = this.findInodeSync(tx, path, 'sync');
|
|
491
|
+
if (data)
|
|
492
|
+
tx.setSync(inode.data, data);
|
|
493
|
+
if (inode.update(metadata))
|
|
494
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
382
495
|
tx.commitSync();
|
|
383
496
|
}
|
|
384
|
-
catch (
|
|
385
|
-
|
|
386
|
-
|
|
497
|
+
catch (e_14) {
|
|
498
|
+
env_14.error = e_14;
|
|
499
|
+
env_14.hasError = true;
|
|
387
500
|
}
|
|
388
501
|
finally {
|
|
389
|
-
__disposeResources(
|
|
502
|
+
__disposeResources(env_14);
|
|
390
503
|
}
|
|
391
504
|
}
|
|
392
505
|
async link(target, link) {
|
|
393
|
-
|
|
506
|
+
var _a;
|
|
507
|
+
const env_15 = { stack: [], error: void 0, hasError: false };
|
|
394
508
|
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));
|
|
509
|
+
const tx = __addDisposableResource(env_15, this.store.transaction(), true);
|
|
510
|
+
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')));
|
|
511
|
+
const inode = await this.findInode(tx, target, 'link');
|
|
512
|
+
inode.nlink++;
|
|
513
|
+
listing[basename(link)] = inode.ino;
|
|
514
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
402
515
|
tx.setSync(newDirNode.data, encodeDirListing(listing));
|
|
403
516
|
tx.commitSync();
|
|
404
517
|
}
|
|
405
|
-
catch (
|
|
406
|
-
|
|
407
|
-
|
|
518
|
+
catch (e_15) {
|
|
519
|
+
env_15.error = e_15;
|
|
520
|
+
env_15.hasError = true;
|
|
408
521
|
}
|
|
409
522
|
finally {
|
|
410
|
-
const
|
|
411
|
-
if (
|
|
412
|
-
await
|
|
523
|
+
const result_8 = __disposeResources(env_15);
|
|
524
|
+
if (result_8)
|
|
525
|
+
await result_8;
|
|
413
526
|
}
|
|
414
527
|
}
|
|
415
528
|
linkSync(target, link) {
|
|
416
|
-
|
|
529
|
+
var _a;
|
|
530
|
+
const env_16 = { stack: [], error: void 0, hasError: false };
|
|
417
531
|
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));
|
|
532
|
+
const tx = __addDisposableResource(env_16, this.store.transaction(), false);
|
|
533
|
+
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')));
|
|
534
|
+
const inode = this.findInodeSync(tx, target, 'link');
|
|
535
|
+
inode.nlink++;
|
|
536
|
+
listing[basename(link)] = inode.ino;
|
|
537
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
425
538
|
tx.setSync(newDirNode.data, encodeDirListing(listing));
|
|
426
539
|
tx.commitSync();
|
|
427
540
|
}
|
|
428
|
-
catch (
|
|
429
|
-
|
|
430
|
-
|
|
541
|
+
catch (e_16) {
|
|
542
|
+
env_16.error = e_16;
|
|
543
|
+
env_16.hasError = true;
|
|
431
544
|
}
|
|
432
545
|
finally {
|
|
433
|
-
__disposeResources(
|
|
546
|
+
__disposeResources(env_16);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Used by lazy file
|
|
551
|
+
* @internal
|
|
552
|
+
*/
|
|
553
|
+
async read(path, offset, length) {
|
|
554
|
+
var _a;
|
|
555
|
+
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
556
|
+
try {
|
|
557
|
+
const tx = __addDisposableResource(env_17, this.store.transaction(), true);
|
|
558
|
+
const inode = await this.findInode(tx, path, 'read');
|
|
559
|
+
const buffer = (_a = (await tx.get(inode.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
560
|
+
return buffer.slice(offset, offset + length);
|
|
561
|
+
}
|
|
562
|
+
catch (e_17) {
|
|
563
|
+
env_17.error = e_17;
|
|
564
|
+
env_17.hasError = true;
|
|
565
|
+
}
|
|
566
|
+
finally {
|
|
567
|
+
const result_9 = __disposeResources(env_17);
|
|
568
|
+
if (result_9)
|
|
569
|
+
await result_9;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Used by lazy file
|
|
574
|
+
* @internal
|
|
575
|
+
*/
|
|
576
|
+
readSync(path, offset, length) {
|
|
577
|
+
var _a;
|
|
578
|
+
const env_18 = { stack: [], error: void 0, hasError: false };
|
|
579
|
+
try {
|
|
580
|
+
const tx = __addDisposableResource(env_18, this.store.transaction(), false);
|
|
581
|
+
const inode = this.findInodeSync(tx, path, 'read');
|
|
582
|
+
const buffer = (_a = tx.getSync(inode.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
583
|
+
return buffer.slice(offset, offset + length);
|
|
584
|
+
}
|
|
585
|
+
catch (e_18) {
|
|
586
|
+
env_18.error = e_18;
|
|
587
|
+
env_18.hasError = true;
|
|
588
|
+
}
|
|
589
|
+
finally {
|
|
590
|
+
__disposeResources(env_18);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Used by lazy file
|
|
595
|
+
* @internal
|
|
596
|
+
*/
|
|
597
|
+
async write(path, data, offset) {
|
|
598
|
+
const env_19 = { stack: [], error: void 0, hasError: false };
|
|
599
|
+
try {
|
|
600
|
+
const tx = __addDisposableResource(env_19, this.store.transaction(), true);
|
|
601
|
+
const inode = await this.findInode(tx, path, 'write');
|
|
602
|
+
const buffer = await tx.get(inode.data);
|
|
603
|
+
buffer.set(data, offset);
|
|
604
|
+
await this.sync(path, buffer, inode);
|
|
605
|
+
}
|
|
606
|
+
catch (e_19) {
|
|
607
|
+
env_19.error = e_19;
|
|
608
|
+
env_19.hasError = true;
|
|
609
|
+
}
|
|
610
|
+
finally {
|
|
611
|
+
const result_10 = __disposeResources(env_19);
|
|
612
|
+
if (result_10)
|
|
613
|
+
await result_10;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Used by lazy file
|
|
618
|
+
* @internal
|
|
619
|
+
*/
|
|
620
|
+
writeSync(path, data, offset) {
|
|
621
|
+
const env_20 = { stack: [], error: void 0, hasError: false };
|
|
622
|
+
try {
|
|
623
|
+
const tx = __addDisposableResource(env_20, this.store.transaction(), false);
|
|
624
|
+
const inode = this.findInodeSync(tx, path, 'write');
|
|
625
|
+
inode.update({ mtimeMs: Date.now() });
|
|
626
|
+
const buffer = tx.getSync(inode.data);
|
|
627
|
+
buffer.set(data, offset);
|
|
628
|
+
tx.setSync(inode.ino, serialize(inode));
|
|
629
|
+
tx.setSync(inode.data, buffer);
|
|
630
|
+
tx.commitSync();
|
|
631
|
+
}
|
|
632
|
+
catch (e_20) {
|
|
633
|
+
env_20.error = e_20;
|
|
634
|
+
env_20.hasError = true;
|
|
635
|
+
}
|
|
636
|
+
finally {
|
|
637
|
+
__disposeResources(env_20);
|
|
434
638
|
}
|
|
435
639
|
}
|
|
436
640
|
/**
|
|
437
641
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
438
642
|
*/
|
|
439
643
|
async checkRoot() {
|
|
440
|
-
const
|
|
644
|
+
const env_21 = { stack: [], error: void 0, hasError: false };
|
|
441
645
|
try {
|
|
442
|
-
const tx = __addDisposableResource(
|
|
443
|
-
if (await tx.get(rootIno))
|
|
646
|
+
const tx = __addDisposableResource(env_21, this.store.transaction(), true);
|
|
647
|
+
if (await tx.get(rootIno))
|
|
444
648
|
return;
|
|
445
|
-
}
|
|
446
649
|
// Create new inode. o777, owned by root:root
|
|
447
650
|
const inode = new Inode();
|
|
448
651
|
inode.ino = rootIno;
|
|
@@ -452,26 +655,25 @@ export class StoreFS extends FileSystem {
|
|
|
452
655
|
await tx.set(rootIno, serialize(inode));
|
|
453
656
|
await tx.commit();
|
|
454
657
|
}
|
|
455
|
-
catch (
|
|
456
|
-
|
|
457
|
-
|
|
658
|
+
catch (e_21) {
|
|
659
|
+
env_21.error = e_21;
|
|
660
|
+
env_21.hasError = true;
|
|
458
661
|
}
|
|
459
662
|
finally {
|
|
460
|
-
const
|
|
461
|
-
if (
|
|
462
|
-
await
|
|
663
|
+
const result_11 = __disposeResources(env_21);
|
|
664
|
+
if (result_11)
|
|
665
|
+
await result_11;
|
|
463
666
|
}
|
|
464
667
|
}
|
|
465
668
|
/**
|
|
466
669
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
467
670
|
*/
|
|
468
671
|
checkRootSync() {
|
|
469
|
-
const
|
|
672
|
+
const env_22 = { stack: [], error: void 0, hasError: false };
|
|
470
673
|
try {
|
|
471
|
-
const tx = __addDisposableResource(
|
|
472
|
-
if (tx.getSync(rootIno))
|
|
674
|
+
const tx = __addDisposableResource(env_22, this.store.transaction(), false);
|
|
675
|
+
if (tx.getSync(rootIno))
|
|
473
676
|
return;
|
|
474
|
-
}
|
|
475
677
|
// Create new inode, mode o777, owned by root:root
|
|
476
678
|
const inode = new Inode();
|
|
477
679
|
inode.ino = rootIno;
|
|
@@ -481,12 +683,12 @@ export class StoreFS extends FileSystem {
|
|
|
481
683
|
tx.setSync(rootIno, serialize(inode));
|
|
482
684
|
tx.commitSync();
|
|
483
685
|
}
|
|
484
|
-
catch (
|
|
485
|
-
|
|
486
|
-
|
|
686
|
+
catch (e_22) {
|
|
687
|
+
env_22.error = e_22;
|
|
688
|
+
env_22.hasError = true;
|
|
487
689
|
}
|
|
488
690
|
finally {
|
|
489
|
-
__disposeResources(
|
|
691
|
+
__disposeResources(env_22);
|
|
490
692
|
}
|
|
491
693
|
}
|
|
492
694
|
/**
|
|
@@ -496,6 +698,7 @@ export class StoreFS extends FileSystem {
|
|
|
496
698
|
* the parent.
|
|
497
699
|
*/
|
|
498
700
|
async _findInode(tx, path, syscall, visited = new Set()) {
|
|
701
|
+
var _a, _b;
|
|
499
702
|
if (visited.has(path)) {
|
|
500
703
|
throw new ErrnoError(Errno.EIO, 'Infinite loop detected while finding inode', path);
|
|
501
704
|
}
|
|
@@ -504,8 +707,8 @@ export class StoreFS extends FileSystem {
|
|
|
504
707
|
return rootIno;
|
|
505
708
|
}
|
|
506
709
|
const { dir: parent, base: filename } = parse(path);
|
|
507
|
-
const inode = parent == '/' ? new Inode(await
|
|
508
|
-
const dirList = decodeDirListing(await
|
|
710
|
+
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);
|
|
711
|
+
const dirList = decodeDirListing((_b = (await tx.get(inode.data))) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENODATA', parent, syscall)));
|
|
509
712
|
if (!(filename in dirList)) {
|
|
510
713
|
throw ErrnoError.With('ENOENT', resolve(parent, filename), syscall);
|
|
511
714
|
}
|
|
@@ -519,6 +722,7 @@ export class StoreFS extends FileSystem {
|
|
|
519
722
|
* @return string The ID of the file's inode in the file system.
|
|
520
723
|
*/
|
|
521
724
|
_findInodeSync(tx, path, syscall, visited = new Set()) {
|
|
725
|
+
var _a, _b;
|
|
522
726
|
if (visited.has(path)) {
|
|
523
727
|
throw new ErrnoError(Errno.EIO, 'Infinite loop detected while finding inode', path);
|
|
524
728
|
}
|
|
@@ -527,8 +731,8 @@ export class StoreFS extends FileSystem {
|
|
|
527
731
|
return rootIno;
|
|
528
732
|
}
|
|
529
733
|
const { dir: parent, base: filename } = parse(path);
|
|
530
|
-
const inode = parent == '/' ? new Inode(
|
|
531
|
-
const dir = decodeDirListing(
|
|
734
|
+
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);
|
|
735
|
+
const dir = decodeDirListing((_b = tx.getSync(inode.data)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENODATA', parent, syscall)));
|
|
532
736
|
if (!(filename in dir)) {
|
|
533
737
|
throw ErrnoError.With('ENOENT', resolve(parent, filename), syscall);
|
|
534
738
|
}
|
|
@@ -540,8 +744,9 @@ export class StoreFS extends FileSystem {
|
|
|
540
744
|
* @todo memoize/cache
|
|
541
745
|
*/
|
|
542
746
|
async findInode(tx, path, syscall, visited = new Set()) {
|
|
747
|
+
var _a;
|
|
543
748
|
const ino = await this._findInode(tx, path, syscall, visited);
|
|
544
|
-
return new Inode(await
|
|
749
|
+
return new Inode((_a = (await tx.get(ino))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
545
750
|
}
|
|
546
751
|
/**
|
|
547
752
|
* Finds the Inode of `path`.
|
|
@@ -550,34 +755,9 @@ export class StoreFS extends FileSystem {
|
|
|
550
755
|
* @todo memoize/cache
|
|
551
756
|
*/
|
|
552
757
|
findInodeSync(tx, path, syscall, visited = new Set()) {
|
|
758
|
+
var _a;
|
|
553
759
|
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;
|
|
760
|
+
return new Inode((_a = tx.getSync(ino)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
581
761
|
}
|
|
582
762
|
/**
|
|
583
763
|
* Adds a new node under a random ID. Retries before giving up in
|
|
@@ -585,7 +765,7 @@ export class StoreFS extends FileSystem {
|
|
|
585
765
|
*/
|
|
586
766
|
async allocNew(tx, path, syscall) {
|
|
587
767
|
for (let i = 0; i < maxInodeAllocTries; i++) {
|
|
588
|
-
const ino =
|
|
768
|
+
const ino = randomInt(0, size_max);
|
|
589
769
|
if (await tx.get(ino)) {
|
|
590
770
|
continue;
|
|
591
771
|
}
|
|
@@ -600,7 +780,7 @@ export class StoreFS extends FileSystem {
|
|
|
600
780
|
*/
|
|
601
781
|
allocNewSync(tx, path, syscall) {
|
|
602
782
|
for (let i = 0; i < maxInodeAllocTries; i++) {
|
|
603
|
-
const ino =
|
|
783
|
+
const ino = randomInt(0, size_max);
|
|
604
784
|
if (tx.getSync(ino)) {
|
|
605
785
|
continue;
|
|
606
786
|
}
|
|
@@ -616,8 +796,9 @@ export class StoreFS extends FileSystem {
|
|
|
616
796
|
* @param mode The mode to create the new file with.
|
|
617
797
|
* @param data The data to store at the file's data node.
|
|
618
798
|
*/
|
|
619
|
-
async commitNew(path, type,
|
|
620
|
-
|
|
799
|
+
async commitNew(path, type, options, data, syscall) {
|
|
800
|
+
var _a;
|
|
801
|
+
const env_23 = { stack: [], error: void 0, hasError: false };
|
|
621
802
|
try {
|
|
622
803
|
/*
|
|
623
804
|
The root always exists.
|
|
@@ -627,10 +808,10 @@ export class StoreFS extends FileSystem {
|
|
|
627
808
|
if (path == '/') {
|
|
628
809
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
629
810
|
}
|
|
630
|
-
const tx = __addDisposableResource(
|
|
811
|
+
const tx = __addDisposableResource(env_23, this.store.transaction(), true);
|
|
631
812
|
const { dir: parentPath, base: fname } = parse(path);
|
|
632
813
|
const parent = await this.findInode(tx, parentPath, syscall);
|
|
633
|
-
const listing = decodeDirListing(await
|
|
814
|
+
const listing = decodeDirListing((_a = (await tx.get(parent.data))) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parentPath, syscall)));
|
|
634
815
|
// Check if file already exists.
|
|
635
816
|
if (listing[fname]) {
|
|
636
817
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
@@ -639,9 +820,9 @@ export class StoreFS extends FileSystem {
|
|
|
639
820
|
const inode = new Inode();
|
|
640
821
|
inode.ino = await this.allocNew(tx, path, syscall);
|
|
641
822
|
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 :
|
|
823
|
+
inode.mode = options.mode | type;
|
|
824
|
+
inode.uid = parent.mode & S_ISUID ? parent.uid : options.uid;
|
|
825
|
+
inode.gid = parent.mode & S_ISGID ? parent.gid : options.gid;
|
|
645
826
|
inode.size = data.length;
|
|
646
827
|
await tx.set(inode.ino, serialize(inode));
|
|
647
828
|
await tx.set(inode.data, data);
|
|
@@ -651,14 +832,14 @@ export class StoreFS extends FileSystem {
|
|
|
651
832
|
await tx.commit();
|
|
652
833
|
return inode;
|
|
653
834
|
}
|
|
654
|
-
catch (
|
|
655
|
-
|
|
656
|
-
|
|
835
|
+
catch (e_23) {
|
|
836
|
+
env_23.error = e_23;
|
|
837
|
+
env_23.hasError = true;
|
|
657
838
|
}
|
|
658
839
|
finally {
|
|
659
|
-
const
|
|
660
|
-
if (
|
|
661
|
-
await
|
|
840
|
+
const result_12 = __disposeResources(env_23);
|
|
841
|
+
if (result_12)
|
|
842
|
+
await result_12;
|
|
662
843
|
}
|
|
663
844
|
}
|
|
664
845
|
/**
|
|
@@ -670,8 +851,9 @@ export class StoreFS extends FileSystem {
|
|
|
670
851
|
* @param data The data to store at the file's data node.
|
|
671
852
|
* @return The Inode for the new file.
|
|
672
853
|
*/
|
|
673
|
-
commitNewSync(path, type,
|
|
674
|
-
|
|
854
|
+
commitNewSync(path, type, options, data, syscall) {
|
|
855
|
+
var _a;
|
|
856
|
+
const env_24 = { stack: [], error: void 0, hasError: false };
|
|
675
857
|
try {
|
|
676
858
|
/*
|
|
677
859
|
The root always exists.
|
|
@@ -681,10 +863,10 @@ export class StoreFS extends FileSystem {
|
|
|
681
863
|
if (path == '/') {
|
|
682
864
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
683
865
|
}
|
|
684
|
-
const tx = __addDisposableResource(
|
|
866
|
+
const tx = __addDisposableResource(env_24, this.store.transaction(), false);
|
|
685
867
|
const { dir: parentPath, base: fname } = parse(path);
|
|
686
868
|
const parent = this.findInodeSync(tx, parentPath, syscall);
|
|
687
|
-
const listing = decodeDirListing(
|
|
869
|
+
const listing = decodeDirListing((_a = tx.getSync(parent.data)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENOENT', parentPath, syscall)));
|
|
688
870
|
// Check if file already exists.
|
|
689
871
|
if (listing[fname]) {
|
|
690
872
|
throw ErrnoError.With('EEXIST', path, syscall);
|
|
@@ -694,9 +876,9 @@ export class StoreFS extends FileSystem {
|
|
|
694
876
|
inode.ino = this.allocNewSync(tx, path, syscall);
|
|
695
877
|
inode.data = this.allocNewSync(tx, path, syscall);
|
|
696
878
|
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 :
|
|
879
|
+
inode.mode = options.mode | type;
|
|
880
|
+
inode.uid = parent.mode & S_ISUID ? parent.uid : options.uid;
|
|
881
|
+
inode.gid = parent.mode & S_ISGID ? parent.gid : options.gid;
|
|
700
882
|
// Update and commit parent directory listing.
|
|
701
883
|
tx.setSync(inode.ino, serialize(inode));
|
|
702
884
|
tx.setSync(inode.data, data);
|
|
@@ -705,12 +887,12 @@ export class StoreFS extends FileSystem {
|
|
|
705
887
|
tx.commitSync();
|
|
706
888
|
return inode;
|
|
707
889
|
}
|
|
708
|
-
catch (
|
|
709
|
-
|
|
710
|
-
|
|
890
|
+
catch (e_24) {
|
|
891
|
+
env_24.error = e_24;
|
|
892
|
+
env_24.hasError = true;
|
|
711
893
|
}
|
|
712
894
|
finally {
|
|
713
|
-
__disposeResources(
|
|
895
|
+
__disposeResources(env_24);
|
|
714
896
|
}
|
|
715
897
|
}
|
|
716
898
|
/**
|
|
@@ -720,16 +902,17 @@ export class StoreFS extends FileSystem {
|
|
|
720
902
|
* @todo Update mtime.
|
|
721
903
|
*/
|
|
722
904
|
async remove(path, isDir, syscall) {
|
|
723
|
-
|
|
905
|
+
var _a, _b;
|
|
906
|
+
const env_25 = { stack: [], error: void 0, hasError: false };
|
|
724
907
|
try {
|
|
725
|
-
const tx = __addDisposableResource(
|
|
726
|
-
const { dir: parent, base: fileName } = parse(path), parentNode = await this.findInode(tx, parent, syscall), listing = decodeDirListing(await
|
|
908
|
+
const tx = __addDisposableResource(env_25, this.store.transaction(), true);
|
|
909
|
+
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
910
|
if (!listing[fileName]) {
|
|
728
911
|
throw ErrnoError.With('ENOENT', path, 'remove');
|
|
729
912
|
}
|
|
730
913
|
const fileIno = listing[fileName];
|
|
731
914
|
// Get file inode.
|
|
732
|
-
const fileNode = new Inode(await
|
|
915
|
+
const fileNode = new Inode((_b = (await tx.get(fileIno))) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
733
916
|
// Remove from directory listing of parent.
|
|
734
917
|
delete listing[fileName];
|
|
735
918
|
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
@@ -744,14 +927,14 @@ export class StoreFS extends FileSystem {
|
|
|
744
927
|
// Success.
|
|
745
928
|
await tx.commit();
|
|
746
929
|
}
|
|
747
|
-
catch (
|
|
748
|
-
|
|
749
|
-
|
|
930
|
+
catch (e_25) {
|
|
931
|
+
env_25.error = e_25;
|
|
932
|
+
env_25.hasError = true;
|
|
750
933
|
}
|
|
751
934
|
finally {
|
|
752
|
-
const
|
|
753
|
-
if (
|
|
754
|
-
await
|
|
935
|
+
const result_13 = __disposeResources(env_25);
|
|
936
|
+
if (result_13)
|
|
937
|
+
await result_13;
|
|
755
938
|
}
|
|
756
939
|
}
|
|
757
940
|
/**
|
|
@@ -761,15 +944,16 @@ export class StoreFS extends FileSystem {
|
|
|
761
944
|
* @todo Update mtime.
|
|
762
945
|
*/
|
|
763
946
|
removeSync(path, isDir, syscall) {
|
|
764
|
-
|
|
947
|
+
var _a, _b;
|
|
948
|
+
const env_26 = { stack: [], error: void 0, hasError: false };
|
|
765
949
|
try {
|
|
766
|
-
const tx = __addDisposableResource(
|
|
767
|
-
const { dir: parent, base: fileName } = parse(path), parentNode = this.findInodeSync(tx, parent, syscall), listing = decodeDirListing(
|
|
950
|
+
const tx = __addDisposableResource(env_26, this.store.transaction(), false);
|
|
951
|
+
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
952
|
if (!fileIno) {
|
|
769
953
|
throw ErrnoError.With('ENOENT', path, 'remove');
|
|
770
954
|
}
|
|
771
955
|
// Get file inode.
|
|
772
|
-
const fileNode = new Inode(
|
|
956
|
+
const fileNode = new Inode((_b = tx.getSync(fileIno)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
773
957
|
// Remove from directory listing of parent.
|
|
774
958
|
delete listing[fileName];
|
|
775
959
|
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
@@ -785,12 +969,12 @@ export class StoreFS extends FileSystem {
|
|
|
785
969
|
// Success.
|
|
786
970
|
tx.commitSync();
|
|
787
971
|
}
|
|
788
|
-
catch (
|
|
789
|
-
|
|
790
|
-
|
|
972
|
+
catch (e_26) {
|
|
973
|
+
env_26.error = e_26;
|
|
974
|
+
env_26.hasError = true;
|
|
791
975
|
}
|
|
792
976
|
finally {
|
|
793
|
-
__disposeResources(
|
|
977
|
+
__disposeResources(env_26);
|
|
794
978
|
}
|
|
795
979
|
}
|
|
796
980
|
}
|