@zenfs/core 0.16.4 → 0.17.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.d.ts +3 -4
- package/dist/backends/fetch.d.ts +8 -3
- package/dist/backends/fetch.js +3 -2
- package/dist/backends/{index/fs.d.ts → file_index.d.ts} +49 -10
- package/dist/backends/{index/fs.js → file_index.js} +84 -5
- package/dist/backends/memory.d.ts +6 -1
- package/dist/backends/memory.js +2 -1
- package/dist/backends/overlay.d.ts +16 -16
- package/dist/backends/overlay.js +59 -82
- package/dist/backends/port/fs.d.ts +6 -2
- package/dist/backends/port/fs.js +4 -2
- package/dist/backends/store/fs.js +484 -304
- package/dist/backends/store/simple.js +5 -1
- package/dist/backends/store/store.d.ts +4 -1
- package/dist/backends/store/store.js +9 -5
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +3 -3
- package/dist/emulation/async.d.ts +0 -3
- package/dist/emulation/async.js +6 -2
- package/dist/emulation/dir.d.ts +4 -0
- package/dist/emulation/dir.js +8 -6
- package/dist/emulation/promises.d.ts +1 -3
- package/dist/emulation/promises.js +25 -2
- package/dist/emulation/sync.js +0 -1
- package/dist/emulation/watchers.d.ts +9 -4
- package/dist/emulation/watchers.js +7 -0
- package/dist/file.d.ts +17 -1
- package/dist/file.js +86 -1
- package/dist/filesystem.d.ts +0 -63
- package/dist/filesystem.js +0 -311
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/mixins/async.d.ts +39 -0
- package/dist/mixins/async.js +216 -0
- package/dist/mixins/mutexed.d.ts +33 -0
- package/dist/mixins/mutexed.js +465 -0
- package/dist/mixins/readonly.d.ts +25 -0
- package/dist/mixins/readonly.js +57 -0
- package/dist/mixins/shared.d.ts +12 -0
- package/dist/mixins/shared.js +4 -0
- package/dist/mixins/sync.d.ts +6 -0
- package/dist/mixins/sync.js +43 -0
- package/package.json +1 -1
- package/src/backends/backend.ts +3 -4
- package/src/backends/fetch.ts +7 -3
- package/src/backends/{index/fs.ts → file_index.ts} +106 -8
- package/src/backends/memory.ts +5 -1
- package/src/backends/overlay.ts +64 -90
- package/src/backends/port/fs.ts +7 -2
- package/src/backends/{index/readme.md → readme.md} +1 -1
- package/src/backends/store/fs.ts +97 -155
- package/src/backends/store/simple.ts +5 -1
- package/src/backends/store/store.ts +10 -5
- package/src/config.ts +3 -1
- package/src/emulation/async.ts +15 -6
- package/src/emulation/dir.ts +19 -16
- package/src/emulation/promises.ts +28 -6
- package/src/emulation/sync.ts +1 -2
- package/src/emulation/watchers.ts +10 -4
- package/src/file.ts +94 -1
- package/src/filesystem.ts +3 -366
- package/src/index.ts +1 -2
- package/src/mixins/async.ts +211 -0
- package/src/mixins/mutexed.ts +245 -0
- package/src/mixins/readonly.ts +97 -0
- package/src/mixins/shared.ts +20 -0
- package/src/mixins/sync.ts +59 -0
- package/dist/backends/index/index.d.ts +0 -43
- package/dist/backends/index/index.js +0 -83
- package/dist/backends/locked.d.ts +0 -92
- package/dist/backends/locked.js +0 -487
- package/src/backends/index/index.ts +0 -104
- package/src/backends/locked.ts +0 -264
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
}
|
|
13
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
14
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
15
|
+
}
|
|
16
|
+
else if (async) {
|
|
17
|
+
env.stack.push({ async: true });
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
21
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
22
|
+
return function (env) {
|
|
23
|
+
function fail(e) {
|
|
24
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
25
|
+
env.hasError = true;
|
|
26
|
+
}
|
|
27
|
+
function next() {
|
|
28
|
+
while (env.stack.length) {
|
|
29
|
+
var rec = env.stack.pop();
|
|
30
|
+
try {
|
|
31
|
+
var result = rec.dispose && rec.dispose.call(rec.value);
|
|
32
|
+
if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
fail(e);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (env.hasError) throw env.error;
|
|
39
|
+
}
|
|
40
|
+
return next();
|
|
41
|
+
};
|
|
42
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
43
|
+
var e = new Error(message);
|
|
44
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
45
|
+
});
|
|
1
46
|
import { R_OK, S_IFDIR, S_IFREG, W_OK } from '../../emulation/constants.js';
|
|
2
47
|
import { basename, dirname, join, resolve } from '../../emulation/path.js';
|
|
3
48
|
import { Errno, ErrnoError } from '../../error.js';
|
|
@@ -55,175 +100,221 @@ export class StoreFS extends FileSystem {
|
|
|
55
100
|
* @todo Make rename compatible with the cache.
|
|
56
101
|
*/
|
|
57
102
|
async rename(oldPath, newPath, cred) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
103
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
104
|
+
try {
|
|
105
|
+
const tx = __addDisposableResource(env_1, this.store.transaction(), true);
|
|
106
|
+
const oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
|
|
107
|
+
// Remove oldPath from parent's directory listing.
|
|
108
|
+
oldDirNode = await this.findINode(tx, oldParent), oldDirList = await this.getDirListing(tx, oldDirNode, oldParent);
|
|
109
|
+
if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
110
|
+
throw ErrnoError.With('EACCES', oldPath, 'rename');
|
|
111
|
+
}
|
|
112
|
+
if (!oldDirList[oldName]) {
|
|
113
|
+
throw ErrnoError.With('ENOENT', oldPath, 'rename');
|
|
114
|
+
}
|
|
115
|
+
const nodeId = oldDirList[oldName];
|
|
116
|
+
delete oldDirList[oldName];
|
|
117
|
+
// Invariant: Can't move a folder inside itself.
|
|
118
|
+
// This funny little hack ensures that the check passes only if oldPath
|
|
119
|
+
// is a subpath of newParent. We append '/' to avoid matching folders that
|
|
120
|
+
// are a substring of the bottom-most folder in the path.
|
|
121
|
+
if ((newParent + '/').indexOf(oldPath + '/') === 0) {
|
|
122
|
+
throw new ErrnoError(Errno.EBUSY, oldParent);
|
|
123
|
+
}
|
|
124
|
+
// Add newPath to parent's directory listing.
|
|
125
|
+
let newDirNode, newDirList;
|
|
126
|
+
if (newParent === oldParent) {
|
|
127
|
+
// Prevent us from re-grabbing the same directory listing, which still
|
|
128
|
+
// contains oldName.
|
|
129
|
+
newDirNode = oldDirNode;
|
|
130
|
+
newDirList = oldDirList;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
newDirNode = await this.findINode(tx, newParent);
|
|
134
|
+
newDirList = await this.getDirListing(tx, newDirNode, newParent);
|
|
135
|
+
}
|
|
136
|
+
if (newDirList[newName]) {
|
|
137
|
+
// If it's a file, delete it.
|
|
138
|
+
const newNameNode = await this.getINode(tx, newDirList[newName], newPath);
|
|
139
|
+
if (newNameNode.toStats().isFile()) {
|
|
93
140
|
await tx.remove(newNameNode.ino);
|
|
94
141
|
await tx.remove(newDirList[newName]);
|
|
95
142
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
throw
|
|
143
|
+
else {
|
|
144
|
+
// If it's a directory, throw a permissions error.
|
|
145
|
+
throw ErrnoError.With('EPERM', newPath, 'rename');
|
|
99
146
|
}
|
|
100
147
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
throw ErrnoError.With('EPERM', newPath, 'rename');
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
newDirList[newName] = nodeId;
|
|
107
|
-
// Commit the two changed directory listings.
|
|
108
|
-
try {
|
|
148
|
+
newDirList[newName] = nodeId;
|
|
149
|
+
// Commit the two changed directory listings.
|
|
109
150
|
await tx.set(oldDirNode.ino, encodeDirListing(oldDirList));
|
|
110
151
|
await tx.set(newDirNode.ino, encodeDirListing(newDirList));
|
|
152
|
+
await tx.commit();
|
|
111
153
|
}
|
|
112
|
-
catch (
|
|
113
|
-
|
|
114
|
-
|
|
154
|
+
catch (e_1) {
|
|
155
|
+
env_1.error = e_1;
|
|
156
|
+
env_1.hasError = true;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
const result_1 = __disposeResources(env_1);
|
|
160
|
+
if (result_1)
|
|
161
|
+
await result_1;
|
|
115
162
|
}
|
|
116
|
-
await tx.commit();
|
|
117
163
|
}
|
|
118
164
|
renameSync(oldPath, newPath, cred) {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (
|
|
153
|
-
|
|
165
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
166
|
+
try {
|
|
167
|
+
const tx = __addDisposableResource(env_2, this.store.transaction(), false);
|
|
168
|
+
const oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
|
|
169
|
+
// Remove oldPath from parent's directory listing.
|
|
170
|
+
oldDirNode = this.findINodeSync(tx, oldParent), oldDirList = this.getDirListingSync(tx, oldDirNode, oldParent);
|
|
171
|
+
if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
172
|
+
throw ErrnoError.With('EACCES', oldPath, 'rename');
|
|
173
|
+
}
|
|
174
|
+
if (!oldDirList[oldName]) {
|
|
175
|
+
throw ErrnoError.With('ENOENT', oldPath, 'rename');
|
|
176
|
+
}
|
|
177
|
+
const ino = oldDirList[oldName];
|
|
178
|
+
delete oldDirList[oldName];
|
|
179
|
+
// Invariant: Can't move a folder inside itself.
|
|
180
|
+
// This funny little hack ensures that the check passes only if oldPath
|
|
181
|
+
// is a subpath of newParent. We append '/' to avoid matching folders that
|
|
182
|
+
// are a substring of the bottom-most folder in the path.
|
|
183
|
+
if ((newParent + '/').indexOf(oldPath + '/') == 0) {
|
|
184
|
+
throw new ErrnoError(Errno.EBUSY, oldParent);
|
|
185
|
+
}
|
|
186
|
+
// Add newPath to parent's directory listing.
|
|
187
|
+
let newDirNode, newDirList;
|
|
188
|
+
if (newParent === oldParent) {
|
|
189
|
+
// Prevent us from re-grabbing the same directory listing, which still
|
|
190
|
+
// contains oldName.
|
|
191
|
+
newDirNode = oldDirNode;
|
|
192
|
+
newDirList = oldDirList;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
newDirNode = this.findINodeSync(tx, newParent);
|
|
196
|
+
newDirList = this.getDirListingSync(tx, newDirNode, newParent);
|
|
197
|
+
}
|
|
198
|
+
if (newDirList[newName]) {
|
|
199
|
+
// If it's a file, delete it.
|
|
200
|
+
const newNameNode = this.getINodeSync(tx, newDirList[newName], newPath);
|
|
201
|
+
if (newNameNode.toStats().isFile()) {
|
|
154
202
|
tx.removeSync(newNameNode.ino);
|
|
155
203
|
tx.removeSync(newDirList[newName]);
|
|
156
204
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
throw
|
|
205
|
+
else {
|
|
206
|
+
// If it's a directory, throw a permissions error.
|
|
207
|
+
throw ErrnoError.With('EPERM', newPath, 'rename');
|
|
160
208
|
}
|
|
161
209
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
throw ErrnoError.With('EPERM', newPath, 'rename');
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
newDirList[newName] = ino;
|
|
168
|
-
// Commit the two changed directory listings.
|
|
169
|
-
try {
|
|
210
|
+
newDirList[newName] = ino;
|
|
211
|
+
// Commit the two changed directory listings.
|
|
170
212
|
tx.setSync(oldDirNode.ino, encodeDirListing(oldDirList));
|
|
171
213
|
tx.setSync(newDirNode.ino, encodeDirListing(newDirList));
|
|
214
|
+
tx.commitSync();
|
|
215
|
+
}
|
|
216
|
+
catch (e_2) {
|
|
217
|
+
env_2.error = e_2;
|
|
218
|
+
env_2.hasError = true;
|
|
172
219
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
throw e;
|
|
220
|
+
finally {
|
|
221
|
+
__disposeResources(env_2);
|
|
176
222
|
}
|
|
177
|
-
tx.commitSync();
|
|
178
223
|
}
|
|
179
224
|
async stat(path, cred) {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
225
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
226
|
+
try {
|
|
227
|
+
const tx = __addDisposableResource(env_3, this.store.transaction(), true);
|
|
228
|
+
const inode = await this.findINode(tx, path);
|
|
229
|
+
if (!inode) {
|
|
230
|
+
throw ErrnoError.With('ENOENT', path, 'stat');
|
|
231
|
+
}
|
|
232
|
+
const stats = inode.toStats();
|
|
233
|
+
if (!stats.hasAccess(R_OK, cred)) {
|
|
234
|
+
throw ErrnoError.With('EACCES', path, 'stat');
|
|
235
|
+
}
|
|
236
|
+
return stats;
|
|
237
|
+
}
|
|
238
|
+
catch (e_3) {
|
|
239
|
+
env_3.error = e_3;
|
|
240
|
+
env_3.hasError = true;
|
|
184
241
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
242
|
+
finally {
|
|
243
|
+
const result_2 = __disposeResources(env_3);
|
|
244
|
+
if (result_2)
|
|
245
|
+
await result_2;
|
|
188
246
|
}
|
|
189
|
-
return stats;
|
|
190
247
|
}
|
|
191
248
|
statSync(path, cred) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
249
|
+
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
250
|
+
try {
|
|
251
|
+
const tx = __addDisposableResource(env_4, this.store.transaction(), false);
|
|
252
|
+
// Get the inode to the item, convert it into a Stats object.
|
|
253
|
+
const stats = this.findINodeSync(tx, path).toStats();
|
|
254
|
+
if (!stats.hasAccess(R_OK, cred)) {
|
|
255
|
+
throw ErrnoError.With('EACCES', path, 'stat');
|
|
256
|
+
}
|
|
257
|
+
return stats;
|
|
258
|
+
}
|
|
259
|
+
catch (e_4) {
|
|
260
|
+
env_4.error = e_4;
|
|
261
|
+
env_4.hasError = true;
|
|
262
|
+
}
|
|
263
|
+
finally {
|
|
264
|
+
__disposeResources(env_4);
|
|
196
265
|
}
|
|
197
|
-
return stats;
|
|
198
266
|
}
|
|
199
267
|
async createFile(path, flag, mode, cred) {
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
return new PreloadFile(this, path, flag, file.toStats(), data);
|
|
268
|
+
const node = await this.commitNew(path, S_IFREG, mode, cred, new Uint8Array(0));
|
|
269
|
+
return new PreloadFile(this, path, flag, node.toStats(), new Uint8Array(0));
|
|
203
270
|
}
|
|
204
271
|
createFileSync(path, flag, mode, cred) {
|
|
205
272
|
this.commitNewSync(path, S_IFREG, mode, cred);
|
|
206
273
|
return this.openFileSync(path, flag, cred);
|
|
207
274
|
}
|
|
208
275
|
async openFile(path, flag, cred) {
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
276
|
+
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
277
|
+
try {
|
|
278
|
+
const tx = __addDisposableResource(env_5, this.store.transaction(), true);
|
|
279
|
+
const node = await this.findINode(tx, path), data = await tx.get(node.ino);
|
|
280
|
+
if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
|
|
281
|
+
throw ErrnoError.With('EACCES', path, 'openFile');
|
|
282
|
+
}
|
|
283
|
+
if (!data) {
|
|
284
|
+
throw ErrnoError.With('ENOENT', path, 'openFile');
|
|
285
|
+
}
|
|
286
|
+
return new PreloadFile(this, path, flag, node.toStats(), data);
|
|
212
287
|
}
|
|
213
|
-
|
|
214
|
-
|
|
288
|
+
catch (e_5) {
|
|
289
|
+
env_5.error = e_5;
|
|
290
|
+
env_5.hasError = true;
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
const result_3 = __disposeResources(env_5);
|
|
294
|
+
if (result_3)
|
|
295
|
+
await result_3;
|
|
215
296
|
}
|
|
216
|
-
return new PreloadFile(this, path, flag, node.toStats(), data);
|
|
217
297
|
}
|
|
218
298
|
openFileSync(path, flag, cred) {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
299
|
+
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
300
|
+
try {
|
|
301
|
+
const tx = __addDisposableResource(env_6, this.store.transaction(), false);
|
|
302
|
+
const node = this.findINodeSync(tx, path), data = tx.getSync(node.ino);
|
|
303
|
+
if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
|
|
304
|
+
throw ErrnoError.With('EACCES', path, 'openFile');
|
|
305
|
+
}
|
|
306
|
+
if (!data) {
|
|
307
|
+
throw ErrnoError.With('ENOENT', path, 'openFile');
|
|
308
|
+
}
|
|
309
|
+
return new PreloadFile(this, path, flag, node.toStats(), data);
|
|
222
310
|
}
|
|
223
|
-
|
|
224
|
-
|
|
311
|
+
catch (e_6) {
|
|
312
|
+
env_6.error = e_6;
|
|
313
|
+
env_6.hasError = true;
|
|
314
|
+
}
|
|
315
|
+
finally {
|
|
316
|
+
__disposeResources(env_6);
|
|
225
317
|
}
|
|
226
|
-
return new PreloadFile(this, path, flag, node.toStats(), data);
|
|
227
318
|
}
|
|
228
319
|
async unlink(path, cred) {
|
|
229
320
|
return this.remove(path, false, cred);
|
|
@@ -249,155 +340,220 @@ export class StoreFS extends FileSystem {
|
|
|
249
340
|
}
|
|
250
341
|
}
|
|
251
342
|
async mkdir(path, mode, cred) {
|
|
252
|
-
|
|
253
|
-
await this.commitNew(tx, path, S_IFDIR, mode, cred, data);
|
|
343
|
+
await this.commitNew(path, S_IFDIR, mode, cred, encode('{}'));
|
|
254
344
|
}
|
|
255
345
|
mkdirSync(path, mode, cred) {
|
|
256
346
|
this.commitNewSync(path, S_IFDIR, mode, cred, encode('{}'));
|
|
257
347
|
}
|
|
258
348
|
async readdir(path, cred) {
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
349
|
+
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
350
|
+
try {
|
|
351
|
+
const tx = __addDisposableResource(env_7, this.store.transaction(), true);
|
|
352
|
+
const node = await this.findINode(tx, path);
|
|
353
|
+
if (!node.toStats().hasAccess(R_OK, cred)) {
|
|
354
|
+
throw ErrnoError.With('EACCES', path, 'readdur');
|
|
355
|
+
}
|
|
356
|
+
return Object.keys(await this.getDirListing(tx, node, path));
|
|
357
|
+
}
|
|
358
|
+
catch (e_7) {
|
|
359
|
+
env_7.error = e_7;
|
|
360
|
+
env_7.hasError = true;
|
|
361
|
+
}
|
|
362
|
+
finally {
|
|
363
|
+
const result_4 = __disposeResources(env_7);
|
|
364
|
+
if (result_4)
|
|
365
|
+
await result_4;
|
|
263
366
|
}
|
|
264
|
-
return Object.keys(await this.getDirListing(tx, node, path));
|
|
265
367
|
}
|
|
266
368
|
readdirSync(path, cred) {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
369
|
+
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
370
|
+
try {
|
|
371
|
+
const tx = __addDisposableResource(env_8, this.store.transaction(), false);
|
|
372
|
+
const node = this.findINodeSync(tx, path);
|
|
373
|
+
if (!node.toStats().hasAccess(R_OK, cred)) {
|
|
374
|
+
throw ErrnoError.With('EACCES', path, 'readdir');
|
|
375
|
+
}
|
|
376
|
+
return Object.keys(this.getDirListingSync(tx, node, path));
|
|
377
|
+
}
|
|
378
|
+
catch (e_8) {
|
|
379
|
+
env_8.error = e_8;
|
|
380
|
+
env_8.hasError = true;
|
|
381
|
+
}
|
|
382
|
+
finally {
|
|
383
|
+
__disposeResources(env_8);
|
|
271
384
|
}
|
|
272
|
-
return Object.keys(this.getDirListingSync(tx, node, path));
|
|
273
385
|
}
|
|
274
386
|
/**
|
|
275
387
|
* Updated the inode and data node at the given path
|
|
276
388
|
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
277
389
|
*/
|
|
278
390
|
async sync(path, data, stats) {
|
|
279
|
-
const
|
|
280
|
-
// We use _findInode because we actually need the INode id.
|
|
281
|
-
fileInodeId = await this._findINode(tx, dirname(path), basename(path)), fileInode = await this.getINode(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
|
|
391
|
+
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
282
392
|
try {
|
|
393
|
+
const tx = __addDisposableResource(env_9, this.store.transaction(), true);
|
|
394
|
+
// We use _findInode because we actually need the INode id.
|
|
395
|
+
const fileInodeId = await this._findINode(tx, dirname(path), basename(path)), fileInode = await this.getINode(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
|
|
283
396
|
// Sync data.
|
|
284
397
|
await tx.set(fileInode.ino, data);
|
|
285
398
|
// Sync metadata.
|
|
286
399
|
if (inodeChanged) {
|
|
287
400
|
await tx.set(fileInodeId, fileInode.data);
|
|
288
401
|
}
|
|
402
|
+
await tx.commit();
|
|
289
403
|
}
|
|
290
|
-
catch (
|
|
291
|
-
|
|
292
|
-
|
|
404
|
+
catch (e_9) {
|
|
405
|
+
env_9.error = e_9;
|
|
406
|
+
env_9.hasError = true;
|
|
407
|
+
}
|
|
408
|
+
finally {
|
|
409
|
+
const result_5 = __disposeResources(env_9);
|
|
410
|
+
if (result_5)
|
|
411
|
+
await result_5;
|
|
293
412
|
}
|
|
294
|
-
await tx.commit();
|
|
295
413
|
}
|
|
296
414
|
/**
|
|
297
415
|
* Updated the inode and data node at the given path
|
|
298
416
|
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
299
417
|
*/
|
|
300
418
|
syncSync(path, data, stats) {
|
|
301
|
-
const
|
|
302
|
-
// We use _findInode because we actually need the INode id.
|
|
303
|
-
fileInodeId = this._findINodeSync(tx, dirname(path), basename(path)), fileInode = this.getINodeSync(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
|
|
419
|
+
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
304
420
|
try {
|
|
421
|
+
const tx = __addDisposableResource(env_10, this.store.transaction(), false);
|
|
422
|
+
// We use _findInode because we actually need the INode id.
|
|
423
|
+
const fileInodeId = this._findINodeSync(tx, dirname(path), basename(path)), fileInode = this.getINodeSync(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
|
|
305
424
|
// Sync data.
|
|
306
425
|
tx.setSync(fileInode.ino, data);
|
|
307
426
|
// Sync metadata.
|
|
308
427
|
if (inodeChanged) {
|
|
309
428
|
tx.setSync(fileInodeId, fileInode.data);
|
|
310
429
|
}
|
|
430
|
+
tx.commitSync();
|
|
431
|
+
}
|
|
432
|
+
catch (e_10) {
|
|
433
|
+
env_10.error = e_10;
|
|
434
|
+
env_10.hasError = true;
|
|
311
435
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
throw e;
|
|
436
|
+
finally {
|
|
437
|
+
__disposeResources(env_10);
|
|
315
438
|
}
|
|
316
|
-
tx.commitSync();
|
|
317
439
|
}
|
|
318
440
|
async link(existing, newpath, cred) {
|
|
319
|
-
const
|
|
320
|
-
if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
|
|
321
|
-
throw ErrnoError.With('EACCES', existingDir, 'link');
|
|
322
|
-
}
|
|
323
|
-
const newDir = dirname(newpath), newDirNode = await this.findINode(tx, newDir), newListing = await this.getDirListing(tx, newDirNode, newDir);
|
|
324
|
-
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
325
|
-
throw ErrnoError.With('EACCES', newDir, 'link');
|
|
326
|
-
}
|
|
327
|
-
const ino = await this._findINode(tx, existingDir, basename(existing));
|
|
328
|
-
const node = await this.getINode(tx, ino, existing);
|
|
329
|
-
if (!node.toStats().hasAccess(W_OK, cred)) {
|
|
330
|
-
throw ErrnoError.With('EACCES', newpath, 'link');
|
|
331
|
-
}
|
|
332
|
-
node.nlink++;
|
|
333
|
-
newListing[basename(newpath)] = ino;
|
|
441
|
+
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
334
442
|
try {
|
|
443
|
+
const tx = __addDisposableResource(env_11, this.store.transaction(), true);
|
|
444
|
+
const existingDir = dirname(existing), existingDirNode = await this.findINode(tx, existingDir);
|
|
445
|
+
if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
|
|
446
|
+
throw ErrnoError.With('EACCES', existingDir, 'link');
|
|
447
|
+
}
|
|
448
|
+
const newDir = dirname(newpath), newDirNode = await this.findINode(tx, newDir), newListing = await this.getDirListing(tx, newDirNode, newDir);
|
|
449
|
+
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
450
|
+
throw ErrnoError.With('EACCES', newDir, 'link');
|
|
451
|
+
}
|
|
452
|
+
const ino = await this._findINode(tx, existingDir, basename(existing));
|
|
453
|
+
const node = await this.getINode(tx, ino, existing);
|
|
454
|
+
if (!node.toStats().hasAccess(W_OK, cred)) {
|
|
455
|
+
throw ErrnoError.With('EACCES', newpath, 'link');
|
|
456
|
+
}
|
|
457
|
+
node.nlink++;
|
|
458
|
+
newListing[basename(newpath)] = ino;
|
|
335
459
|
tx.setSync(ino, node.data);
|
|
336
460
|
tx.setSync(newDirNode.ino, encodeDirListing(newListing));
|
|
461
|
+
tx.commitSync();
|
|
337
462
|
}
|
|
338
|
-
catch (
|
|
339
|
-
|
|
340
|
-
|
|
463
|
+
catch (e_11) {
|
|
464
|
+
env_11.error = e_11;
|
|
465
|
+
env_11.hasError = true;
|
|
466
|
+
}
|
|
467
|
+
finally {
|
|
468
|
+
const result_6 = __disposeResources(env_11);
|
|
469
|
+
if (result_6)
|
|
470
|
+
await result_6;
|
|
341
471
|
}
|
|
342
|
-
tx.commitSync();
|
|
343
472
|
}
|
|
344
473
|
linkSync(existing, newpath, cred) {
|
|
345
|
-
const
|
|
346
|
-
if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
|
|
347
|
-
throw ErrnoError.With('EACCES', existingDir, 'link');
|
|
348
|
-
}
|
|
349
|
-
const newDir = dirname(newpath), newDirNode = this.findINodeSync(tx, newDir), newListing = this.getDirListingSync(tx, newDirNode, newDir);
|
|
350
|
-
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
351
|
-
throw ErrnoError.With('EACCES', newDir, 'link');
|
|
352
|
-
}
|
|
353
|
-
const ino = this._findINodeSync(tx, existingDir, basename(existing));
|
|
354
|
-
const node = this.getINodeSync(tx, ino, existing);
|
|
355
|
-
if (!node.toStats().hasAccess(W_OK, cred)) {
|
|
356
|
-
throw ErrnoError.With('EACCES', newpath, 'link');
|
|
357
|
-
}
|
|
358
|
-
node.nlink++;
|
|
359
|
-
newListing[basename(newpath)] = ino;
|
|
474
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
360
475
|
try {
|
|
476
|
+
const tx = __addDisposableResource(env_12, this.store.transaction(), false);
|
|
477
|
+
const existingDir = dirname(existing), existingDirNode = this.findINodeSync(tx, existingDir);
|
|
478
|
+
if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
|
|
479
|
+
throw ErrnoError.With('EACCES', existingDir, 'link');
|
|
480
|
+
}
|
|
481
|
+
const newDir = dirname(newpath), newDirNode = this.findINodeSync(tx, newDir), newListing = this.getDirListingSync(tx, newDirNode, newDir);
|
|
482
|
+
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
483
|
+
throw ErrnoError.With('EACCES', newDir, 'link');
|
|
484
|
+
}
|
|
485
|
+
const ino = this._findINodeSync(tx, existingDir, basename(existing));
|
|
486
|
+
const node = this.getINodeSync(tx, ino, existing);
|
|
487
|
+
if (!node.toStats().hasAccess(W_OK, cred)) {
|
|
488
|
+
throw ErrnoError.With('EACCES', newpath, 'link');
|
|
489
|
+
}
|
|
490
|
+
node.nlink++;
|
|
491
|
+
newListing[basename(newpath)] = ino;
|
|
361
492
|
tx.setSync(ino, node.data);
|
|
362
493
|
tx.setSync(newDirNode.ino, encodeDirListing(newListing));
|
|
494
|
+
tx.commitSync();
|
|
495
|
+
}
|
|
496
|
+
catch (e_12) {
|
|
497
|
+
env_12.error = e_12;
|
|
498
|
+
env_12.hasError = true;
|
|
363
499
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
throw e;
|
|
500
|
+
finally {
|
|
501
|
+
__disposeResources(env_12);
|
|
367
502
|
}
|
|
368
|
-
tx.commitSync();
|
|
369
503
|
}
|
|
370
504
|
/**
|
|
371
505
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
372
506
|
*/
|
|
373
507
|
async checkRoot() {
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
508
|
+
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
509
|
+
try {
|
|
510
|
+
const tx = __addDisposableResource(env_13, this.store.transaction(), true);
|
|
511
|
+
if (await tx.get(rootIno)) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
// Create new inode. o777, owned by root:root
|
|
515
|
+
const inode = new Inode();
|
|
516
|
+
inode.mode = 0o777 | S_IFDIR;
|
|
517
|
+
// If the root doesn't exist, the first random ID shouldn't exist either.
|
|
518
|
+
await tx.set(inode.ino, encode('{}'));
|
|
519
|
+
await tx.set(rootIno, inode.data);
|
|
520
|
+
await tx.commit();
|
|
521
|
+
}
|
|
522
|
+
catch (e_13) {
|
|
523
|
+
env_13.error = e_13;
|
|
524
|
+
env_13.hasError = true;
|
|
525
|
+
}
|
|
526
|
+
finally {
|
|
527
|
+
const result_7 = __disposeResources(env_13);
|
|
528
|
+
if (result_7)
|
|
529
|
+
await result_7;
|
|
377
530
|
}
|
|
378
|
-
// Create new inode. o777, owned by root:root
|
|
379
|
-
const inode = new Inode();
|
|
380
|
-
inode.mode = 0o777 | S_IFDIR;
|
|
381
|
-
// If the root doesn't exist, the first random ID shouldn't exist either.
|
|
382
|
-
await tx.set(inode.ino, encode('{}'));
|
|
383
|
-
await tx.set(rootIno, inode.data);
|
|
384
|
-
await tx.commit();
|
|
385
531
|
}
|
|
386
532
|
/**
|
|
387
533
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
388
534
|
*/
|
|
389
535
|
checkRootSync() {
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
536
|
+
const env_14 = { stack: [], error: void 0, hasError: false };
|
|
537
|
+
try {
|
|
538
|
+
const tx = __addDisposableResource(env_14, this.store.transaction(), false);
|
|
539
|
+
if (tx.getSync(rootIno)) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
// Create new inode, mode o777, owned by root:root
|
|
543
|
+
const inode = new Inode();
|
|
544
|
+
inode.mode = 0o777 | S_IFDIR;
|
|
545
|
+
// If the root doesn't exist, the first random ID shouldn't exist either.
|
|
546
|
+
tx.setSync(inode.ino, encode('{}'));
|
|
547
|
+
tx.setSync(rootIno, inode.data);
|
|
548
|
+
tx.commitSync();
|
|
549
|
+
}
|
|
550
|
+
catch (e_14) {
|
|
551
|
+
env_14.error = e_14;
|
|
552
|
+
env_14.hasError = true;
|
|
553
|
+
}
|
|
554
|
+
finally {
|
|
555
|
+
__disposeResources(env_14);
|
|
393
556
|
}
|
|
394
|
-
// Create new inode, mode o777, owned by root:root
|
|
395
|
-
const inode = new Inode();
|
|
396
|
-
inode.mode = 0o777 | S_IFDIR;
|
|
397
|
-
// If the root doesn't exist, the first random ID shouldn't exist either.
|
|
398
|
-
tx.setSync(inode.ino, encode('{}'));
|
|
399
|
-
tx.setSync(rootIno, inode.data);
|
|
400
|
-
tx.commitSync();
|
|
401
557
|
}
|
|
402
558
|
/**
|
|
403
559
|
* Helper function for findINode.
|
|
@@ -563,27 +719,29 @@ export class StoreFS extends FileSystem {
|
|
|
563
719
|
* @param cred The UID/GID to create the file with
|
|
564
720
|
* @param data The data to store at the file's data node.
|
|
565
721
|
*/
|
|
566
|
-
async commitNew(
|
|
567
|
-
const
|
|
568
|
-
//Check that the creater has correct access
|
|
569
|
-
if (!parent.toStats().hasAccess(W_OK, cred)) {
|
|
570
|
-
throw ErrnoError.With('EACCES', path, 'commitNewFile');
|
|
571
|
-
}
|
|
572
|
-
const fname = basename(path), listing = await this.getDirListing(tx, parent, parentPath);
|
|
573
|
-
/*
|
|
574
|
-
The root always exists.
|
|
575
|
-
If we don't check this prior to taking steps below,
|
|
576
|
-
we will create a file with name '' in root should path == '/'.
|
|
577
|
-
*/
|
|
578
|
-
if (path === '/') {
|
|
579
|
-
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
580
|
-
}
|
|
581
|
-
// Check if file already exists.
|
|
582
|
-
if (listing[fname]) {
|
|
583
|
-
await tx.abort();
|
|
584
|
-
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
585
|
-
}
|
|
722
|
+
async commitNew(path, type, mode, cred, data) {
|
|
723
|
+
const env_15 = { stack: [], error: void 0, hasError: false };
|
|
586
724
|
try {
|
|
725
|
+
const tx = __addDisposableResource(env_15, this.store.transaction(), true);
|
|
726
|
+
const parentPath = dirname(path), parent = await this.findINode(tx, parentPath);
|
|
727
|
+
//Check that the creater has correct access
|
|
728
|
+
if (!parent.toStats().hasAccess(W_OK, cred)) {
|
|
729
|
+
throw ErrnoError.With('EACCES', path, 'commitNewFile');
|
|
730
|
+
}
|
|
731
|
+
const fname = basename(path), listing = await this.getDirListing(tx, parent, parentPath);
|
|
732
|
+
/*
|
|
733
|
+
The root always exists.
|
|
734
|
+
If we don't check this prior to taking steps below,
|
|
735
|
+
we will create a file with name '' in root should path == '/'.
|
|
736
|
+
*/
|
|
737
|
+
if (path === '/') {
|
|
738
|
+
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
739
|
+
}
|
|
740
|
+
// Check if file already exists.
|
|
741
|
+
if (listing[fname]) {
|
|
742
|
+
await tx.abort();
|
|
743
|
+
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
744
|
+
}
|
|
587
745
|
// Commit data.
|
|
588
746
|
const inode = new Inode();
|
|
589
747
|
inode.ino = await this.addNew(tx, data, path);
|
|
@@ -597,9 +755,14 @@ export class StoreFS extends FileSystem {
|
|
|
597
755
|
await tx.commit();
|
|
598
756
|
return inode;
|
|
599
757
|
}
|
|
600
|
-
catch (
|
|
601
|
-
|
|
602
|
-
|
|
758
|
+
catch (e_15) {
|
|
759
|
+
env_15.error = e_15;
|
|
760
|
+
env_15.hasError = true;
|
|
761
|
+
}
|
|
762
|
+
finally {
|
|
763
|
+
const result_8 = __disposeResources(env_15);
|
|
764
|
+
if (result_8)
|
|
765
|
+
await result_8;
|
|
603
766
|
}
|
|
604
767
|
}
|
|
605
768
|
/**
|
|
@@ -612,27 +775,29 @@ export class StoreFS extends FileSystem {
|
|
|
612
775
|
* @return The Inode for the new file.
|
|
613
776
|
*/
|
|
614
777
|
commitNewSync(path, type, mode, cred, data = new Uint8Array()) {
|
|
615
|
-
const
|
|
616
|
-
//Check that the creater has correct access
|
|
617
|
-
if (!parent.toStats().hasAccess(W_OK, cred)) {
|
|
618
|
-
throw ErrnoError.With('EACCES', path, 'commitNewFile');
|
|
619
|
-
}
|
|
620
|
-
const fname = basename(path), listing = this.getDirListingSync(tx, parent, parentPath);
|
|
621
|
-
/*
|
|
622
|
-
The root always exists.
|
|
623
|
-
If we don't check this prior to taking steps below,
|
|
624
|
-
we will create a file with name '' in root should p == '/'.
|
|
625
|
-
*/
|
|
626
|
-
if (path === '/') {
|
|
627
|
-
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
628
|
-
}
|
|
629
|
-
// Check if file already exists.
|
|
630
|
-
if (listing[fname]) {
|
|
631
|
-
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
632
|
-
}
|
|
633
|
-
const node = new Inode();
|
|
778
|
+
const env_16 = { stack: [], error: void 0, hasError: false };
|
|
634
779
|
try {
|
|
780
|
+
const tx = __addDisposableResource(env_16, this.store.transaction(), false);
|
|
781
|
+
const parentPath = dirname(path), parent = this.findINodeSync(tx, parentPath);
|
|
782
|
+
//Check that the creater has correct access
|
|
783
|
+
if (!parent.toStats().hasAccess(W_OK, cred)) {
|
|
784
|
+
throw ErrnoError.With('EACCES', path, 'commitNewFile');
|
|
785
|
+
}
|
|
786
|
+
const fname = basename(path), listing = this.getDirListingSync(tx, parent, parentPath);
|
|
787
|
+
/*
|
|
788
|
+
The root always exists.
|
|
789
|
+
If we don't check this prior to taking steps below,
|
|
790
|
+
we will create a file with name '' in root should p == '/'.
|
|
791
|
+
*/
|
|
792
|
+
if (path === '/') {
|
|
793
|
+
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
794
|
+
}
|
|
795
|
+
// Check if file already exists.
|
|
796
|
+
if (listing[fname]) {
|
|
797
|
+
throw ErrnoError.With('EEXIST', path, 'commitNewFile');
|
|
798
|
+
}
|
|
635
799
|
// Commit data.
|
|
800
|
+
const node = new Inode();
|
|
636
801
|
node.ino = this.addNewSync(tx, data, path);
|
|
637
802
|
node.size = data.length;
|
|
638
803
|
node.mode = mode | type;
|
|
@@ -641,13 +806,16 @@ export class StoreFS extends FileSystem {
|
|
|
641
806
|
// Update and commit parent directory listing.
|
|
642
807
|
listing[fname] = this.addNewSync(tx, node.data, path);
|
|
643
808
|
tx.setSync(parent.ino, encodeDirListing(listing));
|
|
809
|
+
tx.commitSync();
|
|
810
|
+
return node;
|
|
811
|
+
}
|
|
812
|
+
catch (e_16) {
|
|
813
|
+
env_16.error = e_16;
|
|
814
|
+
env_16.hasError = true;
|
|
644
815
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
throw e;
|
|
816
|
+
finally {
|
|
817
|
+
__disposeResources(env_16);
|
|
648
818
|
}
|
|
649
|
-
tx.commitSync();
|
|
650
|
-
return node;
|
|
651
819
|
}
|
|
652
820
|
/**
|
|
653
821
|
* Remove all traces of the given path from the file system.
|
|
@@ -656,38 +824,45 @@ export class StoreFS extends FileSystem {
|
|
|
656
824
|
* @todo Update mtime.
|
|
657
825
|
*/
|
|
658
826
|
async remove(path, isDir, cred) {
|
|
659
|
-
const
|
|
660
|
-
if (!listing[fileName]) {
|
|
661
|
-
throw ErrnoError.With('ENOENT', path, 'removeEntry');
|
|
662
|
-
}
|
|
663
|
-
const fileIno = listing[fileName];
|
|
664
|
-
// Get file inode.
|
|
665
|
-
const fileNode = await this.getINode(tx, fileIno, path);
|
|
666
|
-
if (!fileNode.toStats().hasAccess(W_OK, cred)) {
|
|
667
|
-
throw ErrnoError.With('EACCES', path, 'removeEntry');
|
|
668
|
-
}
|
|
669
|
-
// Remove from directory listing of parent.
|
|
670
|
-
delete listing[fileName];
|
|
671
|
-
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
672
|
-
throw ErrnoError.With('EISDIR', path, 'removeEntry');
|
|
673
|
-
}
|
|
674
|
-
if (isDir && !fileNode.toStats().isDirectory()) {
|
|
675
|
-
throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
|
|
676
|
-
}
|
|
827
|
+
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
677
828
|
try {
|
|
829
|
+
const tx = __addDisposableResource(env_17, this.store.transaction(), true);
|
|
830
|
+
const parent = dirname(path), parentNode = await this.findINode(tx, parent), listing = await this.getDirListing(tx, parentNode, parent), fileName = basename(path);
|
|
831
|
+
if (!listing[fileName]) {
|
|
832
|
+
throw ErrnoError.With('ENOENT', path, 'removeEntry');
|
|
833
|
+
}
|
|
834
|
+
const fileIno = listing[fileName];
|
|
835
|
+
// Get file inode.
|
|
836
|
+
const fileNode = await this.getINode(tx, fileIno, path);
|
|
837
|
+
if (!fileNode.toStats().hasAccess(W_OK, cred)) {
|
|
838
|
+
throw ErrnoError.With('EACCES', path, 'removeEntry');
|
|
839
|
+
}
|
|
840
|
+
// Remove from directory listing of parent.
|
|
841
|
+
delete listing[fileName];
|
|
842
|
+
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
843
|
+
throw ErrnoError.With('EISDIR', path, 'removeEntry');
|
|
844
|
+
}
|
|
845
|
+
if (isDir && !fileNode.toStats().isDirectory()) {
|
|
846
|
+
throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
|
|
847
|
+
}
|
|
678
848
|
await tx.set(parentNode.ino, encodeDirListing(listing));
|
|
679
849
|
if (--fileNode.nlink < 1) {
|
|
680
850
|
// remove file
|
|
681
851
|
await tx.remove(fileNode.ino);
|
|
682
852
|
await tx.remove(fileIno);
|
|
683
853
|
}
|
|
854
|
+
// Success.
|
|
855
|
+
await tx.commit();
|
|
856
|
+
}
|
|
857
|
+
catch (e_17) {
|
|
858
|
+
env_17.error = e_17;
|
|
859
|
+
env_17.hasError = true;
|
|
684
860
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
861
|
+
finally {
|
|
862
|
+
const result_9 = __disposeResources(env_17);
|
|
863
|
+
if (result_9)
|
|
864
|
+
await result_9;
|
|
688
865
|
}
|
|
689
|
-
// Success.
|
|
690
|
-
await tx.commit();
|
|
691
866
|
}
|
|
692
867
|
/**
|
|
693
868
|
* Remove all traces of the given path from the file system.
|
|
@@ -696,24 +871,26 @@ export class StoreFS extends FileSystem {
|
|
|
696
871
|
* @todo Update mtime.
|
|
697
872
|
*/
|
|
698
873
|
removeSync(path, isDir, cred) {
|
|
699
|
-
const
|
|
700
|
-
if (!fileIno) {
|
|
701
|
-
throw ErrnoError.With('ENOENT', path, 'removeEntry');
|
|
702
|
-
}
|
|
703
|
-
// Get file inode.
|
|
704
|
-
const fileNode = this.getINodeSync(tx, fileIno, path);
|
|
705
|
-
if (!fileNode.toStats().hasAccess(W_OK, cred)) {
|
|
706
|
-
throw ErrnoError.With('EACCES', path, 'removeEntry');
|
|
707
|
-
}
|
|
708
|
-
// Remove from directory listing of parent.
|
|
709
|
-
delete listing[fileName];
|
|
710
|
-
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
711
|
-
throw ErrnoError.With('EISDIR', path, 'removeEntry');
|
|
712
|
-
}
|
|
713
|
-
if (isDir && !fileNode.toStats().isDirectory()) {
|
|
714
|
-
throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
|
|
715
|
-
}
|
|
874
|
+
const env_18 = { stack: [], error: void 0, hasError: false };
|
|
716
875
|
try {
|
|
876
|
+
const tx = __addDisposableResource(env_18, this.store.transaction(), false);
|
|
877
|
+
const parent = dirname(path), parentNode = this.findINodeSync(tx, parent), listing = this.getDirListingSync(tx, parentNode, parent), fileName = basename(path), fileIno = listing[fileName];
|
|
878
|
+
if (!fileIno) {
|
|
879
|
+
throw ErrnoError.With('ENOENT', path, 'removeEntry');
|
|
880
|
+
}
|
|
881
|
+
// Get file inode.
|
|
882
|
+
const fileNode = this.getINodeSync(tx, fileIno, path);
|
|
883
|
+
if (!fileNode.toStats().hasAccess(W_OK, cred)) {
|
|
884
|
+
throw ErrnoError.With('EACCES', path, 'removeEntry');
|
|
885
|
+
}
|
|
886
|
+
// Remove from directory listing of parent.
|
|
887
|
+
delete listing[fileName];
|
|
888
|
+
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
889
|
+
throw ErrnoError.With('EISDIR', path, 'removeEntry');
|
|
890
|
+
}
|
|
891
|
+
if (isDir && !fileNode.toStats().isDirectory()) {
|
|
892
|
+
throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
|
|
893
|
+
}
|
|
717
894
|
// Update directory listing.
|
|
718
895
|
tx.setSync(parentNode.ino, encodeDirListing(listing));
|
|
719
896
|
if (--fileNode.nlink < 1) {
|
|
@@ -721,12 +898,15 @@ export class StoreFS extends FileSystem {
|
|
|
721
898
|
tx.removeSync(fileNode.ino);
|
|
722
899
|
tx.removeSync(fileIno);
|
|
723
900
|
}
|
|
901
|
+
// Success.
|
|
902
|
+
tx.commitSync();
|
|
903
|
+
}
|
|
904
|
+
catch (e_18) {
|
|
905
|
+
env_18.error = e_18;
|
|
906
|
+
env_18.hasError = true;
|
|
724
907
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
throw e;
|
|
908
|
+
finally {
|
|
909
|
+
__disposeResources(env_18);
|
|
728
910
|
}
|
|
729
|
-
// Success.
|
|
730
|
-
tx.commitSync();
|
|
731
911
|
}
|
|
732
912
|
}
|