@bytecodealliance/preview2-shim 0.0.16 → 0.0.18

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.
@@ -1,78 +1,437 @@
1
- import { openSync, constants, statSync, lstatSync, fstatSync, closeSync, readdirSync } from 'node:fs';
2
- import { _createFsStream, _dropFsStream, _getFsStreamContext } from './io.js';
3
-
4
- // default is full permissions
5
- let preopenCnt = 4;
6
- export let _descriptors = {
7
- 3: { type: 'directory', path: '/', parent: null, subpathTypes: {} }
8
- };
9
- let directories = [[3, '/']];
10
-
11
- export function _setPreopens (preopens) {
12
- _descriptors = {};
13
- directories = [,,];
14
- for (const [virtualPath, path] of Object.entries(preopens)) {
15
- _descriptors[preopenCnt] = { type: 'directory', path, parent: null, subpathTypes: {} };
16
- directories.push([preopenCnt++, virtualPath]);
17
- }
18
- }
1
+ import { streams } from '../common/io.js';
2
+ import { environment } from './cli.js';
3
+ import { constants, readSync, openSync, opendirSync, closeSync, fstatSync, lstatSync, statSync, writeSync, mkdirSync } from 'node:fs';
4
+ import { platform } from 'node:process';
19
5
 
20
- export function _getFullPath (fd) {
21
- let path = '';
22
- while (fd) {
23
- path = _descriptors[fd].path + path;
24
- fd = _descriptors[fd].parent;
25
- }
26
- return path;
27
- }
6
+ const { InputStream, OutputStream, Error: StreamError } = streams;
28
7
 
29
- export function _getDescriptorType (fd) {
30
- return _descriptors[fd].type;
31
- }
8
+ const isWindows = platform === 'win32';
32
9
 
33
- export function _setDescriptorType (fd, type) {
34
- _descriptors[fd].type = type;
10
+ const nsMagnitude = 1_000_000_000_000n;
11
+ function nsToDateTime (ns) {
12
+ const seconds = ns / nsMagnitude;
13
+ const nanoseconds = Number(ns % seconds);
14
+ return { seconds, nanoseconds };
35
15
  }
36
16
 
37
- export function _setSubdescriptorType (fd, path, type) {
38
- while (_descriptors[fd].parent) {
39
- path = _descriptors[fd].path + path;
40
- fd = _descriptors[fd].parent;
41
- }
42
- _descriptors[fd].subpathTypes[path] = type;
17
+ function lookupType (obj) {
18
+ if (obj.isFile())
19
+ return 'regular-file';
20
+ else if (obj.isSocket())
21
+ return 'socket';
22
+ else if (obj.isSymbolicLink())
23
+ return 'symbolic-link';
24
+ else if (obj.isFIFO())
25
+ return 'fifo';
26
+ else if (obj.isDirectory())
27
+ return 'directory';
28
+ else if (obj.isCharacterDevice())
29
+ return 'character-device';
30
+ else if (obj.isBlockDevice())
31
+ return 'block-device';
32
+ return 'unknown';
43
33
  }
44
34
 
45
- export function _addOpenedDescriptor (fd, path, parentFd) {
46
- if (fd < preopenCnt || _descriptors[fd])
47
- throw 'bad-descriptor';
48
- let type = null;
49
- for (const [_path, _type] of Object.entries(_descriptors[parentFd].subpathTypes)) {
50
- if (_path === path)
51
- type = _type;
35
+ /**
36
+ * @typedef {
37
+ * { hostPreopen: string } |
38
+ * { fullPath: string, fd: number }
39
+ * } DescriptorProps
40
+ */
41
+ export class FileSystem {
42
+ // Note: This should implement per-segment semantics of openAt, but we cannot currently
43
+ // due to the lack of support for openat() in Node.js.
44
+ // Tracking issue: https://github.com/libuv/libuv/issues/4167
45
+
46
+ // TODO: support followSymlinks
47
+ getFullPath (descriptor, subpath, _followSymlinks) {
48
+ if (subpath.indexOf('\\') !== -1)
49
+ subpath = subpath.replace(/\\/g, '/');
50
+ if (subpath[0] === '/') {
51
+ let bestPreopenMatch = '';
52
+ for (const preopenEntry of this.preopenEntries) {
53
+ if (subpath.startsWith(preopenEntry[1]) && (!bestPreopenMatch || bestPreopenMatch.length < preopenEntry[1].length)) {
54
+ bestPreopenMatch = preopenEntry;
55
+ }
56
+ }
57
+ if (!bestPreopenMatch)
58
+ throw 'no-entry';
59
+ descriptor = bestPreopenMatch[0];
60
+ subpath = subpath.slice(bestPreopenMatch[1]);
61
+ if (subpath[0] === '/')
62
+ subpath = subpath.slice(1);
63
+ }
64
+ if (subpath.startsWith('.'))
65
+ subpath = subpath.slice(subpath[1] === '/' ? 2 : 1);
66
+ if (descriptor.hostPreopen)
67
+ return descriptor.hostPreopen + (descriptor.hostPreopen.endsWith('/') ? '' : '/') + subpath;
68
+ return descriptor.fullPath + '/' + subpath;
52
69
  }
53
- _descriptors[fd] = { path, type, parent: parentFd, subpathTypes: {} };
54
- }
55
70
 
56
- export function _removeOpenedDescriptor (fd) {
57
- if (fd < preopenCnt)
58
- throw 'eperm';
59
- delete _descriptors[fd];
60
- }
71
+ /**
72
+ *
73
+ * @param {[string, string][]} preopens
74
+ * @param {import('./cli.js').environment} environment
75
+ * @returns
76
+ */
77
+ constructor (preopens, environment) {
78
+ const fs = this;
79
+ this.cwd = environment.initialCwd();
80
+
81
+ class FileInputStream extends InputStream {
82
+ constructor (hostFd, position) {
83
+ super({
84
+ blockingRead (len) {
85
+ const buf = new Uint8Array(Number(len));
86
+ try {
87
+ var bytesRead = readSync(this.hostFd, buf, 0, buf.byteLength, this.position);
88
+ } catch (e) {
89
+ throw { tag: 'last-operation-failed', val: new StreamError(e.message) };
90
+ }
91
+ this.position += bytesRead;
92
+ if (bytesRead < buf.byteLength) {
93
+ if (bytesRead === 0)
94
+ throw { tag: 'closed' };
95
+ return new Uint8Array(buf.buffer, 0, bytesRead);
96
+ }
97
+ return buf;
98
+ },
99
+ subscribe () {
100
+ // TODO
101
+ },
102
+ drop () {
103
+ // TODO
104
+ }
105
+ });
106
+ this.hostFd = hostFd;
107
+ this.position = Number(position);
108
+ }
109
+ }
110
+
111
+ class FileOutputStream extends OutputStream {
112
+ constructor (hostFd, position) {
113
+ super({
114
+ write (contents) {
115
+ let totalWritten = 0;
116
+ while (totalWritten !== contents.byteLength) {
117
+ const bytesWritten = writeSync(this.hostFd, contents, null, null, this.position);
118
+ totalWritten += bytesWritten;
119
+ contents = new Uint8Array(contents.buffer, bytesWritten);
120
+ }
121
+ this.position += contents.byteLength;
122
+ },
123
+ blockingFlush () {
124
+
125
+ },
126
+ drop () {
127
+
128
+ }
129
+ });
130
+ this.hostFd = hostFd;
131
+ this.position = Number(position);
132
+ }
133
+ }
134
+
135
+ class DirectoryEntryStream {
136
+ constructor (dir) {
137
+ this.dir = dir;
138
+ }
139
+ readDirectoryEntry () {
140
+ let entry;
141
+ try {
142
+ entry = this.dir.readSync();
143
+ } catch (e) {
144
+ throw convertFsError(e);
145
+ }
146
+ if (entry === null) {
147
+ return null;
148
+ }
149
+ const name = entry.name;
150
+ const type = lookupType(entry);
151
+ return { name, type };
152
+ }
153
+ drop () {
154
+ this.dir.closeSync();
155
+ }
156
+ }
157
+
158
+ /**
159
+ * @implements {DescriptorProps}
160
+ */
161
+ class Descriptor {
162
+ constructor () {
163
+ this.id = fs.descriptorCnt++;
164
+ }
165
+ readViaStream(offset) {
166
+ if (this.hostPreopen)
167
+ throw { tag: 'last-operation-failed', val: new StreamError };
168
+ return new FileInputStream(this.fd, offset);
169
+ }
170
+ writeViaStream(offset) {
171
+ if (this.hostPreopen)
172
+ throw 'is-directory';
173
+ return new FileOutputStream(this.fd, offset);
174
+ }
175
+
176
+ appendViaStream() {
177
+ console.log(`[filesystem] APPEND STREAM ${this.id}`);
178
+ }
179
+
180
+ advise(offset, length, advice) {
181
+ console.log(`[filesystem] ADVISE`, this.id, offset, length, advice);
182
+ }
183
+
184
+ syncData() {
185
+ console.log(`[filesystem] SYNC DATA ${this.id}`);
186
+ }
187
+
188
+ getFlags() {
189
+ console.log(`[filesystem] FLAGS FOR ${this.id}`);
190
+ }
191
+
192
+ getType() {
193
+ if (this.hostPreopen) return 'directory';
194
+ const stats = fstatSync(this.fd);
195
+ return lookupType(stats);
196
+ }
197
+
198
+ setFlags(flags) {
199
+ console.log(`[filesystem] SET FLAGS ${this.id} ${JSON.stringify(flags)}`);
200
+ }
201
+
202
+ setSize(size) {
203
+ console.log(`[filesystem] SET SIZE`, this.id, size);
204
+ }
205
+
206
+ setTimes(dataAccessTimestamp, dataModificationTimestamp) {
207
+ console.log(`[filesystem] SET TIMES`, this.id, dataAccessTimestamp, dataModificationTimestamp);
208
+ }
209
+
210
+ read(length, offset) {
211
+ if (!this.fullPath) throw 'bad-descriptor';
212
+ const buf = new Uint8Array(length);
213
+ const bytesRead = readSync(this.fd, buf, Number(offset), length, 0);
214
+ const out = new Uint8Array(buf.buffer, 0, bytesRead);
215
+ return [out, bytesRead === 0 ? 'ended' : 'open'];
216
+ }
217
+
218
+ write(buffer, offset) {
219
+ if (!this.fullPath) throw 'bad-descriptor';
220
+ return BigInt(writeSync(this.fd, buffer, Number(offset), buffer.byteLength - offset, 0));
221
+ }
222
+
223
+ readDirectory() {
224
+ if (!this.fullPath) throw 'bad-descriptor';
225
+ try {
226
+ const dir = opendirSync(isWindows ? this.fullPath.slice(1) : this.fullPath);
227
+ return new DirectoryEntryStream(dir);
228
+ }
229
+ catch (e) {
230
+ throw convertFsError(e);
231
+ }
232
+ }
233
+
234
+ sync() {
235
+ console.log(`[filesystem] SYNC`, this.id);
236
+ }
237
+
238
+ createDirectoryAt(path) {
239
+ const fullPath = fs.getFullPath(this, path);
240
+ try {
241
+ mkdirSync(fullPath);
242
+ }
243
+ catch (e) {
244
+ throw convertFsError(e);
245
+ }
246
+ }
247
+
248
+ stat() {
249
+ if (this.hostPreopen) throw 'invalid';
250
+ let stats;
251
+ try {
252
+ stats = fstatSync(this.fd, { bigint: true });
253
+ }
254
+ catch (e) {
255
+ convertFsError(e);
256
+ }
257
+ const type = lookupType(stats);
258
+ return {
259
+ type,
260
+ linkCount: stats.nlink,
261
+ size: stats.size,
262
+ dataAccessTimestamp: nsToDateTime(stats.atimeNs),
263
+ dataModificationTimestamp: nsToDateTime(stats.mtimeNs),
264
+ statusChangeTimestamp: nsToDateTime(stats.ctimeNs),
265
+ };
266
+ }
267
+
268
+ statAt(pathFlags, path) {
269
+ const fullPath = fs.getFullPath(this, path, false);
270
+ let stats;
271
+ try {
272
+ stats = (pathFlags.symlinkFollow ? statSync : lstatSync)(isWindows ? fullPath.slice(1) : fullPath, { bigint: true });
273
+ }
274
+ catch (e) {
275
+ convertFsError(e);
276
+ }
277
+ const type = lookupType(stats);
278
+ return {
279
+ type,
280
+ linkCount: stats.nlink,
281
+ size: stats.size,
282
+ dataAccessTimestamp: nsToDateTime(stats.atimeNs),
283
+ dataModificationTimestamp: nsToDateTime(stats.mtimeNs),
284
+ statusChangeTimestamp: nsToDateTime(stats.ctimeNs),
285
+ };
286
+ }
287
+
288
+ setTimesAt() {
289
+ console.log(`[filesystem] SET TIMES AT`, this.id);
290
+ }
291
+
292
+ linkAt() {
293
+ console.log(`[filesystem] LINK AT`, this.id);
294
+ }
295
+
296
+ openAt(pathFlags, path, openFlags, descriptorFlags, modes) {
297
+ const fullPath = fs.getFullPath(this, path, pathFlags.symlinkFollow);
298
+ let fsOpenFlags = 0x0;
299
+ if (openFlags.create)
300
+ fsOpenFlags |= constants.O_CREAT;
301
+ if (openFlags.directory)
302
+ fsOpenFlags |= constants.O_DIRECTORY;
303
+ if (openFlags.exclusive)
304
+ fsOpenFlags |= constants.O_EXCL;
305
+ if (openFlags.truncate)
306
+ fsOpenFlags |= constants.O_TRUNC;
307
+
308
+ if (descriptorFlags.read && descriptorFlags.write)
309
+ fsOpenFlags |= constants.O_RDWR;
310
+ else if (descriptorFlags.write)
311
+ fsOpenFlags |= constants.O_WRONLY;
312
+ // TODO:
313
+ // if (descriptorFlags.fileIntegritySync)
314
+ // if (descriptorFlags.dataIntegritySync)
315
+ // if (descriptorFlags.requestedWriteSync)
316
+ // if (descriptorFlags.mutateDirectory)
317
+
318
+ let fsMode = 0x0;
319
+ if (modes.readable)
320
+ fsMode |= 0o444;
321
+ if (modes.writeable)
322
+ fsMode |= 0o222;
323
+ if (modes.executable)
324
+ fsMode |= 0o111;
325
+
326
+ try {
327
+ const fd = openSync(isWindows ? fullPath.slice(1) : fullPath, fsOpenFlags, fsMode);
328
+ return Object.assign(new Descriptor(), { fullPath, fd });
329
+ }
330
+ catch (e) {
331
+ throw convertFsError(e);
332
+ }
333
+ }
334
+
335
+ readlinkAt() {
336
+ console.log(`[filesystem] READLINK AT`, this.id);
337
+ }
338
+
339
+ removeDirectoryAt() {
340
+ console.log(`[filesystem] REMOVE DIR AT`, this.id);
341
+ }
342
+
343
+ renameAt() {
344
+ console.log(`[filesystem] RENAME AT`, this.id);
345
+ }
346
+
347
+ symlinkAt() {
348
+ console.log(`[filesystem] SYMLINK AT`, this.id);
349
+ }
350
+
351
+ unlinkFileAt() {
352
+ console.log(`[filesystem] UNLINK FILE AT`, this.id);
353
+ }
354
+
355
+ changeFilePermissionsAt() {
356
+ console.log(`[filesystem] CHANGE FILE PERMISSIONS AT`, this.id);
357
+ }
358
+
359
+ changeDirectoryPermissionsAt() {
360
+ console.log(`[filesystem] CHANGE DIR PERMISSIONS AT`, this.id);
361
+ }
362
+
363
+ lockShared() {
364
+ console.log(`[filesystem] LOCK SHARED`, this.id);
365
+ }
366
+
367
+ lockExclusive() {
368
+ console.log(`[filesystem] LOCK EXCLUSIVE`, this.id);
369
+ }
370
+
371
+ tryLockShared() {
372
+ console.log(`[filesystem] TRY LOCK SHARED`, this.id);
373
+ }
374
+
375
+ tryLockExclusive() {
376
+ console.log(`[filesystem] TRY LOCK EXCLUSIVE`, this.id);
377
+ }
378
+
379
+ unlock() {
380
+ console.log(`[filesystem] UNLOCK`, this.id);
381
+ }
382
+
383
+ drop() {
384
+ if (this.fd)
385
+ closeSync(this.fd);
386
+ }
387
+
388
+ metadataHash() {
389
+ if (this.hostPreopen)
390
+ return { upper: 0n, lower: BigInt(this.id) };
391
+ try {
392
+ const stats = fstatSync(this.fd, { bigint: true });
393
+ return { upper: stats.mtimeNs, lower: stats.ino };
394
+ }
395
+ catch (e) {
396
+ convertFsError(e);
397
+ }
398
+ }
399
+
400
+ metadataHashAt(pathFlags, path) {
401
+ const fullPath = fs.getFullPath(this, path, false);
402
+ try {
403
+ const stats = (pathFlags.symlinkFollow ? statSync : lstatSync)(isWindows ? fullPath.slice(1) : fullPath, { bigint: true });
404
+ return { upper: stats.mtimeNs, lower: stats.ino };
405
+ }
406
+ catch (e) {
407
+ convertFsError(e);
408
+ }
409
+ }
410
+ }
61
411
 
62
- export const preopens = {
63
- getDirectories () {
64
- return directories;
412
+ this.descriptorCnt = 3;
413
+ this.preopenEntries = [];
414
+ for (const [virtualPath, hostPreopen] of Object.entries(preopens)) {
415
+ const preopenEntry = [Object.assign(new Descriptor(), { hostPreopen }), virtualPath];
416
+ this.preopenEntries.push(preopenEntry);
417
+ }
418
+ this.preopens = {
419
+ Descriptor,
420
+ getDirectories () {
421
+ return fs.preopenEntries;
422
+ }
423
+ };
424
+ this.types = {
425
+ Descriptor,
426
+ };
65
427
  }
66
428
  }
67
429
 
68
- const nsMagnitude = 1_000_000_000_000n;
69
- function nsToDateTime (ns) {
70
- const seconds = ns / nsMagnitude;
71
- const nanoseconds = Number(ns % seconds);
72
- return { seconds, nanoseconds };
73
- }
430
+ const _fs = new FileSystem({ '/': '/' }, environment);
431
+
432
+ export const { preopens, types } = _fs;
74
433
 
75
- function _convertFsError (e) {
434
+ function convertFsError (e) {
76
435
  switch (e.code) {
77
436
  case 'EACCES': throw 'access';
78
437
  case 'EAGAIN':
@@ -115,287 +474,3 @@ function _convertFsError (e) {
115
474
  default: throw e;
116
475
  }
117
476
  }
118
-
119
- function _lookupType (obj) {
120
- if (obj.isFile())
121
- return 'regular-file';
122
- else if (obj.isSocket())
123
- return 'socket';
124
- else if (obj.isSymbolicLink())
125
- return 'symbolic-link';
126
- else if (obj.isFIFO())
127
- return 'fifo';
128
- else if (obj.isDirectory())
129
- return 'directory';
130
- else if (obj.isCharacterDevice())
131
- return 'character-device';
132
- else if (obj.isBlockDevice())
133
- return 'block-device';
134
- return 'unknown';
135
- }
136
-
137
- export const types = {
138
- readViaStream(fd, offset) {
139
- if (Number(offset) !== 0)
140
- throw new Error('Read streams with non-zero offset not currently supported');
141
- const stream = _createFsStream(fd, 'file', { offset: 0 });
142
- return stream;
143
- },
144
-
145
- writeViaStream(fd, offset) {
146
- console.log(`[filesystem] WRITE STREAM ${fd} ${offset}`);
147
- },
148
-
149
- appendViaStream(fd) {
150
- console.log(`[filesystem] APPEND STREAM ${fd}`);
151
- },
152
-
153
- advise(fd, offset, length, advice) {
154
- console.log(`[filesystem] ADVISE`, fd, offset, length, advice);
155
- },
156
-
157
- syncData(fd) {
158
- console.log(`[filesystem] SYNC DATA ${fd}`);
159
- },
160
-
161
- getFlags(fd) {
162
- console.log(`[filesystem] FLAGS FOR ${fd}`);
163
- },
164
-
165
- getType(fd) {
166
- let type = _getDescriptorType(fd);
167
- if (type === null) {
168
- types.stat(fd);
169
- type = _getDescriptorType(fd);
170
- }
171
- return type;
172
- },
173
-
174
- setFlags(fd, flags) {
175
- console.log(`[filesystem] SET FLAGS ${fd} ${JSON.stringify(flags)}`);
176
- },
177
-
178
- setSize(fd, size) {
179
- console.log(`[filesystem] SET SIZE`, fd, size);
180
- },
181
-
182
- setTimes(fd, dataAccessTimestamp, dataModificationTimestamp) {
183
- console.log(`[filesystem] SET TIMES`, fd, dataAccessTimestamp, dataModificationTimestamp);
184
- },
185
-
186
- read(fd, length, offset) {
187
- console.log(`[filesystem] READ`, fd, length, offset);
188
- },
189
-
190
- write(fd, buffer, offset) {
191
- console.log(`[filesystem] WRITE`, fd, buffer, offset);
192
- },
193
-
194
- readDirectory(fd) {
195
- const fullPath = _getFullPath(fd);
196
- let dirs;
197
- try {
198
- dirs = readdirSync(fullPath, { withFileTypes: true });
199
- }
200
- catch (e) {
201
- _convertFsError(e);
202
- }
203
- return _createFsStream(fd, 'dir', { dirs, cursor: 0, fd });
204
- },
205
-
206
- sync(fd) {
207
- console.log(`[filesystem] SYNC`, fd);
208
- },
209
-
210
- createDirectoryAt(fd, path) {
211
- console.log(`[filesystem] CREATE DIRECTORY`, fd, path);
212
- },
213
-
214
- stat(fd) {
215
- let stats;
216
- try {
217
- stats = fstatSync(fd, { bigint: true });
218
- }
219
- catch (e) {
220
- _convertFsError(e);
221
- }
222
- const type = _lookupType(stats);
223
- _setDescriptorType(fd, type);
224
- return {
225
- device: stats.dev,
226
- inode: stats.ino,
227
- type,
228
- linkCount: stats.nlink,
229
- size: stats.size,
230
- dataAccessTimestamp: nsToDateTime(stats.atimeNs),
231
- dataModificationTimestamp: nsToDateTime(stats.mtimeNs),
232
- statusChangeTimestamp: nsToDateTime(stats.ctimeNs),
233
- };
234
- },
235
-
236
- statAt(fd, { symlinkFollow }, path) {
237
- const fullPath = _descriptors[fd].path + path;
238
- let stats;
239
- try {
240
- stats = (symlinkFollow ? statSync : lstatSync)(fullPath, { bigint: true });
241
- }
242
- catch (e) {
243
- _convertFsError(e);
244
- }
245
- const type = _lookupType(stats);
246
- _setSubdescriptorType(fd, path, type);
247
- return {
248
- device: stats.dev,
249
- inode: stats.ino,
250
- type,
251
- linkCount: stats.nlink,
252
- size: stats.size,
253
- dataAccessTimestamp: nsToDateTime(stats.atimeNs),
254
- dataModificationTimestamp: nsToDateTime(stats.mtimeNs),
255
- statusChangeTimestamp: nsToDateTime(stats.ctimeNs),
256
- };
257
- },
258
-
259
- setTimesAt(fd) {
260
- console.log(`[filesystem] SET TIMES AT`, fd);
261
- },
262
-
263
- linkAt(fd) {
264
- console.log(`[filesystem] LINK AT`, fd);
265
- },
266
-
267
- openAt(fd, pathFlags, path, openFlags, descriptorFlags, modes) {
268
- // TODO
269
- // if (pathFlags.symlinkFollow) {
270
- // // resolve symlink
271
- // }
272
- const fullPath = _descriptors[fd].path + path;
273
- let fsOpenFlags = 0x0;
274
- if (openFlags.create)
275
- fsOpenFlags |= constants.O_CREAT;
276
- if (openFlags.directory)
277
- fsOpenFlags |= constants.O_DIRECTORY;
278
- if (openFlags.exclusive)
279
- fsOpenFlags |= constants.O_EXCL;
280
- if (openFlags.truncate)
281
- fsOpenFlags |= constants.O_TRUNC;
282
- if (descriptorFlags.read && descriptorFlags.write)
283
- fsOpenFlags |= constants.O_RDWR;
284
- else if (descriptorFlags.write)
285
- fsOpenFlags |= constants.O_WRONLY;
286
- // if (descriptorFlags.fileIntegritySync)
287
- // if (descriptorFlags.dataIntegritySync)
288
- // if (descriptorFlags.requestedWriteSync)
289
- // if (descriptorFlags.mutateDirectory)
290
- let fsMode = 0x0;
291
- if (modes.readable)
292
- fsMode |= 0o444;
293
- if (modes.writeable)
294
- fsMode |= 0o222;
295
- if (modes.executable)
296
- fsMode |= 0o111;
297
- let localFd;
298
- try {
299
- localFd = openSync(fullPath, fsOpenFlags, fsMode);
300
- }
301
- catch (e) {
302
- _convertFsError(e);
303
- }
304
- _addOpenedDescriptor(localFd, path, fd);
305
- return localFd;
306
- },
307
-
308
- readlinkAt(fd) {
309
- console.log(`[filesystem] READLINK AT`, fd);
310
- },
311
-
312
- removeDirectoryAt(fd) {
313
- console.log(`[filesystem] REMOVE DIR AT`, fd);
314
- },
315
-
316
- renameAt(fd) {
317
- console.log(`[filesystem] RENAME AT`, fd);
318
- },
319
-
320
- symlinkAt(fd) {
321
- console.log(`[filesystem] SYMLINK AT`, fd);
322
- },
323
-
324
- unlinkFileAt(fd) {
325
- console.log(`[filesystem] UNLINK FILE AT`, fd);
326
- },
327
-
328
- changeFilePermissionsAt(fd) {
329
- console.log(`[filesystem] CHANGE FILE PERMISSIONS AT`, fd);
330
- },
331
-
332
- changeDirectoryPermissionsAt(fd) {
333
- console.log(`[filesystem] CHANGE DIR PERMISSIONS AT`, fd);
334
- },
335
-
336
- lockShared(fd) {
337
- console.log(`[filesystem] LOCK SHARED`, fd);
338
- },
339
-
340
- lockExclusive(fd) {
341
- console.log(`[filesystem] LOCK EXCLUSIVE`, fd);
342
- },
343
-
344
- tryLockShared(fd) {
345
- console.log(`[filesystem] TRY LOCK SHARED`, fd);
346
- },
347
-
348
- tryLockExclusive(fd) {
349
- console.log(`[filesystem] TRY LOCK EXCLUSIVE`, fd);
350
- },
351
-
352
- unlock(fd) {
353
- console.log(`[filesystem] UNLOCK`, fd);
354
- },
355
-
356
- dropDescriptor(fd) {
357
- _removeOpenedDescriptor(fd);
358
- closeSync(fd);
359
- },
360
-
361
- readDirectoryEntry(stream) {
362
- const streamValue = _getFsStreamContext(stream, 'dir');
363
- if (streamValue.cursor === streamValue.dirs.length)
364
- return null;
365
- const dir = streamValue.dirs[streamValue.cursor++];
366
- const type = _lookupType(dir);
367
- _setSubdescriptorType(streamValue.fd, '/' + dir.name, type);
368
- return { inode: null, type, name: dir.name };
369
- },
370
-
371
- dropDirectoryEntryStream(stream) {
372
- _dropFsStream(stream);
373
- },
374
-
375
- metadataHash(fd) {
376
- let stats;
377
- try {
378
- stats = fstatSync(fd, { bigint: true });
379
- }
380
- catch (e) {
381
- _convertFsError(e);
382
- }
383
- const type = _lookupType(stats);
384
- _setDescriptorType(fd, type);
385
- return { upper: BigInt(stats.size), lower: stats.mtimeNs };
386
- },
387
-
388
- metadataHashAt(fd, { symlinkFollow }, path) {
389
- const fullPath = _descriptors[fd].path + path;
390
- let stats;
391
- try {
392
- stats = (symlinkFollow ? statSync : lstatSync)(fullPath, { bigint: true });
393
- }
394
- catch (e) {
395
- _convertFsError(e);
396
- }
397
- const type = _lookupType(stats);
398
- _setSubdescriptorType(fd, path, type);
399
- return { upper: BigInt(stats.size), lower: stats.mtimeNs };
400
- }
401
- };