@zenfs/core 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/internal/inode.js +3 -1
- package/dist/node/async.js +3 -3
- package/dist/node/promises.js +16 -16
- package/dist/node/sync.js +16 -16
- package/dist/vfs/async.js +8 -8
- package/dist/vfs/file.d.ts +11 -1
- package/dist/vfs/file.js +26 -4
- package/dist/vfs/ioctl.js +2 -2
- package/dist/vfs/sync.js +8 -8
- package/dist/vfs/watchers.js +1 -1
- package/dist/vfs/xattr.js +8 -8
- package/package.json +1 -1
- package/tests/common/utf8stream.test.ts +1 -1
- package/tests/fs/permissions.test.ts +1 -1
package/dist/internal/inode.js
CHANGED
|
@@ -642,8 +642,10 @@ export function isFIFO(metadata) {
|
|
|
642
642
|
*/
|
|
643
643
|
export function hasAccess($, inode, access) {
|
|
644
644
|
const { credentials } = contextOf($);
|
|
645
|
-
if (isSymbolicLink(inode)
|
|
645
|
+
if (isSymbolicLink(inode))
|
|
646
646
|
return true;
|
|
647
|
+
if (credentials.euid === 0 || credentials.egid === 0)
|
|
648
|
+
return !(access & c.X_OK) || isDirectory(inode) || !!(inode.mode & (c.S_IXUSR | c.S_IXGRP | c.S_IXOTH));
|
|
647
649
|
let perm = 0;
|
|
648
650
|
if (credentials.uid === inode.uid) {
|
|
649
651
|
if (inode.mode & c.S_IRUSR)
|
package/dist/node/async.js
CHANGED
|
@@ -328,7 +328,7 @@ export function access(path, cbMode, cb = nop) {
|
|
|
328
328
|
access;
|
|
329
329
|
const statWatchers = new Map();
|
|
330
330
|
export function watchFile(path, options, listener) {
|
|
331
|
-
const normalizedPath = normalizePath(path);
|
|
331
|
+
const normalizedPath = normalizePath.call(this, path);
|
|
332
332
|
const opts = typeof options != 'function' ? options : {};
|
|
333
333
|
if (typeof options == 'function') {
|
|
334
334
|
listener = options;
|
|
@@ -365,7 +365,7 @@ watchFile;
|
|
|
365
365
|
* @param listener Optional listener to remove.
|
|
366
366
|
*/
|
|
367
367
|
export function unwatchFile(path, listener = nop) {
|
|
368
|
-
const normalizedPath = normalizePath(path);
|
|
368
|
+
const normalizedPath = normalizePath.call(this, path);
|
|
369
369
|
const entry = statWatchers.get(normalizedPath);
|
|
370
370
|
if (entry) {
|
|
371
371
|
if (listener && listener !== nop) {
|
|
@@ -384,7 +384,7 @@ export function unwatchFile(path, listener = nop) {
|
|
|
384
384
|
}
|
|
385
385
|
unwatchFile;
|
|
386
386
|
export function watch(path, options, listener) {
|
|
387
|
-
const watcher = new FSWatcher(this, normalizePath(path), typeof options == 'object' ? options : {});
|
|
387
|
+
const watcher = new FSWatcher(this, normalizePath.call(this, path), typeof options == 'object' ? options : {});
|
|
388
388
|
listener = typeof options == 'function' ? options : listener;
|
|
389
389
|
watcher.on('change', listener || nop);
|
|
390
390
|
return watcher;
|
package/dist/node/promises.js
CHANGED
|
@@ -529,7 +529,7 @@ rename;
|
|
|
529
529
|
* Test whether or not `path` exists by checking with the file system.
|
|
530
530
|
*/
|
|
531
531
|
export async function exists(path) {
|
|
532
|
-
path = normalizePath(path);
|
|
532
|
+
path = normalizePath.call(this, path);
|
|
533
533
|
try {
|
|
534
534
|
const { fs, path: resolved } = await _async.resolve(this, path);
|
|
535
535
|
return await fs.exists(resolved);
|
|
@@ -579,7 +579,7 @@ truncate;
|
|
|
579
579
|
export async function unlink(path) {
|
|
580
580
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
581
581
|
try {
|
|
582
|
-
path = normalizePath(path);
|
|
582
|
+
path = normalizePath.call(this, path);
|
|
583
583
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
584
584
|
const $ex = { syscall: 'unlink', path };
|
|
585
585
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
@@ -691,7 +691,7 @@ appendFile;
|
|
|
691
691
|
export async function rmdir(path) {
|
|
692
692
|
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
693
693
|
try {
|
|
694
|
-
path = normalizePath(path);
|
|
694
|
+
path = normalizePath.call(this, path);
|
|
695
695
|
const { fs, path: resolved } = await _async.resolve(this, path);
|
|
696
696
|
const $ex = { syscall: 'rmdir', path };
|
|
697
697
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
@@ -722,7 +722,7 @@ export async function mkdir(path, options) {
|
|
|
722
722
|
}
|
|
723
723
|
mkdir;
|
|
724
724
|
export async function readdir(path, options) {
|
|
725
|
-
path = normalizePath(path);
|
|
725
|
+
path = normalizePath.call(this, path);
|
|
726
726
|
const opt = typeof options === 'object' && options != null ? options : { encoding: options, withFileTypes: false, recursive: false };
|
|
727
727
|
const rawEntries = await _async.readdir.call(this, path, opt);
|
|
728
728
|
const values = [];
|
|
@@ -755,11 +755,11 @@ export async function symlink(dest, path, type = 'file') {
|
|
|
755
755
|
try {
|
|
756
756
|
if (!['file', 'dir', 'junction'].includes(type))
|
|
757
757
|
throw new TypeError('Invalid symlink type: ' + type);
|
|
758
|
-
path = normalizePath(path);
|
|
758
|
+
path = normalizePath.call(this, path);
|
|
759
759
|
if (await exists.call(this, path))
|
|
760
760
|
throw UV('EEXIST', 'symlink', path);
|
|
761
761
|
const handle = __addDisposableResource(env_7, await _async.open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
|
|
762
|
-
const encoded = encodeUTF8(normalizePath(dest, true));
|
|
762
|
+
const encoded = encodeUTF8(normalizePath.call(this, dest, true));
|
|
763
763
|
await handle.write(encoded, 0, encoded.length, 0);
|
|
764
764
|
await handle.chmod(constants.S_IFLNK);
|
|
765
765
|
}
|
|
@@ -775,7 +775,7 @@ export async function symlink(dest, path, type = 'file') {
|
|
|
775
775
|
}
|
|
776
776
|
symlink;
|
|
777
777
|
export async function readlink(path, options) {
|
|
778
|
-
path = normalizePath(path);
|
|
778
|
+
path = normalizePath.call(this, path);
|
|
779
779
|
const buf = Buffer.from(await _async.readlink.call(this, path), 'utf-8');
|
|
780
780
|
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
781
781
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
@@ -824,7 +824,7 @@ lchown;
|
|
|
824
824
|
export async function chmod(path, mode) {
|
|
825
825
|
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
826
826
|
try {
|
|
827
|
-
const handle = __addDisposableResource(env_10, await open.call(this, path, 'r+').catch(rethrow({ syscall: 'chmod', path: normalizePath(path) })), true);
|
|
827
|
+
const handle = __addDisposableResource(env_10, await open.call(this, path, 'r+').catch(rethrow({ syscall: 'chmod', path: normalizePath.call(this, path) })), true);
|
|
828
828
|
await handle.chmod(mode);
|
|
829
829
|
}
|
|
830
830
|
catch (e_10) {
|
|
@@ -911,7 +911,7 @@ export async function lutimes(path, atime, mtime) {
|
|
|
911
911
|
lutimes;
|
|
912
912
|
export async function realpath(path, options) {
|
|
913
913
|
const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
|
|
914
|
-
path = normalizePath(path);
|
|
914
|
+
path = normalizePath.call(this, path);
|
|
915
915
|
const { fullPath } = await _async.resolve(this, path);
|
|
916
916
|
if (encoding == 'utf8' || encoding == 'utf-8')
|
|
917
917
|
return fullPath;
|
|
@@ -976,7 +976,7 @@ access;
|
|
|
976
976
|
* @param path The path to the file or directory to remove.
|
|
977
977
|
*/
|
|
978
978
|
export async function rm(path, options) {
|
|
979
|
-
path = normalizePath(path);
|
|
979
|
+
path = normalizePath.call(this, path);
|
|
980
980
|
const stats = await lstat.call(this, path).catch((error) => {
|
|
981
981
|
if (error.code == 'ENOENT' && options?.force)
|
|
982
982
|
return undefined;
|
|
@@ -1034,8 +1034,8 @@ export async function mkdtempDisposable(prefix, options) {
|
|
|
1034
1034
|
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
|
|
1035
1035
|
*/
|
|
1036
1036
|
export async function copyFile(src, dest, mode) {
|
|
1037
|
-
src = normalizePath(src);
|
|
1038
|
-
dest = normalizePath(dest);
|
|
1037
|
+
src = normalizePath.call(this, src);
|
|
1038
|
+
dest = normalizePath.call(this, dest);
|
|
1039
1039
|
if (mode && mode & constants.COPYFILE_EXCL && (await exists.call(this, dest)))
|
|
1040
1040
|
throw UV('EEXIST', 'copyFile', dest);
|
|
1041
1041
|
await writeFile.call(this, dest, await readFile.call(this, src));
|
|
@@ -1050,7 +1050,7 @@ copyFile;
|
|
|
1050
1050
|
* @todo Use options
|
|
1051
1051
|
*/
|
|
1052
1052
|
export function opendir(path, options) {
|
|
1053
|
-
path = normalizePath(path);
|
|
1053
|
+
path = normalizePath.call(this, path);
|
|
1054
1054
|
return Promise.resolve(new Dir(path, this));
|
|
1055
1055
|
}
|
|
1056
1056
|
opendir;
|
|
@@ -1067,8 +1067,8 @@ opendir;
|
|
|
1067
1067
|
* * `recursive`: If `true`, copies directories recursively.
|
|
1068
1068
|
*/
|
|
1069
1069
|
export async function cp(source, destination, opts) {
|
|
1070
|
-
source = normalizePath(source);
|
|
1071
|
-
destination = normalizePath(destination);
|
|
1070
|
+
source = normalizePath.call(this, source);
|
|
1071
|
+
destination = normalizePath.call(this, destination);
|
|
1072
1072
|
const srcStats = await lstat.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
1073
1073
|
if (opts?.errorOnExist && (await exists.call(this, destination)))
|
|
1074
1074
|
throw UV('EEXIST', 'cp', destination);
|
|
@@ -1116,7 +1116,7 @@ export async function cp(source, destination, opts) {
|
|
|
1116
1116
|
}
|
|
1117
1117
|
cp;
|
|
1118
1118
|
export async function statfs(path, opts) {
|
|
1119
|
-
path = normalizePath(path);
|
|
1119
|
+
path = normalizePath.call(this, path);
|
|
1120
1120
|
const { fs } = resolveMount(path, this);
|
|
1121
1121
|
return Promise.resolve(_statfs(fs, opts?.bigint));
|
|
1122
1122
|
}
|
package/dist/node/sync.js
CHANGED
|
@@ -76,7 +76,7 @@ renameSync;
|
|
|
76
76
|
* Test whether or not `path` exists by checking with the file system.
|
|
77
77
|
*/
|
|
78
78
|
export function existsSync(path) {
|
|
79
|
-
path = normalizePath(path);
|
|
79
|
+
path = normalizePath.call(this, path);
|
|
80
80
|
try {
|
|
81
81
|
const { fs, path: resolvedPath } = _sync.resolve(this, path);
|
|
82
82
|
return fs.existsSync(resolvedPath);
|
|
@@ -133,7 +133,7 @@ export function truncateSync(path, len = 0) {
|
|
|
133
133
|
}
|
|
134
134
|
truncateSync;
|
|
135
135
|
export function unlinkSync(path) {
|
|
136
|
-
path = normalizePath(path);
|
|
136
|
+
path = normalizePath.call(this, path);
|
|
137
137
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
138
138
|
try {
|
|
139
139
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
@@ -250,7 +250,7 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
250
250
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
251
251
|
const file = typeof filename == 'number'
|
|
252
252
|
? fromFD(this, filename)
|
|
253
|
-
: _sync.open(this, normalizePath(filename), {
|
|
253
|
+
: _sync.open(this, normalizePath.call(this, filename), {
|
|
254
254
|
flag,
|
|
255
255
|
mode: options.mode,
|
|
256
256
|
});
|
|
@@ -354,7 +354,7 @@ futimesSync;
|
|
|
354
354
|
export function rmdirSync(path) {
|
|
355
355
|
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
356
356
|
try {
|
|
357
|
-
path = normalizePath(path);
|
|
357
|
+
path = normalizePath.call(this, path);
|
|
358
358
|
const { fs, path: resolved } = _sync.resolve(this, path);
|
|
359
359
|
const stats = wrap(fs, 'statSync', { path, syscall: 'rmdir' })(resolved);
|
|
360
360
|
if (!isDirectory(stats))
|
|
@@ -383,7 +383,7 @@ export function mkdirSync(path, options) {
|
|
|
383
383
|
mkdirSync;
|
|
384
384
|
export function readdirSync(path, options) {
|
|
385
385
|
options = typeof options === 'object' ? options : { encoding: options };
|
|
386
|
-
path = normalizePath(path);
|
|
386
|
+
path = normalizePath.call(this, path);
|
|
387
387
|
const entries = [];
|
|
388
388
|
const rawEntries = _sync.readdir.call(this, path, options ?? undefined);
|
|
389
389
|
for (const raw of rawEntries) {
|
|
@@ -415,9 +415,9 @@ export function symlinkSync(target, path, type = 'file') {
|
|
|
415
415
|
try {
|
|
416
416
|
if (!['file', 'dir', 'junction'].includes(type))
|
|
417
417
|
throw new TypeError('Invalid symlink type: ' + type);
|
|
418
|
-
path = normalizePath(path);
|
|
418
|
+
path = normalizePath.call(this, path);
|
|
419
419
|
const file = __addDisposableResource(env_6, _sync.open(this, path, { flag: 'wx', mode: 0o644 }), false);
|
|
420
|
-
file.writeSync(encodeUTF8(normalizePath(target, true)));
|
|
420
|
+
file.writeSync(encodeUTF8(normalizePath.call(this, target, true)));
|
|
421
421
|
file.chmodSync(constants.S_IFLNK);
|
|
422
422
|
}
|
|
423
423
|
catch (e_6) {
|
|
@@ -466,7 +466,7 @@ export function chmodSync(path, mode) {
|
|
|
466
466
|
fd = openSync.call(this, path, 'r+');
|
|
467
467
|
}
|
|
468
468
|
catch (e) {
|
|
469
|
-
throw setUVMessage(Object.assign(e, { syscall: 'chmod', path: normalizePath(path) }));
|
|
469
|
+
throw setUVMessage(Object.assign(e, { syscall: 'chmod', path: normalizePath.call(this, path) }));
|
|
470
470
|
}
|
|
471
471
|
fchmodSync.call(this, fd, mode);
|
|
472
472
|
closeSync.call(this, fd);
|
|
@@ -498,7 +498,7 @@ export function lutimesSync(path, atime, mtime) {
|
|
|
498
498
|
lutimesSync;
|
|
499
499
|
export function realpathSync(path, options) {
|
|
500
500
|
const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
|
|
501
|
-
path = normalizePath(path, true);
|
|
501
|
+
path = normalizePath.call(this, path, true);
|
|
502
502
|
const { fullPath } = _sync.resolve(this, path);
|
|
503
503
|
if (encoding == 'utf8' || encoding == 'utf-8')
|
|
504
504
|
return fullPath;
|
|
@@ -521,7 +521,7 @@ accessSync;
|
|
|
521
521
|
* @param path The path to the file or directory to remove.
|
|
522
522
|
*/
|
|
523
523
|
export function rmSync(path, options) {
|
|
524
|
-
path = normalizePath(path);
|
|
524
|
+
path = normalizePath.call(this, path);
|
|
525
525
|
let stats;
|
|
526
526
|
try {
|
|
527
527
|
stats = lstatSync.bind(this)(path);
|
|
@@ -580,8 +580,8 @@ export function mkdtempDisposableSync(prefix, options) {
|
|
|
580
580
|
* - `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
|
|
581
581
|
*/
|
|
582
582
|
export function copyFileSync(source, destination, flags) {
|
|
583
|
-
source = normalizePath(source);
|
|
584
|
-
destination = normalizePath(destination);
|
|
583
|
+
source = normalizePath.call(this, source);
|
|
584
|
+
destination = normalizePath.call(this, destination);
|
|
585
585
|
if (flags && flags & constants.COPYFILE_EXCL && existsSync.call(this, destination))
|
|
586
586
|
throw UV('EEXIST', 'copyFile', destination);
|
|
587
587
|
writeFileSync.call(this, destination, readFileSync.call(this, source));
|
|
@@ -628,7 +628,7 @@ writevSync;
|
|
|
628
628
|
* @todo Handle options
|
|
629
629
|
*/
|
|
630
630
|
export function opendirSync(path, options) {
|
|
631
|
-
path = normalizePath(path);
|
|
631
|
+
path = normalizePath.call(this, path);
|
|
632
632
|
return new Dir(path, this);
|
|
633
633
|
}
|
|
634
634
|
opendirSync;
|
|
@@ -645,8 +645,8 @@ opendirSync;
|
|
|
645
645
|
* - `recursive`: If `true`, copies directories recursively.
|
|
646
646
|
*/
|
|
647
647
|
export function cpSync(source, destination, opts) {
|
|
648
|
-
source = normalizePath(source);
|
|
649
|
-
destination = normalizePath(destination);
|
|
648
|
+
source = normalizePath.call(this, source);
|
|
649
|
+
destination = normalizePath.call(this, destination);
|
|
650
650
|
const srcStats = lstatSync.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
651
651
|
if (opts?.errorOnExist && existsSync.call(this, destination))
|
|
652
652
|
throw UV('EEXIST', 'cp', destination);
|
|
@@ -688,7 +688,7 @@ export function cpSync(source, destination, opts) {
|
|
|
688
688
|
}
|
|
689
689
|
cpSync;
|
|
690
690
|
export function statfsSync(path, options) {
|
|
691
|
-
path = normalizePath(path);
|
|
691
|
+
path = normalizePath.call(this, path);
|
|
692
692
|
const { fs } = resolveMount(path, this);
|
|
693
693
|
return _statfs(fs, options?.bigint);
|
|
694
694
|
}
|
package/dist/vfs/async.js
CHANGED
|
@@ -114,7 +114,7 @@ export async function resolve($, path, preserveSymlinks, extra) {
|
|
|
114
114
|
* @internal
|
|
115
115
|
*/
|
|
116
116
|
export async function open($, path, opt) {
|
|
117
|
-
path = normalizePath(path);
|
|
117
|
+
path = normalizePath.call($, path);
|
|
118
118
|
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
119
119
|
const $ex = { syscall: 'open', path };
|
|
120
120
|
// eslint-disable-next-line prefer-const
|
|
@@ -169,7 +169,7 @@ export async function open($, path, opt) {
|
|
|
169
169
|
return handle;
|
|
170
170
|
}
|
|
171
171
|
export async function readlink(path) {
|
|
172
|
-
path = normalizePath(path);
|
|
172
|
+
path = normalizePath.call(this, path);
|
|
173
173
|
const $ex = { syscall: 'readlink', path };
|
|
174
174
|
const { fs, stats, path: resolved } = await resolve(this, path, true, $ex);
|
|
175
175
|
if (!stats)
|
|
@@ -184,7 +184,7 @@ export async function readlink(path) {
|
|
|
184
184
|
return decodeUTF8(data);
|
|
185
185
|
}
|
|
186
186
|
export async function mkdir(path, options = {}) {
|
|
187
|
-
const original = normalizePath(path);
|
|
187
|
+
const original = normalizePath.call(this, path);
|
|
188
188
|
const { euid: uid, egid: gid } = contextOf(this).credentials;
|
|
189
189
|
const { mode = 0o777, recursive } = options;
|
|
190
190
|
const $ex = { syscall: 'mkdir', path: original };
|
|
@@ -238,7 +238,7 @@ export async function mkdir(path, options = {}) {
|
|
|
238
238
|
return firstCreated;
|
|
239
239
|
}
|
|
240
240
|
export async function readdir(path, options = {}) {
|
|
241
|
-
path = normalizePath(path);
|
|
241
|
+
path = normalizePath.call(this, path);
|
|
242
242
|
// Node reports `readdir` failures as `scandir`
|
|
243
243
|
const $ex = { syscall: 'scandir', path };
|
|
244
244
|
const { fs, path: resolved, stats } = await resolve(this, path, false, $ex);
|
|
@@ -290,8 +290,8 @@ export async function readdir(path, options = {}) {
|
|
|
290
290
|
export async function rename(oldPath, newPath) {
|
|
291
291
|
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
292
292
|
try {
|
|
293
|
-
oldPath = normalizePath(oldPath);
|
|
294
|
-
newPath = normalizePath(newPath);
|
|
293
|
+
oldPath = normalizePath.call(this, oldPath);
|
|
294
|
+
newPath = normalizePath.call(this, newPath);
|
|
295
295
|
const $ex = { syscall: 'rename', path: oldPath, dest: newPath };
|
|
296
296
|
const src = await resolve(this, oldPath, true, $ex);
|
|
297
297
|
const dst = resolveMount(newPath, this, $ex);
|
|
@@ -344,8 +344,8 @@ export async function rename(oldPath, newPath) {
|
|
|
344
344
|
export async function link(target, link) {
|
|
345
345
|
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
346
346
|
try {
|
|
347
|
-
target = normalizePath(target);
|
|
348
|
-
link = normalizePath(link);
|
|
347
|
+
target = normalizePath.call(this, target);
|
|
348
|
+
link = normalizePath.call(this, link);
|
|
349
349
|
const $ex = { syscall: 'link', path: target, dest: link };
|
|
350
350
|
const { fs, path: resolved } = resolveMount(target, this, $ex);
|
|
351
351
|
const dst = resolveMount(link, this, $ex);
|
package/dist/vfs/file.d.ts
CHANGED
|
@@ -45,6 +45,10 @@ export declare class Handle {
|
|
|
45
45
|
* Whether the file is open or closed
|
|
46
46
|
*/
|
|
47
47
|
protected closed: boolean;
|
|
48
|
+
/** How many descriptors refer to this open file */
|
|
49
|
+
protected refs: number;
|
|
50
|
+
/** Take another reference to the open file */
|
|
51
|
+
ref(): this;
|
|
48
52
|
get isClosed(): boolean;
|
|
49
53
|
/**
|
|
50
54
|
* Creates a file handle for the vnode.
|
|
@@ -141,11 +145,17 @@ export declare class Handle {
|
|
|
141
145
|
streamWrite(options: StreamOptions): WritableStream;
|
|
142
146
|
}
|
|
143
147
|
/**
|
|
148
|
+
* Give an open file a descriptor
|
|
144
149
|
* @internal @hidden
|
|
145
150
|
*/
|
|
146
|
-
export declare function toFD(file: Handle): number;
|
|
151
|
+
export declare function toFD(file: Handle, $?: V_Context): number;
|
|
147
152
|
/**
|
|
148
153
|
* @internal @hidden
|
|
149
154
|
*/
|
|
150
155
|
export declare function fromFD($: V_Context, fd: number): Handle;
|
|
151
156
|
export declare function deleteFD($: V_Context, fd: number): boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Give an open file another descriptor
|
|
159
|
+
* @internal @hidden
|
|
160
|
+
*/
|
|
161
|
+
export declare function dupFD($: V_Context, fd: number): number;
|
package/dist/vfs/file.js
CHANGED
|
@@ -152,6 +152,15 @@ let Handle = (() => {
|
|
|
152
152
|
* Whether the file is open or closed
|
|
153
153
|
*/
|
|
154
154
|
closed = false;
|
|
155
|
+
/** How many descriptors refer to this open file */
|
|
156
|
+
refs = 1;
|
|
157
|
+
/** Take another reference to the open file */
|
|
158
|
+
ref() {
|
|
159
|
+
if (this.closed)
|
|
160
|
+
throw UV('EBADF', 'dup', this.path);
|
|
161
|
+
this.refs++;
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
155
164
|
get isClosed() {
|
|
156
165
|
return this.closed;
|
|
157
166
|
}
|
|
@@ -199,6 +208,8 @@ let Handle = (() => {
|
|
|
199
208
|
if (this.closed)
|
|
200
209
|
throw UV('EBADF', 'close', this.path);
|
|
201
210
|
this.syncSync();
|
|
211
|
+
if (--this.refs > 0)
|
|
212
|
+
return;
|
|
202
213
|
this.disposeSync(true);
|
|
203
214
|
}
|
|
204
215
|
/**
|
|
@@ -406,6 +417,8 @@ let Handle = (() => {
|
|
|
406
417
|
if (this.closed)
|
|
407
418
|
throw UV('EBADF', 'close', this.path);
|
|
408
419
|
await this.sync();
|
|
420
|
+
if (--this.refs > 0)
|
|
421
|
+
return;
|
|
409
422
|
this.dispose(true);
|
|
410
423
|
}
|
|
411
424
|
/**
|
|
@@ -671,12 +684,14 @@ let Handle = (() => {
|
|
|
671
684
|
export { Handle };
|
|
672
685
|
// descriptors
|
|
673
686
|
/**
|
|
687
|
+
* Give an open file a descriptor
|
|
674
688
|
* @internal @hidden
|
|
675
689
|
*/
|
|
676
|
-
export function toFD(file) {
|
|
677
|
-
const map = contextOf(
|
|
678
|
-
|
|
679
|
-
|
|
690
|
+
export function toFD(file, $ = file.context) {
|
|
691
|
+
const map = contextOf($).descriptors;
|
|
692
|
+
let fd = 0;
|
|
693
|
+
while (map.has(fd))
|
|
694
|
+
fd++;
|
|
680
695
|
map.set(fd, file);
|
|
681
696
|
return fd;
|
|
682
697
|
}
|
|
@@ -694,3 +709,10 @@ export function fromFD($, fd) {
|
|
|
694
709
|
export function deleteFD($, fd) {
|
|
695
710
|
return contextOf($).descriptors.delete(fd);
|
|
696
711
|
}
|
|
712
|
+
/**
|
|
713
|
+
* Give an open file another descriptor
|
|
714
|
+
* @internal @hidden
|
|
715
|
+
*/
|
|
716
|
+
export function dupFD($, fd) {
|
|
717
|
+
return toFD(fromFD($, fd).ref(), $);
|
|
718
|
+
}
|
package/dist/vfs/ioctl.js
CHANGED
|
@@ -26,7 +26,7 @@ export async function ioctl(path, command, ...args) {
|
|
|
26
26
|
vnode.refs++;
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
29
|
-
path = normalizePath(path);
|
|
29
|
+
path = normalizePath.call(this, path);
|
|
30
30
|
const mnt = await resolveAsync(this, path, false, { syscall: 'ioctl', path });
|
|
31
31
|
if (!mnt.stats)
|
|
32
32
|
throw UV('ENOENT', { syscall: 'ioctl', path });
|
|
@@ -64,7 +64,7 @@ export function ioctlSync(path, command, ...args) {
|
|
|
64
64
|
vnode.refs++;
|
|
65
65
|
}
|
|
66
66
|
else {
|
|
67
|
-
path = normalizePath(path);
|
|
67
|
+
path = normalizePath.call(this, path);
|
|
68
68
|
const mnt = resolveSync(this, path, false, { syscall: 'ioctl', path });
|
|
69
69
|
if (!mnt.stats)
|
|
70
70
|
throw UV('ENOENT', { syscall: 'ioctl', path });
|
package/dist/vfs/sync.js
CHANGED
|
@@ -114,7 +114,7 @@ export function resolve($, path, preserveSymlinks, extra) {
|
|
|
114
114
|
* @internal
|
|
115
115
|
*/
|
|
116
116
|
export function open($, path, opt) {
|
|
117
|
-
path = normalizePath(path);
|
|
117
|
+
path = normalizePath.call($, path);
|
|
118
118
|
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
119
119
|
path = opt.preserveSymlinks ? path : resolve($, path).fullPath;
|
|
120
120
|
const { fs, path: resolved } = resolveMount(path, $);
|
|
@@ -175,7 +175,7 @@ export function open($, path, opt) {
|
|
|
175
175
|
return file;
|
|
176
176
|
}
|
|
177
177
|
export function readlink(path) {
|
|
178
|
-
path = normalizePath(path);
|
|
178
|
+
path = normalizePath.call(this, path);
|
|
179
179
|
const { fs, stats, path: resolved } = resolve(this, path, true, { syscall: 'readlink' });
|
|
180
180
|
if (!stats)
|
|
181
181
|
throw UV('ENOENT', 'readlink', path);
|
|
@@ -189,7 +189,7 @@ export function readlink(path) {
|
|
|
189
189
|
return decodeUTF8(data);
|
|
190
190
|
}
|
|
191
191
|
export function mkdir(path, options = {}) {
|
|
192
|
-
const original = normalizePath(path);
|
|
192
|
+
const original = normalizePath.call(this, path);
|
|
193
193
|
const $ex = { syscall: 'mkdir', path: original };
|
|
194
194
|
const { fullPath: realParent } = resolve(this, dirname(original), false, $ex);
|
|
195
195
|
const { fs, path: target } = resolveMount(join(realParent, basename(original)), this, $ex);
|
|
@@ -246,7 +246,7 @@ export function mkdir(path, options = {}) {
|
|
|
246
246
|
return firstCreated;
|
|
247
247
|
}
|
|
248
248
|
export function readdir(path, options = {}) {
|
|
249
|
-
path = normalizePath(path);
|
|
249
|
+
path = normalizePath.call(this, path);
|
|
250
250
|
const { fs, path: resolved } = resolve(this, path);
|
|
251
251
|
// Node reports `readdir` failures as `scandir`
|
|
252
252
|
const stats = cacheOf(fs).get(resolved)?.inode ?? wrap(fs, 'statSync', { path, syscall: 'scandir' })(resolved);
|
|
@@ -300,8 +300,8 @@ export function readdir(path, options = {}) {
|
|
|
300
300
|
export function rename(oldPath, newPath) {
|
|
301
301
|
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
302
302
|
try {
|
|
303
|
-
oldPath = normalizePath(oldPath);
|
|
304
|
-
newPath = normalizePath(newPath);
|
|
303
|
+
oldPath = normalizePath.call(this, oldPath);
|
|
304
|
+
newPath = normalizePath.call(this, newPath);
|
|
305
305
|
const $ex = { syscall: 'rename', path: oldPath, dest: newPath };
|
|
306
306
|
const src = resolve(this, oldPath, true, $ex);
|
|
307
307
|
const dst = resolveMount(newPath, this, $ex);
|
|
@@ -357,8 +357,8 @@ export function rename(oldPath, newPath) {
|
|
|
357
357
|
export function link(target, link) {
|
|
358
358
|
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
359
359
|
try {
|
|
360
|
-
target = normalizePath(target);
|
|
361
|
-
link = normalizePath(link);
|
|
360
|
+
target = normalizePath.call(this, target);
|
|
361
|
+
link = normalizePath.call(this, link);
|
|
362
362
|
const $ex = { syscall: 'link', path: target, dest: link };
|
|
363
363
|
const { fs, path: resolved } = resolveMount(target, this, $ex);
|
|
364
364
|
const dst = resolveMount(link, this, $ex);
|
package/dist/vfs/watchers.js
CHANGED
|
@@ -151,7 +151,7 @@ export function emitChange(context, eventType, filename) {
|
|
|
151
151
|
const $ = contextOf(context);
|
|
152
152
|
if ($)
|
|
153
153
|
filename = join($.root ?? '/', filename);
|
|
154
|
-
filename = normalizePath(filename);
|
|
154
|
+
filename = normalizePath.call(context, filename);
|
|
155
155
|
// Notify watchers, including ones on parent directories if they are watching recursively.
|
|
156
156
|
for (let path = filename;; path = dirname(path)) {
|
|
157
157
|
const watchersForPath = watchers.get(path);
|
package/dist/vfs/xattr.js
CHANGED
|
@@ -17,7 +17,7 @@ function checkName($, name, path, syscall) {
|
|
|
17
17
|
throw UV('ENOTSUP', syscall, path);
|
|
18
18
|
}
|
|
19
19
|
export async function get(path, name, opt = {}) {
|
|
20
|
-
path = normalizePath(path);
|
|
20
|
+
path = normalizePath.call(this, path);
|
|
21
21
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
22
22
|
checkName(this, name, path, 'xattr.get');
|
|
23
23
|
const inode = await fs.stat(resolved).catch(rethrow('xattr.get', path));
|
|
@@ -31,7 +31,7 @@ export async function get(path, name, opt = {}) {
|
|
|
31
31
|
return opt.encoding == 'buffer' || !opt.encoding ? buffer : buffer.toString(opt.encoding);
|
|
32
32
|
}
|
|
33
33
|
export function getSync(path, name, opt = {}) {
|
|
34
|
-
path = normalizePath(path);
|
|
34
|
+
path = normalizePath.call(this, path);
|
|
35
35
|
checkName(this, name, path, 'xattr.get');
|
|
36
36
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
37
37
|
let inode;
|
|
@@ -59,7 +59,7 @@ export function getSync(path, name, opt = {}) {
|
|
|
59
59
|
* @param opt Options for the operation
|
|
60
60
|
*/
|
|
61
61
|
export async function set(path, name, value, opt = {}) {
|
|
62
|
-
path = normalizePath(path);
|
|
62
|
+
path = normalizePath.call(this, path);
|
|
63
63
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
64
64
|
checkName(this, name, path, 'xattr.set');
|
|
65
65
|
const inode = await fs.stat(resolved).catch(rethrow('xattr.set', path));
|
|
@@ -83,7 +83,7 @@ export async function set(path, name, value, opt = {}) {
|
|
|
83
83
|
* @param opt Options for the operation
|
|
84
84
|
*/
|
|
85
85
|
export function setSync(path, name, value, opt = {}) {
|
|
86
|
-
path = normalizePath(path);
|
|
86
|
+
path = normalizePath.call(this, path);
|
|
87
87
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
88
88
|
checkName(this, name, path, 'xattr.set');
|
|
89
89
|
let inode;
|
|
@@ -116,7 +116,7 @@ export function setSync(path, name, value, opt = {}) {
|
|
|
116
116
|
* @param name Name of the attribute to remove
|
|
117
117
|
*/
|
|
118
118
|
export async function remove(path, name) {
|
|
119
|
-
path = normalizePath(path);
|
|
119
|
+
path = normalizePath.call(this, path);
|
|
120
120
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
121
121
|
checkName(this, name, path, 'xattr.remove');
|
|
122
122
|
const inode = await fs.stat(resolved).catch(rethrow('xattr.remove', path));
|
|
@@ -136,7 +136,7 @@ export async function remove(path, name) {
|
|
|
136
136
|
* @param name Name of the attribute to remove
|
|
137
137
|
*/
|
|
138
138
|
export function removeSync(path, name) {
|
|
139
|
-
path = normalizePath(path);
|
|
139
|
+
path = normalizePath.call(this, path);
|
|
140
140
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
141
141
|
checkName(this, name, path, 'xattr.remove');
|
|
142
142
|
let inode;
|
|
@@ -167,7 +167,7 @@ export function removeSync(path, name) {
|
|
|
167
167
|
* @returns Array of attribute names
|
|
168
168
|
*/
|
|
169
169
|
export async function list(path) {
|
|
170
|
-
path = normalizePath(path);
|
|
170
|
+
path = normalizePath.call(this, path);
|
|
171
171
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
172
172
|
const inode = await fs.stat(resolved).catch(rethrow('xattr.list', path));
|
|
173
173
|
if (!inode.attributes)
|
|
@@ -181,7 +181,7 @@ export async function list(path) {
|
|
|
181
181
|
* @returns Array of attribute names
|
|
182
182
|
*/
|
|
183
183
|
export function listSync(path) {
|
|
184
|
-
path = normalizePath(path);
|
|
184
|
+
path = normalizePath.call(this, path);
|
|
185
185
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
186
186
|
let inode;
|
|
187
187
|
try {
|
package/package.json
CHANGED
|
@@ -54,7 +54,7 @@ suite('Permissions', config('permissions'), () => {
|
|
|
54
54
|
assert.equal(error.code, 'EACCES');
|
|
55
55
|
});
|
|
56
56
|
if (!stats) return;
|
|
57
|
-
assert(hasAccess(defaultContext, stats, X_OK));
|
|
57
|
+
if (stats.isDirectory()) assert(hasAccess(defaultContext, stats, X_OK));
|
|
58
58
|
|
|
59
59
|
function checkError(access: number) {
|
|
60
60
|
return function (error: Exception) {
|