GeezerVison is showing github.com — fs: improve error performance of `chownSync` · nodejs/node@ea7902d
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +54Lines changed: 54 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common'); | | 4 | +const fs = require('fs'); | | 5 | +const assert = require('assert'); | | 6 | +const tmpdir = require('../../test/common/tmpdir'); | | 7 | + | | 8 | +if (process.platform === 'win32') { | | 9 | + console.log('Skipping: Windows does not have `getuid` or `getgid`'); | | 10 | + process.exit(0); | | 11 | +} | | 12 | + | | 13 | +const bench = common.createBenchmark(main, { | | 14 | + type: ['existing', 'non-existing'], | | 15 | + method: ['chownSync', 'lchownSync'], | | 16 | + n: [1e4], | | 17 | +}); | | 18 | + | | 19 | +function main({ n, type, method }) { | | 20 | + const uid = process.getuid(); | | 21 | + const gid = process.getgid(); | | 22 | + const fsMethod = fs[method]; | | 23 | + | | 24 | + switch (type) { | | 25 | + case 'existing': { | | 26 | + tmpdir.refresh(); | | 27 | + const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`); | | 28 | + fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8'); | | 29 | + bench.start(); | | 30 | + for (let i = 0; i < n; i++) { | | 31 | + fsMethod(tmpfile, uid, gid); | | 32 | + } | | 33 | + bench.end(n); | | 34 | + break; | | 35 | + } | | 36 | + case 'non-existing': { | | 37 | + const path = tmpdir.resolve(`.non-existing-file-${Date.now()}`); | | 38 | + let hasError = false; | | 39 | + bench.start(); | | 40 | + for (let i = 0; i < n; i++) { | | 41 | + try { | | 42 | + fs[method](path, uid, gid); | | 43 | + } catch { | | 44 | + hasError = true; | | 45 | + } | | 46 | + } | | 47 | + bench.end(n); | | 48 | + assert(hasError); | | 49 | + break; | | 50 | + } | | 51 | + default: | | 52 | + new Error('Invalid type'); | | 53 | + } | | 54 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/fs.js +5-3Lines changed: 5 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2087,9 +2087,11 @@ function chownSync(path, uid, gid) { | 2087 | 2087 | path = getValidatedPath(path); | 2088 | 2088 | validateInteger(uid, 'uid', -1, kMaxUserId); | 2089 | 2089 | validateInteger(gid, 'gid', -1, kMaxUserId); | 2090 | | - const ctx = { path }; | 2091 | | - binding.chown(pathModule.toNamespacedPath(path), uid, gid, undefined, ctx); | 2092 | | - handleErrorFromBinding(ctx); | | 2090 | + binding.chown( | | 2091 | + pathModule.toNamespacedPath(path), | | 2092 | + uid, | | 2093 | + gid, | | 2094 | + ); | 2093 | 2095 | } | 2094 | 2096 |
| 2095 | 2097 | /** | |
Collapse file Copy file name to clipboardExpand all lines: src/node_file.cc +5-7Lines changed: 5 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2607,18 +2607,16 @@ static void Chown(const FunctionCallbackInfo<Value>& args) { | 2607 | 2607 | CHECK(IsSafeJsInt(args[2])); | 2608 | 2608 | const uv_gid_t gid = static_cast<uv_gid_t>(args[2].As<Integer>()->Value()); | 2609 | 2609 |
| 2610 | | - FSReqBase* req_wrap_async = GetReqWrap(args, 3); | 2611 | | - if (req_wrap_async != nullptr) { // chown(path, uid, gid, req) | | 2610 | + if (argc > 3) { // chown(path, uid, gid, req) | | 2611 | + FSReqBase* req_wrap_async = GetReqWrap(args, 3); | 2612 | 2612 | FS_ASYNC_TRACE_BEGIN1( | 2613 | 2613 | UV_FS_CHOWN, req_wrap_async, "path", TRACE_STR_COPY(*path)) | 2614 | 2614 | AsyncCall(env, req_wrap_async, args, "chown", UTF8, AfterNoArgs, | 2615 | 2615 | uv_fs_chown, *path, uid, gid); | 2616 | | - } else { // chown(path, uid, gid, undefined, ctx) | 2617 | | - CHECK_EQ(argc, 5); | 2618 | | - FSReqWrapSync req_wrap_sync; | | 2616 | + } else { // chown(path, uid, gid) | | 2617 | + FSReqWrapSync req_wrap_sync("chown", *path); | 2619 | 2618 | FS_SYNC_TRACE_BEGIN(chown); | 2620 | | - SyncCall(env, args[4], &req_wrap_sync, "chown", | 2621 | | - uv_fs_chown, *path, uid, gid); | | 2619 | + SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_chown, *path, uid, gid); | 2622 | 2620 | FS_SYNC_TRACE_END(chown); | 2623 | 2621 | } | 2624 | 2622 | } | |
Collapse file Copy file name to clipboardExpand all lines: typings/internalBinding/fs.d.ts +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -67,6 +67,7 @@ declare namespace InternalFSBinding { | 67 | 67 | function chown(path: string, uid: number, gid: number, req: FSReqCallback): void; | 68 | 68 | function chown(path: string, uid: number, gid: number, req: undefined, ctx: FSSyncContext): void; | 69 | 69 | function chown(path: string, uid: number, gid: number, usePromises: typeof kUsePromises): Promise<void>; | | 70 | + function chown(path: string, uid: number, gid: number): void; | 70 | 71 |
| 71 | 72 | function close(fd: number, req: FSReqCallback): void; | 72 | 73 | function close(fd: number, req: undefined, ctx: FSSyncContext): void; | |
|