@zenfs/core 2.5.8 → 2.6.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/cow.d.ts +13 -0
- package/dist/backends/cow.js +48 -11
- package/dist/backends/single_buffer.d.ts +2 -2
- package/dist/backends/store/fs.d.ts +6 -6
- package/dist/backends/store/fs.js +10 -2
- package/dist/internal/devices.d.ts +6 -6
- package/dist/internal/index_fs.d.ts +4 -4
- package/dist/node/async.js +1 -1
- package/dist/node/dir.d.ts +3 -1
- package/dist/node/dir.js +23 -5
- package/dist/node/promises.d.ts +3 -1
- package/dist/node/promises.js +128 -89
- package/dist/node/streams.d.ts +4 -0
- package/dist/node/streams.js +9 -10
- package/dist/node/sync.js +71 -40
- package/dist/utils.d.ts +8 -1
- package/dist/utils.js +26 -7
- package/dist/vfs/async.js +224 -85
- package/dist/vfs/file.d.ts +13 -7
- package/dist/vfs/file.js +661 -357
- package/dist/vfs/shared.d.ts +1 -0
- package/dist/vfs/shared.js +19 -3
- package/dist/vfs/sync.js +214 -85
- package/dist/vfs/vcache.d.ts +66 -0
- package/dist/vfs/vcache.js +249 -0
- package/dist/vfs/vnode.d.ts +66 -0
- package/dist/vfs/vnode.js +200 -0
- package/dist/vfs/watchers.js +4 -2
- package/dist/vfs/xattr.js +2 -2
- package/eslint.shared.js +1 -1
- package/package.json +3 -3
- package/scripts/make-index.js +7 -1
- package/scripts/test.js +28 -21
- package/tests/backend/port.test.ts +3 -3
- package/tests/backend/store.test.ts +49 -0
- package/tests/common.ts +62 -0
- package/tests/fetch/fetch.ts +6 -0
- package/tests/fetch/run.sh +2 -2
- package/tests/fetch/server.js +3 -3
- package/tests/fs/append.test.ts +5 -5
- package/tests/fs/concurrency.test.ts +52 -0
- package/tests/fs/dir.test.ts +13 -15
- package/tests/fs/directory.test.ts +32 -31
- package/tests/fs/errors.test.ts +151 -31
- package/tests/fs/exists.test.ts +4 -4
- package/tests/fs/links.test.ts +4 -11
- package/tests/fs/open.test.ts +4 -4
- package/tests/fs/permissions.test.ts +15 -15
- package/tests/fs/read.test.ts +9 -9
- package/tests/fs/readFile.test.ts +9 -9
- package/tests/fs/rename.test.ts +8 -8
- package/tests/fs/scaling.test.ts +4 -4
- package/tests/fs/stat.test.ts +20 -20
- package/tests/fs/streams.test.ts +9 -6
- package/tests/fs/tempdir.test.ts +33 -10
- package/tests/fs/times.test.ts +11 -11
- package/tests/fs/truncate.test.ts +6 -6
- package/tests/fs/watch.test.ts +107 -53
- package/tests/fs/write.test.ts +10 -10
- package/tests/fs/xattr.test.ts +3 -3
- package/tests/native/run.sh +3 -0
- package/tests/native/setup.ts +230 -0
- package/types/readable-stream.d.ts +2 -2
package/dist/vfs/file.js
CHANGED
|
@@ -1,371 +1,674 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
+
}
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
35
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
36
|
+
if (value !== null && value !== void 0) {
|
|
37
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
38
|
+
var dispose, inner;
|
|
39
|
+
if (async) {
|
|
40
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
41
|
+
dispose = value[Symbol.asyncDispose];
|
|
42
|
+
}
|
|
43
|
+
if (dispose === void 0) {
|
|
44
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
45
|
+
dispose = value[Symbol.dispose];
|
|
46
|
+
if (async) inner = dispose;
|
|
47
|
+
}
|
|
48
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
49
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
50
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
51
|
+
}
|
|
52
|
+
else if (async) {
|
|
53
|
+
env.stack.push({ async: true });
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
58
|
+
return function (env) {
|
|
59
|
+
function fail(e) {
|
|
60
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
61
|
+
env.hasError = true;
|
|
62
|
+
}
|
|
63
|
+
var r, s = 0;
|
|
64
|
+
function next() {
|
|
65
|
+
while (r = env.stack.pop()) {
|
|
66
|
+
try {
|
|
67
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
68
|
+
if (r.dispose) {
|
|
69
|
+
var result = r.dispose.call(r.value);
|
|
70
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
71
|
+
}
|
|
72
|
+
else s |= 1;
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
fail(e);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
79
|
+
if (env.hasError) throw env.error;
|
|
80
|
+
}
|
|
81
|
+
return next();
|
|
82
|
+
};
|
|
83
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
84
|
+
var e = new Error(message);
|
|
85
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
86
|
+
});
|
|
1
87
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
88
|
import { UV, withErrno } from 'kerium';
|
|
89
|
+
import { memoize } from 'utilium';
|
|
3
90
|
import * as c from '../constants.js';
|
|
4
91
|
import { contextOf } from '../internal/contexts.js';
|
|
5
92
|
import { _chown, InodeFlags, isBlockDevice, isCharacterDevice } from '../internal/inode.js';
|
|
6
93
|
import '../polyfills.js';
|
|
94
|
+
import { validateFD } from '../utils.js';
|
|
95
|
+
import { cacheOf } from './vcache.js';
|
|
96
|
+
/** The chunk size used when streaming reads and writes */
|
|
97
|
+
const streamChunkSize = 0x1000;
|
|
7
98
|
/**
|
|
8
99
|
* @internal
|
|
9
100
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
this.inode.size = length;
|
|
111
|
-
this.inode.ctimeMs = Date.now();
|
|
112
|
-
if (this._isSync)
|
|
113
|
-
this.syncSync();
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Write buffer to the file.
|
|
117
|
-
* @param buffer Uint8Array containing the data to write to the file.
|
|
118
|
-
* @param offset Offset in the buffer to start reading data from.
|
|
119
|
-
* @param length The amount of bytes to write to the file.
|
|
120
|
-
* @param position Offset from the beginning of the file where this data should be written.
|
|
121
|
-
* If position is null, the data will be written at the current position.
|
|
122
|
-
* @returns bytes written
|
|
123
|
-
*/
|
|
124
|
-
writeSync(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
125
|
-
if (this.closed)
|
|
126
|
-
throw UV('EBADF', 'write', this.path);
|
|
127
|
-
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
128
|
-
throw UV('EBADF', 'write', this.path);
|
|
129
|
-
if (this.fs.attributes.has('readonly'))
|
|
130
|
-
throw UV('EROFS', 'write', this.path);
|
|
131
|
-
if (this.inode.flags & InodeFlags.Immutable)
|
|
132
|
-
throw UV('EPERM', 'write', this.path);
|
|
133
|
-
this.dirty = true;
|
|
134
|
-
const end = position + length;
|
|
135
|
-
const slice = buffer.subarray(offset, offset + length);
|
|
136
|
-
if (!isCharacterDevice(this.inode) && !isBlockDevice(this.inode) && end > this.inode.size)
|
|
137
|
-
this.inode.size = end;
|
|
138
|
-
this.inode.mtimeMs = Date.now();
|
|
139
|
-
this.inode.ctimeMs = Date.now();
|
|
140
|
-
this._position = position + slice.byteLength;
|
|
141
|
-
this.fs.writeSync(this.internalPath, slice, position);
|
|
142
|
-
if (this._isSync)
|
|
143
|
-
this.syncSync();
|
|
144
|
-
return slice.byteLength;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Read data from the file.
|
|
148
|
-
* @param buffer The buffer that the data will be written to.
|
|
149
|
-
* @param offset The offset within the buffer where writing will start.
|
|
150
|
-
* @param length An integer specifying the number of bytes to read.
|
|
151
|
-
* @param position An integer specifying where to begin reading from in the file.
|
|
152
|
-
* If position is null, data will be read from the current file position.
|
|
153
|
-
* @returns number of bytes written
|
|
154
|
-
*/
|
|
155
|
-
readSync(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
156
|
-
if (this.closed)
|
|
157
|
-
throw UV('EBADF', 'read', this.path);
|
|
158
|
-
if (this.flag & c.O_WRONLY)
|
|
159
|
-
throw UV('EBADF', 'read', this.path);
|
|
160
|
-
if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
|
|
161
|
-
this.dirty = true;
|
|
162
|
-
this.inode.atimeMs = Date.now();
|
|
163
|
-
}
|
|
164
|
-
let end = position + length;
|
|
165
|
-
if (!isCharacterDevice(this.inode) && !isBlockDevice(this.inode) && end > this.inode.size) {
|
|
166
|
-
end = position + Math.max(this.inode.size - position, 0);
|
|
167
|
-
}
|
|
168
|
-
this._position = end;
|
|
169
|
-
const uint8 = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
170
|
-
this.fs.readSync(this.internalPath, uint8.subarray(offset, offset + length), position, end);
|
|
171
|
-
if (this._isSync)
|
|
172
|
-
this.syncSync();
|
|
173
|
-
return end - position;
|
|
174
|
-
}
|
|
175
|
-
chmodSync(mode) {
|
|
176
|
-
if (this.closed)
|
|
177
|
-
throw UV('EBADF', 'chmod', this.path);
|
|
178
|
-
this.dirty = true;
|
|
179
|
-
this.inode.mode = (this.inode.mode & (mode > c.S_IFMT ? ~c.S_IFMT : c.S_IFMT)) | mode;
|
|
180
|
-
if (this._isSync || mode > c.S_IFMT)
|
|
181
|
-
this.syncSync();
|
|
182
|
-
}
|
|
183
|
-
chownSync(uid, gid) {
|
|
184
|
-
if (this.closed)
|
|
185
|
-
throw UV('EBADF', 'chmod', this.path);
|
|
186
|
-
this.dirty = true;
|
|
187
|
-
_chown(this.inode, uid, gid);
|
|
188
|
-
if (this._isSync)
|
|
189
|
-
this.syncSync();
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Change the file timestamps of the file.
|
|
193
|
-
*/
|
|
194
|
-
utimesSync(atime, mtime) {
|
|
195
|
-
if (this.closed)
|
|
196
|
-
throw UV('EBADF', 'utimes', this.path);
|
|
197
|
-
this.dirty = true;
|
|
198
|
-
this.inode.atimeMs = atime;
|
|
199
|
-
this.inode.mtimeMs = mtime;
|
|
200
|
-
if (this._isSync)
|
|
101
|
+
let Handle = (() => {
|
|
102
|
+
let _instanceExtraInitializers = [];
|
|
103
|
+
let _get_inode_decorators;
|
|
104
|
+
let _get_fs_decorators;
|
|
105
|
+
return class Handle {
|
|
106
|
+
static {
|
|
107
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
108
|
+
__esDecorate(this, null, _get_inode_decorators, { kind: "getter", name: "inode", static: false, private: false, access: { has: obj => "inode" in obj, get: obj => obj.inode }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
109
|
+
__esDecorate(this, null, _get_fs_decorators, { kind: "getter", name: "fs", static: false, private: false, access: { has: obj => "fs" in obj, get: obj => obj.fs }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
110
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
111
|
+
}
|
|
112
|
+
context = __runInitializers(this, _instanceExtraInitializers);
|
|
113
|
+
path;
|
|
114
|
+
internalPath;
|
|
115
|
+
flag;
|
|
116
|
+
vnode;
|
|
117
|
+
/**
|
|
118
|
+
* Current position
|
|
119
|
+
*/
|
|
120
|
+
_position = 0;
|
|
121
|
+
/**
|
|
122
|
+
* Get the current file position.
|
|
123
|
+
*
|
|
124
|
+
* We emulate the following bug mentioned in the Node documentation:
|
|
125
|
+
*
|
|
126
|
+
* On Linux, positional writes don't work when the file is opened in append mode.
|
|
127
|
+
* The kernel ignores the position argument and always appends the data to the end of the file.
|
|
128
|
+
* @returns The current file position.
|
|
129
|
+
*/
|
|
130
|
+
get position() {
|
|
131
|
+
return this.flag & c.O_APPEND ? this.inode.size : this._position;
|
|
132
|
+
}
|
|
133
|
+
set position(value) {
|
|
134
|
+
this._position = value;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The inode for the file. This is shared between all handles for the file via the vnode.
|
|
138
|
+
*/
|
|
139
|
+
get inode() {
|
|
140
|
+
return this.vnode.inode;
|
|
141
|
+
}
|
|
142
|
+
get fs() {
|
|
143
|
+
return this.vnode.fs;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Whether the file has changes which have not been written to the FS
|
|
147
|
+
*/
|
|
148
|
+
get dirty() {
|
|
149
|
+
return this.vnode.dirty;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Whether the file is open or closed
|
|
153
|
+
*/
|
|
154
|
+
closed = false;
|
|
155
|
+
get isClosed() {
|
|
156
|
+
return this.closed;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Creates a file handle for the vnode.
|
|
160
|
+
*/
|
|
161
|
+
constructor(context, path, internalPath, flag, vnode) {
|
|
162
|
+
this.context = context;
|
|
163
|
+
this.path = path;
|
|
164
|
+
this.internalPath = internalPath;
|
|
165
|
+
this.flag = flag;
|
|
166
|
+
this.vnode = vnode;
|
|
167
|
+
}
|
|
168
|
+
get _isSync() {
|
|
169
|
+
return !!(this.flag & c.O_SYNC || this.inode.flags & InodeFlags.Sync || this.fs.attributes.has('sync'));
|
|
170
|
+
}
|
|
171
|
+
[(_get_inode_decorators = [memoize], _get_fs_decorators = [memoize], Symbol.dispose)]() {
|
|
172
|
+
this.closeSync();
|
|
173
|
+
}
|
|
174
|
+
syncSync() {
|
|
175
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
176
|
+
try {
|
|
177
|
+
if (this.closed)
|
|
178
|
+
throw UV('EBADF', 'sync', this.path);
|
|
179
|
+
if (!this.dirty)
|
|
180
|
+
return;
|
|
181
|
+
const _ = __addDisposableResource(env_1, this.vnode.lockSync('ro'), false);
|
|
182
|
+
this.vnode.syncSync();
|
|
183
|
+
}
|
|
184
|
+
catch (e_1) {
|
|
185
|
+
env_1.error = e_1;
|
|
186
|
+
env_1.hasError = true;
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
__disposeResources(env_1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Default implementation maps to `syncSync`.
|
|
194
|
+
*/
|
|
195
|
+
datasyncSync() {
|
|
196
|
+
return this.syncSync();
|
|
197
|
+
}
|
|
198
|
+
closeSync() {
|
|
199
|
+
if (this.closed)
|
|
200
|
+
throw UV('EBADF', 'close', this.path);
|
|
201
201
|
this.syncSync();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
202
|
+
this.disposeSync();
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Cleans up. This will *not* sync the file data to the FS
|
|
206
|
+
*/
|
|
207
|
+
disposeSync(force) {
|
|
208
|
+
if (this.closed)
|
|
209
|
+
throw UV('EBADF', 'close', this.path);
|
|
210
|
+
if (this.dirty && !force)
|
|
211
|
+
throw UV('EBUSY', 'close', this.path);
|
|
212
|
+
this.closed = true;
|
|
213
|
+
cacheOf(this.fs).unref(this.vnode);
|
|
214
|
+
}
|
|
215
|
+
truncateSync(length) {
|
|
216
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
217
|
+
try {
|
|
218
|
+
if (length < 0)
|
|
219
|
+
throw UV('EINVAL', 'truncate', this.path);
|
|
220
|
+
if (this.closed)
|
|
221
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
222
|
+
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
223
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
224
|
+
if (this.fs.attributes.has('readonly'))
|
|
225
|
+
throw UV('EROFS', 'truncate', this.path);
|
|
226
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
227
|
+
throw UV('EPERM', 'truncate', this.path);
|
|
228
|
+
const _ = __addDisposableResource(env_2, this.vnode.lockSync('rw'), false);
|
|
229
|
+
this.vnode.truncate(length);
|
|
230
|
+
if (this._isSync)
|
|
231
|
+
this.vnode.syncSync();
|
|
232
|
+
}
|
|
233
|
+
catch (e_2) {
|
|
234
|
+
env_2.error = e_2;
|
|
235
|
+
env_2.hasError = true;
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
__disposeResources(env_2);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Write buffer to the file.
|
|
243
|
+
* @param buffer Uint8Array containing the data to write to the file.
|
|
244
|
+
* @param offset Offset in the buffer to start reading data from.
|
|
245
|
+
* @param length The amount of bytes to write to the file.
|
|
246
|
+
* @param position Offset from the beginning of the file where this data should be written.
|
|
247
|
+
* If position is null, the data will be written at the current position.
|
|
248
|
+
* @returns bytes written
|
|
249
|
+
*/
|
|
250
|
+
writeSync(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
251
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
252
|
+
try {
|
|
253
|
+
if (this.closed)
|
|
254
|
+
throw UV('EBADF', 'write', this.path);
|
|
255
|
+
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
256
|
+
throw UV('EBADF', 'write', this.path);
|
|
257
|
+
if (this.fs.attributes.has('readonly'))
|
|
258
|
+
throw UV('EROFS', 'write', this.path);
|
|
259
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
260
|
+
throw UV('EPERM', 'write', this.path);
|
|
261
|
+
const _ = __addDisposableResource(env_3, this.vnode.lockSync('rw'), false);
|
|
262
|
+
const slice = buffer.subarray(offset, offset + length);
|
|
263
|
+
this.vnode.writeSync(slice, position);
|
|
264
|
+
this._position = position + slice.byteLength;
|
|
265
|
+
if (this._isSync)
|
|
266
|
+
this.vnode.syncSync();
|
|
267
|
+
return slice.byteLength;
|
|
268
|
+
}
|
|
269
|
+
catch (e_3) {
|
|
270
|
+
env_3.error = e_3;
|
|
271
|
+
env_3.hasError = true;
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
__disposeResources(env_3);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Read data from the file.
|
|
279
|
+
* @param buffer The buffer that the data will be written to.
|
|
280
|
+
* @param offset The offset within the buffer where writing will start.
|
|
281
|
+
* @param length An integer specifying the number of bytes to read.
|
|
282
|
+
* @param position An integer specifying where to begin reading from in the file.
|
|
283
|
+
* If position is null, data will be read from the current file position.
|
|
284
|
+
* @returns number of bytes written
|
|
285
|
+
*/
|
|
286
|
+
readSync(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
287
|
+
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
288
|
+
try {
|
|
289
|
+
if (this.closed)
|
|
290
|
+
throw UV('EBADF', 'read', this.path);
|
|
291
|
+
if (this.flag & c.O_WRONLY)
|
|
292
|
+
throw UV('EBADF', 'read', this.path);
|
|
293
|
+
const _ = __addDisposableResource(env_4, this.vnode.lockSync('ro'), false);
|
|
294
|
+
if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
|
|
295
|
+
this.vnode.metadataDirty = true;
|
|
296
|
+
this.inode.atimeMs = Date.now();
|
|
297
|
+
}
|
|
298
|
+
let end = position + length;
|
|
299
|
+
if (!isCharacterDevice(this.inode) && !isBlockDevice(this.inode) && end > this.inode.size) {
|
|
300
|
+
end = position + Math.max(this.inode.size - position, 0);
|
|
301
|
+
}
|
|
302
|
+
this._position = end;
|
|
303
|
+
const uint8 = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
304
|
+
this.vnode.readSync(uint8.subarray(offset, offset + length), position, end);
|
|
305
|
+
if (this._isSync)
|
|
306
|
+
this.vnode.syncSync();
|
|
307
|
+
return end - position;
|
|
308
|
+
}
|
|
309
|
+
catch (e_4) {
|
|
310
|
+
env_4.error = e_4;
|
|
311
|
+
env_4.hasError = true;
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
__disposeResources(env_4);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
chmodSync(mode) {
|
|
318
|
+
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
319
|
+
try {
|
|
320
|
+
if (this.closed)
|
|
321
|
+
throw UV('EBADF', 'chmod', this.path);
|
|
322
|
+
const _ = __addDisposableResource(env_5, this.vnode.lockSync('rw'), false);
|
|
323
|
+
this.vnode.metadataDirty = true;
|
|
324
|
+
this.inode.mode = (this.inode.mode & (mode > c.S_IFMT ? ~c.S_IFMT : c.S_IFMT)) | mode;
|
|
325
|
+
if (this._isSync || mode > c.S_IFMT)
|
|
326
|
+
this.vnode.syncSync();
|
|
327
|
+
}
|
|
328
|
+
catch (e_5) {
|
|
329
|
+
env_5.error = e_5;
|
|
330
|
+
env_5.hasError = true;
|
|
331
|
+
}
|
|
332
|
+
finally {
|
|
333
|
+
__disposeResources(env_5);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
chownSync(uid, gid) {
|
|
337
|
+
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
338
|
+
try {
|
|
339
|
+
if (this.closed)
|
|
340
|
+
throw UV('EBADF', 'chmod', this.path);
|
|
341
|
+
const _ = __addDisposableResource(env_6, this.vnode.lockSync('rw'), false);
|
|
342
|
+
this.vnode.metadataDirty = true;
|
|
343
|
+
_chown(this.inode, uid, gid);
|
|
344
|
+
if (this._isSync)
|
|
345
|
+
this.vnode.syncSync();
|
|
346
|
+
}
|
|
347
|
+
catch (e_6) {
|
|
348
|
+
env_6.error = e_6;
|
|
349
|
+
env_6.hasError = true;
|
|
350
|
+
}
|
|
351
|
+
finally {
|
|
352
|
+
__disposeResources(env_6);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Change the file timestamps of the file.
|
|
357
|
+
*/
|
|
358
|
+
utimesSync(atime, mtime) {
|
|
359
|
+
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
360
|
+
try {
|
|
361
|
+
if (this.closed)
|
|
362
|
+
throw UV('EBADF', 'utimes', this.path);
|
|
363
|
+
const _ = __addDisposableResource(env_7, this.vnode.lockSync('rw'), false);
|
|
364
|
+
this.vnode.metadataDirty = true;
|
|
365
|
+
this.inode.atimeMs = atime;
|
|
366
|
+
this.inode.mtimeMs = mtime;
|
|
367
|
+
if (this._isSync)
|
|
368
|
+
this.vnode.syncSync();
|
|
369
|
+
}
|
|
370
|
+
catch (e_7) {
|
|
371
|
+
env_7.error = e_7;
|
|
372
|
+
env_7.hasError = true;
|
|
373
|
+
}
|
|
374
|
+
finally {
|
|
375
|
+
__disposeResources(env_7);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
async [Symbol.asyncDispose]() {
|
|
379
|
+
await this.close();
|
|
380
|
+
}
|
|
381
|
+
async sync() {
|
|
382
|
+
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
383
|
+
try {
|
|
384
|
+
if (this.closed)
|
|
385
|
+
throw UV('EBADF', 'sync', this.path);
|
|
386
|
+
if (!this.dirty)
|
|
387
|
+
return;
|
|
388
|
+
const _ = __addDisposableResource(env_8, await this.vnode.lock('ro'), false);
|
|
389
|
+
await this.vnode.sync();
|
|
390
|
+
}
|
|
391
|
+
catch (e_8) {
|
|
392
|
+
env_8.error = e_8;
|
|
393
|
+
env_8.hasError = true;
|
|
394
|
+
}
|
|
395
|
+
finally {
|
|
396
|
+
__disposeResources(env_8);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Default implementation maps to `sync`.
|
|
401
|
+
*/
|
|
402
|
+
datasync() {
|
|
403
|
+
return this.sync();
|
|
404
|
+
}
|
|
405
|
+
async close() {
|
|
406
|
+
if (this.closed)
|
|
407
|
+
throw UV('EBADF', 'close', this.path);
|
|
346
408
|
await this.sync();
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
409
|
+
this.dispose();
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Cleans up. This will *not* sync the file data to the FS
|
|
413
|
+
*/
|
|
414
|
+
dispose(force) {
|
|
415
|
+
if (this.closed)
|
|
416
|
+
throw UV('EBADF', 'close', this.path);
|
|
417
|
+
if (this.dirty && !force)
|
|
418
|
+
throw UV('EBUSY', 'close', this.path);
|
|
419
|
+
this.closed = true;
|
|
420
|
+
cacheOf(this.fs).unref(this.vnode);
|
|
421
|
+
}
|
|
422
|
+
stat() {
|
|
423
|
+
if (this.closed)
|
|
424
|
+
throw UV('EBADF', 'stat', this.path);
|
|
425
|
+
return this.inode;
|
|
426
|
+
}
|
|
427
|
+
async truncate(length) {
|
|
428
|
+
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
429
|
+
try {
|
|
430
|
+
if (length < 0)
|
|
431
|
+
throw UV('EINVAL', 'truncate', this.path);
|
|
432
|
+
if (this.closed)
|
|
433
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
434
|
+
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
435
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
436
|
+
if (this.fs.attributes.has('readonly'))
|
|
437
|
+
throw UV('EROFS', 'truncate', this.path);
|
|
438
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
439
|
+
throw UV('EPERM', 'truncate', this.path);
|
|
440
|
+
const _ = __addDisposableResource(env_9, await this.vnode.lock('rw'), false);
|
|
441
|
+
this.vnode.truncate(length);
|
|
442
|
+
if (this._isSync)
|
|
443
|
+
await this.vnode.sync();
|
|
444
|
+
}
|
|
445
|
+
catch (e_9) {
|
|
446
|
+
env_9.error = e_9;
|
|
447
|
+
env_9.hasError = true;
|
|
448
|
+
}
|
|
449
|
+
finally {
|
|
450
|
+
__disposeResources(env_9);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Write buffer to the file.
|
|
455
|
+
* @param buffer Uint8Array containing the data to write to the file.
|
|
456
|
+
* @param offset Offset in the buffer to start reading data from.
|
|
457
|
+
* @param length The amount of bytes to write to the file.
|
|
458
|
+
* @param position Offset from the beginning of the file where this data should be written.
|
|
459
|
+
* If position is null, the data will be written at the current position.
|
|
460
|
+
* @returns bytes written
|
|
461
|
+
*/
|
|
462
|
+
async write(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
463
|
+
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
464
|
+
try {
|
|
465
|
+
if (this.closed)
|
|
466
|
+
throw UV('EBADF', 'write', this.path);
|
|
467
|
+
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
468
|
+
throw UV('EBADF', 'write', this.path);
|
|
469
|
+
if (this.fs.attributes.has('readonly'))
|
|
470
|
+
throw UV('EROFS', 'write', this.path);
|
|
471
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
472
|
+
throw UV('EPERM', 'write', this.path);
|
|
473
|
+
const _ = __addDisposableResource(env_10, await this.vnode.lock('rw'), false);
|
|
474
|
+
const slice = buffer.subarray(offset, offset + length);
|
|
475
|
+
await this.vnode.write(slice, position);
|
|
476
|
+
this._position = position + slice.byteLength;
|
|
477
|
+
if (this._isSync)
|
|
478
|
+
await this.vnode.sync();
|
|
479
|
+
return slice.byteLength;
|
|
480
|
+
}
|
|
481
|
+
catch (e_10) {
|
|
482
|
+
env_10.error = e_10;
|
|
483
|
+
env_10.hasError = true;
|
|
484
|
+
}
|
|
485
|
+
finally {
|
|
486
|
+
__disposeResources(env_10);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Read data from the file.
|
|
491
|
+
* @param buffer The buffer that the data will be written to.
|
|
492
|
+
* @param offset The offset within the buffer where writing will start.
|
|
493
|
+
* @param length An integer specifying the number of bytes to read.
|
|
494
|
+
* @param position An integer specifying where to begin reading from in the file.
|
|
495
|
+
* If position is null, data will be read from the current file position.
|
|
496
|
+
* @returns number of bytes written
|
|
497
|
+
*/
|
|
498
|
+
async read(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
499
|
+
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
500
|
+
try {
|
|
501
|
+
if (this.closed)
|
|
502
|
+
throw UV('EBADF', 'read', this.path);
|
|
503
|
+
if (this.flag & c.O_WRONLY)
|
|
504
|
+
throw UV('EBADF', 'read', this.path);
|
|
505
|
+
const _ = __addDisposableResource(env_11, await this.vnode.lock('ro'), false);
|
|
506
|
+
if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
|
|
507
|
+
this.vnode.metadataDirty = true;
|
|
508
|
+
this.inode.atimeMs = Date.now();
|
|
509
|
+
}
|
|
510
|
+
let end = position + length;
|
|
511
|
+
if (!isCharacterDevice(this.inode) && !isBlockDevice(this.inode) && end > this.inode.size) {
|
|
512
|
+
end = position + Math.max(this.inode.size - position, 0);
|
|
513
|
+
}
|
|
514
|
+
this._position = end;
|
|
515
|
+
const uint8 = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
516
|
+
await this.vnode.read(uint8.subarray(offset, offset + length), position, end);
|
|
517
|
+
if (this._isSync)
|
|
518
|
+
await this.vnode.sync();
|
|
519
|
+
return end - position;
|
|
520
|
+
}
|
|
521
|
+
catch (e_11) {
|
|
522
|
+
env_11.error = e_11;
|
|
523
|
+
env_11.hasError = true;
|
|
524
|
+
}
|
|
525
|
+
finally {
|
|
526
|
+
__disposeResources(env_11);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
async chmod(mode) {
|
|
530
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
531
|
+
try {
|
|
532
|
+
if (this.closed)
|
|
533
|
+
throw UV('EBADF', 'chmod', this.path);
|
|
534
|
+
const _ = __addDisposableResource(env_12, await this.vnode.lock('rw'), false);
|
|
535
|
+
this.vnode.metadataDirty = true;
|
|
536
|
+
this.inode.mode = (this.inode.mode & (mode > c.S_IFMT ? ~c.S_IFMT : c.S_IFMT)) | mode;
|
|
537
|
+
if (this._isSync || mode > c.S_IFMT)
|
|
538
|
+
await this.vnode.sync();
|
|
539
|
+
}
|
|
540
|
+
catch (e_12) {
|
|
541
|
+
env_12.error = e_12;
|
|
542
|
+
env_12.hasError = true;
|
|
543
|
+
}
|
|
544
|
+
finally {
|
|
545
|
+
__disposeResources(env_12);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
async chown(uid, gid) {
|
|
549
|
+
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
550
|
+
try {
|
|
551
|
+
if (this.closed)
|
|
552
|
+
throw UV('EBADF', 'chown', this.path);
|
|
553
|
+
const _ = __addDisposableResource(env_13, await this.vnode.lock('rw'), false);
|
|
554
|
+
this.vnode.metadataDirty = true;
|
|
555
|
+
_chown(this.inode, uid, gid);
|
|
556
|
+
if (this._isSync)
|
|
557
|
+
await this.vnode.sync();
|
|
558
|
+
}
|
|
559
|
+
catch (e_13) {
|
|
560
|
+
env_13.error = e_13;
|
|
561
|
+
env_13.hasError = true;
|
|
562
|
+
}
|
|
563
|
+
finally {
|
|
564
|
+
__disposeResources(env_13);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Change the file timestamps of the file.
|
|
569
|
+
*/
|
|
570
|
+
async utimes(atime, mtime) {
|
|
571
|
+
const env_14 = { stack: [], error: void 0, hasError: false };
|
|
572
|
+
try {
|
|
573
|
+
if (this.closed)
|
|
574
|
+
throw UV('EBADF', 'utimes', this.path);
|
|
575
|
+
const _ = __addDisposableResource(env_14, await this.vnode.lock('rw'), false);
|
|
576
|
+
this.vnode.metadataDirty = true;
|
|
577
|
+
this.inode.atimeMs = atime;
|
|
578
|
+
this.inode.mtimeMs = mtime;
|
|
579
|
+
if (this._isSync)
|
|
580
|
+
await this.vnode.sync();
|
|
581
|
+
}
|
|
582
|
+
catch (e_14) {
|
|
583
|
+
env_14.error = e_14;
|
|
584
|
+
env_14.hasError = true;
|
|
585
|
+
}
|
|
586
|
+
finally {
|
|
587
|
+
__disposeResources(env_14);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Create a stream for reading the file.
|
|
592
|
+
* @todo Don't repeat ourselves with the implementation in `FileSystem`
|
|
593
|
+
*/
|
|
594
|
+
streamRead(options) {
|
|
595
|
+
if (this.closed)
|
|
596
|
+
throw UV('EBADF', 'streamRead', this.path);
|
|
597
|
+
const { vnode } = this;
|
|
598
|
+
return new ReadableStream({
|
|
599
|
+
async start(controller) {
|
|
600
|
+
const env_15 = { stack: [], error: void 0, hasError: false };
|
|
601
|
+
try {
|
|
602
|
+
const _ = __addDisposableResource(env_15, await vnode.lock('ro'), false);
|
|
603
|
+
const { start = 0, end = vnode.inode.size } = options;
|
|
604
|
+
for (let offset = start; offset < end; offset += streamChunkSize) {
|
|
605
|
+
const bytesRead = offset + streamChunkSize > end ? end - offset : streamChunkSize;
|
|
606
|
+
const buffer = new Uint8Array(bytesRead);
|
|
607
|
+
await vnode.read(buffer, offset, offset + bytesRead).catch(controller.error.bind(controller));
|
|
608
|
+
controller.enqueue(buffer);
|
|
609
|
+
}
|
|
610
|
+
controller.close();
|
|
611
|
+
}
|
|
612
|
+
catch (e_15) {
|
|
613
|
+
env_15.error = e_15;
|
|
614
|
+
env_15.hasError = true;
|
|
615
|
+
}
|
|
616
|
+
finally {
|
|
617
|
+
__disposeResources(env_15);
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
type: 'bytes',
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Create a stream for writing the file.
|
|
625
|
+
* Chunks are written to the vnode's cache, then synced when the stream is closed.
|
|
626
|
+
* @todo Don't repeat ourselves with the implementation in `FileSystem`
|
|
627
|
+
*/
|
|
628
|
+
streamWrite(options) {
|
|
629
|
+
if (this.closed)
|
|
630
|
+
throw UV('EBADF', 'write', this.path);
|
|
631
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
632
|
+
throw UV('EPERM', 'write', this.path);
|
|
633
|
+
if (this.fs.attributes.has('readonly'))
|
|
634
|
+
throw UV('EROFS', 'write', this.path);
|
|
635
|
+
const { vnode } = this;
|
|
636
|
+
let position = options.start ?? 0;
|
|
637
|
+
return new WritableStream({
|
|
638
|
+
async write(chunk, controller) {
|
|
639
|
+
const env_16 = { stack: [], error: void 0, hasError: false };
|
|
640
|
+
try {
|
|
641
|
+
const _ = __addDisposableResource(env_16, await vnode.lock('rw'), false);
|
|
642
|
+
await vnode.write(chunk, position).catch(controller.error.bind(controller));
|
|
643
|
+
position += chunk.byteLength;
|
|
644
|
+
}
|
|
645
|
+
catch (e_16) {
|
|
646
|
+
env_16.error = e_16;
|
|
647
|
+
env_16.hasError = true;
|
|
648
|
+
}
|
|
649
|
+
finally {
|
|
650
|
+
__disposeResources(env_16);
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
async close() {
|
|
654
|
+
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
655
|
+
try {
|
|
656
|
+
const _ = __addDisposableResource(env_17, await vnode.lock('ro'), false);
|
|
657
|
+
await vnode.sync();
|
|
658
|
+
}
|
|
659
|
+
catch (e_17) {
|
|
660
|
+
env_17.error = e_17;
|
|
661
|
+
env_17.hasError = true;
|
|
662
|
+
}
|
|
663
|
+
finally {
|
|
664
|
+
__disposeResources(env_17);
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
})();
|
|
671
|
+
export { Handle };
|
|
369
672
|
// descriptors
|
|
370
673
|
/**
|
|
371
674
|
* @internal @hidden
|
|
@@ -380,6 +683,7 @@ export function toFD(file) {
|
|
|
380
683
|
* @internal @hidden
|
|
381
684
|
*/
|
|
382
685
|
export function fromFD($, fd) {
|
|
686
|
+
validateFD(fd);
|
|
383
687
|
const map = contextOf($).descriptors;
|
|
384
688
|
const value = map.get(fd);
|
|
385
689
|
if (!value)
|