@zenfs/core 1.2.3 → 1.2.5
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/config.d.ts +2 -2
- package/dist/config.js +1 -1
- package/dist/emulation/config.d.ts +5 -1
- package/dist/emulation/config.js +5 -1
- package/dist/emulation/promises.js +54 -43
- package/dist/emulation/sync.js +0 -1
- package/dist/file.js +12 -9
- package/package.json +1 -1
- package/src/config.ts +3 -3
- package/src/emulation/config.ts +6 -1
- package/src/emulation/promises.ts +2 -3
- package/src/emulation/sync.ts +0 -1
- package/src/file.ts +14 -7
- package/tests/fs/chmod.test.ts +12 -16
- package/tests/fs/truncate.test.ts +12 -12
package/dist/config.d.ts
CHANGED
|
@@ -54,13 +54,13 @@ export interface Configuration<T extends ConfigMounts> extends SharedConfig {
|
|
|
54
54
|
*/
|
|
55
55
|
disableAccessChecks: boolean;
|
|
56
56
|
/**
|
|
57
|
-
* If true, disables `read` and `readSync` from
|
|
57
|
+
* If true, disables `read` and `readSync` from updating the atime.
|
|
58
58
|
*
|
|
59
59
|
* This can increase performance.
|
|
60
60
|
* @experimental
|
|
61
61
|
* @default false
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
disableUpdateOnRead: boolean;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
66
|
* Configures ZenFS with single mount point /
|
package/dist/config.js
CHANGED
|
@@ -70,7 +70,7 @@ export async function configure(configuration) {
|
|
|
70
70
|
Object.assign(credentials, { uid, gid, suid: uid, sgid: gid, euid: uid, egid: gid });
|
|
71
71
|
cache.setEnabled(configuration.cacheStats ?? false);
|
|
72
72
|
config.checkAccess = !configuration.disableAccessChecks;
|
|
73
|
-
config.
|
|
73
|
+
config.updateOnRead = !configuration.disableUpdateOnRead;
|
|
74
74
|
if (configuration.addDevices) {
|
|
75
75
|
const devfs = new DeviceFS();
|
|
76
76
|
devfs.createDevice('/null', nullDevice);
|
|
@@ -6,5 +6,9 @@ export declare const config: {
|
|
|
6
6
|
/**
|
|
7
7
|
* Whether to sync atime updates immediately when reading from a file
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
updateOnRead: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* If a file's buffer is not large enough to store content when writing and the buffer can't be resized, reuse the buffer passed to write()
|
|
12
|
+
*/
|
|
13
|
+
unsafeBufferReplace: boolean;
|
|
10
14
|
};
|
package/dist/emulation/config.js
CHANGED
|
@@ -6,5 +6,9 @@ export const config = {
|
|
|
6
6
|
/**
|
|
7
7
|
* Whether to sync atime updates immediately when reading from a file
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
updateOnRead: true,
|
|
10
|
+
/**
|
|
11
|
+
* If a file's buffer is not large enough to store content when writing and the buffer can't be resized, reuse the buffer passed to write()
|
|
12
|
+
*/
|
|
13
|
+
unsafeBufferReplace: false,
|
|
10
14
|
};
|
|
@@ -485,7 +485,6 @@ async function _open(path, _flag, _mode = 0o644, resolveSymlinks) {
|
|
|
485
485
|
*/
|
|
486
486
|
if (isTruncating(flag)) {
|
|
487
487
|
await handle.truncate(0);
|
|
488
|
-
await handle.sync();
|
|
489
488
|
}
|
|
490
489
|
return handle;
|
|
491
490
|
}
|
|
@@ -738,24 +737,17 @@ link;
|
|
|
738
737
|
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
739
738
|
*/
|
|
740
739
|
export async function symlink(target, path, type = 'file') {
|
|
741
|
-
if (!['file', 'dir', 'junction'].includes(type)) {
|
|
742
|
-
throw new ErrnoError(Errno.EINVAL, 'Invalid symlink type: ' + type);
|
|
743
|
-
}
|
|
744
|
-
if (await exists(path)) {
|
|
745
|
-
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
|
|
746
|
-
}
|
|
747
|
-
await writeFile(path, target.toString());
|
|
748
|
-
const handle = await _open(path, 'r+', 0o644, false);
|
|
749
|
-
await handle.file._setType(constants.S_IFLNK);
|
|
750
|
-
}
|
|
751
|
-
symlink;
|
|
752
|
-
export async function readlink(path, options) {
|
|
753
740
|
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
754
741
|
try {
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
742
|
+
if (!['file', 'dir', 'junction'].includes(type)) {
|
|
743
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid symlink type: ' + type);
|
|
744
|
+
}
|
|
745
|
+
if (await exists(path)) {
|
|
746
|
+
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
|
|
747
|
+
}
|
|
748
|
+
const handle = __addDisposableResource(env_5, await _open(path, 'w+', 0o644, false), true);
|
|
749
|
+
await handle.writeFile(target.toString());
|
|
750
|
+
await handle.file._setType(constants.S_IFLNK);
|
|
759
751
|
}
|
|
760
752
|
catch (e_5) {
|
|
761
753
|
env_5.error = e_5;
|
|
@@ -767,13 +759,14 @@ export async function readlink(path, options) {
|
|
|
767
759
|
await result_5;
|
|
768
760
|
}
|
|
769
761
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
export async function chown(path, uid, gid) {
|
|
762
|
+
symlink;
|
|
763
|
+
export async function readlink(path, options) {
|
|
773
764
|
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
774
765
|
try {
|
|
775
|
-
const handle = __addDisposableResource(env_6, await
|
|
776
|
-
await handle.
|
|
766
|
+
const handle = __addDisposableResource(env_6, await _open(normalizePath(path), 'r', 0o644, false), true);
|
|
767
|
+
const value = await handle.readFile();
|
|
768
|
+
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
769
|
+
return encoding == 'buffer' ? value : value.toString(encoding);
|
|
777
770
|
}
|
|
778
771
|
catch (e_6) {
|
|
779
772
|
env_6.error = e_6;
|
|
@@ -785,11 +778,12 @@ export async function chown(path, uid, gid) {
|
|
|
785
778
|
await result_6;
|
|
786
779
|
}
|
|
787
780
|
}
|
|
788
|
-
|
|
789
|
-
|
|
781
|
+
readlink;
|
|
782
|
+
// PROPERTY OPERATIONS
|
|
783
|
+
export async function chown(path, uid, gid) {
|
|
790
784
|
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
791
785
|
try {
|
|
792
|
-
const handle = __addDisposableResource(env_7, await
|
|
786
|
+
const handle = __addDisposableResource(env_7, await open(path, 'r+'), true);
|
|
793
787
|
await handle.chown(uid, gid);
|
|
794
788
|
}
|
|
795
789
|
catch (e_7) {
|
|
@@ -802,12 +796,12 @@ export async function lchown(path, uid, gid) {
|
|
|
802
796
|
await result_7;
|
|
803
797
|
}
|
|
804
798
|
}
|
|
805
|
-
|
|
806
|
-
export async function
|
|
799
|
+
chown;
|
|
800
|
+
export async function lchown(path, uid, gid) {
|
|
807
801
|
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
808
802
|
try {
|
|
809
|
-
const handle = __addDisposableResource(env_8, await
|
|
810
|
-
await handle.
|
|
803
|
+
const handle = __addDisposableResource(env_8, await _open(path, 'r+', 0o644, false), true);
|
|
804
|
+
await handle.chown(uid, gid);
|
|
811
805
|
}
|
|
812
806
|
catch (e_8) {
|
|
813
807
|
env_8.error = e_8;
|
|
@@ -819,11 +813,11 @@ export async function chmod(path, mode) {
|
|
|
819
813
|
await result_8;
|
|
820
814
|
}
|
|
821
815
|
}
|
|
822
|
-
|
|
823
|
-
export async function
|
|
816
|
+
lchown;
|
|
817
|
+
export async function chmod(path, mode) {
|
|
824
818
|
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
825
819
|
try {
|
|
826
|
-
const handle = __addDisposableResource(env_9, await
|
|
820
|
+
const handle = __addDisposableResource(env_9, await open(path, 'r+'), true);
|
|
827
821
|
await handle.chmod(mode);
|
|
828
822
|
}
|
|
829
823
|
catch (e_9) {
|
|
@@ -836,15 +830,12 @@ export async function lchmod(path, mode) {
|
|
|
836
830
|
await result_9;
|
|
837
831
|
}
|
|
838
832
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
* Change file timestamps of the file referenced by the supplied path.
|
|
842
|
-
*/
|
|
843
|
-
export async function utimes(path, atime, mtime) {
|
|
833
|
+
chmod;
|
|
834
|
+
export async function lchmod(path, mode) {
|
|
844
835
|
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
845
836
|
try {
|
|
846
|
-
const handle = __addDisposableResource(env_10, await
|
|
847
|
-
await handle.
|
|
837
|
+
const handle = __addDisposableResource(env_10, await _open(path, 'r+', 0o644, false), true);
|
|
838
|
+
await handle.chmod(mode);
|
|
848
839
|
}
|
|
849
840
|
catch (e_10) {
|
|
850
841
|
env_10.error = e_10;
|
|
@@ -856,15 +847,15 @@ export async function utimes(path, atime, mtime) {
|
|
|
856
847
|
await result_10;
|
|
857
848
|
}
|
|
858
849
|
}
|
|
859
|
-
|
|
850
|
+
lchmod;
|
|
860
851
|
/**
|
|
861
852
|
* Change file timestamps of the file referenced by the supplied path.
|
|
862
853
|
*/
|
|
863
|
-
export async function
|
|
854
|
+
export async function utimes(path, atime, mtime) {
|
|
864
855
|
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
865
856
|
try {
|
|
866
|
-
const handle = __addDisposableResource(env_11, await
|
|
867
|
-
await handle.utimes(
|
|
857
|
+
const handle = __addDisposableResource(env_11, await open(path, 'r+'), true);
|
|
858
|
+
await handle.utimes(atime, mtime);
|
|
868
859
|
}
|
|
869
860
|
catch (e_11) {
|
|
870
861
|
env_11.error = e_11;
|
|
@@ -876,6 +867,26 @@ export async function lutimes(path, atime, mtime) {
|
|
|
876
867
|
await result_11;
|
|
877
868
|
}
|
|
878
869
|
}
|
|
870
|
+
utimes;
|
|
871
|
+
/**
|
|
872
|
+
* Change file timestamps of the file referenced by the supplied path.
|
|
873
|
+
*/
|
|
874
|
+
export async function lutimes(path, atime, mtime) {
|
|
875
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
876
|
+
try {
|
|
877
|
+
const handle = __addDisposableResource(env_12, await _open(path, 'r+', 0o644, false), true);
|
|
878
|
+
await handle.utimes(new Date(atime), new Date(mtime));
|
|
879
|
+
}
|
|
880
|
+
catch (e_12) {
|
|
881
|
+
env_12.error = e_12;
|
|
882
|
+
env_12.hasError = true;
|
|
883
|
+
}
|
|
884
|
+
finally {
|
|
885
|
+
const result_12 = __disposeResources(env_12);
|
|
886
|
+
if (result_12)
|
|
887
|
+
await result_12;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
879
890
|
lutimes;
|
|
880
891
|
export async function realpath(path, options) {
|
|
881
892
|
path = normalizePath(path);
|
package/dist/emulation/sync.js
CHANGED
package/dist/file.js
CHANGED
|
@@ -299,17 +299,21 @@ export class PreloadFile extends File {
|
|
|
299
299
|
if (this.closed) {
|
|
300
300
|
throw ErrnoError.With('EBADF', this.path, 'File.write');
|
|
301
301
|
}
|
|
302
|
-
this.dirty = true;
|
|
303
302
|
if (!isWriteable(this.flag)) {
|
|
304
303
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
|
|
305
304
|
}
|
|
305
|
+
this.dirty = true;
|
|
306
306
|
const end = position + length;
|
|
307
|
+
const slice = buffer.slice(offset, offset + length);
|
|
307
308
|
if (end > this.stats.size) {
|
|
308
309
|
this.stats.size = end;
|
|
309
310
|
if (end > this._buffer.byteLength) {
|
|
310
311
|
if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength <= end) {
|
|
311
312
|
this._buffer.buffer.resize(end);
|
|
312
313
|
}
|
|
314
|
+
else if (config.unsafeBufferReplace) {
|
|
315
|
+
this._buffer = slice;
|
|
316
|
+
}
|
|
313
317
|
else {
|
|
314
318
|
// Extend the buffer!
|
|
315
319
|
const newBuffer = new Uint8Array(new ArrayBuffer(end, this.fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }));
|
|
@@ -318,7 +322,6 @@ export class PreloadFile extends File {
|
|
|
318
322
|
}
|
|
319
323
|
}
|
|
320
324
|
}
|
|
321
|
-
const slice = buffer.slice(offset, offset + length);
|
|
322
325
|
this._buffer.set(slice, position);
|
|
323
326
|
this.stats.mtimeMs = Date.now();
|
|
324
327
|
this.position = position + slice.byteLength;
|
|
@@ -358,17 +361,19 @@ export class PreloadFile extends File {
|
|
|
358
361
|
if (!isReadable(this.flag)) {
|
|
359
362
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
|
|
360
363
|
}
|
|
361
|
-
|
|
364
|
+
if (config.updateOnRead) {
|
|
365
|
+
this.dirty = true;
|
|
366
|
+
this.stats.atimeMs = Date.now();
|
|
367
|
+
}
|
|
362
368
|
position ?? (position = this.position);
|
|
363
369
|
let end = position + length;
|
|
364
370
|
if (end > this.stats.size) {
|
|
365
371
|
end = position + Math.max(this.stats.size - position, 0);
|
|
366
372
|
}
|
|
367
|
-
this.stats.atimeMs = Date.now();
|
|
368
373
|
this._position = end;
|
|
369
374
|
const bytesRead = end - position;
|
|
370
375
|
if (bytesRead == 0) {
|
|
371
|
-
// No copy/read. Return
|
|
376
|
+
// No copy/read. Return immediately for better performance
|
|
372
377
|
return bytesRead;
|
|
373
378
|
}
|
|
374
379
|
new Uint8Array(buffer.buffer, offset, length).set(this._buffer.slice(position, end));
|
|
@@ -384,8 +389,7 @@ export class PreloadFile extends File {
|
|
|
384
389
|
*/
|
|
385
390
|
async read(buffer, offset, length, position) {
|
|
386
391
|
const bytesRead = this._read(buffer, offset, length, position);
|
|
387
|
-
|
|
388
|
-
await this.sync();
|
|
392
|
+
await this.sync();
|
|
389
393
|
return { bytesRead, buffer };
|
|
390
394
|
}
|
|
391
395
|
/**
|
|
@@ -399,8 +403,7 @@ export class PreloadFile extends File {
|
|
|
399
403
|
*/
|
|
400
404
|
readSync(buffer, offset, length, position) {
|
|
401
405
|
const bytesRead = this._read(buffer, offset, length, position);
|
|
402
|
-
|
|
403
|
-
this.syncSync();
|
|
406
|
+
this.syncSync();
|
|
404
407
|
return bytesRead;
|
|
405
408
|
}
|
|
406
409
|
async chmod(mode) {
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -119,13 +119,13 @@ export interface Configuration<T extends ConfigMounts> extends SharedConfig {
|
|
|
119
119
|
disableAccessChecks: boolean;
|
|
120
120
|
|
|
121
121
|
/**
|
|
122
|
-
* If true, disables `read` and `readSync` from
|
|
122
|
+
* If true, disables `read` and `readSync` from updating the atime.
|
|
123
123
|
*
|
|
124
124
|
* This can increase performance.
|
|
125
125
|
* @experimental
|
|
126
126
|
* @default false
|
|
127
127
|
*/
|
|
128
|
-
|
|
128
|
+
disableUpdateOnRead: boolean;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/**
|
|
@@ -153,7 +153,7 @@ export async function configure<T extends ConfigMounts>(configuration: Partial<C
|
|
|
153
153
|
|
|
154
154
|
cache.setEnabled(configuration.cacheStats ?? false);
|
|
155
155
|
config.checkAccess = !configuration.disableAccessChecks;
|
|
156
|
-
config.
|
|
156
|
+
config.updateOnRead = !configuration.disableUpdateOnRead;
|
|
157
157
|
|
|
158
158
|
if (configuration.addDevices) {
|
|
159
159
|
const devfs = new DeviceFS();
|
package/src/emulation/config.ts
CHANGED
|
@@ -7,5 +7,10 @@ export const config = {
|
|
|
7
7
|
/**
|
|
8
8
|
* Whether to sync atime updates immediately when reading from a file
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
updateOnRead: true,
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* If a file's buffer is not large enough to store content when writing and the buffer can't be resized, reuse the buffer passed to write()
|
|
14
|
+
*/
|
|
15
|
+
unsafeBufferReplace: false,
|
|
11
16
|
};
|
|
@@ -529,7 +529,6 @@ async function _open(path: fs.PathLike, _flag: fs.OpenMode, _mode: fs.Mode = 0o6
|
|
|
529
529
|
*/
|
|
530
530
|
if (isTruncating(flag)) {
|
|
531
531
|
await handle.truncate(0);
|
|
532
|
-
await handle.sync();
|
|
533
532
|
}
|
|
534
533
|
|
|
535
534
|
return handle;
|
|
@@ -832,8 +831,8 @@ export async function symlink(target: fs.PathLike, path: fs.PathLike, type: fs.s
|
|
|
832
831
|
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
|
|
833
832
|
}
|
|
834
833
|
|
|
835
|
-
await
|
|
836
|
-
|
|
834
|
+
await using handle = await _open(path, 'w+', 0o644, false);
|
|
835
|
+
await handle.writeFile(target.toString());
|
|
837
836
|
await handle.file._setType(constants.S_IFLNK);
|
|
838
837
|
}
|
|
839
838
|
symlink satisfies typeof promises.symlink;
|
package/src/emulation/sync.ts
CHANGED
package/src/file.ts
CHANGED
|
@@ -453,17 +453,22 @@ export class PreloadFile<FS extends FileSystem> extends File {
|
|
|
453
453
|
if (this.closed) {
|
|
454
454
|
throw ErrnoError.With('EBADF', this.path, 'File.write');
|
|
455
455
|
}
|
|
456
|
-
|
|
456
|
+
|
|
457
457
|
if (!isWriteable(this.flag)) {
|
|
458
458
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
|
|
459
459
|
}
|
|
460
|
+
|
|
461
|
+
this.dirty = true;
|
|
460
462
|
const end = position + length;
|
|
463
|
+
const slice = buffer.slice(offset, offset + length);
|
|
461
464
|
|
|
462
465
|
if (end > this.stats.size) {
|
|
463
466
|
this.stats.size = end;
|
|
464
467
|
if (end > this._buffer.byteLength) {
|
|
465
468
|
if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength! <= end) {
|
|
466
469
|
this._buffer.buffer.resize(end);
|
|
470
|
+
} else if (config.unsafeBufferReplace) {
|
|
471
|
+
this._buffer = slice;
|
|
467
472
|
} else {
|
|
468
473
|
// Extend the buffer!
|
|
469
474
|
const newBuffer = new Uint8Array(new ArrayBuffer(end, this.fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }));
|
|
@@ -472,7 +477,7 @@ export class PreloadFile<FS extends FileSystem> extends File {
|
|
|
472
477
|
}
|
|
473
478
|
}
|
|
474
479
|
}
|
|
475
|
-
|
|
480
|
+
|
|
476
481
|
this._buffer.set(slice, position);
|
|
477
482
|
this.stats.mtimeMs = Date.now();
|
|
478
483
|
this.position = position + slice.byteLength;
|
|
@@ -515,17 +520,19 @@ export class PreloadFile<FS extends FileSystem> extends File {
|
|
|
515
520
|
if (!isReadable(this.flag)) {
|
|
516
521
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
|
|
517
522
|
}
|
|
518
|
-
|
|
523
|
+
if (config.updateOnRead) {
|
|
524
|
+
this.dirty = true;
|
|
525
|
+
this.stats.atimeMs = Date.now();
|
|
526
|
+
}
|
|
519
527
|
position ??= this.position;
|
|
520
528
|
let end = position + length;
|
|
521
529
|
if (end > this.stats.size) {
|
|
522
530
|
end = position + Math.max(this.stats.size - position, 0);
|
|
523
531
|
}
|
|
524
|
-
this.stats.atimeMs = Date.now();
|
|
525
532
|
this._position = end;
|
|
526
533
|
const bytesRead = end - position;
|
|
527
534
|
if (bytesRead == 0) {
|
|
528
|
-
// No copy/read. Return
|
|
535
|
+
// No copy/read. Return immediately for better performance
|
|
529
536
|
return bytesRead;
|
|
530
537
|
}
|
|
531
538
|
new Uint8Array(buffer.buffer, offset, length).set(this._buffer.slice(position, end));
|
|
@@ -542,7 +549,7 @@ export class PreloadFile<FS extends FileSystem> extends File {
|
|
|
542
549
|
*/
|
|
543
550
|
public async read<TBuffer extends ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{ bytesRead: number; buffer: TBuffer }> {
|
|
544
551
|
const bytesRead = this._read(buffer, offset, length, position);
|
|
545
|
-
|
|
552
|
+
await this.sync();
|
|
546
553
|
return { bytesRead, buffer };
|
|
547
554
|
}
|
|
548
555
|
|
|
@@ -557,7 +564,7 @@ export class PreloadFile<FS extends FileSystem> extends File {
|
|
|
557
564
|
*/
|
|
558
565
|
public readSync(buffer: ArrayBufferView, offset?: number, length?: number, position?: number): number {
|
|
559
566
|
const bytesRead = this._read(buffer, offset, length, position);
|
|
560
|
-
|
|
567
|
+
this.syncSync();
|
|
561
568
|
return bytesRead;
|
|
562
569
|
}
|
|
563
570
|
|
package/tests/fs/chmod.test.ts
CHANGED
|
@@ -4,45 +4,41 @@ import { fs } from '../common.js';
|
|
|
4
4
|
|
|
5
5
|
const asyncMode = 0o777;
|
|
6
6
|
const syncMode = 0o644;
|
|
7
|
+
const file = 'a.js';
|
|
7
8
|
|
|
8
9
|
suite('chmod tests', () => {
|
|
9
10
|
test('chmod', async () => {
|
|
10
|
-
|
|
11
|
+
await fs.promises.chmod(file, asyncMode.toString(8));
|
|
11
12
|
|
|
12
|
-
await fs.promises.
|
|
13
|
+
const stats = await fs.promises.stat(file);
|
|
14
|
+
assert.equal(stats.mode & 0o777, asyncMode);
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
assert((
|
|
16
|
-
|
|
17
|
-
fs.chmodSync(file1, syncMode);
|
|
18
|
-
assert((fs.statSync(file1).mode & 0o777) === syncMode);
|
|
16
|
+
fs.chmodSync(file, syncMode);
|
|
17
|
+
assert.equal(fs.statSync(file).mode & 0o777, syncMode);
|
|
19
18
|
});
|
|
20
19
|
|
|
21
20
|
test('fchmod', async () => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const handle = await fs.promises.open(file2, 'a', 0o644);
|
|
21
|
+
const handle = await fs.promises.open(file, 'a', 0o644);
|
|
25
22
|
|
|
26
23
|
await handle.chmod(asyncMode);
|
|
27
24
|
const stats = await handle.stat();
|
|
28
25
|
|
|
29
|
-
assert(
|
|
26
|
+
assert.equal(stats.mode & 0o777, asyncMode);
|
|
30
27
|
|
|
31
28
|
fs.fchmodSync(handle.fd, syncMode);
|
|
32
|
-
assert(
|
|
29
|
+
assert.equal(fs.statSync(file).mode & 0o777, syncMode);
|
|
33
30
|
});
|
|
34
31
|
|
|
35
32
|
test('lchmod', async () => {
|
|
36
33
|
const link = 'symbolic-link';
|
|
37
|
-
const target = 'a1.js';
|
|
38
34
|
|
|
39
|
-
await fs.promises.symlink(
|
|
35
|
+
await fs.promises.symlink(file, link);
|
|
40
36
|
await fs.promises.lchmod(link, asyncMode);
|
|
41
37
|
|
|
42
38
|
const stats = await fs.promises.lstat(link);
|
|
43
|
-
assert(
|
|
39
|
+
assert.equal(stats.mode & 0o777, asyncMode);
|
|
44
40
|
|
|
45
41
|
fs.lchmodSync(link, syncMode);
|
|
46
|
-
assert(
|
|
42
|
+
assert.equal(fs.lstatSync(link).mode & 0o777, syncMode);
|
|
47
43
|
});
|
|
48
44
|
});
|
|
@@ -10,22 +10,22 @@ const path: string = 'truncate-file.txt',
|
|
|
10
10
|
suite('Truncate, sync', () => {
|
|
11
11
|
test('initial write', () => {
|
|
12
12
|
fs.writeFileSync(path, data);
|
|
13
|
-
assert(fs.statSync(path).size
|
|
13
|
+
assert.equal(fs.statSync(path).size, size);
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
test('truncate to 1024', () => {
|
|
17
17
|
fs.truncateSync(path, 1024);
|
|
18
|
-
assert(fs.statSync(path).size
|
|
18
|
+
assert.equal(fs.statSync(path).size, 1024);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
test('truncate to 0', () => {
|
|
22
22
|
fs.truncateSync(path);
|
|
23
|
-
assert(fs.statSync(path).size
|
|
23
|
+
assert.equal(fs.statSync(path).size, 0);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
test('write', () => {
|
|
27
27
|
fs.writeFileSync(path, data);
|
|
28
|
-
assert(fs.statSync(path).size
|
|
28
|
+
assert.equal(fs.statSync(path).size, size);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
let fd: number;
|
|
@@ -35,12 +35,12 @@ suite('Truncate, sync', () => {
|
|
|
35
35
|
|
|
36
36
|
test('ftruncate to 1024', () => {
|
|
37
37
|
fs.ftruncateSync(fd, 1024);
|
|
38
|
-
assert(fs.fstatSync(fd).size
|
|
38
|
+
assert.equal(fs.fstatSync(fd).size, 1024);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
test('ftruncate to 0', () => {
|
|
42
42
|
fs.ftruncateSync(fd);
|
|
43
|
-
assert(fs.fstatSync(fd).size
|
|
43
|
+
assert.equal(fs.fstatSync(fd).size, 0);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
test('close fd', () => {
|
|
@@ -53,22 +53,22 @@ suite('Truncate, async', () => {
|
|
|
53
53
|
test('initial write', async () => {
|
|
54
54
|
await fs.promises.writeFile(path, data);
|
|
55
55
|
|
|
56
|
-
assert(
|
|
56
|
+
assert.equal(await statSize(path), 1024 * 16);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
test('truncate to 1024', async () => {
|
|
60
60
|
await fs.promises.truncate(path, 1024);
|
|
61
|
-
assert(
|
|
61
|
+
assert.equal(await statSize(path), 1024);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
test('truncate to 0', async () => {
|
|
65
65
|
await fs.promises.truncate(path);
|
|
66
|
-
assert(
|
|
66
|
+
assert.equal(await statSize(path), 0);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
test('write', async () => {
|
|
70
70
|
await fs.promises.writeFile(path, data);
|
|
71
|
-
assert(
|
|
71
|
+
assert.equal(await statSize(path), size);
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
let handle: FileHandle;
|
|
@@ -79,13 +79,13 @@ suite('Truncate, async', () => {
|
|
|
79
79
|
test('handle.truncate to 1024', async () => {
|
|
80
80
|
await handle.truncate(1024);
|
|
81
81
|
await handle.sync();
|
|
82
|
-
assert(
|
|
82
|
+
assert.equal(await statSize(path), 1024);
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
test('handle.truncate to 0', async () => {
|
|
86
86
|
await handle.truncate();
|
|
87
87
|
await handle.sync();
|
|
88
|
-
assert(
|
|
88
|
+
assert.equal(await statSize(path), 0);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
test('close handle', async () => {
|