From 828e171107a0834c93e4194e3cc847d1261d049f Mon Sep 17 00:00:00 2001 From: Huachao Mao Date: Mon, 14 Oct 2019 11:18:21 +0800 Subject: [PATCH 01/33] doc: add server header into the discarded list of http message.headers PR-URL: https://github.com/nodejs/node/pull/29962 Reviewed-By: James M Snell Reviewed-By: Trivikram Kamat --- doc/api/http.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/http.md b/doc/api/http.md index e52da24779bdcf..0807cc09d08b58 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1765,7 +1765,7 @@ header name: * Duplicates of `age`, `authorization`, `content-length`, `content-type`, `etag`, `expires`, `from`, `host`, `if-modified-since`, `if-unmodified-since`, `last-modified`, `location`, `max-forwards`, `proxy-authorization`, `referer`, -`retry-after`, or `user-agent` are discarded. +`retry-after`, `server`, or `user-agent` are discarded. * `set-cookie` is always an array. Duplicates are added to the array. * For duplicate `cookie` headers, the values are joined together with '; '. * For all other headers, the values are joined together with ', '. From d80ece68ac9a94754082a8e5713d9d1056ef1b2e Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 13 Oct 2019 23:46:56 -0400 Subject: [PATCH 02/33] doc: re-enable passing remark-lint rule PR-URL: https://github.com/nodejs/node/pull/29961 Reviewed-By: Rich Trott Reviewed-By: Gireesh Punathil --- doc/api/crypto.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index b4f91c1d559e71..345ce542962420 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3048,7 +3048,7 @@ The following constants exported by `crypto.constants` apply to various uses of the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. ### OpenSSL Options - + @@ -3204,7 +3204,6 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
Constant
### OpenSSL Engine Constants - From dc83ff9056888ce2b7921a3399ed54cb026fb3ef Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 13 Oct 2019 23:49:20 -0400 Subject: [PATCH 03/33] doc: remove unused Markdown reference links PR-URL: https://github.com/nodejs/node/pull/29961 Reviewed-By: Rich Trott Reviewed-By: Gireesh Punathil --- doc/api/n-api.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index cefb66b614808a..40145674671433 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -4657,8 +4657,6 @@ that points to its own memory allocated by a native module). Registering externally allocated memory will trigger global garbage collections more often than it would otherwise. - - ## Promises N-API provides facilities for creating `Promise` objects as described in @@ -4846,8 +4844,6 @@ NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[out] loop`: The current libuv loop instance. - - ## Asynchronous Thread-safe Function Calls JavaScript functions can normally only be called from a native addon's main @@ -5175,10 +5171,7 @@ This API may only be called from the main thread. [Section 25.4]: https://tc39.github.io/ecma262/#sec-promise-objects [`Number.MIN_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.min_safe_integer [`Number.MAX_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.max_safe_integer -[Working with JavaScript Functions]: #n_api_working_with_javascript_functions [Working with JavaScript Properties]: #n_api_working_with_javascript_properties -[Working with JavaScript Values - Abstract Operations]: #n_api_working_with_javascript_values_abstract_operations -[Working with JavaScript Values]: #n_api_working_with_javascript_values [`init` hooks]: async_hooks.html#async_hooks_init_asyncid_type_triggerasyncid_resource [`napi_add_finalizer`]: #n_api_napi_add_finalizer [`napi_async_init`]: #n_api_napi_async_init @@ -5194,8 +5187,6 @@ This API may only be called from the main thread. [`napi_create_type_error`]: #n_api_napi_create_type_error [`napi_define_class`]: #n_api_napi_define_class [`napi_delete_async_work`]: #n_api_napi_delete_async_work -[`napi_delete_element`]: #n_api_napi_delete_element -[`napi_delete_property`]: #n_api_napi_delete_property [`napi_delete_reference`]: #n_api_napi_delete_reference [`napi_escape_handle`]: #n_api_napi_escape_handle [`napi_get_and_clear_last_exception`]: #n_api_napi_get_and_clear_last_exception @@ -5205,7 +5196,6 @@ This API may only be called from the main thread. [`napi_get_property`]: #n_api_napi_get_property [`napi_get_reference_value`]: #n_api_napi_get_reference_value [`napi_get_value_external`]: #n_api_napi_get_value_external -[`napi_has_own_property`]: #n_api_napi_has_own_property [`napi_has_property`]: #n_api_napi_has_property [`napi_is_error`]: #n_api_napi_is_error [`napi_is_exception_pending`]: #n_api_napi_is_exception_pending From b1b8663a233e3168565ceb618b2c14b6542fa871 Mon Sep 17 00:00:00 2001 From: Matteo Rossi Date: Mon, 14 Oct 2019 17:39:39 +0200 Subject: [PATCH 04/33] test: add cb error test for fs.close() Provides some missing test coverage. PR-URL: https://github.com/nodejs/node/pull/29970 Reviewed-By: Jeremiah Senkpiel Reviewed-By: Rich Trott Reviewed-By: James M Snell --- test/parallel/test-fs-close-errors.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/parallel/test-fs-close-errors.js b/test/parallel/test-fs-close-errors.js index 42d990410f9848..6168d5c20ab8e5 100644 --- a/test/parallel/test-fs-close-errors.js +++ b/test/parallel/test-fs-close-errors.js @@ -17,3 +17,19 @@ const fs = require('fs'); assert.throws(() => fs.close(input), errObj); assert.throws(() => fs.closeSync(input), errObj); }); + +{ + // Test error when cb is not a function + const fd = fs.openSync(__filename, 'r'); + + const errObj = { + code: 'ERR_INVALID_CALLBACK', + name: 'TypeError' + }; + + ['', false, null, {}, []].forEach((input) => { + assert.throws(() => fs.close(fd, input), errObj); + }); + + fs.closeSync(fd); +} From 3eae67047088bfee66c02f9893f44b61f430be87 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Wed, 9 Oct 2019 13:27:26 -0700 Subject: [PATCH 05/33] src: refine maps parsing for large pages Multiple sections may be marked as "r-xp" and with the executable's path. We use the location of the `__nodetext` symbol added by the linker script to ensure that the range we retrieve from the maps file does indeed contain the Node.js text section. Thanks to Suresh Srinivas ! PR-URL: https://github.com/nodejs/node/pull/29973 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: David Carlier --- src/large_pages/node_large_page.cc | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/large_pages/node_large_page.cc b/src/large_pages/node_large_page.cc index 220f71fa105ff5..4e2f8fc4410316 100644 --- a/src/large_pages/node_large_page.cc +++ b/src/large_pages/node_large_page.cc @@ -83,11 +83,11 @@ static void PrintSystemError(int error) { return; } -inline int64_t hugepage_align_up(int64_t addr) { +inline uintptr_t hugepage_align_up(uintptr_t addr) { return (((addr) + (hps) - 1) & ~((hps) - 1)); } -inline int64_t hugepage_align_down(int64_t addr) { +inline uintptr_t hugepage_align_down(uintptr_t addr) { return ((addr) & ~((hps) - 1)); } @@ -103,7 +103,7 @@ static struct text_region FindNodeTextRegion() { std::string permission; std::string dev; char dash; - int64_t start, end, offset, inode; + uintptr_t start, end, offset, inode; struct text_region nregion; nregion.found_text_region = false; @@ -138,18 +138,20 @@ static struct text_region FindNodeTextRegion() { std::string pathname; iss >> pathname; if (pathname == exename && permission == "r-xp") { - start = reinterpret_cast(&__nodetext); - char* from = reinterpret_cast(hugepage_align_up(start)); - char* to = reinterpret_cast(hugepage_align_down(end)); - - if (from < to) { - size_t size = to - from; - nregion.found_text_region = true; - nregion.from = from; - nregion.to = to; - nregion.total_hugepages = size / hps; + uintptr_t ntext = reinterpret_cast(&__nodetext); + if (ntext >= start && ntext < end) { + char* from = reinterpret_cast(hugepage_align_up(ntext)); + char* to = reinterpret_cast(hugepage_align_down(end)); + + if (from < to) { + size_t size = to - from; + nregion.found_text_region = true; + nregion.from = from; + nregion.to = to; + nregion.total_hugepages = size / hps; + } + break; } - break; } } } From 62b4ca6e325c40265e6f8b97707889effcc1ea18 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 16 Oct 2019 12:55:15 +0200 Subject: [PATCH 06/33] doc: clarify readable.unshift null/EOF PR-URL: https://github.com/nodejs/node/pull/29950 Reviewed-By: Matteo Collina Reviewed-By: Jeremiah Senkpiel --- doc/api/stream.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index 52d8183d8ddbc1..ef0bbb502735d3 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1288,8 +1288,10 @@ changes: * `encoding` {string} Encoding of string chunks. Must be a valid `Buffer` encoding, such as `'utf8'` or `'ascii'`. -Passing `chunk` as `null` signals the end of the stream (EOF), after which no -more data can be written. +Passing `chunk` as `null` signals the end of the stream (EOF) and behaves the +same as `readable.push(null)`, after which no more data can be written. The EOF +signal is put at the end of the buffer and any buffered data will still be +flushed. The `readable.unshift()` method pushes a chunk of data back into the internal buffer. This is useful in certain situations where a stream is being consumed by From cfd45ebf94ffccca780e7340d863d698410e07bd Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 30 Sep 2019 14:55:59 -0500 Subject: [PATCH 07/33] module: refactor modules bootstrap PR-URL: https://github.com/nodejs/node/pull/29937 Reviewed-By: Myles Borins Reviewed-By: Joyee Cheung --- doc/api/esm.md | 8 +-- lib/internal/bootstrap/loaders.js | 5 +- lib/internal/bootstrap/pre_execution.js | 69 ++++++++++++++++--- lib/internal/main/run_main_module.js | 9 ++- lib/internal/main/worker_thread.js | 5 +- lib/internal/modules/cjs/loader.js | 66 ++++++++++-------- lib/internal/modules/esm/loader.js | 11 ++- lib/internal/modules/esm/module_job.js | 8 +-- lib/internal/modules/esm/module_map.js | 3 +- lib/internal/modules/esm/translators.js | 8 ++- lib/internal/process/esm_loader.js | 50 ++++++++------ lib/internal/process/execution.js | 2 +- lib/repl.js | 15 ++-- test/es-module/test-esm-loader-modulemap.js | 2 +- test/es-module/test-esm-no-extension.js | 7 -- test/parallel/test-bootstrap-modules.js | 1 - .../test-internal-module-map-asserts.js | 8 +-- 17 files changed, 176 insertions(+), 101 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index e585ae4db63646..e1002f11fb3054 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -886,13 +886,13 @@ _isMain_ is **true** when resolving the Node.js application entry point. > 1. Throw a _Module Not Found_ error. > 1. If _pjson.exports_ is not **null** or **undefined**, then > 1. If _pjson.exports_ is a String or Array, then -> 1. Return _PACKAGE_EXPORTS_TARGET_RESOLVE(packageURL, pjson.exports, -> "")_. +> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, +> _pjson.exports_, "")_. > 1. If _pjson.exports is an Object, then > 1. If _pjson.exports_ contains a _"."_ property, then > 1. Let _mainExport_ be the _"."_ property in _pjson.exports_. -> 1. Return _PACKAGE_EXPORTS_TARGET_RESOLVE(packageURL, mainExport, -> "")_. +> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, +> _mainExport_, "")_. > 1. If _pjson.main_ is a String, then > 1. Let _resolvedMain_ be the URL resolution of _packageURL_, "/", and > _pjson.main_. diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js index 775fea064ecb63..48afed2556a51b 100644 --- a/lib/internal/bootstrap/loaders.js +++ b/lib/internal/bootstrap/loaders.js @@ -220,7 +220,10 @@ NativeModule.prototype.compileForPublicLoader = function(needToSyncExports) { this.compile(); if (needToSyncExports) { if (!this.exportKeys) { - this.exportKeys = Object.keys(this.exports); + // When using --expose-internals, we do not want to reflect the named + // exports from core modules as this can trigger unnecessary getters. + const internal = this.id.startsWith('internal/'); + this.exportKeys = internal ? [] : Object.keys(this.exports); } this.getESMFacade(); this.syncExports(); diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index 1126fbcdd71bce..80ac97ee450efa 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -5,6 +5,7 @@ const { Object, SafeWeakMap } = primordials; const { getOptionValue } = require('internal/options'); const { Buffer } = require('buffer'); const { ERR_MANIFEST_ASSERT_INTEGRITY } = require('internal/errors').codes; +const path = require('path'); function prepareMainThreadExecution(expandArgv1 = false) { // Patch the process object with legacy properties and normalizations @@ -404,7 +405,6 @@ function initializeESMLoader() { 'The ESM module loader is experimental.', 'ExperimentalWarning', undefined); } - const { setImportModuleDynamicallyCallback, setInitializeImportMetaObjectCallback @@ -414,14 +414,6 @@ function initializeESMLoader() { // track of for different ESM modules. setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject); setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback); - const userLoader = getOptionValue('--experimental-loader'); - // If --experimental-loader is specified, create a loader with user hooks. - // Otherwise create the default loader. - if (userLoader) { - const { emitExperimentalWarning } = require('internal/util'); - emitExperimentalWarning('--experimental-loader'); - } - esm.initializeLoader(process.cwd(), userLoader); } } @@ -446,11 +438,70 @@ function loadPreloadModules() { } } +function resolveMainPath(main) { + const { toRealPath, Module: CJSModule } = + require('internal/modules/cjs/loader'); + + // Note extension resolution for the main entry point can be deprecated in a + // future major. + let mainPath = CJSModule._findPath(path.resolve(main), null, true); + if (!mainPath) + return; + + const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); + if (!preserveSymlinksMain) + mainPath = toRealPath(mainPath); + + return mainPath; +} + +function shouldUseESMLoader(mainPath) { + const experimentalModules = getOptionValue('--experimental-modules'); + if (!experimentalModules) + return false; + const userLoader = getOptionValue('--experimental-loader'); + if (userLoader) + return true; + // Determine the module format of the main + if (mainPath && mainPath.endsWith('.mjs')) + return true; + if (!mainPath || mainPath.endsWith('.cjs')) + return false; + const { readPackageScope } = require('internal/modules/cjs/loader'); + const pkg = readPackageScope(mainPath); + return pkg && pkg.data.type === 'module'; +} + +function runMainESM(mainPath) { + const esmLoader = require('internal/process/esm_loader'); + const { pathToFileURL } = require('internal/url'); + const { hasUncaughtExceptionCaptureCallback } = + require('internal/process/execution'); + return esmLoader.initializeLoader().then(() => { + const main = path.isAbsolute(mainPath) ? + pathToFileURL(mainPath).href : mainPath; + return esmLoader.ESMLoader.import(main).catch((e) => { + if (hasUncaughtExceptionCaptureCallback()) { + process._fatalException(e); + return; + } + internalBinding('errors').triggerUncaughtException( + e, + true /* fromPromise */ + ); + }); + }); +} + + module.exports = { patchProcessObject, + resolveMainPath, + runMainESM, setupCoverageHooks, setupWarningHandler, setupDebugEnv, + shouldUseESMLoader, prepareMainThreadExecution, initializeDeprecations, initializeESMLoader, diff --git a/lib/internal/main/run_main_module.js b/lib/internal/main/run_main_module.js index 2cad569dcce9fd..77d997b97a1c7a 100644 --- a/lib/internal/main/run_main_module.js +++ b/lib/internal/main/run_main_module.js @@ -10,8 +10,7 @@ const CJSModule = require('internal/modules/cjs/loader').Module; markBootstrapComplete(); -// Note: this actually tries to run the module as a ESM first if -// --experimental-modules is on. -// TODO(joyeecheung): can we move that logic to here? Note that this -// is an undocumented method available via `require('module').runMain` -CJSModule.runMain(); +// Note: this loads the module through the ESM loader if +// --experimental-loader is provided or --experimental-modules is on +// and the module is determined to be an ES module +CJSModule.runMain(process.argv[1]); diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js index 50a19be77dd78d..7cf8ffb8b401f5 100644 --- a/lib/internal/main/worker_thread.js +++ b/lib/internal/main/worker_thread.js @@ -140,8 +140,9 @@ port.on('message', (message) => { const { evalScript } = require('internal/process/execution'); evalScript('[worker eval]', filename); } else { - process.argv[1] = filename; // script filename - require('module').runMain(); + // script filename + const CJSModule = require('internal/modules/cjs/loader').Module; + CJSModule.runMain(process.argv[1] = filename); } } else if (message.type === STDIO_PAYLOAD) { const { stream, chunk, encoding } = message; diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index a8dd3bbaa3f5ae..a28383690ae2d9 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -69,9 +69,14 @@ const { ERR_REQUIRE_ESM } = require('internal/errors').codes; const { validateString } = require('internal/validators'); +const { + resolveMainPath, + shouldUseESMLoader, + runMainESM +} = require('internal/bootstrap/pre_execution'); const pendingDeprecation = getOptionValue('--pending-deprecation'); -module.exports = { wrapSafe, Module }; +module.exports = { wrapSafe, Module, toRealPath, readPackageScope }; let asyncESM, ModuleJob, ModuleWrap, kInstantiated; @@ -810,6 +815,10 @@ Module.prototype.load = function(filename) { this.paths = Module._nodeModulePaths(path.dirname(filename)); const extension = findLongestRegisteredExtension(filename); + // allow .mjs to be overridden + if (filename.endsWith('.mjs') && !Module._extensions['.mjs']) { + throw new ERR_REQUIRE_ESM(filename); + } Module._extensions[extension](this, filename); this.loaded = true; @@ -823,14 +832,19 @@ Module.prototype.load = function(filename) { if (module !== undefined && module.module !== undefined) { if (module.module.getStatus() >= kInstantiated) module.module.setExport('default', exports); - } else { // preemptively cache + } else { + // Preemptively cache + // We use a function to defer promise creation for async hooks. ESMLoader.moduleMap.set( url, - new ModuleJob(ESMLoader, url, () => + // Module job creation will start promises. + // We make it a function to lazily trigger those promises + // for async hooks compatibility. + () => new ModuleJob(ESMLoader, url, () => new ModuleWrap(url, undefined, ['default'], function() { this.setExport('default', exports); }) - ) + , false /* isMain */, false /* inspectBrk */) ); } } @@ -859,7 +873,7 @@ Module.prototype.require = function(id) { var resolvedArgv; let hasPausedEntry = false; -function wrapSafe(filename, content) { +function wrapSafe(filename, content, cjsModuleInstance) { if (patched) { const wrapper = Module.wrap(content); return vm.runInThisContext(wrapper, { @@ -867,7 +881,7 @@ function wrapSafe(filename, content) { lineOffset: 0, displayErrors: true, importModuleDynamically: experimentalModules ? async (specifier) => { - const loader = await asyncESM.loaderPromise; + const loader = asyncESM.ESMLoader; return loader.import(specifier, normalizeReferrerURL(filename)); } : undefined, }); @@ -892,9 +906,8 @@ function wrapSafe(filename, content) { ] ); } catch (err) { - if (experimentalModules) { + if (experimentalModules && process.mainModule === cjsModuleInstance) enrichCJSError(err); - } throw err; } @@ -902,7 +915,7 @@ function wrapSafe(filename, content) { const { callbackMap } = internalBinding('module_wrap'); callbackMap.set(compiled.cacheKey, { importModuleDynamically: async (specifier) => { - const loader = await asyncESM.loaderPromise; + const loader = asyncESM.ESMLoader; return loader.import(specifier, normalizeReferrerURL(filename)); } }); @@ -925,7 +938,7 @@ Module.prototype._compile = function(content, filename) { } maybeCacheSourceMap(filename, content, this); - const compiledWrapper = wrapSafe(filename, content); + const compiledWrapper = wrapSafe(filename, content, this); var inspectorWrapper = null; if (getOptionValue('--inspect-brk') && process._eval == null) { @@ -981,7 +994,11 @@ Module._extensions['.js'] = function(module, filename) { 'files in that package scope as ES modules.\nInstead rename ' + `${basename} to end in .cjs, change the requiring code to use ` + 'import(), or remove "type": "module" from ' + - `${path.resolve(pkg.path, 'package.json')}.` + `${path.resolve(pkg.path, 'package.json')}.`, + undefined, + undefined, + undefined, + true ); warnRequireESM = false; } @@ -1024,26 +1041,15 @@ Module._extensions['.node'] = function(module, filename) { return process.dlopen(module, path.toNamespacedPath(filename)); }; -Module._extensions['.mjs'] = function(module, filename) { - throw new ERR_REQUIRE_ESM(filename); -}; - // Bootstrap main module. -Module.runMain = function() { - // Load the main module--the command line argument. - if (experimentalModules) { - asyncESM.loaderPromise.then((loader) => { - return loader.import(pathToFileURL(process.argv[1]).href); - }) - .catch((e) => { - internalBinding('errors').triggerUncaughtException( - e, - true /* fromPromise */ - ); - }); - return; +Module.runMain = function(main = process.argv[1]) { + const resolvedMain = resolveMainPath(main); + const useESMLoader = shouldUseESMLoader(resolvedMain); + if (useESMLoader) { + runMainESM(resolvedMain || main); + } else { + Module._load(main, null, true); } - Module._load(process.argv[1], null, true); }; function createRequireFromPath(filename) { @@ -1164,7 +1170,7 @@ Module.Module = Module; // We have to load the esm things after module.exports! if (experimentalModules) { - asyncESM = require('internal/process/esm_loader'); ModuleJob = require('internal/modules/esm/module_job'); + asyncESM = require('internal/process/esm_loader'); ({ ModuleWrap, kInstantiated } = internalBinding('module_wrap')); } diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index a62529e9b32250..875fb97f912a85 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -22,6 +22,7 @@ const createDynamicModule = require( 'internal/modules/esm/create_dynamic_module'); const { translators } = require('internal/modules/esm/translators'); const { ModuleWrap } = internalBinding('module_wrap'); +const { getOptionValue } = require('internal/options'); const debug = require('internal/util/debuglog').debuglog('esm'); @@ -118,7 +119,7 @@ class Loader { url = pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href ) { const evalInstance = (url) => new ModuleWrap(url, undefined, source, 0, 0); - const job = new ModuleJob(this, url, evalInstance, false); + const job = new ModuleJob(this, url, evalInstance, false, false); this.moduleMap.set(url, job); const { module, result } = await job.run(); return { @@ -146,6 +147,9 @@ class Loader { async getModuleJob(specifier, parentURL) { const { url, format } = await this.resolve(specifier, parentURL); let job = this.moduleMap.get(url); + // CommonJS will set functions for lazy job evaluation. + if (typeof job === 'function') + this.moduleMap.set(url, job = job()); if (job !== undefined) return job; @@ -169,7 +173,10 @@ class Loader { loaderInstance = translators.get(format); } - job = new ModuleJob(this, url, loaderInstance, parentURL === undefined); + const inspectBrk = parentURL === undefined && + format === 'module' && getOptionValue('--inspect-brk'); + job = new ModuleJob(this, url, loaderInstance, parentURL === undefined, + inspectBrk); this.moduleMap.set(url, job); return job; } diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index ef11e2ec833b89..df1edc3810c080 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -9,7 +9,6 @@ const { const { ModuleWrap } = internalBinding('module_wrap'); const { decorateErrorStack } = require('internal/util'); -const { getOptionValue } = require('internal/options'); const assert = require('internal/assert'); const resolvedPromise = SafePromise.resolve(); @@ -22,9 +21,10 @@ let hasPausedEntry = false; class ModuleJob { // `loader` is the Loader instance used for loading dependencies. // `moduleProvider` is a function - constructor(loader, url, moduleProvider, isMain) { + constructor(loader, url, moduleProvider, isMain, inspectBrk) { this.loader = loader; this.isMain = isMain; + this.inspectBrk = inspectBrk; // This is a Promise<{ module, reflect }>, whose fields will be copied // onto `this` by `link()` below once it has been resolved. @@ -83,12 +83,12 @@ class ModuleJob { }; await addJobsToDependencyGraph(this); try { - if (!hasPausedEntry && this.isMain && getOptionValue('--inspect-brk')) { + if (!hasPausedEntry && this.inspectBrk) { hasPausedEntry = true; const initWrapper = internalBinding('inspector').callAndPauseOnStart; initWrapper(this.module.instantiate, this.module); } else { - this.module.instantiate(); + this.module.instantiate(true); } } catch (e) { decorateErrorStack(e); diff --git a/lib/internal/modules/esm/module_map.js b/lib/internal/modules/esm/module_map.js index 01521fb7885ee1..41adc0079ada31 100644 --- a/lib/internal/modules/esm/module_map.js +++ b/lib/internal/modules/esm/module_map.js @@ -16,7 +16,8 @@ class ModuleMap extends SafeMap { } set(url, job) { validateString(url, 'url'); - if (job instanceof ModuleJob !== true) { + if (job instanceof ModuleJob !== true && + typeof job !== 'function') { throw new ERR_INVALID_ARG_TYPE('job', 'ModuleJob', job); } debug(`Storing ${url} in ModuleMap`); diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 18ccfb35e81c8a..34a9a140dd7732 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -23,7 +23,6 @@ const fs = require('fs'); const { fileURLToPath, URL } = require('url'); const { debuglog } = require('internal/util/debuglog'); const { promisify } = require('internal/util'); -const esmLoader = require('internal/process/esm_loader'); const { ERR_INVALID_URL, ERR_INVALID_URL_SCHEME, @@ -69,9 +68,12 @@ function initializeImportMeta(meta, { url }) { meta.url = url; } +let esmLoader; async function importModuleDynamically(specifier, { url }) { - const loader = await esmLoader.loaderPromise; - return loader.import(specifier, url); + if (!esmLoader) { + esmLoader = require('internal/process/esm_loader'); + } + return esmLoader.ESMLoader.import(specifier, url); } // Strategy for loading a standard JavaScript module diff --git a/lib/internal/process/esm_loader.js b/lib/internal/process/esm_loader.js index 69e1fd00163cdb..49463e284c541f 100644 --- a/lib/internal/process/esm_loader.js +++ b/lib/internal/process/esm_loader.js @@ -3,12 +3,14 @@ const { ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, } = require('internal/errors').codes; - +const assert = require('internal/assert'); const { Loader } = require('internal/modules/esm/loader'); const { pathToFileURL } = require('internal/url'); const { getModuleFromWrap, } = require('internal/vm/module'); +const { getOptionValue } = require('internal/options'); +const userLoader = getOptionValue('--experimental-loader'); exports.initializeImportMetaObject = function(wrap, meta) { const { callbackMap } = internalBinding('module_wrap'); @@ -21,6 +23,7 @@ exports.initializeImportMetaObject = function(wrap, meta) { }; exports.importModuleDynamicallyCallback = async function(wrap, specifier) { + assert(calledInitialize === true || !userLoader); const { callbackMap } = internalBinding('module_wrap'); if (callbackMap.has(wrap)) { const { importModuleDynamically } = callbackMap.get(wrap); @@ -32,24 +35,31 @@ exports.importModuleDynamicallyCallback = async function(wrap, specifier) { throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING(); }; -let loaderResolve; -exports.loaderPromise = new Promise((resolve) => loaderResolve = resolve); - -exports.ESMLoader = undefined; +let ESMLoader = new Loader(); +exports.ESMLoader = ESMLoader; -exports.initializeLoader = function(cwd, userLoader) { - let ESMLoader = new Loader(); - const loaderPromise = (async () => { - if (userLoader) { - const hooks = await ESMLoader.import( - userLoader, pathToFileURL(`${cwd}/`).href); - ESMLoader = new Loader(); - ESMLoader.hook(hooks); - exports.ESMLoader = ESMLoader; - } - return ESMLoader; +let calledInitialize = false; +exports.initializeLoader = initializeLoader; +async function initializeLoader() { + assert(calledInitialize === false); + calledInitialize = true; + if (!userLoader) + return; + let cwd; + try { + cwd = process.cwd() + '/'; + } catch { + cwd = 'file:///'; + } + // If --experimental-loader is specified, create a loader with user hooks. + // Otherwise create the default loader. + const { emitExperimentalWarning } = require('internal/util'); + emitExperimentalWarning('--experimental-loader'); + return (async () => { + const hooks = + await ESMLoader.import(userLoader, pathToFileURL(cwd).href); + ESMLoader = new Loader(); + ESMLoader.hook(hooks); + return exports.ESMLoader = ESMLoader; })(); - loaderResolve(loaderPromise); - - exports.ESMLoader = ESMLoader; -}; +} diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 06dfbce2958f08..eed554263c213c 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -39,7 +39,7 @@ function evalModule(source, print) { const { log, error } = require('internal/console/global'); const { decorateErrorStack } = require('internal/util'); const asyncESM = require('internal/process/esm_loader'); - asyncESM.loaderPromise.then(async (loader) => { + Promise.resolve(asyncESM.ESMLoader).then(async (loader) => { const { result } = await loader.eval(source); if (print) { log(result); diff --git a/lib/repl.js b/lib/repl.js index bce90a18602e8f..88b0f5658489fc 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -99,6 +99,7 @@ const { } = internalBinding('contextify'); const history = require('internal/repl/history'); +const { setImmediate } = require('timers'); // Lazy-loaded. let processTopLevelAwait; @@ -338,11 +339,9 @@ function REPLServer(prompt, script = vm.createScript(code, { filename: file, displayErrors: true, - importModuleDynamically: experimentalModules ? - async (specifier) => { - return (await asyncESM.loaderPromise).import(specifier, pwd); - } : - undefined + importModuleDynamically: experimentalModules ? async (specifier) => { + return asyncESM.ESMLoader.import(specifier, pwd); + } : undefined }); } catch (e) { debug('parse error %j', code, e); @@ -1080,7 +1079,11 @@ function complete(line, callback) { // All this is only profitable if the nested REPL does not have a // bufferedCommand. if (!magic[kBufferedCommandSymbol]) { - magic._domain.on('error', (err) => { throw err; }); + magic._domain.on('error', (err) => { + setImmediate(() => { + throw err; + }); + }); return magic.complete(line, callback); } } diff --git a/test/es-module/test-esm-loader-modulemap.js b/test/es-module/test-esm-loader-modulemap.js index 5493c6c47c9643..70f5a1015907a2 100644 --- a/test/es-module/test-esm-loader-modulemap.js +++ b/test/es-module/test-esm-loader-modulemap.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --expose-internals --experimental-modules // This test ensures that the type checking of ModuleMap throws // errors appropriately diff --git a/test/es-module/test-esm-no-extension.js b/test/es-module/test-esm-no-extension.js index e3f30d6e3c2808..81b8e5b4327ad0 100644 --- a/test/es-module/test-esm-no-extension.js +++ b/test/es-module/test-esm-no-extension.js @@ -15,11 +15,6 @@ const child = spawn(process.execPath, [ entry ]); -let stderr = ''; -child.stderr.setEncoding('utf8'); -child.stderr.on('data', (data) => { - stderr += data; -}); let stdout = ''; child.stdout.setEncoding('utf8'); child.stdout.on('data', (data) => { @@ -29,6 +24,4 @@ child.on('close', common.mustCall((code, signal) => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); assert.strictEqual(stdout, 'executed\n'); - assert.strictEqual(stderr, `(node:${child.pid}) ` + - 'ExperimentalWarning: The ESM module loader is experimental.\n'); })); diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index 939658a3b0553f..c963630f5d32ab 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -92,7 +92,6 @@ if (common.isMainThread) { expectedModules.add('NativeModule internal/streams/state'); expectedModules.add('NativeModule internal/worker'); expectedModules.add('NativeModule internal/worker/io'); - expectedModules.add('NativeModule module'); expectedModules.add('NativeModule stream'); expectedModules.add('NativeModule worker_threads'); } diff --git a/test/parallel/test-internal-module-map-asserts.js b/test/parallel/test-internal-module-map-asserts.js index 4563fc605e0792..614da43aba0acb 100644 --- a/test/parallel/test-internal-module-map-asserts.js +++ b/test/parallel/test-internal-module-map-asserts.js @@ -12,7 +12,7 @@ const ModuleMap = require('internal/modules/esm/module_map'); code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: /^The "url" argument must be of type string/ - }, 15); + }, 12); const moduleMap = new ModuleMap(); @@ -21,7 +21,7 @@ const ModuleMap = require('internal/modules/esm/module_map'); // but I think it's useless, and was not simple to mock... const job = undefined; - [{}, [], true, 1, () => {}].forEach((value) => { + [{}, [], true, 1].forEach((value) => { assert.throws(() => moduleMap.get(value), errorReg); assert.throws(() => moduleMap.has(value), errorReg); assert.throws(() => moduleMap.set(value, job), errorReg); @@ -34,11 +34,11 @@ const ModuleMap = require('internal/modules/esm/module_map'); code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: /^The "job" argument must be of type ModuleJob/ - }, 5); + }, 4); const moduleMap = new ModuleMap(); - [{}, [], true, 1, () => {}].forEach((value) => { + [{}, [], true, 1].forEach((value) => { assert.throws(() => moduleMap.set('', value), errorReg); }); } From 9729c5da8a005a2707310b24274b0b14f362907c Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Mon, 14 Oct 2019 13:28:42 -0400 Subject: [PATCH 08/33] esm: modify resolution order for specifier flag Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations. PR-URL: https://github.com/nodejs/node/pull/29974 Reviewed-By: Jan Krems Reviewed-By: Guy Bedford Reviewed-By: James M Snell --- lib/internal/modules/esm/default_resolve.js | 4 ++++ src/module_wrap.cc | 5 ++--- test/es-module/test-esm-specifiers.mjs | 6 +++--- .../node_modules/implicit-main-type-module/entry.js | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/internal/modules/esm/default_resolve.js b/lib/internal/modules/esm/default_resolve.js index 7686e3e003eede..88af3cb5f8d286 100644 --- a/lib/internal/modules/esm/default_resolve.js +++ b/lib/internal/modules/esm/default_resolve.js @@ -9,6 +9,8 @@ const { getOptionValue } = require('internal/options'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const experimentalJsonModules = getOptionValue('--experimental-json-modules'); +const esModuleSpecifierResolution = + getOptionValue('--es-module-specifier-resolution'); const typeFlag = getOptionValue('--input-type'); const experimentalWasmModules = getOptionValue('--experimental-wasm-modules'); const { resolve: moduleWrapResolve, @@ -110,6 +112,8 @@ function resolve(specifier, parentURL) { if (!format) { if (isMain) format = type === TYPE_MODULE ? 'module' : 'commonjs'; + else if (esModuleSpecifierResolution === 'node') + format = 'commonjs'; else throw new ERR_UNKNOWN_FILE_EXTENSION(fileURLToPath(url)); } diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 97e6b5453d33c2..e7df8688cb8582 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -48,11 +48,10 @@ using v8::Undefined; using v8::Value; static const char* const EXTENSIONS[] = { - ".mjs", - ".cjs", ".js", ".json", - ".node" + ".node", + ".mjs" }; ModuleWrap::ModuleWrap(Environment* env, diff --git a/test/es-module/test-esm-specifiers.mjs b/test/es-module/test-esm-specifiers.mjs index 0c5e1ac04ad1a8..59d54cbf63dc79 100644 --- a/test/es-module/test-esm-specifiers.mjs +++ b/test/es-module/test-esm-specifiers.mjs @@ -1,5 +1,5 @@ // Flags: --experimental-modules --es-module-specifier-resolution=node -import { mustNotCall } from '../common'; +import { mustNotCall } from '../common/index.mjs'; import assert from 'assert'; // commonJS index.js @@ -14,8 +14,8 @@ assert.strictEqual(commonjs, 'commonjs'); assert.strictEqual(module, 'module'); assert.strictEqual(success, 'success'); assert.strictEqual(explicit, 'esm'); -assert.strictEqual(implicit, 'esm'); -assert.strictEqual(implicitModule, 'esm'); +assert.strictEqual(implicit, 'cjs'); +assert.strictEqual(implicitModule, 'cjs'); async function main() { try { diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js index 5d7af588fd65b7..06db4db1581b44 100644 --- a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js @@ -1 +1 @@ -export default 'nope'; +export default 'cjs'; From 2dc4da0d8bf85ce81921587de2b155cdf2b2cf5d Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Wed, 16 Oct 2019 13:47:02 -0400 Subject: [PATCH 09/33] build: build benchmark addons like test addons Build the addons for benchmarks in the same way that the addons for tests are built. PR-URL: https://github.com/nodejs/node/pull/29995 Fixes: https://github.com/nodejs/build/issues/1961 Refs: https://github.com/nodejs/node/commit/53ca0b9ae145c430842bf78e553e3b6cbd2823aa#commitcomment-35494896 Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott Reviewed-By: Beth Griggs Reviewed-By: Jiawen Geng --- Makefile | 36 ++++++++++++++--------------------- benchmark/napi/ref/.gitignore | 1 + 2 files changed, 15 insertions(+), 22 deletions(-) create mode 100644 benchmark/napi/ref/.gitignore diff --git a/Makefile b/Makefile index 87afe29b46828f..53dea85eb8f553 100644 --- a/Makefile +++ b/Makefile @@ -347,24 +347,6 @@ test-valgrind: all test-check-deopts: all $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) --check-deopts parallel sequential -benchmark/napi/function_call/build/$(BUILDTYPE)/binding.node: \ - benchmark/napi/function_call/napi_binding.c \ - benchmark/napi/function_call/binding.cc \ - benchmark/napi/function_call/binding.gyp | all - $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \ - --python="$(PYTHON)" \ - --directory="$(shell pwd)/benchmark/napi/function_call" \ - --nodedir="$(shell pwd)" - -benchmark/napi/function_args/build/$(BUILDTYPE)/binding.node: \ - benchmark/napi/function_args/napi_binding.c \ - benchmark/napi/function_args/binding.cc \ - benchmark/napi/function_args/binding.gyp | all - $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \ - --python="$(PYTHON)" \ - --directory="$(shell pwd)/benchmark/napi/function_args" \ - --nodedir="$(shell pwd)" - DOCBUILDSTAMP_PREREQS = tools/doc/addon-verify.js doc/api/addons.md ifeq ($(OSTYPE),aix) @@ -470,6 +452,17 @@ test/node-api/.buildstamp: $(ADDONS_PREREQS) \ # TODO(bnoordhuis) Force rebuild after gyp or node-gyp update. build-node-api-tests: | $(NODE_EXE) test/node-api/.buildstamp +BENCHMARK_NAPI_BINDING_GYPS := $(wildcard benchmark/napi/*/binding.gyp) + +BENCHMARK_NAPI_BINDING_SOURCES := \ + $(wildcard benchmark/napi/*/*.c) \ + $(wildcard benchmark/napi/*/*.cc) \ + $(wildcard benchmark/napi/*/*.h) + +benchmark/napi/.buildstamp: $(ADDONS_PREREQS) \ + $(BENCHMARK_NAPI_BINDING_GYPS) $(BENCHMARK_NAPI_BINDING_SOURCES) + @$(call run_build_addons,"$$PWD/benchmark/napi",$@) + .PHONY: clear-stalled clear-stalled: @echo "Clean up any leftover processes but don't error if found." @@ -1163,13 +1156,12 @@ bench: bench-addons-build # Build required addons for benchmark before running it. .PHONY: bench-addons-build -bench-addons-build: benchmark/napi/function_call/build/$(BUILDTYPE)/binding.node \ - benchmark/napi/function_args/build/$(BUILDTYPE)/binding.node +bench-addons-build: | $(NODE_EXE) benchmark/napi/.buildstamp .PHONY: bench-addons-clean bench-addons-clean: - $(RM) -r benchmark/napi/function_call/build - $(RM) -r benchmark/napi/function_args/build + $(RM) -r benchmark/napi/*/build + $(RM) benchmark/napi/.buildstamp .PHONY: lint-md-rollup lint-md-rollup: diff --git a/benchmark/napi/ref/.gitignore b/benchmark/napi/ref/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/benchmark/napi/ref/.gitignore @@ -0,0 +1 @@ +build/ From b92afcd90c3eea494a22397234dced6d1d8c4032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 14 Oct 2019 14:51:48 +0200 Subject: [PATCH 10/33] build: fix version checks in configure.py Fixes: https://github.com/nodejs/node/issues/29927 Refs: https://github.com/nodejs/node/pull/29931 PR-URL: https://github.com/nodejs/node/pull/29965 Reviewed-By: Richard Lau Reviewed-By: David Carlier Reviewed-By: Luigi Pinca Reviewed-By: Ben Noordhuis --- configure.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/configure.py b/configure.py index dd93d56e552526..7305727c8881e0 100755 --- a/configure.py +++ b/configure.py @@ -14,6 +14,7 @@ import bz2 from distutils.spawn import find_executable as which +from distutils.version import StrictVersion # If not run from node/, cd to node/. os.chdir(os.path.dirname(__file__) or '.') @@ -1231,10 +1232,10 @@ def without_ssl_error(option): # supported asm compiler for AVX2. See https://github.com/openssl/openssl/ # blob/OpenSSL_1_1_0-stable/crypto/modes/asm/aesni-gcm-x86_64.pl#L52-L69 openssl110_asm_supported = \ - ('gas_version' in variables and float(variables['gas_version']) >= 2.23) or \ - ('xcode_version' in variables and float(variables['xcode_version']) >= 5.0) or \ - ('llvm_version' in variables and float(variables['llvm_version']) >= 3.3) or \ - ('nasm_version' in variables and float(variables['nasm_version']) >= 2.10) + ('gas_version' in variables and StrictVersion(variables['gas_version']) >= StrictVersion('2.23')) or \ + ('xcode_version' in variables and StrictVersion(variables['xcode_version']) >= StrictVersion('5.0')) or \ + ('llvm_version' in variables and StrictVersion(variables['llvm_version']) >= StrictVersion('3.3')) or \ + ('nasm_version' in variables and StrictVersion(variables['nasm_version']) >= StrictVersion('2.10')) if is_x86 and not openssl110_asm_supported: error('''Did not find a new enough assembler, install one or build with From ff4f2999e69e0a9d205a5b6d96374e2a201628a1 Mon Sep 17 00:00:00 2001 From: akitsu-sanae Date: Tue, 15 Oct 2019 23:04:56 +0800 Subject: [PATCH 11/33] doc: fix tls version typo PR-URL: https://github.com/nodejs/node/pull/29984 Reviewed-By: Sam Roberts Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: Richard Lau Reviewed-By: Gireesh Punathil Reviewed-By: Trivikram Kamat --- doc/api/tls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/tls.md b/doc/api/tls.md index c2e169af3257f8..5529bd3529aecc 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1677,7 +1677,7 @@ added: v11.4.0 [`tls.createSecureContext()`][]. It can be assigned any of the supported TLS protocol versions, `'TLSv1.3'`, `'TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. **Default:** `'TLSv1.3'`, unless changed using CLI options. Using - `--tls-max-v1.2` sets the default to `'TLSv1.2`'. Using `--tls-max-v1.3` sets + `--tls-max-v1.2` sets the default to `'TLSv1.2'`. Using `--tls-max-v1.3` sets the default to `'TLSv1.3'`. If multiple of the options are provided, the highest maximum is used. @@ -1688,7 +1688,7 @@ added: v11.4.0 * {string} The default value of the `minVersion` option of [`tls.createSecureContext()`][]. It can be assigned any of the supported TLS - protocol versions, `'TLSv1.3'`, `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. + protocol versions, `'TLSv1.3'`, `'TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. **Default:** `'TLSv1.2'`, unless changed using CLI options. Using `--tls-min-v1.0` sets the default to `'TLSv1'`. Using `--tls-min-v1.1` sets the default to `'TLSv1.1'`. Using `--tls-min-v1.3` sets the default to From c096f251e46884d3809b00200662bd7363566d70 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 16 Oct 2019 09:39:14 -0700 Subject: [PATCH 12/33] test: remove common.skipIfInspectorEnabled() common.skipIfInspectorEnabled() is only used once in all of the tests. The test is more clear (in my opinion, at least) without the abstraction so put the check directly in the test. Additionally, it honestly looks like an error (which is how I noticed it in the first place) and that someone mistyped the far more common skipIfInspectorDisabled(). PR-URL: https://github.com/nodejs/node/pull/29993 Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Gireesh Punathil --- test/common/index.js | 7 ------- test/parallel/test-coverage-with-inspector-disabled.js | 4 +++- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/test/common/index.js b/test/common/index.js index 00ebd283a0c3e9..98a26872223cb9 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -651,12 +651,6 @@ function skipIfInspectorDisabled() { } } -function skipIfInspectorEnabled() { - if (process.features.inspector) { - skip('V8 inspector is enabled'); - } -} - function skipIfReportDisabled() { if (!process.config.variables.node_report) { skip('Diagnostic reporting is disabled'); @@ -789,7 +783,6 @@ module.exports = { skipIf32Bits, skipIfEslintMissing, skipIfInspectorDisabled, - skipIfInspectorEnabled, skipIfReportDisabled, skipIfWorker, diff --git a/test/parallel/test-coverage-with-inspector-disabled.js b/test/parallel/test-coverage-with-inspector-disabled.js index 0b0c2aea43fa60..f2ba070859527e 100644 --- a/test/parallel/test-coverage-with-inspector-disabled.js +++ b/test/parallel/test-coverage-with-inspector-disabled.js @@ -1,7 +1,9 @@ 'use strict'; const common = require('../common'); -common.skipIfInspectorEnabled(); +if (process.features.inspector) { + common.skip('V8 inspector is enabled'); +} const fixtures = require('../common/fixtures'); const assert = require('assert'); From ccf58835c70a2c70a7898980d574f89100c4b0fe Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 5 Sep 2019 15:56:12 +0200 Subject: [PATCH 13/33] build: use python3 to build and test on Travis Request Python 3 with pyenv and ensure that python3 is used by Makefile to run Python scripts. PR-URL: https://github.com/nodejs/node/pull/29451 Reviewed-By: Richard Lau Reviewed-By: Sam Roberts Reviewed-By: Rod Vagg --- .travis.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93456573438b1c..8aa321ec1626d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,13 +6,10 @@ x-ccache-setup-steps: &ccache-setup-steps os: linux language: cpp -# Currently this file can only support one PYTHON_VERSION. -# To experiment with Python 3, comment out Python 2.7 and uncomment one of the Python 3 versions. env: global: - - PYTHON_VERSION="2.7.15" - # - PYTHON_VERSION="3.6.7" - # - PYTHON_VERSION="3.7.1" + - PYTHON_VERSION="3.7.1" + - PYTHON=python3 jobs: include: - stage: "Compile" From b019ccd59d8f541005db8b219fe00c708174afe6 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Wed, 16 Oct 2019 15:37:40 -0700 Subject: [PATCH 14/33] src: initialize openssl only once For compatibility with OpenSSL 1.1.0 and 1.0.1 a series of initialization wrappers were being called, many deprecated, and many calling each other internally already. Compatibility is unnecessary in 12.x and later, which support only OpenSSL 1.1.1, and the multiple calls cause the configuration file to be loaded multiple times. Fixes: https://github.com/nodejs/node/issues/29702 See: - https://mta.openssl.org/pipermail/openssl-users/2019-October/011303.html - https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_init_ssl.html - https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_init_crypto.html PR-URL: https://github.com/nodejs/node/pull/29999 Reviewed-By: James M Snell Reviewed-By: Shelley Vohr --- src/node.cc | 7 ------- src/node_crypto.cc | 27 ++++++++------------------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/node.cc b/src/node.cc index 17963d0b11b297..5dbb837425d1f4 100644 --- a/src/node.cc +++ b/src/node.cc @@ -833,13 +833,6 @@ int InitializeNodeWithArgs(std::vector* argv, &default_env_options->redirect_warnings); } -#if HAVE_OPENSSL - std::string* openssl_config = &per_process::cli_options->openssl_config; - if (openssl_config->empty()) { - credentials::SafeGetenv("OPENSSL_CONF", openssl_config); - } -#endif - #if !defined(NODE_WITHOUT_NODE_OPTIONS) std::string node_options; diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 3405fbb5b45aa4..d2563c0fb5326b 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -6964,30 +6964,19 @@ void TimingSafeEqual(const FunctionCallbackInfo& args) { } void InitCryptoOnce() { - SSL_load_error_strings(); - OPENSSL_no_config(); +#ifndef OPENSSL_IS_BORINGSSL + OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); // --openssl-config=... if (!per_process::cli_options->openssl_config.empty()) { - OPENSSL_load_builtin_modules(); -#ifndef OPENSSL_NO_ENGINE - ENGINE_load_builtin_engines(); -#endif - ERR_clear_error(); - CONF_modules_load_file(per_process::cli_options->openssl_config.c_str(), - nullptr, - CONF_MFLAGS_DEFAULT_SECTION); - int err = ERR_get_error(); - if (0 != err) { - fprintf(stderr, - "openssl config failed: %s\n", - ERR_error_string(err, nullptr)); - CHECK_NE(err, 0); - } + const char* conf = per_process::cli_options->openssl_config.c_str(); + OPENSSL_INIT_set_config_filename(settings, conf); } - SSL_library_init(); - OpenSSL_add_all_algorithms(); + OPENSSL_init_ssl(0, settings); + OPENSSL_INIT_free(settings); + settings = nullptr; +#endif #ifdef NODE_FIPS_MODE /* Override FIPS settings in cnf file, if needed. */ From 029976750847a38f2117e12cacfaf3366831c87e Mon Sep 17 00:00:00 2001 From: Minwoo Jung Date: Thu, 17 Oct 2019 21:12:09 +0900 Subject: [PATCH 15/33] doc: update collaborator email address update collaborator email address PR-URL: https://github.com/nodejs/node/pull/30007 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- .mailmap | 4 +++- README.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index 127e1782b394a2..6d7e00af1a482f 100644 --- a/.mailmap +++ b/.mailmap @@ -270,7 +270,9 @@ Miguel Angel Asencio Hurtado maasencioh Mike Kaufman Minqi Pan P.S.V.R -Minwoo Jung JungMinu +Minwoo Jung JungMinu +Minwoo Jung +Minwoo Jung Miroslav Bajtoš Mitar Milutinovic Myles Borins diff --git a/README.md b/README.md index 8bc15d76e1d10c..c46aac2a42cab4 100644 --- a/README.md +++ b/README.md @@ -345,7 +345,7 @@ For information about the governance of the Node.js project, see * [julianduque](https://github.com/julianduque) - **Julian Duque** <julianduquej@gmail.com> (he/him) * [JungMinu](https://github.com/JungMinu) - -**Minwoo Jung** <minwoo@nodesource.com> (he/him) +**Minwoo Jung** <nodecorelab@gmail.com> (he/him) * [kfarnung](https://github.com/kfarnung) - **Kyle Farnung** <kfarnung@microsoft.com> (he/him) * [kunalspathak](https://github.com/kunalspathak) - From e110d81b17756f6f06ad41bfc026e3ece9f839d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 18 Oct 2019 11:56:21 +0200 Subject: [PATCH 16/33] test: fix test runner for Python 3 on Windows Explicitly open files with utf8 encoding, otherwise the system could use another encoding such as latin1 by default. PR-URL: https://github.com/nodejs/node/pull/30023 Reviewed-By: Richard Lau Reviewed-By: Christian Clauss Reviewed-By: Luigi Pinca --- test/testpy/__init__.py | 3 ++- tools/test.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/testpy/__init__.py b/test/testpy/__init__.py index 9c70e18d6a1291..c89ab6e8b576f4 100644 --- a/test/testpy/__init__.py +++ b/test/testpy/__init__.py @@ -29,6 +29,7 @@ import os import re from functools import reduce +from io import open FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") @@ -56,7 +57,7 @@ def GetName(self): def GetCommand(self): result = [self.config.context.GetVm(self.arch, self.mode)] - source = open(self.file).read() + source = open(self.file, encoding='utf8').read() flags_match = FLAGS_PATTERN.search(source) if flags_match: flags = flags_match.group(1).strip().split() diff --git a/tools/test.py b/tools/test.py index 878e2bef35da46..04babded24b590 100755 --- a/tools/test.py +++ b/tools/test.py @@ -45,6 +45,7 @@ import errno import copy +from io import open from os.path import join, dirname, abspath, basename, isdir, exists from datetime import datetime try: @@ -733,8 +734,8 @@ def disableCoreFiles(): ) os.close(fd_out) os.close(fd_err) - output = open(outname).read() - errors = open(errname).read() + output = open(outname, encoding='utf8').read() + errors = open(errname, encoding='utf8').read() CheckedUnlink(outname) CheckedUnlink(errname) From e04d0584a510e5c58d4b1a1477534202173b90ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 18 Oct 2019 11:04:35 +0200 Subject: [PATCH 17/33] build: default Windows build to Visual Studio 2019 Building and testing Node.js with Visual Studio 2019 is now working as expected. Fallback to VS 2017 if VS 2019 was not found. Fixes: https://github.com/nodejs/node/issues/27214 PR-URL: https://github.com/nodejs/node/pull/30022 Reviewed-By: Jiawen Geng Reviewed-By: Richard Lau Reviewed-By: Beth Griggs --- BUILDING.md | 9 ++++---- vcbuild.bat | 64 ++++++++++++++++++++++++++--------------------------- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index aadba46020012d..006c21521df1f5 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -498,9 +498,9 @@ $ backtrace * [Python 2.7](https://www.python.org/downloads/) * The "Desktop development with C++" workload from - [Visual Studio 2017](https://www.visualstudio.com/downloads/) or the - "Visual C++ build tools" workload from the - [Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017), + [Visual Studio 2017 or 2019](https://visualstudio.microsoft.com/downloads/) or + the "Visual C++ build tools" workload from the + [Build Tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019), with the default optional components. * Basic Unix tools required for some tests, [Git for Windows](https://git-scm.com/download/win) includes Git Bash @@ -513,7 +513,8 @@ $ backtrace Optional requirements to build the MSI installer package: * The [WiX Toolset v3.11](https://wixtoolset.org/releases/) and the - [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension). + [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension) + or the [Wix Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2019Extension). Optional requirements for compiling for Windows 10 on ARM (ARM64): diff --git a/vcbuild.bat b/vcbuild.bat index 7613bd8b5ab129..5ddc04aeb25a4a 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -236,26 +236,26 @@ if %target_arch%==x64 if %msvs_host_arch%==amd64 set vcvarsall_arg=amd64 @rem also if both are x86 if %target_arch%==x86 if %msvs_host_arch%==x86 set vcvarsall_arg=x86 -@rem Look for Visual Studio 2017 -:vs-set-2017 -if defined target_env if "%target_env%" NEQ "vs2017" goto vs-set-2019 -echo Looking for Visual Studio 2017 -call tools\msvs\vswhere_usability_wrapper.cmd "[15.0,16.0)" -if "_%VCINSTALLDIR%_" == "__" goto msbuild-not-found +@rem Look for Visual Studio 2019 +:vs-set-2019 +if defined target_env if "%target_env%" NEQ "vs2019" goto vs-set-2017 +echo Looking for Visual Studio 2019 +call tools\msvs\vswhere_usability_wrapper.cmd "[16.0,17.0)" +if "_%VCINSTALLDIR%_" == "__" goto vs-set-2017 if defined msi ( - echo Looking for WiX installation for Visual Studio 2017... + echo Looking for WiX installation for Visual Studio 2019... if not exist "%WIX%\SDK\VS2017" ( - echo Failed to find WiX install for Visual Studio 2017 - echo VS2017 support for WiX is only present starting at version 3.11 - goto msbuild-not-found + echo Failed to find WiX install for Visual Studio 2019 + echo VS2019 support for WiX is only present starting at version 3.11 + goto vs-set-2017 ) if not exist "%VCINSTALLDIR%\..\MSBuild\Microsoft\WiX" ( - echo Failed to find the WiX Toolset Visual Studio 2017 Extension - goto msbuild-not-found + echo Failed to find the WiX Toolset Visual Studio 2019 Extension + goto vs-set-2017 ) ) -@rem check if VS2017 is already setup, and for the requested arch -if "_%VisualStudioVersion%_" == "_15.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2017 +@rem check if VS2019 is already setup, and for the requested arch +if "_%VisualStudioVersion%_" == "_16.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2019 @rem need to clear VSINSTALLDIR for vcvarsall to work as expected set "VSINSTALLDIR=" @rem prevent VsDevCmd.bat from changing the current working directory @@ -263,34 +263,34 @@ set "VSCMD_START_DIR=%CD%" set vcvars_call="%VCINSTALLDIR%\Auxiliary\Build\vcvarsall.bat" %vcvarsall_arg% echo calling: %vcvars_call% call %vcvars_call% -if errorlevel 1 goto msbuild-not-found +if errorlevel 1 goto vs-set-2017 if defined DEBUG_HELPER @ECHO ON -:found_vs2017 +:found_vs2019 echo Found MSVS version %VisualStudioVersion% -set GYP_MSVS_VERSION=2017 -set PLATFORM_TOOLSET=v141 +set GYP_MSVS_VERSION=2019 +set PLATFORM_TOOLSET=v142 goto msbuild-found -@rem Look for Visual Studio 2019 -:vs-set-2019 -if defined target_env if "%target_env%" NEQ "vs2019" goto msbuild-not-found -echo Looking for Visual Studio 2019 -call tools\msvs\vswhere_usability_wrapper.cmd "[16.0,17.0)" +@rem Look for Visual Studio 2017 +:vs-set-2017 +if defined target_env if "%target_env%" NEQ "vs2017" goto msbuild-not-found +echo Looking for Visual Studio 2017 +call tools\msvs\vswhere_usability_wrapper.cmd "[15.0,16.0)" if "_%VCINSTALLDIR%_" == "__" goto msbuild-not-found if defined msi ( - echo Looking for WiX installation for Visual Studio 2019... + echo Looking for WiX installation for Visual Studio 2017... if not exist "%WIX%\SDK\VS2017" ( - echo Failed to find WiX install for Visual Studio 2019 - echo VS2019 support for WiX is only present starting at version 3.11 + echo Failed to find WiX install for Visual Studio 2017 + echo VS2017 support for WiX is only present starting at version 3.11 goto msbuild-not-found ) if not exist "%VCINSTALLDIR%\..\MSBuild\Microsoft\WiX" ( - echo Failed to find the WiX Toolset Visual Studio 2019 Extension + echo Failed to find the WiX Toolset Visual Studio 2017 Extension goto msbuild-not-found ) ) -@rem check if VS2019 is already setup, and for the requested arch -if "_%VisualStudioVersion%_" == "_16.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2019 +@rem check if VS2017 is already setup, and for the requested arch +if "_%VisualStudioVersion%_" == "_15.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2017 @rem need to clear VSINSTALLDIR for vcvarsall to work as expected set "VSINSTALLDIR=" @rem prevent VsDevCmd.bat from changing the current working directory @@ -300,10 +300,10 @@ echo calling: %vcvars_call% call %vcvars_call% if errorlevel 1 goto msbuild-not-found if defined DEBUG_HELPER @ECHO ON -:found_vs2019 +:found_vs2017 echo Found MSVS version %VisualStudioVersion% -set GYP_MSVS_VERSION=2019 -set PLATFORM_TOOLSET=v142 +set GYP_MSVS_VERSION=2017 +set PLATFORM_TOOLSET=v141 goto msbuild-found :msbuild-not-found From a25d2fcf8b1cc72a2938e3f47304a4b886f5617c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 18 Oct 2019 11:18:28 +0200 Subject: [PATCH 18/33] build: make configure --without-snapshot a no-op From V8 7.9, the option will no longer exist upstream. Refs: https://chromium-review.googlesource.com/c/chromium/src/+/1796325 PR-URL: https://github.com/nodejs/node/pull/30021 Reviewed-By: Joyee Cheung Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca --- configure.py | 13 ++++++------- node.gyp | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/configure.py b/configure.py index 7305727c8881e0..f1badfdb932bb9 100755 --- a/configure.py +++ b/configure.py @@ -507,7 +507,7 @@ parser.add_option('--without-snapshot', action='store_true', - dest='without_snapshot', + dest='unused_without_snapshot', help=optparse.SUPPRESS_HELP) parser.add_option('--without-siphash', @@ -967,13 +967,13 @@ def configure_node(o): cross_compiling = (options.cross_compiling if options.cross_compiling is not None else target_arch != host_arch) - want_snapshots = not options.without_snapshot - o['variables']['want_separate_host_toolset'] = int( - cross_compiling and want_snapshots) + if options.unused_without_snapshot: + warn('building --without-snapshot is no longer possible') + + o['variables']['want_separate_host_toolset'] = int(cross_compiling) if not options.without_node_snapshot: - o['variables']['node_use_node_snapshot'] = b( - not cross_compiling and want_snapshots) + o['variables']['node_use_node_snapshot'] = b(not cross_compiling) else: o['variables']['node_use_node_snapshot'] = 'false' @@ -1177,7 +1177,6 @@ def configure_v8(o): o['variables']['v8_random_seed'] = 0 # Use a random seed for hash tables. o['variables']['v8_promise_internal_field_count'] = 1 # Add internal field to promises for async hooks. o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1 - o['variables']['v8_use_snapshot'] = 0 if options.without_snapshot else 1 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) diff --git a/node.gyp b/node.gyp index 9bf8fa2b994da1..ecdecb05f4da8f 100644 --- a/node.gyp +++ b/node.gyp @@ -1,7 +1,7 @@ { 'variables': { 'v8_use_siphash%': 0, - 'v8_use_snapshot%': 0, + 'v8_use_snapshot%': 1, 'v8_trace_maps%': 0, 'node_use_dtrace%': 'false', 'node_use_etw%': 'false', From 9d332ab4cee8e95d6df753a0ca1bbe9c5b798651 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sat, 19 Oct 2019 16:46:32 -0500 Subject: [PATCH 19/33] deps: upgrade to libuv 1.33.1 Notable changes: - uv_random() has been added. - More work to read those pesky Windows environment variables. - Several build fixes for Tier 3 platforms (Android, NetBSD, OpenBSD, Haiku). - Stop using fsevents to watch files (using kqueue again). PR-URL: https://github.com/nodejs/node/pull/29996 Reviewed-By: Richard Lau Reviewed-By: Anna Henningsen Reviewed-By: David Carlier Reviewed-By: Trivikram Kamat Reviewed-By: Jiawen Geng Reviewed-By: James M Snell Reviewed-By: Gireesh Punathil --- deps/uv/AUTHORS | 8 ++ deps/uv/CMakeLists.txt | 42 ++++-- deps/uv/ChangeLog | 80 +++++++++++ deps/uv/Makefile.am | 18 ++- deps/uv/SUPPORTED_PLATFORMS.md | 7 +- deps/uv/configure.ac | 4 +- deps/uv/docs/src/fs.rst | 14 +- deps/uv/docs/src/handle.rst | 14 +- deps/uv/docs/src/misc.rst | 45 ++++++ deps/uv/docs/src/tty.rst | 39 ++++++ deps/uv/include/uv.h | 41 ++++++ deps/uv/include/uv/version.h | 4 +- deps/uv/src/random.c | 121 ++++++++++++++++ deps/uv/src/threadpool.c | 4 + deps/uv/src/unix/android-ifaddrs.c | 2 + deps/uv/src/unix/bsd-ifaddrs.c | 2 + deps/uv/src/unix/core.c | 6 +- deps/uv/src/unix/darwin-proctitle.c | 139 +++++++++---------- deps/uv/src/unix/fs.c | 30 ++-- deps/uv/src/unix/fsevents.c | 6 +- deps/uv/src/unix/internal.h | 6 + deps/uv/src/unix/kqueue.c | 44 +++--- deps/uv/src/unix/linux-core.c | 53 +++++-- deps/uv/src/unix/linux-syscalls.c | 25 ++++ deps/uv/src/unix/linux-syscalls.h | 1 + deps/uv/src/unix/openbsd.c | 2 +- deps/uv/src/unix/pipe.c | 2 +- deps/uv/src/unix/proctitle.c | 4 + deps/uv/src/unix/random-devurandom.c | 93 +++++++++++++ deps/uv/src/unix/random-getentropy.c | 57 ++++++++ deps/uv/src/unix/random-getrandom.c | 88 ++++++++++++ deps/uv/src/unix/random-sysctl.c | 100 +++++++++++++ deps/uv/src/unix/tty.c | 7 + deps/uv/src/unix/udp.c | 22 +-- deps/uv/src/uv-common.c | 3 + deps/uv/src/win/fs.c | 17 +-- deps/uv/src/win/internal.h | 2 + deps/uv/src/win/tcp.c | 2 +- deps/uv/src/win/tty.c | 44 +++--- deps/uv/src/win/udp.c | 2 +- deps/uv/src/win/util.c | 17 ++- deps/uv/src/win/winapi.c | 11 ++ deps/uv/src/win/winapi.h | 8 ++ deps/uv/src/win/winsock.h | 8 ++ deps/uv/test/test-env-vars.c | 8 +- deps/uv/test/test-fs-copyfile.c | 2 +- deps/uv/test/test-fs-event.c | 72 +++++++--- deps/uv/test/test-fs-readdir.c | 2 +- deps/uv/test/test-ip4-addr.c | 4 + deps/uv/test/test-ip6-addr.c | 9 ++ deps/uv/test/test-list.h | 8 ++ deps/uv/test/test-process-title-threadsafe.c | 6 +- deps/uv/test/test-random.c | 94 +++++++++++++ deps/uv/test/test-threadpool-cancel.c | 41 ++++++ deps/uv/test/test-udp-multicast-join.c | 2 +- deps/uv/test/test-udp-multicast-join6.c | 4 +- deps/uv/test/test.gyp | 4 +- deps/uv/uv.gyp | 15 +- 58 files changed, 1282 insertions(+), 233 deletions(-) create mode 100644 deps/uv/src/random.c create mode 100644 deps/uv/src/unix/random-devurandom.c create mode 100644 deps/uv/src/unix/random-getentropy.c create mode 100644 deps/uv/src/unix/random-getrandom.c create mode 100644 deps/uv/src/unix/random-sysctl.c create mode 100644 deps/uv/test/test-random.c diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 8c3d342d33e6f8..408cfd6541a339 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -403,3 +403,11 @@ Vladimir Karnushin MaYuming Eneas U de Queiroz Daniel Hahler +Yang Yu +David Carlier +Calvin Hill +Isabella Muerte <63051+slurps-mad-rips@users.noreply.github.com> +Ouyang Yadong +ZYSzys +Carl Lei +Stefan Bender diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt index 6f18f3397d0129..7da5e688166c04 100644 --- a/deps/uv/CMakeLists.txt +++ b/deps/uv/CMakeLists.txt @@ -1,6 +1,15 @@ # TODO: determine CMAKE_SYSTEM_NAME on OS/390. Currently assumes "OS/390". -cmake_minimum_required(VERSION 2.8.12) -project(libuv) +cmake_minimum_required(VERSION 3.4) +project(libuv LANGUAGES C) + +include(CMakePackageConfigHelpers) +include(CMakeDependentOption) +include(GNUInstallDirs) +include(CTest) + +cmake_dependent_option(LIBUV_BUILD_TESTS + "Build the unit tests when BUILD_TESTING is enabled and we are the root project" ON + "BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) if(MSVC) list(APPEND uv_cflags /W4) @@ -14,6 +23,7 @@ set(uv_sources src/fs-poll.c src/idna.c src/inet.c + src/random.c src/strscpy.c src/threadpool.c src/timer.c @@ -72,7 +82,6 @@ set(uv_test_sources test/test-idna.c test/test-ip4-addr.c test/test-ip6-addr.c - test/test-ip6-addr.c test/test-ipc-heavy-traffic-deadlock-bug.c test/test-ipc-send-recv.c test/test-ipc.c @@ -108,6 +117,7 @@ set(uv_test_sources test/test-process-title-threadsafe.c test/test-process-title.c test/test-queue-foreach-delete.c + test/test-random.c test/test-ref.c test/test-run-nowait.c test/test-run-once.c @@ -236,6 +246,7 @@ else() src/unix/pipe.c src/unix/poll.c src/unix/process.c + src/unix/random-devurandom.c src/unix/signal.c src/unix/stream.c src/unix/tcp.c @@ -284,6 +295,14 @@ if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD") list(APPEND uv_sources src/unix/bsd-ifaddrs.c src/unix/kqueue.c) endif() +if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND uv_sources src/unix/random-getrandom.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + list(APPEND uv_sources src/unix/random-getentropy.c) +endif() + if(APPLE) list(APPEND uv_defines _DARWIN_UNLIMITED_SELECT=1 _DARWIN_USE_64_BIT_INODE=1) list(APPEND uv_sources @@ -300,6 +319,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") src/unix/linux-inotify.c src/unix/linux-syscalls.c src/unix/procfs-exepath.c + src/unix/random-getrandom.c + src/unix/random-sysctl.c src/unix/sysinfo-loadavg.c) endif() @@ -356,11 +377,7 @@ target_compile_options(uv_a PRIVATE ${uv_cflags}) target_include_directories(uv_a PUBLIC include PRIVATE src) target_link_libraries(uv_a ${uv_libraries}) -option(libuv_buildtests "Build the unit tests when BUILD_TESTING is enabled." ON) - -include(CTest) -if(BUILD_TESTING AND libuv_buildtests) - enable_testing() +if(LIBUV_BUILD_TESTS) add_executable(uv_run_tests ${uv_test_sources}) target_compile_definitions(uv_run_tests PRIVATE ${uv_defines} USING_UV_SHARED=1) @@ -380,7 +397,6 @@ endif() if(UNIX) # Now for some gibbering horrors from beyond the stars... - include(GNUInstallDirs) foreach(x ${uv_libraries}) set(LIBS "${LIBS} -l${x}") endforeach(x) @@ -402,3 +418,11 @@ if(UNIX) install(TARGETS uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() + +if(WIN32) + install(DIRECTORY include/ DESTINATION include) + install(FILES LICENSE DESTINATION .) + install(TARGETS uv uv_a + RUNTIME DESTINATION lib/$ + ARCHIVE DESTINATION lib/$) +endif() diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 093579de8e4985..cd4451ae69c0c1 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,83 @@ +2019.10.20, Version 1.33.1 (Stable), 07ad32138f4d2285ba2226b5e20462b27b091a59 + +Changes since version 1.33.0: + +* linux: fix arm64 SYS__sysctl build breakage (Ben Noordhuis) + + +2019.10.17, Version 1.33.0 (Stable), e56e42e9310e4437e1886dbd6771792c14c0a5f3 + +Changes since version 1.32.0: + +* Revert "linux: drop code path for epoll_pwait-less kernels" (Yang Yu) + +* build: fix build error with __ANDROID_API__ < 21 (Yang Yu) + +* win: fix reading hidden env vars (Anna Henningsen) + +* unix,win: add uv_random() (Ben Noordhuis) + +* win: simplify mkdtemp (Saúl Ibarra Corretgé) + +* docs: fix literal-includes in User Guide (Nhan Khong) + +* win, tty: fix problem of receiving unexpected SIGWINCH (erw7) + +* unix: fix {Net,Open}BSD build (David Carlier) + +* win,mingw: Fix undefined MCAST_* constants (Crunkle) + +* build: Add link for test/fixtures/lorem_ipsum.txt (Andrew Paprocki) + +* fs: use statvfs in uv__fs_statfs() for Haiku (Calvin Hill) + +* fsevents: stop using fsevents to watch files (Jameson Nash) + +* fsevents: regression in watching / (Jameson Nash) + +* build,cmake: don't try to detect a C++ compiler (Isabella Muerte) + +* build: fix build warning on cygwin (MaYuming) + +* unix: set sin_len and sin6_len (Ouyang Yadong) + +* test: fix order of operations in test (cjihrig) + +* doc: improve uv_fs_readdir() cleanup docs (cjihrig) + +* build: remove duplicated test in build files (ZYSzys) + +* android: enable getentropy on Android >= 28 (David Carlier) + +* android: fix build (David Carlier) + +* darwin: speed up uv_set_process_title() (Ben Noordhuis) + +* darwin: assume pthread_setname_np() is available (Ben Noordhuis) + +* unix,udp: ensure addr is non-null (Jameson Nash) + +* win,tty: add uv_tty_{get,set}_vterm_state (erw7) + +* win: fix uv_statfs_t leak in uv_fs_statfs() (Ryan Liptak) + +* build: install files on windows via cmake (Carl Lei) + +* darwin,test: include AvailabilityMacros.h (Saúl Ibarra Corretgé) + +* darwin,test: update loop time after sleeping (Saúl Ibarra Corretgé) + +* doc: remove old FreeBSD 9 related note (Saúl Ibarra Corretgé) + +* doc: improve uv_{send,recv}_buffer_size() docs (Ryan Liptak) + +* build: move -Wno-long-long check to configure time (Ben Noordhuis) + +* unix: update uv_fs_copyfile() fallback logic (Stefan Bender) + +* win: cast setsockopt struct to const char* (Shelley Vohr) + + 2019.09.10, Version 1.32.0 (Stable), 697bea87b3a0b0e9b4e5ff86b39d1dedb70ee46d Changes since version 1.31.0: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 099b0efb084343..ce4ca274b217ee 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -35,6 +35,7 @@ libuv_la_SOURCES = src/fs-poll.c \ src/idna.h \ src/inet.c \ src/queue.h \ + src/random.c \ src/strscpy.c \ src/strscpy.h \ src/threadpool.c \ @@ -105,6 +106,7 @@ libuv_la_SOURCES += src/unix/async.c \ src/unix/pipe.c \ src/unix/poll.c \ src/unix/process.c \ + src/unix/random-devurandom.c \ src/unix/signal.c \ src/unix/spinlock.h \ src/unix/stream.c \ @@ -138,11 +140,7 @@ EXTRA_DIST = test/fixtures/empty_file \ TESTS = test/run-tests check_PROGRAMS = test/run-tests -if OS390 test_run_tests_CFLAGS = -else -test_run_tests_CFLAGS = -Wno-long-long -endif if SUNOS # Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers @@ -240,6 +238,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-process-title.c \ test/test-process-title-threadsafe.c \ test/test-queue-foreach-delete.c \ + test/test-random.c \ test/test-ref.c \ test/test-run-nowait.c \ test/test-run-once.c \ @@ -414,7 +413,8 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/darwin-proctitle.c \ src/unix/fsevents.c \ src/unix/kqueue.c \ - src/unix/proctitle.c + src/unix/proctitle.c \ + src/unix/random-getentropy.c test_run_tests_LDFLAGS += -lutil endif @@ -434,7 +434,8 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/bsd-proctitle.c \ src/unix/freebsd.c \ src/unix/kqueue.c \ - src/unix/posix-hrtime.c + src/unix/posix-hrtime.c \ + src/unix/random-getrandom.c test_run_tests_LDFLAGS += -lutil endif @@ -465,6 +466,8 @@ libuv_la_SOURCES += src/unix/linux-core.c \ src/unix/linux-syscalls.h \ src/unix/procfs-exepath.c \ src/unix/proctitle.c \ + src/unix/random-getrandom.c \ + src/unix/random-sysctl.c \ src/unix/sysinfo-loadavg.c test_run_tests_LDFLAGS += -lutil endif @@ -498,7 +501,8 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/bsd-proctitle.c \ src/unix/kqueue.c \ src/unix/openbsd.c \ - src/unix/posix-hrtime.c + src/unix/posix-hrtime.c \ + src/unix/random-getentropy.c test_run_tests_LDFLAGS += -lutil endif diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index 077191086ce524..29e4844ff323d3 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -5,7 +5,7 @@ | GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | | macOS | Tier 1 | macOS >= 10.7 | | | Windows | Tier 1 | >= Windows 7 | MSVC 2008 and later are supported | -| FreeBSD | Tier 1 | >= 9 (see note) | | +| FreeBSD | Tier 1 | >= 10 | | | AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix | | z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos | | Linux with musl | Tier 2 | musl >= 1.0 | | @@ -16,11 +16,6 @@ | SunOS | Tier 3 | Solaris 121 and later | | | Other | Tier 3 | N/A | | -#### Note on FreeBSD 9 - -While FreeBSD is supported as Tier 1, FreeBSD 9 will get Tier 2 support until -it reaches end of life, in December 2016. - ## Support types * **Tier 1**: Officially supported and tested with CI. Any contributed patch diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index b503e538298dd9..07ad0cde81a656 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.32.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.33.1], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) @@ -32,6 +32,7 @@ CC_CHECK_CFLAGS_APPEND([-g]) CC_CHECK_CFLAGS_APPEND([-std=gnu89]) CC_CHECK_CFLAGS_APPEND([-Wall]) CC_CHECK_CFLAGS_APPEND([-Wextra]) +CC_CHECK_CFLAGS_APPEND([-Wno-long-long]) CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter]) CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes]) # AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12. @@ -80,4 +81,5 @@ AC_CHECK_HEADERS([sys/ahafs_evProds.h]) AC_CONFIG_FILES([Makefile libuv.pc]) AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file]) AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node]) +AC_CONFIG_LINKS([test/fixtures/lorem_ipsum.txt:test/fixtures/lorem_ipsum.txt]) AC_OUTPUT diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index aabe49b3f3a981..dc16ff08e65a93 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -295,7 +295,8 @@ API .. note:: On success this function allocates memory that must be freed using - `uv_fs_req_cleanup()`. + `uv_fs_req_cleanup()`. `uv_fs_req_cleanup()` must be called before + closing the directory with `uv_fs_closedir()`. .. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) .. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) @@ -358,10 +359,13 @@ API is to overwrite the destination if it exists. - `UV_FS_COPYFILE_FICLONE`: If present, `uv_fs_copyfile()` will attempt to create a copy-on-write reflink. If the underlying platform does not - support copy-on-write, then a fallback copy mechanism is used. + support copy-on-write, or an error occurs while attempting to use + copy-on-write, a fallback copy mechanism based on + :c:func:`uv_fs_sendfile()` is used. - `UV_FS_COPYFILE_FICLONE_FORCE`: If present, `uv_fs_copyfile()` will attempt to create a copy-on-write reflink. If the underlying platform does - not support copy-on-write, then an error is returned. + not support copy-on-write, or an error occurs while attempting to use + copy-on-write, then an error is returned. .. warning:: If the destination path is created, but an error occurs while copying @@ -374,6 +378,10 @@ API .. versionchanged:: 1.20.0 `UV_FS_COPYFILE_FICLONE` and `UV_FS_COPYFILE_FICLONE_FORCE` are supported. + .. versionchanged:: 1.33.0 If an error occurs while using + `UV_FS_COPYFILE_FICLONE_FORCE`, that error is returned. Previously, + all errors were mapped to `UV_ENOTSUP`. + .. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) Limited equivalent to :man:`sendfile(2)`. diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst index 0a25bfa8b27dd1..943c51d94ba6c4 100644 --- a/deps/uv/docs/src/handle.rst +++ b/deps/uv/docs/src/handle.rst @@ -190,8 +190,11 @@ just for some handle types. Gets or sets the size of the send buffer that the operating system uses for the socket. - If `*value` == 0, it will return the current send buffer size, - otherwise it will use `*value` to set the new send buffer size. + If `*value` == 0, then it will set `*value` to the current send buffer size. + If `*value` > 0 then it will use `*value` to set the new send buffer size. + + On success, zero is returned. On error, a negative result is + returned. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows. @@ -204,8 +207,11 @@ just for some handle types. Gets or sets the size of the receive buffer that the operating system uses for the socket. - If `*value` == 0, it will return the current receive buffer size, - otherwise it will use `*value` to set the new receive buffer size. + If `*value` == 0, then it will set `*value` to the current receive buffer size. + If `*value` > 0 then it will use `*value` to set the new receive buffer size. + + On success, zero is returned. On error, a negative result is + returned. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows. diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 3ecfce486c4da2..8e167e3ec4ec1d 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -46,6 +46,12 @@ Data types Replacement function for :man:`free(3)`. See :c:func:`uv_replace_allocator`. +.. c:type:: void (*uv_random_cb)(uv_random_t* req, int status, void* buf, size_t buflen) + + Callback passed to :c:func:`uv_random`. `status` is non-zero in case of + error. The `buf` pointer is the same pointer that was passed to + :c:func:`uv_random`. + .. c:type:: uv_file Cross platform representation of a file handle. @@ -191,6 +197,9 @@ Data types char* value; } uv_env_item_t; +.. c:type:: uv_random_t + + Random data request type. API --- @@ -648,3 +657,39 @@ API argument to `gettimeofday()` is not supported, as it is considered obsolete. .. versionadded:: 1.28.0 + +.. c:function:: int uv_random(uv_loop_t* loop, uv_random_t* req, void* buf, size_t buflen, unsigned int flags, uv_random_cb cb) + + Fill `buf` with exactly `buflen` cryptographically strong random bytes + acquired from the system CSPRNG. `flags` is reserved for future extension + and must currently be 0. + + Short reads are not possible. When less than `buflen` random bytes are + available, a non-zero error value is returned or passed to the callback. + + The synchronous version may block indefinitely when not enough entropy + is available. The asynchronous version may not ever finish when the system + is low on entropy. + + Sources of entropy: + + - Windows: `RtlGenRandom _`. + - Linux, Android: :man:`getrandom(2)` if available, or :man:`urandom(4)` + after reading from `/dev/random` once, or the `KERN_RANDOM` + :man:`sysctl(2)`. + - FreeBSD: `getrandom(2) _`, + or `/dev/urandom` after reading from `/dev/random` once. + - macOS, OpenBSD: `getentropy(2) _` + if available, or `/dev/urandom` after reading from `/dev/random` once. + - AIX: `/dev/random`. + - IBM i: `/dev/urandom`. + - Other UNIX: `/dev/urandom` after reading from `/dev/random` once. + + :returns: 0 on success, or an error code < 0 on failure. The contents of + `buf` is undefined after an error. + + .. note:: + When using the synchronous version, both `loop` and `req` parameters + are not used and can be set to `NULL`. + + .. versionadded:: 1.33.0 diff --git a/deps/uv/docs/src/tty.rst b/deps/uv/docs/src/tty.rst index 9889a0a0b6465b..ad379dab0dd001 100644 --- a/deps/uv/docs/src/tty.rst +++ b/deps/uv/docs/src/tty.rst @@ -33,6 +33,23 @@ Data types UV_TTY_MODE_IO } uv_tty_mode_t; +.. c:type:: uv_tty_vtermstate_t + Console virtual terminal mode type: + + :: + + typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process virtual terminal sequences. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED + } uv_tty_vtermstate_t + Public members @@ -98,3 +115,25 @@ API Gets the current Window size. On success it returns 0. .. seealso:: The :c:type:`uv_stream_t` API functions also apply. + +.. c:function:: void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) + + Controls whether console virtual terminal sequences are processed by libuv + or console. + Useful in particular for enabling ConEmu support of ANSI X3.64 and Xterm + 256 colors. Otherwise Windows10 consoles are usually detected automatically. + + This function is only meaningful on Windows systems. On Unix it is silently + ignored. + + .. versionadded:: 1.33.0 + +.. c:function:: int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) + + Get the current state of whether console virtual terminal sequences are + handled by libuv or the console. + + This function is not implemented on Unix, where it returns ``UV_ENOTSUP``. + + .. versionadded:: 1.33.0 + diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index ee45bcaefce1d3..0e8132e4384be0 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -177,6 +177,7 @@ extern "C" { XX(WORK, work) \ XX(GETADDRINFO, getaddrinfo) \ XX(GETNAMEINFO, getnameinfo) \ + XX(RANDOM, random) \ typedef enum { #define XX(code, _) UV_ ## code = UV__ ## code, @@ -234,6 +235,7 @@ typedef struct uv_connect_s uv_connect_t; typedef struct uv_udp_send_s uv_udp_send_t; typedef struct uv_fs_s uv_fs_t; typedef struct uv_work_s uv_work_t; +typedef struct uv_random_s uv_random_t; /* None of the above. */ typedef struct uv_env_item_s uv_env_item_t; @@ -330,6 +332,10 @@ typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service); +typedef void (*uv_random_cb)(uv_random_t* req, + int status, + void* buf, + size_t buflen); typedef struct { long tv_sec; @@ -700,10 +706,25 @@ typedef enum { UV_TTY_MODE_IO } uv_tty_mode_t; +typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process the virtual terminal sequence. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED +} uv_tty_vtermstate_t; + + UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode); UV_EXTERN int uv_tty_reset_mode(void); UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); +UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state); +UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state); #ifdef __cplusplus extern "C++" { @@ -1574,6 +1595,26 @@ UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); + +struct uv_random_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* private */ + int status; + void* buf; + size_t buflen; + uv_random_cb cb; + struct uv__work work_req; +}; + +UV_EXTERN int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, /* For future extension; must be 0. */ + uv_random_cb cb); + #if defined(IF_NAMESIZE) # define UV_IF_NAMESIZE (IF_NAMESIZE + 1) #elif defined(IFNAMSIZ) diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h index 928647b8200502..ca94be6dd4fba6 100644 --- a/deps/uv/include/uv/version.h +++ b/deps/uv/include/uv/version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 32 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_MINOR 33 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/src/random.c b/deps/uv/src/random.c new file mode 100644 index 00000000000000..8c4fe32013dc9a --- /dev/null +++ b/deps/uv/src/random.c @@ -0,0 +1,121 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv-common.h" + +#ifdef _WIN32 +# include "win/internal.h" +#else +# include "unix/internal.h" +#endif + +static int uv__random(void* buf, size_t buflen) { + int rc; + +#if defined(__PASE__) + rc = uv__random_readpath("/dev/urandom", buf, buflen); +#elif defined(_AIX) + rc = uv__random_readpath("/dev/random", buf, buflen); +#elif defined(__APPLE__) || defined(__OpenBSD__) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) + rc = uv__random_getentropy(buf, buflen); + if (rc == UV_ENOSYS) + rc = uv__random_devurandom(buf, buflen); +#elif defined(__FreeBSD__) || defined(__linux__) + rc = uv__random_getrandom(buf, buflen); + if (rc == UV_ENOSYS) + rc = uv__random_devurandom(buf, buflen); +# if defined(__linux__) + switch (rc) { + case UV_EACCES: + case UV_EIO: + case UV_ELOOP: + case UV_EMFILE: + case UV_ENFILE: + case UV_ENOENT: + case UV_EPERM: + rc = uv__random_sysctl(buf, buflen); + break; + } +# endif +#elif defined(_WIN32) + uv__once_init(); + rc = uv__random_rtlgenrandom(buf, buflen); +#else + rc = uv__random_devurandom(buf, buflen); +#endif + + return rc; +} + + +static void uv__random_work(struct uv__work* w) { + uv_random_t* req; + + req = container_of(w, uv_random_t, work_req); + req->status = uv__random(req->buf, req->buflen); +} + + +static void uv__random_done(struct uv__work* w, int status) { + uv_random_t* req; + + req = container_of(w, uv_random_t, work_req); + uv__req_unregister(req->loop, req); + + if (status == 0) + status = req->status; + + req->cb(req, status, req->buf, req->buflen); +} + + +int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, + uv_random_cb cb) { + if (buflen > 0x7FFFFFFFu) + return UV_E2BIG; + + if (flags != 0) + return UV_EINVAL; + + if (cb == NULL) + return uv__random(buf, buflen); + + uv__req_init(loop, req, UV_RANDOM); + req->loop = loop; + req->status = 0; + req->cb = cb; + req->buf = buf; + req->buflen = buflen; + + uv__work_submit(loop, + &req->work_req, + UV__WORK_CPU, + uv__random_work, + uv__random_done); + + return 0; +} diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 7aa575508fa8c4..a8f433f0510800 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -372,6 +372,10 @@ int uv_cancel(uv_req_t* req) { loop = ((uv_getnameinfo_t*) req)->loop; wreq = &((uv_getnameinfo_t*) req)->work_req; break; + case UV_RANDOM: + loop = ((uv_random_t*) req)->loop; + wreq = &((uv_random_t*) req)->work_req; + break; case UV_WORK: loop = ((uv_work_t*) req)->loop; wreq = &((uv_work_t*) req)->work_req; diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c index 99fb25a43b4279..7d48c6af57ca46 100644 --- a/deps/uv/src/unix/android-ifaddrs.c +++ b/deps/uv/src/unix/android-ifaddrs.c @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include typedef struct NetlinkList { @@ -475,6 +476,7 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); l_addedNetmask = 1; } + break; case IFA_BROADCAST: l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); break; diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c index 0d7bbe662a5c53..a3385af17c889f 100644 --- a/deps/uv/src/unix/bsd-ifaddrs.c +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -69,7 +69,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { struct ifaddrs* addrs; struct ifaddrs* ent; uv_interface_address_t* address; +#if !(defined(__CYGWIN__) || defined(__MSYS__)) int i; +#endif *count = 0; *addresses = NULL; diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 366c43c2ab0843..ffce948c957403 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -66,7 +66,8 @@ extern char** environ; #if defined(__DragonFly__) || \ defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || \ + defined(__OpenBSD__) # include # include # include @@ -76,7 +77,8 @@ extern char** environ; # if defined(__NetBSD__) # define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d)) # endif -# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__) +# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \ + defined(__NetBSD__) || defined(__OpenBSD__) # define UV__SOCK_NONBLOCK SOCK_NONBLOCK # define UV__SOCK_CLOEXEC SOCK_CLOEXEC # endif diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c index dabde2239ccab3..eced23c2da7ccf 100644 --- a/deps/uv/src/unix/darwin-proctitle.c +++ b/deps/uv/src/unix/darwin-proctitle.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -33,61 +34,52 @@ # include #endif +#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) -static int uv__pthread_setname_np(const char* name) { - int (*dynamic_pthread_setname_np)(const char* name); - char namebuf[64]; /* MAXTHREADNAMESIZE */ - int err; - - /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */ - *(void **)(&dynamic_pthread_setname_np) = - dlsym(RTLD_DEFAULT, "pthread_setname_np"); - - if (dynamic_pthread_setname_np == NULL) - return UV_ENOSYS; - - strncpy(namebuf, name, sizeof(namebuf) - 1); - namebuf[sizeof(namebuf) - 1] = '\0'; - err = dynamic_pthread_setname_np(namebuf); - if (err) - return UV__ERR(err); +#if !TARGET_OS_IPHONE +static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, + const char*, + CFStringEncoding); +static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); +static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); +static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); +static CFTypeRef (*pLSGetCurrentApplicationASN)(void); +static OSStatus (*pLSSetApplicationInformationItem)(int, + CFTypeRef, + CFStringRef, + CFStringRef, + CFDictionaryRef*); +static void* application_services_handle; +static void* core_foundation_handle; +static CFBundleRef launch_services_bundle; +static CFStringRef* display_name_key; +static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); +static CFBundleRef (*pCFBundleGetMainBundle)(void); +static CFBundleRef hi_services_bundle; +static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); +static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, + void*); + + +UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) { + if (core_foundation_handle != NULL) { + dlclose(core_foundation_handle); + core_foundation_handle = NULL; + } - return 0; + if (application_services_handle != NULL) { + dlclose(application_services_handle); + application_services_handle = NULL; + } } +#endif /* !TARGET_OS_IPHONE */ -int uv__set_process_title(const char* title) { -#if TARGET_OS_IPHONE - return uv__pthread_setname_np(title); -#else - CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, - const char*, - CFStringEncoding); - CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); - void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); - void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); - CFTypeRef (*pLSGetCurrentApplicationASN)(void); - OSStatus (*pLSSetApplicationInformationItem)(int, - CFTypeRef, - CFStringRef, - CFStringRef, - CFDictionaryRef*); - void* application_services_handle; - void* core_foundation_handle; - CFBundleRef launch_services_bundle; - CFStringRef* display_name_key; - CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); - CFBundleRef (*pCFBundleGetMainBundle)(void); - CFBundleRef hi_services_bundle; +void uv__set_process_title_platform_init(void) { +#if !TARGET_OS_IPHONE OSStatus (*pSetApplicationIsDaemon)(int); - CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); - void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, - void*); - CFTypeRef asn; - int err; - err = UV_ENOENT; application_services_handle = dlopen("/System/Library/Frameworks/" "ApplicationServices.framework/" "Versions/A/ApplicationServices", @@ -116,8 +108,6 @@ int uv__set_process_title(const char* title) { goto out; } -#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) - launch_services_bundle = pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices")); @@ -148,13 +138,14 @@ int uv__set_process_title(const char* title) { "CFBundleGetInfoDictionary"); *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle, "CFBundleGetMainBundle"); + if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) goto out; /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */ hi_services_bundle = pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices")); - err = UV_ENOENT; + if (hi_services_bundle == NULL) goto out; @@ -168,42 +159,38 @@ int uv__set_process_title(const char* title) { pCFBundleGetFunctionPointerForName( launch_services_bundle, S("_LSSetApplicationLaunchServicesServerConnectionStatus")); + if (pSetApplicationIsDaemon == NULL || pLSApplicationCheckIn == NULL || pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) { goto out; } - if (pSetApplicationIsDaemon(1) != noErr) - goto out; + /* Prevent crash when LaunchServices cannot be connected to. */ + pSetApplicationIsDaemon(1); + return; - pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); +out: + uv__set_process_title_platform_fini(); +#endif /* !TARGET_OS_IPHONE */ +} - /* Check into process manager?! */ - pLSApplicationCheckIn(-2, - pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); - asn = pLSGetCurrentApplicationASN(); +void uv__set_process_title(const char* title) { + char namebuf[64 /* MAXTHREADNAMESIZE */]; - err = UV_EINVAL; - if (pLSSetApplicationInformationItem(-2, /* Magic value. */ - asn, - *display_name_key, - S(title), - NULL) != noErr) { - goto out; +#if !TARGET_OS_IPHONE + if (core_foundation_handle != NULL) { + CFTypeRef asn; + pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); + pLSApplicationCheckIn(/* Magic value */ -2, + pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); + asn = pLSGetCurrentApplicationASN(); + pLSSetApplicationInformationItem(/* Magic value */ -2, asn, + *display_name_key, S(title), NULL); } - - uv__pthread_setname_np(title); /* Don't care if it fails. */ - err = 0; - -out: - if (core_foundation_handle != NULL) - dlclose(core_foundation_handle); - - if (application_services_handle != NULL) - dlclose(application_services_handle); - - return err; #endif /* !TARGET_OS_IPHONE */ + + uv__strscpy(namebuf, title, sizeof(namebuf)); + pthread_setname_np(namebuf); } diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index fd3dd4c287e9ba..b37cfbbc7a04ee 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -78,7 +78,7 @@ defined(__NetBSD__) # include # include -#elif defined(__sun) || defined(__MVS__) +#elif defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__) # include #else # include @@ -216,7 +216,11 @@ static ssize_t uv__fs_futime(uv_fs_t* req) { ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000; ts[1].tv_sec = req->mtime; ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000; +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + return utimensat(req->file, NULL, ts, 0); +#else return futimens(req->file, ts); +#endif #elif defined(__APPLE__) \ || defined(__DragonFly__) \ || defined(__FreeBSD__) \ @@ -528,7 +532,7 @@ static int uv__fs_closedir(uv_fs_t* req) { static int uv__fs_statfs(uv_fs_t* req) { uv_statfs_t* stat_fs; -#if defined(__sun) || defined(__MVS__) +#if defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__) struct statvfs buf; if (0 != statvfs(req->path, &buf)) @@ -545,7 +549,7 @@ static int uv__fs_statfs(uv_fs_t* req) { return -1; } -#if defined(__sun) || defined(__MVS__) +#if defined(__sun) || defined(__MVS__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) stat_fs->f_type = 0; /* f_type is not supported. */ #else stat_fs->f_type = buf.f_type; @@ -1051,18 +1055,14 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { #ifdef FICLONE if (req->flags & UV_FS_COPYFILE_FICLONE || req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { - if (ioctl(dstfd, FICLONE, srcfd) == -1) { - /* If an error occurred that the sendfile fallback also won't handle, or - this is a force clone then exit. Otherwise, fall through to try using - sendfile(). */ - if (errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) { - err = UV__ERR(errno); - goto out; - } else if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { - err = UV_ENOTSUP; - goto out; - } - } else { + if (ioctl(dstfd, FICLONE, srcfd) == 0) { + /* ioctl() with FICLONE succeeded. */ + goto out; + } + /* If an error occurred and force was set, return the error to the caller; + * fall back to sendfile() when force was not set. */ + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + err = UV__ERR(errno); goto out; } } diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index ddacda31fef87e..deeaa63d4730de 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -263,10 +263,12 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef, if (len < handle->realpath_len) continue; + /* Make sure that realpath actually named a directory, + * (unless watching root, which alone keeps a trailing slash on the realpath) + * or that we matched the whole string */ if (handle->realpath_len != len && + handle->realpath_len > 1 && path[handle->realpath_len] != '/') - /* Make sure that realpath actually named a directory, - * or that we matched the whole string */ continue; if (memcmp(path, handle->realpath, handle->realpath_len) != 0) diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 260616474ec151..47f220000dcd73 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -270,6 +270,12 @@ uv_handle_type uv__handle_type(int fd); FILE* uv__open_file(const char* path); int uv__getpwuid_r(uv_passwd_t* pwd); +/* random */ +int uv__random_devurandom(void* buf, size_t buflen); +int uv__random_getrandom(void* buf, size_t buflen); +int uv__random_getentropy(void* buf, size_t buflen); +int uv__random_readpath(const char* path, void* buf, size_t buflen); +int uv__random_sysctl(void* buf, size_t buflen); #if defined(__APPLE__) int uv___stream_fd(const uv_stream_t* handle); diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index c04e7a485cf992..ad09f4031318ca 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -454,10 +454,26 @@ int uv_fs_event_start(uv_fs_event_t* handle, const char* path, unsigned int flags) { int fd; +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + struct stat statbuf; +#endif if (uv__is_active(handle)) return UV_EINVAL; + handle->cb = cb; + handle->path = uv__strdup(path); + if (handle->path == NULL) + return UV_ENOMEM; + + /* TODO open asynchronously - but how do we report back errors? */ + fd = open(handle->path, O_RDONLY); + if (fd == -1) { + uv__free(handle->path); + handle->path = NULL; + return UV__ERR(errno); + } + #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 /* Nullify field to perform checks later */ handle->cf_cb = NULL; @@ -465,14 +481,17 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->realpath_len = 0; handle->cf_flags = flags; + if (fstat(fd, &statbuf)) + goto fallback; + /* FSEvents works only with directories */ + if (!(statbuf.st_mode & S_IFDIR)) + goto fallback; + if (!uv__has_forked_with_cfrunloop) { int r; - /* The fallback fd is not used */ + /* The fallback fd is no longer needed */ + uv__close_nocheckstdio(fd); handle->event_watcher.fd = -1; - handle->path = uv__strdup(path); - if (handle->path == NULL) - return UV_ENOMEM; - handle->cb = cb; r = uv__fsevents_init(handle); if (r == 0) { uv__handle_start(handle); @@ -482,20 +501,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, } return r; } +fallback: #endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ - /* TODO open asynchronously - but how do we report back errors? */ - fd = open(path, O_RDONLY); - if (fd == -1) - return UV__ERR(errno); - - handle->path = uv__strdup(path); - if (handle->path == NULL) { - uv__close_nocheckstdio(fd); - return UV_ENOMEM; - } - - handle->cb = cb; uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__fs_event, fd); uv__io_start(handle->loop, &handle->event_watcher, POLLIN); @@ -514,7 +522,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (!uv__has_forked_with_cfrunloop) + if (!uv__has_forked_with_cfrunloop && handle->cf_cb != NULL) r = uv__fsevents_close(handle); #endif diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 433e201fe19dbf..a155a374e76c2d 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -90,7 +90,12 @@ int uv__platform_loop_init(uv_loop_t* loop) { * a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all * architectures, we just use that instead. */ +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + fd = -1; + errno = ENOSYS; +#else fd = epoll_create1(O_CLOEXEC); +#endif /* epoll_create1() can fail either because it's not implemented (old kernel) * or because it doesn't understand the O_CLOEXEC flag. @@ -203,6 +208,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { * that being the largest value I have seen in the wild (and only once.) */ static const int max_safe_timeout = 1789569; + static int no_epoll_pwait; + static int no_epoll_wait; struct epoll_event events[1024]; struct epoll_event* pe; struct epoll_event e; @@ -210,7 +217,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { QUEUE* q; uv__io_t* w; sigset_t sigset; - sigset_t* psigset; + uint64_t sigmask; uint64_t base; int have_signals; int nevents; @@ -262,11 +269,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { w->events = w->pevents; } - psigset = NULL; + sigmask = 0; if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { sigemptyset(&sigset); sigaddset(&sigset, SIGPROF); - psigset = &sigset; + sigmask |= 1 << (SIGPROF - 1); } assert(timeout >= -1); @@ -281,11 +288,35 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) timeout = max_safe_timeout; - nfds = epoll_pwait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout, - psigset); + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) + abort(); + + if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + nfds = -1; + errno = ENOSYS; +#else + nfds = epoll_pwait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout, + &sigset); +#endif + if (nfds == -1 && errno == ENOSYS) + no_epoll_pwait = 1; + } else { + nfds = epoll_wait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout); + if (nfds == -1 && errno == ENOSYS) + no_epoll_wait = 1; + } + + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) + abort(); /* Update loop->time unconditionally. It's tempting to skip the update when * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the @@ -306,6 +337,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } if (nfds == -1) { + if (errno == ENOSYS) { + /* epoll_wait() or epoll_pwait() failed, try the other system call. */ + assert(no_epoll_wait == 0 || no_epoll_pwait == 0); + continue; + } + if (errno != EINTR) abort(); diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c index 5637cf98a7b338..950387860f04cc 100644 --- a/deps/uv/src/unix/linux-syscalls.c +++ b/deps/uv/src/unix/linux-syscalls.c @@ -203,6 +203,22 @@ # endif #endif /* __NR_statx */ +#ifndef __NR_getrandom +# if defined(__x86_64__) +# define __NR_getrandom 318 +# elif defined(__i386__) +# define __NR_getrandom 355 +# elif defined(__aarch64__) +# define __NR_getrandom 384 +# elif defined(__arm__) +# define __NR_getrandom (UV_SYSCALL_BASE + 384) +# elif defined(__ppc__) +# define __NR_getrandom 359 +# elif defined(__s390__) +# define __NR_getrandom 349 +# endif +#endif /* __NR_getrandom */ + int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) { #if defined(__i386__) unsigned long args[4]; @@ -367,3 +383,12 @@ int uv__statx(int dirfd, return errno = ENOSYS, -1; #endif } + + +ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) { +#if defined(__NR_getrandom) + return syscall(__NR_getrandom, buf, buflen, flags); +#else + return errno = ENOSYS, -1; +#endif +} diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h index 7e58bfa2189692..b7729b82aea9ba 100644 --- a/deps/uv/src/unix/linux-syscalls.h +++ b/deps/uv/src/unix/linux-syscalls.h @@ -148,5 +148,6 @@ int uv__statx(int dirfd, int flags, unsigned int mask, struct uv__statx* statxbuf); +ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags); #endif /* UV_LINUX_SYSCALL_H_ */ diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index 1f5228dc13fd7a..199a34658a7948 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -186,7 +186,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { int numcpus = 1; int which[] = {CTL_HW,HW_MODEL,0}; size_t size; - int i; + int i, j; uv_cpu_info_t* cpu_info; size = sizeof(model); diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index 834766863220fe..cdf24fa9763cb1 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -261,7 +261,7 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle, addrlen = strlen(sa.sun_path); - if (addrlen >= *size) { + if ((size_t)addrlen >= *size) { *size = addrlen + 1; return UV_ENOBUFS; } diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 1a8c7a7090e8a6..a5ce2030c55be8 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -24,6 +24,7 @@ #include #include +extern void uv__set_process_title_platform_init(void); extern void uv__set_process_title(const char* title); static uv_mutex_t process_title_mutex; @@ -38,6 +39,9 @@ static struct { static void init_process_title_mutex_once(void) { uv_mutex_init(&process_title_mutex); +#ifdef __APPLE__ + uv__set_process_title_platform_init(); +#endif } diff --git a/deps/uv/src/unix/random-devurandom.c b/deps/uv/src/unix/random-devurandom.c new file mode 100644 index 00000000000000..bfc40d20f88cb7 --- /dev/null +++ b/deps/uv/src/unix/random-devurandom.c @@ -0,0 +1,93 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +static uv_once_t once = UV_ONCE_INIT; +static int status; + + +int uv__random_readpath(const char* path, void* buf, size_t buflen) { + struct stat s; + size_t pos; + ssize_t n; + int fd; + + fd = uv__open_cloexec(path, O_RDONLY); + + if (fd == -1) + return UV__ERR(errno); + + if (fstat(fd, &s)) { + uv__close(fd); + return UV__ERR(errno); + } + + if (!S_ISCHR(s.st_mode)) { + uv__close(fd); + return UV_EIO; + } + + for (pos = 0; pos != buflen; pos += n) { + do + n = read(fd, (char*) buf + pos, buflen - pos); + while (n == -1 && errno == EINTR); + + if (n == -1) { + uv__close(fd); + return UV__ERR(errno); + } + + if (n == 0) { + uv__close(fd); + return UV_EIO; + } + } + + uv__close(fd); + return 0; +} + + +static void uv__random_devurandom_init(void) { + char c; + + /* Linux's and NetBSD's random(4) man page suggests applications should read + * at least once from /dev/random before switching to /dev/urandom in order + * to seed the system RNG. Reads from /dev/random can of course block + * indefinitely until entropy is available but that's the point. + */ + status = uv__random_readpath("/dev/random", &c, 1); +} + + +int uv__random_devurandom(void* buf, size_t buflen) { + uv_once(&once, uv__random_devurandom_init); + + if (status != 0) + return status; + + return uv__random_readpath("/dev/urandom", buf, buflen); +} diff --git a/deps/uv/src/unix/random-getentropy.c b/deps/uv/src/unix/random-getentropy.c new file mode 100644 index 00000000000000..c45d9fd4a2b7c0 --- /dev/null +++ b/deps/uv/src/unix/random-getentropy.c @@ -0,0 +1,57 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +typedef int (*uv__getentropy_cb)(void *, size_t); + +static uv__getentropy_cb uv__getentropy; +static uv_once_t once = UV_ONCE_INIT; + + +static void uv__random_getentropy_init(void) { + uv__getentropy = (uv__getentropy_cb) dlsym(RTLD_DEFAULT, "getentropy"); +} + + +int uv__random_getentropy(void* buf, size_t buflen) { + size_t pos; + size_t stride; + + uv_once(&once, uv__random_getentropy_init); + + if (uv__getentropy == NULL) + return UV_ENOSYS; + + /* getentropy() returns an error for requests > 256 bytes. */ + for (pos = 0, stride = 256; pos + stride < buflen; pos += stride) + if (uv__getentropy((char *) buf + pos, stride)) + return UV__ERR(errno); + + if (uv__getentropy((char *) buf + pos, buflen - pos)) + return UV__ERR(errno); + + return 0; +} diff --git a/deps/uv/src/unix/random-getrandom.c b/deps/uv/src/unix/random-getrandom.c new file mode 100644 index 00000000000000..bcc94089bcb64e --- /dev/null +++ b/deps/uv/src/unix/random-getrandom.c @@ -0,0 +1,88 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#ifdef __linux__ + +#include "linux-syscalls.h" + +#define uv__random_getrandom_init() 0 + +#else /* !__linux__ */ + +#include +#include + +typedef ssize_t (*uv__getrandom_cb)(void *, size_t, unsigned); + +static uv__getrandom_cb uv__getrandom; +static uv_once_t once = UV_ONCE_INIT; + +static void uv__random_getrandom_init_once(void) { + uv__getrandom = (uv__getrandom_cb) dlsym(RTLD_DEFAULT, "getrandom"); +} + +static int uv__random_getrandom_init(void) { + uv_once(&once, uv__random_getrandom_init_once); + + if (uv__getrandom == NULL) + return UV_ENOSYS; + + return 0; +} + +#endif /* !__linux__ */ + +int uv__random_getrandom(void* buf, size_t buflen) { + ssize_t n; + size_t pos; + int rc; + + rc = uv__random_getrandom_init(); + if (rc != 0) + return rc; + + for (pos = 0; pos != buflen; pos += n) { + do { + n = buflen - pos; + + /* Most getrandom() implementations promise that reads <= 256 bytes + * will always succeed and won't be interrupted by signals. + * It's therefore useful to split it up in smaller reads because + * one big read may, in theory, continuously fail with EINTR. + */ + if (n > 256) + n = 256; + + n = uv__getrandom((char *) buf + pos, n, 0); + } while (n == -1 && errno == EINTR); + + if (n == -1) + return UV__ERR(errno); + + if (n == 0) + return UV_EIO; + } + + return 0; +} diff --git a/deps/uv/src/unix/random-sysctl.c b/deps/uv/src/unix/random-sysctl.c new file mode 100644 index 00000000000000..fb182ded09296b --- /dev/null +++ b/deps/uv/src/unix/random-sysctl.c @@ -0,0 +1,100 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#include +#include + + +struct uv__sysctl_args { + int* name; + int nlen; + void* oldval; + size_t* oldlenp; + void* newval; + size_t newlen; + unsigned long unused[4]; +}; + + +/* TODO(bnoordhuis) Use {CTL_KERN, KERN_ARND} on FreeBSD (and NetBSD?) */ +int uv__random_sysctl(void* buf, size_t buflen) { + static int name[] = {1 /*CTL_KERN*/, 40 /*KERN_RANDOM*/, 6 /*RANDOM_UUID*/}; + struct uv__sysctl_args args; + char uuid[16]; + char* p; + char* pe; + size_t n; + + p = buf; + pe = p + buflen; + + while (p < pe) { + memset(&args, 0, sizeof(args)); + + args.name = name; + args.nlen = ARRAY_SIZE(name); + args.oldval = uuid; + args.oldlenp = &n; + n = sizeof(uuid); + + /* Emits a deprecation warning with some kernels but that seems like + * an okay trade-off for the fallback of the fallback: this function is + * only called when neither getrandom(2) nor /dev/urandom are available. + * Fails with ENOSYS on kernels configured without CONFIG_SYSCTL_SYSCALL. + * At least arm64 never had a _sysctl system call and therefore doesn't + * have a SYS__sysctl define either. + */ +#ifdef SYS__sysctl + if (syscall(SYS__sysctl, &args) == -1) + return UV__ERR(errno); +#else + { + (void) &args; + return UV_ENOSYS; + } +#endif + + if (n != sizeof(uuid)) + return UV_EIO; /* Can't happen. */ + + /* uuid[] is now a type 4 UUID. Bytes 6 and 8 (counting from zero) contain + * 4 and 5 bits of entropy, respectively. For ease of use, we skip those + * and only use 14 of the 16 bytes. + */ + uuid[6] = uuid[14]; + uuid[8] = uuid[15]; + + n = pe - p; + if (n > 14) + n = 14; + + memcpy(p, uuid, n); + p += n; + } + + return 0; +} diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c index 74d3d75d7615d9..e7c520f77402bc 100644 --- a/deps/uv/src/unix/tty.c +++ b/deps/uv/src/unix/tty.c @@ -365,3 +365,10 @@ int uv_tty_reset_mode(void) { return err; } + +void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) { +} + +int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) { + return UV_ENOTSUP; +} diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index dba8eff8382edd..98215f7e1d212b 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -165,9 +165,6 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { */ count = 32; - memset(&h, 0, sizeof(h)); - h.msg_name = &peer; - do { buf = uv_buf_init(NULL, 0); handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf); @@ -177,6 +174,9 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { } assert(buf.base != NULL); + memset(&h, 0, sizeof(h)); + memset(&peer, 0, sizeof(peer)); + h.msg_name = &peer; h.msg_namelen = sizeof(peer); h.msg_iov = (void*) &buf; h.msg_iovlen = 1; @@ -193,17 +193,11 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0); } else { - const struct sockaddr *addr; - if (h.msg_namelen == 0) - addr = NULL; - else - addr = (const struct sockaddr*) &peer; - flags = 0; if (h.msg_flags & MSG_TRUNC) flags |= UV_UDP_PARTIAL; - handle->recv_cb(handle, nread, &buf, addr, flags); + handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags); } } /* recv_cb callback may decide to pause or close the handle */ @@ -659,6 +653,7 @@ static int uv__udp_set_membership6(uv_udp_t* handle, } +#if !defined(__OpenBSD__) && !defined(__NetBSD__) static int uv__udp_set_source_membership4(uv_udp_t* handle, const struct sockaddr_in* multicast_addr, const char* interface_addr, @@ -749,6 +744,7 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle, return 0; } +#endif int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { @@ -846,6 +842,7 @@ int uv_udp_set_source_membership(uv_udp_t* handle, const char* interface_addr, const char* source_addr, uv_membership membership) { +#if !defined(__OpenBSD__) && !defined(__NetBSD__) int err; struct sockaddr_storage mcast_addr; struct sockaddr_in* mcast_addr4; @@ -873,7 +870,7 @@ int uv_udp_set_source_membership(uv_udp_t* handle, src_addr6, membership); } - + err = uv_ip4_addr(source_addr, 0, src_addr4); if (err) return err; @@ -882,6 +879,9 @@ int uv_udp_set_source_membership(uv_udp_t* handle, interface_addr, src_addr4, membership); +#else + return UV_ENOSYS; +#endif } diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index 70db53ab04dacf..cec4ac6281b91b 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -211,6 +211,9 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) { memset(addr, 0, sizeof(*addr)); addr->sin_family = AF_INET; addr->sin_port = htons(port); +#ifdef SIN6_LEN + addr->sin_len = sizeof(*addr); +#endif return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr)); } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 5dccca77999dbd..3ab486080cdfa7 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -36,8 +36,6 @@ #include "handle-inl.h" #include "fs-fd-hash-inl.h" -#include - #define UV_FS_FREE_PATHS 0x0002 #define UV_FS_FREE_PTR 0x0008 @@ -1207,9 +1205,7 @@ void fs__mkdtemp(uv_fs_t* req) { WCHAR *cp, *ep; unsigned int tries, i; size_t len; - HCRYPTPROV h_crypt_prov; uint64_t v; - BOOL released; len = wcslen(req->file.pathw); ep = req->file.pathw + len; @@ -1218,16 +1214,10 @@ void fs__mkdtemp(uv_fs_t* req) { return; } - if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - tries = TMP_MAX; do { - if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); + if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) { + SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE); break; } @@ -1248,8 +1238,6 @@ void fs__mkdtemp(uv_fs_t* req) { } } while (--tries); - released = CryptReleaseContext(h_crypt_prov, 0); - assert(released); if (tries == 0) { SET_REQ_RESULT(req, -1); } @@ -2587,6 +2575,7 @@ static void fs__statfs(uv_fs_t* req) { stat_fs->f_files = 0; stat_fs->f_ffree = 0; req->ptr = stat_fs; + req->flags |= UV_FS_FREE_PTR; SET_REQ_RESULT(req, 0); } diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index 70ddaa533244e2..058ddb8edc6d10 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -280,6 +280,8 @@ int uv__getsockpeername(const uv_handle_t* handle, int* namelen, int delayed_error); +int uv__random_rtlgenrandom(void* buf, size_t buflen); + /* * Process stdio handles. diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 81e48136a3b9ef..fd34c623d8c543 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -556,7 +556,7 @@ int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { if (handle->flags & UV_HANDLE_SHUTTING) return UV_EINVAL; - if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, &l, sizeof(l))) + if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l))) return uv_translate_sys_error(WSAGetLastError()); uv_close((uv_handle_t*) handle, close_cb); diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 8f84bcd0e45544..5d5b92d0d2d6bd 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -149,13 +149,9 @@ static char uv_tty_default_fg_bright = 0; static char uv_tty_default_bg_bright = 0; static char uv_tty_default_inverse = 0; -typedef enum { - UV_SUPPORTED, - UV_UNCHECKED, - UV_UNSUPPORTED -} uv_vtermstate_t; /* Determine whether or not ANSI support is enabled. */ -static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED; +static BOOL uv__need_check_vterm_state = TRUE; +static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED; static void uv__determine_vterm_state(HANDLE handle); void uv_console_init(void) { @@ -169,10 +165,15 @@ void uv_console_init(void) { 0, 0); if (uv__tty_console_handle != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO sb_info; QueueUserWorkItem(uv__tty_console_resize_message_loop_thread, NULL, WT_EXECUTELONGFUNCTION); uv_mutex_init(&uv__tty_console_resize_mutex); + if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) { + uv__tty_console_width = sb_info.dwSize.X; + uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + } } } @@ -218,7 +219,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) { * between all uv_tty_t handles. */ uv_sem_wait(&uv_tty_output_lock); - if (uv__vterm_state == UV_UNCHECKED) + if (uv__need_check_vterm_state) uv__determine_vterm_state(handle); /* Remember the original console text attributes. */ @@ -1670,7 +1671,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle, uv_buf_t buf = bufs[i]; unsigned int j; - if (uv__vterm_state == UV_SUPPORTED && buf.len > 0) { + if (uv__vterm_state == UV_TTY_SUPPORTED && buf.len > 0) { utf16_buf_used = MultiByteToWideChar(CP_UTF8, 0, buf.base, @@ -2275,32 +2276,24 @@ int uv_tty_reset_mode(void) { static void uv__determine_vterm_state(HANDLE handle) { DWORD dwMode = 0; + uv__need_check_vterm_state = FALSE; if (!GetConsoleMode(handle, &dwMode)) { - uv__vterm_state = UV_UNSUPPORTED; return; } dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; if (!SetConsoleMode(handle, dwMode)) { - uv__vterm_state = UV_UNSUPPORTED; return; } - uv__vterm_state = UV_SUPPORTED; + uv__vterm_state = UV_TTY_SUPPORTED; } static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) { - CONSOLE_SCREEN_BUFFER_INFO sb_info; NTSTATUS status; ULONG_PTR conhost_pid; MSG msg; - if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) - return 0; - - uv__tty_console_width = sb_info.dwSize.X; - uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; - if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL) return 0; @@ -2375,6 +2368,7 @@ static void uv__tty_console_signal_resize(void) { height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; uv_mutex_lock(&uv__tty_console_resize_mutex); + assert(uv__tty_console_width != -1 && uv__tty_console_height != -1); if (width != uv__tty_console_width || height != uv__tty_console_height) { uv__tty_console_width = width; uv__tty_console_height = height; @@ -2384,3 +2378,17 @@ static void uv__tty_console_signal_resize(void) { uv_mutex_unlock(&uv__tty_console_resize_mutex); } } + +void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) { + uv_sem_wait(&uv_tty_output_lock); + uv__need_check_vterm_state = FALSE; + uv__vterm_state = state; + uv_sem_post(&uv_tty_output_lock); +} + +int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) { + uv_sem_wait(&uv_tty_output_lock); + *state = uv__vterm_state; + uv_sem_post(&uv_tty_output_lock); + return 0; +} diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 39fc34d3bfcd94..3daa55f62db063 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -856,7 +856,7 @@ int uv_udp_set_source_membership(uv_udp_t* handle, src_addr6, membership); } - + err = uv_ip4_addr(source_addr, 0, src_addr4); if (err) return err; diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 8849d041bf0283..4bbeb3154123dd 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -1417,7 +1417,9 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) { if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0) goto fail; - ptr = strchr(buf, '='); + /* Using buf + 1 here because we know that `buf` has length at least 1, + * and some special environment variables on Windows start with a = sign. */ + ptr = strchr(buf + 1, '='); if (ptr == NULL) { uv__free(buf); goto do_continue; @@ -1858,3 +1860,16 @@ int uv_gettimeofday(uv_timeval64_t* tv) { tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10); return 0; } + +int uv__random_rtlgenrandom(void* buf, size_t buflen) { + if (pRtlGenRandom == NULL) + return UV_ENOSYS; + + if (buflen == 0) + return 0; + + if (pRtlGenRandom(buf, buflen) == FALSE) + return UV_EIO; + + return 0; +} diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index 19e4377faf5599..85a9de8a2295ec 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -36,6 +36,9 @@ sNtQueryDirectoryFile pNtQueryDirectoryFile; sNtQuerySystemInformation pNtQuerySystemInformation; sNtQueryInformationProcess pNtQueryInformationProcess; +/* Advapi32 function pointers */ +sRtlGenRandom pRtlGenRandom; + /* Kernel32 function pointers */ sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; @@ -51,6 +54,7 @@ void uv_winapi_init(void) { HMODULE powrprof_module; HMODULE user32_module; HMODULE kernel32_module; + HMODULE advapi32_module; ntdll_module = GetModuleHandleA("ntdll.dll"); if (ntdll_module == NULL) { @@ -135,4 +139,11 @@ void uv_winapi_init(void) { GetProcAddress(user32_module, "SetWinEventHook"); } + advapi32_module = GetModuleHandleA("advapi32.dll"); + if (advapi32_module == NULL) { + uv_fatal_error(GetLastError(), "GetModuleHandleA"); + } + + pRtlGenRandom = + (sRtlGenRandom) GetProcAddress(advapi32_module, "SystemFunction036"); } diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index 322a212dd73c19..fcc70652a9aedb 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4589,6 +4589,11 @@ typedef NTSTATUS (NTAPI *sNtQueryInformationProcess) ULONG Length, PULONG ReturnLength); +/* + * Advapi32 headers + */ +typedef BOOLEAN (WINAPI *sRtlGenRandom)(PVOID Buffer, ULONG BufferLength); + /* * Kernel32 headers */ @@ -4731,6 +4736,9 @@ extern sNtQueryDirectoryFile pNtQueryDirectoryFile; extern sNtQuerySystemInformation pNtQuerySystemInformation; extern sNtQueryInformationProcess pNtQueryInformationProcess; +/* Advapi32 function pointers */ +extern sRtlGenRandom pRtlGenRandom; + /* Kernel32 function pointers */ extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; diff --git a/deps/uv/src/win/winsock.h b/deps/uv/src/win/winsock.h index 7ecb755bfb061b..2af958870a7de6 100644 --- a/deps/uv/src/win/winsock.h +++ b/deps/uv/src/win/winsock.h @@ -54,6 +54,14 @@ # define SIO_BASE_HANDLE 0x48000022 #endif +#ifndef MCAST_JOIN_SOURCE_GROUP +# define MCAST_JOIN_SOURCE_GROUP 45 +#endif + +#ifndef MCAST_LEAVE_SOURCE_GROUP +# define MCAST_LEAVE_SOURCE_GROUP 46 +#endif + /* * TDI defines that are only in the DDK. * We only need receive flags so far. diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c index 3814699356db55..3c9de95b102a07 100644 --- a/deps/uv/test/test-env-vars.c +++ b/deps/uv/test/test-env-vars.c @@ -30,7 +30,7 @@ TEST_IMPL(env_vars) { const char* name2 = "UV_TEST_FOO2"; char buf[BUF_SIZE]; size_t size; - int i, r, envcount, found; + int i, r, envcount, found, found_win_special; uv_env_item_t* envitems; /* Reject invalid inputs when setting an environment variable */ @@ -108,6 +108,7 @@ TEST_IMPL(env_vars) { ASSERT(envcount > 0); found = 0; + found_win_special = 0; for (i = 0; i < envcount; i++) { /* printf("Env: %s = %s\n", envitems[i].name, envitems[i].value); */ @@ -117,10 +118,15 @@ TEST_IMPL(env_vars) { } else if (strcmp(envitems[i].name, name2) == 0) { found++; ASSERT(strlen(envitems[i].value) == 0); + } else if (envitems[i].name[0] == '=') { + found_win_special++; } } ASSERT(found == 2); +#ifdef _WIN32 + ASSERT(found_win_special > 0); +#endif uv_os_free_environ(envitems, envcount); diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c index def3d967e74f5b..c3e698e5852cba 100644 --- a/deps/uv/test/test-fs-copyfile.c +++ b/deps/uv/test/test-fs-copyfile.c @@ -188,7 +188,7 @@ TEST_IMPL(fs_copyfile) { unlink(dst); r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE_FORCE, NULL); - ASSERT(r == 0 || r == UV_ENOSYS || r == UV_ENOTSUP); + ASSERT(r <= 0); if (r == 0) handle_result(&req); diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index ea34bd63a70625..e694d258ea9306 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -25,6 +25,10 @@ #include #include +#if defined(__APPLE__) && !TARGET_OS_IPHONE +# include +#endif + #ifndef HAVE_KQUEUE # if defined(__APPLE__) || \ defined(__DragonFly__) || \ @@ -47,6 +51,7 @@ static const char file_prefix[] = "fsevent-"; static const int fs_event_file_count = 16; #if defined(__APPLE__) || defined(_WIN32) static const char file_prefix_in_subdir[] = "subdir"; +static int fs_multievent_cb_called; #endif static uv_timer_t timer; static int timer_cb_called; @@ -280,7 +285,7 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, if (filename && strcmp(filename, file_prefix_in_subdir) == 0) return; #endif - fs_event_cb_called++; + fs_multievent_cb_called++; ASSERT(handle == &fs_event); ASSERT(status == 0); ASSERT(events == UV_CHANGE || events == UV_RENAME); @@ -298,7 +303,7 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, if (fs_event_created + fs_event_removed == fs_event_file_count) { /* Once we've processed all create events, delete all files */ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); - } else if (fs_event_cb_called == 2 * fs_event_file_count) { + } else if (fs_multievent_cb_called == 2 * fs_event_file_count) { /* Once we've processed all create and delete events, stop watching */ uv_close((uv_handle_t*) &timer, close_cb); uv_close((uv_handle_t*) handle, close_cb); @@ -393,6 +398,21 @@ static void timer_cb_watch_twice(uv_timer_t* handle) { uv_close((uv_handle_t*) handle, NULL); } +static void fs_event_cb_close(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(status == 0); + + ASSERT(fs_event_cb_called < 3); + ++fs_event_cb_called; + + if (fs_event_cb_called == 3) { + uv_close((uv_handle_t*) handle, close_cb); + } +} + + TEST_IMPL(fs_event_watch_dir) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); @@ -434,10 +454,12 @@ TEST_IMPL(fs_event_watch_dir) { return 0; } + TEST_IMPL(fs_event_watch_dir_recursive) { #if defined(__APPLE__) || defined(_WIN32) uv_loop_t* loop; int r; + uv_fs_event_t fs_event_root; /* Setup */ loop = uv_default_loop(); @@ -451,17 +473,37 @@ TEST_IMPL(fs_event_watch_dir_recursive) { r = uv_fs_event_init(loop, &fs_event); ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file_in_subdir, "watch_dir", UV_FS_EVENT_RECURSIVE); + r = uv_fs_event_start(&fs_event, + fs_event_cb_dir_multi_file_in_subdir, + "watch_dir", + UV_FS_EVENT_RECURSIVE); ASSERT(r == 0); r = uv_timer_init(loop, &timer); ASSERT(r == 0); r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0); ASSERT(r == 0); +#ifndef _WIN32 + /* Also try to watch the root directory. + * This will be noisier, so we're just checking for any couple events to happen. */ + r = uv_fs_event_init(loop, &fs_event_root); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event_root, + fs_event_cb_close, + "/", + UV_FS_EVENT_RECURSIVE); + ASSERT(r == 0); +#else + fs_event_cb_called += 3; + close_cb_called += 1; + (void)fs_event_root; +#endif + uv_run(loop, UV_RUN_DEFAULT); - ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed); - ASSERT(close_cb_called == 2); + ASSERT(fs_multievent_cb_called == fs_event_created + fs_event_removed); + ASSERT(fs_event_cb_called == 3); + ASSERT(close_cb_called == 3); /* Cleanup */ fs_event_unlink_files_in_subdir(NULL); @@ -596,6 +638,7 @@ TEST_IMPL(fs_event_watch_file_exact_path) { * versions. Give a long delay here to let the system settle before running * the test. */ uv_sleep(1100); + uv_update_time(loop); #endif r = uv_fs_event_init(loop, &fs_event); @@ -656,6 +699,13 @@ TEST_IMPL(fs_event_watch_file_current_dir) { /* Setup */ remove("watch_file"); create_file("watch_file"); +#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_12) + /* Empirically, kevent seems to (sometimes) report the preceeding + * create_file events prior to macOS 10.11.6 in the subsequent fs_event_start + * So let the system settle before running the test. */ + uv_sleep(1100); + uv_update_time(loop); +#endif r = uv_fs_event_init(loop, &fs_event); ASSERT(r == 0); @@ -864,18 +914,6 @@ TEST_IMPL(fs_event_close_with_pending_event) { return 0; } -static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, - int events, int status) { - ASSERT(status == 0); - - ASSERT(fs_event_cb_called < 3); - ++fs_event_cb_called; - - if (fs_event_cb_called == 3) { - uv_close((uv_handle_t*) handle, close_cb); - } -} - TEST_IMPL(fs_event_close_in_callback) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); diff --git a/deps/uv/test/test-fs-readdir.c b/deps/uv/test/test-fs-readdir.c index a767f1fb885dcd..5efc853cc67f0f 100644 --- a/deps/uv/test/test-fs-readdir.c +++ b/deps/uv/test/test-fs-readdir.c @@ -62,12 +62,12 @@ static void empty_readdir_cb(uv_fs_t* req) { ASSERT(req->fs_type == UV_FS_READDIR); ASSERT(req->result == 0); dir = req->ptr; + uv_fs_req_cleanup(req); r = uv_fs_closedir(uv_default_loop(), &closedir_req, dir, empty_closedir_cb); ASSERT(r == 0); - uv_fs_req_cleanup(req); } static void empty_opendir_cb(uv_fs_t* req) { diff --git a/deps/uv/test/test-ip4-addr.c b/deps/uv/test/test-ip4-addr.c index c72f36a694455d..dfefb0f914a6ef 100644 --- a/deps/uv/test/test-ip4-addr.c +++ b/deps/uv/test/test-ip4-addr.c @@ -42,6 +42,10 @@ TEST_IMPL(ip4_addr) { ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr)); ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr)); +#ifdef SIN6_LEN + ASSERT(addr.sin_len == sizeof(addr)); +#endif + /* for broken address family */ ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1", &addr.sin_addr.s_addr)); diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index bbf33a4854ed23..39d570659daafe 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -160,3 +160,12 @@ TEST_IMPL(ip6_pton) { #undef GOOD_ADDR_LIST #undef BAD_ADDR_LIST + +#ifdef SIN6_LEN +TEST_IMPL(ip6_sin6_len) { + struct sockaddr_in6 s; + ASSERT(uv_ip6_addr("::", 0, &s) < 0); + ASSERT(s.sin6_len == sizeof(s)); + return 0; +} +#endif diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index b6066f27276dc6..ad94c52d0c5866 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -395,6 +395,7 @@ TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) TEST_DECLARE (threadpool_cancel_getaddrinfo) TEST_DECLARE (threadpool_cancel_getnameinfo) +TEST_DECLARE (threadpool_cancel_random) TEST_DECLARE (threadpool_cancel_work) TEST_DECLARE (threadpool_cancel_fs) TEST_DECLARE (threadpool_cancel_single) @@ -464,6 +465,9 @@ HELPER_DECLARE (pipe_echo_server) TEST_DECLARE (queue_foreach_delete) +TEST_DECLARE (random_async) +TEST_DECLARE (random_sync) + TEST_DECLARE (handle_type_name) TEST_DECLARE (req_type_name) TEST_DECLARE (getters_setters) @@ -1000,6 +1004,7 @@ TASK_LIST_START TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 60000) TEST_ENTRY (threadpool_cancel_getaddrinfo) TEST_ENTRY (threadpool_cancel_getnameinfo) + TEST_ENTRY (threadpool_cancel_random) TEST_ENTRY (threadpool_cancel_work) TEST_ENTRY (threadpool_cancel_fs) TEST_ENTRY (threadpool_cancel_single) @@ -1018,6 +1023,9 @@ TASK_LIST_START TEST_ENTRY (queue_foreach_delete) + TEST_ENTRY (random_async) + TEST_ENTRY (random_sync) + TEST_ENTRY (handle_type_name) TEST_ENTRY (req_type_name) TEST_ENTRY (getters_setters) diff --git a/deps/uv/test/test-process-title-threadsafe.c b/deps/uv/test/test-process-title-threadsafe.c index 5b30f17f44d529..19098eda0c4019 100644 --- a/deps/uv/test/test-process-title-threadsafe.c +++ b/deps/uv/test/test-process-title-threadsafe.c @@ -25,11 +25,7 @@ #include -#ifdef __APPLE__ -# define NUM_ITERATIONS 10 -#else -# define NUM_ITERATIONS 50 -#endif +#define NUM_ITERATIONS 50 static const char* titles[] = { "8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled", diff --git a/deps/uv/test/test-random.c b/deps/uv/test/test-random.c new file mode 100644 index 00000000000000..2e3ce4424d29eb --- /dev/null +++ b/deps/uv/test/test-random.c @@ -0,0 +1,94 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include + +static char scratch[256]; +static int random_cb_called; + + +static void random_cb(uv_random_t* req, int status, void* buf, size_t buflen) { + char zero[sizeof(scratch)]; + + memset(zero, 0, sizeof(zero)); + + ASSERT(0 == status); + ASSERT(buf == (void*) scratch); + + if (random_cb_called == 0) { + ASSERT(buflen == 0); + ASSERT(0 == memcmp(scratch, zero, sizeof(zero))); + } else { + ASSERT(buflen == sizeof(scratch)); + /* Buy a lottery ticket if you manage to trip this assertion. */ + ASSERT(0 != memcmp(scratch, zero, sizeof(zero))); + } + + random_cb_called++; +} + + +TEST_IMPL(random_async) { + uv_random_t req; + uv_loop_t* loop; + + loop = uv_default_loop(); + ASSERT(UV_EINVAL == uv_random(loop, &req, scratch, sizeof(scratch), -1, + random_cb)); + ASSERT(UV_E2BIG == uv_random(loop, &req, scratch, -1, -1, random_cb)); + + ASSERT(0 == uv_random(loop, &req, scratch, 0, 0, random_cb)); + ASSERT(0 == random_cb_called); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == random_cb_called); + + ASSERT(0 == uv_random(loop, &req, scratch, sizeof(scratch), 0, random_cb)); + ASSERT(1 == random_cb_called); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(2 == random_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(random_sync) { + char zero[256]; + char buf[256]; + + ASSERT(UV_EINVAL == uv_random(NULL, NULL, buf, sizeof(buf), -1, NULL)); + ASSERT(UV_E2BIG == uv_random(NULL, NULL, buf, -1, -1, NULL)); + + memset(buf, 0, sizeof(buf)); + ASSERT(0 == uv_random(NULL, NULL, buf, sizeof(buf), 0, NULL)); + + /* Buy a lottery ticket if you manage to trip this assertion. */ + memset(zero, 0, sizeof(zero)); + ASSERT(0 != memcmp(buf, zero, sizeof(zero))); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c index dd13d8ae4bf1fa..be252c6f723451 100644 --- a/deps/uv/test/test-threadpool-cancel.c +++ b/deps/uv/test/test-threadpool-cancel.c @@ -37,6 +37,11 @@ struct cancel_info { uv_timer_t timer_handle; }; +struct random_info { + uv_random_t random_req; + char buf[1]; +}; + static unsigned fs_cb_called; static unsigned done_cb_called; static unsigned done2_cb_called; @@ -143,6 +148,19 @@ static void nop_done_cb(uv_work_t* req, int status) { } +static void nop_random_cb(uv_random_t* req, int status, void* buf, size_t len) { + struct random_info* ri; + + ri = container_of(req, struct random_info, random_req); + + ASSERT(status == UV_ECANCELED); + ASSERT(buf == (void*) ri->buf); + ASSERT(len == sizeof(ri->buf)); + + done_cb_called++; +} + + TEST_IMPL(threadpool_cancel_getaddrinfo) { uv_getaddrinfo_t reqs[4]; struct cancel_info ci; @@ -212,6 +230,29 @@ TEST_IMPL(threadpool_cancel_getnameinfo) { } +TEST_IMPL(threadpool_cancel_random) { + struct random_info req; + uv_loop_t* loop; + + saturate_threadpool(); + loop = uv_default_loop(); + ASSERT(0 == uv_random(loop, + &req.random_req, + &req.buf, + sizeof(req.buf), + 0, + nop_random_cb)); + ASSERT(0 == uv_cancel((uv_req_t*) &req)); + ASSERT(0 == done_cb_called); + unblock_threadpool(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == done_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + TEST_IMPL(threadpool_cancel_work) { struct cancel_info ci; uv_work_t reqs[16]; diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c index 9ee80e44e7c24a..6bac072db09631 100644 --- a/deps/uv/test/test-udp-multicast-join.c +++ b/deps/uv/test/test-udp-multicast-join.c @@ -74,7 +74,7 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { static int do_send(uv_udp_send_t* send_req) { uv_buf_t buf; struct sockaddr_in addr; - + buf = uv_buf_init("PING", 4); ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr)); diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c index edcd371b2c22c0..5de27a7fb292db 100644 --- a/deps/uv/test/test-udp-multicast-join6.c +++ b/deps/uv/test/test-udp-multicast-join6.c @@ -86,7 +86,7 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { static int do_send(uv_udp_send_t* send_req) { uv_buf_t buf; struct sockaddr_in6 addr; - + buf = uv_buf_init("PING", 4); ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr)); @@ -195,7 +195,7 @@ TEST_IMPL(udp_multicast_join6) { r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb); ASSERT(r == 0); - + r = do_send(&req); ASSERT(r == 0); diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp index 60792ad6ebbb57..73ff42c56e431c 100644 --- a/deps/uv/test/test.gyp +++ b/deps/uv/test/test.gyp @@ -52,6 +52,7 @@ 'test-hrtime.c', 'test-idle.c', 'test-idna.c', + 'test-ip4-addr.c', 'test-ip6-addr.c', 'test-ipc-heavy-traffic-deadlock-bug.c', 'test-ipc-send-recv.c', @@ -90,6 +91,7 @@ 'test-process-title.c', 'test-process-title-threadsafe.c', 'test-queue-foreach-delete.c', + 'test-random.c', 'test-ref.c', 'test-run-nowait.c', 'test-run-once.c', @@ -158,8 +160,6 @@ 'test-udp-multicast-join6.c', 'test-dlerror.c', 'test-udp-multicast-ttl.c', - 'test-ip4-addr.c', - 'test-ip6-addr.c', 'test-udp-multicast-interface.c', 'test-udp-multicast-interface6.c', 'test-udp-try-send.c', diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 75a6d9781995ae..051bdc937c9fd3 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -75,6 +75,7 @@ 'src/idna.h', 'src/inet.c', 'src/queue.h', + 'src/random.c', 'src/strscpy.c', 'src/strscpy.h', 'src/threadpool.c', @@ -167,6 +168,7 @@ 'src/unix/pipe.c', 'src/unix/poll.c', 'src/unix/process.c', + 'src/unix/random-devurandom.c', 'src/unix/signal.c', 'src/unix/spinlock.h', 'src/unix/stream.c', @@ -226,7 +228,8 @@ 'sources': [ 'src/unix/darwin.c', 'src/unix/fsevents.c', - 'src/unix/darwin-proctitle.c' + 'src/unix/darwin-proctitle.c', + 'src/unix/random-getentropy.c', ], 'defines': [ '_DARWIN_USE_64_BIT_INODE=1', @@ -241,6 +244,8 @@ 'src/unix/linux-syscalls.c', 'src/unix/linux-syscalls.h', 'src/unix/procfs-exepath.c', + 'src/unix/random-getrandom.c', + 'src/unix/random-sysctl.c', 'src/unix/sysinfo-loadavg.c', ], 'link_settings': { @@ -320,8 +325,14 @@ [ 'OS=="freebsd" or OS=="dragonflybsd"', { 'sources': [ 'src/unix/freebsd.c' ], }], + [ 'OS=="freebsd"', { + 'sources': [ 'src/unix/random-getrandom.c' ], + }], [ 'OS=="openbsd"', { - 'sources': [ 'src/unix/openbsd.c' ], + 'sources': [ + 'src/unix/openbsd.c', + 'src/unix/random-getentropy.c', + ], }], [ 'OS=="netbsd"', { 'link_settings': { From 972144073b51b1fecf966dcb03ebf83e61e78e2d Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Thu, 17 Oct 2019 12:11:54 +0200 Subject: [PATCH 20/33] src: remove unused iomanip include This commit removes the include of the IO manipulators header as I can't find that it is used anywhere. PR-URL: https://github.com/nodejs/node/pull/30004 Reviewed-By: Gireesh Punathil Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: David Carlier Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca --- src/node_report.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/node_report.cc b/src/node_report.cc index 088c63b9e8402d..25a4d671c8f1bd 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -18,7 +18,6 @@ #include #include #include -#include constexpr int NODE_REPORT_VERSION = 1; constexpr int NANOS_PER_SEC = 1000 * 1000 * 1000; From 0c88dc19327d8daaebf46bbed9a9ce80b40bf2ae Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Fri, 18 Oct 2019 10:56:24 -0700 Subject: [PATCH 21/33] src: fewer uses of NODE_USE_V8_PLATFORM PR-URL: https://github.com/nodejs/node/pull/30029 Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Gus Caplan Reviewed-By: Minwoo Jung Reviewed-By: Joyee Cheung --- src/env.h | 2 +- src/node.cc | 2 +- src/node_main_instance.cc | 2 +- src/node_worker.cc | 12 ++++++------ src/node_worker.h | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/env.h b/src/env.h index 46aecfd2521260..0e34c43ebafdf2 100644 --- a/src/env.h +++ b/src/env.h @@ -868,7 +868,7 @@ class Environment : public MemoryRetainer { void CreateProperties(); // Should be called before InitializeInspector() void InitializeDiagnostics(); -#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM +#if HAVE_INSPECTOR // If the environment is created for a worker, pass parent_handle and // the ownership if transferred into the Environment. int InitializeInspector(inspector::ParentInspectorHandle* parent_handle); diff --git a/src/node.cc b/src/node.cc index 5dbb837425d1f4..935be9343f0025 100644 --- a/src/node.cc +++ b/src/node.cc @@ -226,7 +226,7 @@ MaybeLocal ExecuteBootstrapper(Environment* env, return scope.EscapeMaybe(result); } -#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM +#if HAVE_INSPECTOR int Environment::InitializeInspector( inspector::ParentInspectorHandle* parent_handle) { std::string inspector_path; diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index e41e0c1fb6fe1f..be53b585f0a106 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -204,7 +204,7 @@ std::unique_ptr NodeMainInstance::CreateMainEnvironment( // TODO(joyeecheung): when we snapshot the bootstrapped context, // the inspector and diagnostics setup should after after deserialization. -#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM +#if HAVE_INSPECTOR *exit_code = env->InitializeInspector(nullptr); #endif if (*exit_code != 0) { diff --git a/src/node_worker.cc b/src/node_worker.cc index 3913c51112a021..20b162bd8135ba 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -8,7 +8,7 @@ #include "util-inl.h" #include "async_wrap-inl.h" -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR #include "inspector/worker_inspector.h" // ParentInspectorHandle #endif @@ -39,7 +39,7 @@ namespace worker { namespace { -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR void WaitForWorkerInspectorToStop(Environment* child) { child->inspector_agent()->WaitForDisconnect(); child->inspector_agent()->Stop(); @@ -82,7 +82,7 @@ Worker::Worker(Environment* env, Number::New(env->isolate(), static_cast(thread_id_))) .Check(); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR inspector_parent_handle_ = env->inspector_agent()->GetParentHandle(thread_id_, url); #endif @@ -193,7 +193,7 @@ void Worker::Run() { Locker locker(isolate_); Isolate::Scope isolate_scope(isolate_); SealHandleScope outer_seal(isolate_); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR bool inspector_started = false; #endif @@ -225,7 +225,7 @@ void Worker::Run() { env_->stop_sub_worker_contexts(); env_->RunCleanup(); RunAtExit(env_.get()); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR if (inspector_started) WaitForWorkerInspectorToStop(env_.get()); #endif @@ -270,7 +270,7 @@ void Worker::Run() { if (is_stopped()) return; { env_->InitializeDiagnostics(); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR env_->InitializeInspector(inspector_parent_handle_.release()); inspector_started = true; #endif diff --git a/src/node_worker.h b/src/node_worker.h index ffc4f19882cc26..77f68801e7c247 100644 --- a/src/node_worker.h +++ b/src/node_worker.h @@ -65,7 +65,7 @@ class Worker : public AsyncWrap { bool start_profiler_idle_notifier_; uv_thread_t tid_; -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR std::unique_ptr inspector_parent_handle_; #endif From f155dfeecb9246db1a54c26e7e76fcbd33bd269d Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 20 Oct 2019 14:29:02 +0200 Subject: [PATCH 22/33] test: expand Worker test for non-shared ArrayBuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test would be broken by V8 7.9 due to the changed `ArrayBuffer` backing store management (the same way that V8 7.8 broke this for `SharedArrayBuffer`s). While working on a solution, it would be good to already have this test in Node.js to avoid unnecessary accidental breakage. Refs: https://github.com/nodejs/node-v8/issues/115 PR-URL: https://github.com/nodejs/node/pull/30044 Reviewed-By: Yongsheng Zhang Reviewed-By: Michaël Zasso Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Luigi Pinca --- ...er-sharedarraybuffer-from-worker-thread.js | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js b/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js index 56dfe2ec41ab3a..ce8410f6dd3d75 100644 --- a/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js +++ b/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js @@ -5,19 +5,24 @@ const assert = require('assert'); const { Worker } = require('worker_threads'); // Regression test for https://github.com/nodejs/node/issues/28777 -// Make sure that SharedArrayBuffers created in Worker threads are accessible -// after the creating thread ended. +// Make sure that SharedArrayBuffers and transferred ArrayBuffers created in +// Worker threads are accessible after the creating thread ended. -const w = new Worker(` -const { parentPort } = require('worker_threads'); -const sharedArrayBuffer = new SharedArrayBuffer(4); -parentPort.postMessage(sharedArrayBuffer); -`, { eval: true }); +for (const ctor of ['ArrayBuffer', 'SharedArrayBuffer']) { + const w = new Worker(` + const { parentPort } = require('worker_threads'); + const arrayBuffer = new ${ctor}(4); + parentPort.postMessage( + arrayBuffer, + '${ctor}' === 'SharedArrayBuffer' ? [] : [arrayBuffer]); + `, { eval: true }); -let sharedArrayBuffer; -w.once('message', common.mustCall((message) => sharedArrayBuffer = message)); -w.once('exit', common.mustCall(() => { - const uint8array = new Uint8Array(sharedArrayBuffer); - uint8array[0] = 42; - assert.deepStrictEqual(uint8array, new Uint8Array([42, 0, 0, 0])); -})); + let arrayBuffer; + w.once('message', common.mustCall((message) => arrayBuffer = message)); + w.once('exit', common.mustCall(() => { + assert.strictEqual(arrayBuffer.constructor.name, ctor); + const uint8array = new Uint8Array(arrayBuffer); + uint8array[0] = 42; + assert.deepStrictEqual(uint8array, new Uint8Array([42, 0, 0, 0])); + })); +} From 46aa4810adad10785a03223d42c371df4af0f56a Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Sun, 20 Oct 2019 07:21:50 +0200 Subject: [PATCH 23/33] stream: remove dead code `String.prototype.split()` returns an array of strings so the branch is never taken. Fixes: https://github.com/nodejs/node/issues/30040 PR-URL: https://github.com/nodejs/node/pull/30041 Reviewed-By: Yongsheng Zhang Reviewed-By: David Carlier Reviewed-By: Anna Henningsen Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Jiawen Geng Reviewed-By: Trivikram Kamat Reviewed-By: Matteo Collina --- lib/stream.js | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/lib/stream.js b/lib/stream.js index 826f0e6d9adb6c..ff8838f4251594 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -43,23 +43,18 @@ Stream.Stream = Stream; Stream._isUint8Array = require('internal/util/types').isUint8Array; -const version = process.version.substr(1).split('.'); -if (version[0] === 0 && version[1] < 12) { - Stream._uint8ArrayToBuffer = Buffer; -} else { - try { - const internalBuffer = require('internal/buffer'); - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return new internalBuffer.FastBuffer(chunk.buffer, - chunk.byteOffset, - chunk.byteLength); - }; - } catch (e) { // eslint-disable-line no-unused-vars - } +try { + const internalBuffer = require('internal/buffer'); + Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { + return new internalBuffer.FastBuffer(chunk.buffer, + chunk.byteOffset, + chunk.byteLength); + }; +} catch (e) { // eslint-disable-line no-unused-vars +} - if (!Stream._uint8ArrayToBuffer) { - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return Buffer.prototype.slice.call(chunk); - }; - } +if (!Stream._uint8ArrayToBuffer) { + Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { + return Buffer.prototype.slice.call(chunk); + }; } From f3712dfe832d97af99be05b7ab76aa21d4fc9ac9 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Sun, 20 Oct 2019 13:36:49 +0200 Subject: [PATCH 24/33] stream: simplify uint8ArrayToBuffer helper The fallback code is no longer used when exporting to readable-stream. Refs: https://github.com/nodejs/node/pull/29514 PR-URL: https://github.com/nodejs/node/pull/30041 Fixes: https://github.com/nodejs/node/issues/30040 Reviewed-By: Yongsheng Zhang Reviewed-By: David Carlier Reviewed-By: Anna Henningsen Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Jiawen Geng Reviewed-By: Trivikram Kamat Reviewed-By: Matteo Collina --- lib/stream.js | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/lib/stream.js b/lib/stream.js index ff8838f4251594..725038ba9c0d1c 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -21,9 +21,9 @@ 'use strict'; -const { Buffer } = require('buffer'); const pipeline = require('internal/streams/pipeline'); const eos = require('internal/streams/end-of-stream'); +const internalBuffer = require('internal/buffer'); // Note: export Stream before Readable/Writable/Duplex/... // to avoid a cross-reference(require) issues @@ -42,19 +42,8 @@ Stream.finished = eos; Stream.Stream = Stream; Stream._isUint8Array = require('internal/util/types').isUint8Array; - -try { - const internalBuffer = require('internal/buffer'); - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return new internalBuffer.FastBuffer(chunk.buffer, - chunk.byteOffset, - chunk.byteLength); - }; -} catch (e) { // eslint-disable-line no-unused-vars -} - -if (!Stream._uint8ArrayToBuffer) { - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return Buffer.prototype.slice.call(chunk); - }; -} +Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { + return new internalBuffer.FastBuffer(chunk.buffer, + chunk.byteOffset, + chunk.byteLength); +}; From 35bffcdd9d8e55548e96cb9859ee0b134969f4a7 Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Sat, 19 Oct 2019 16:16:40 +0300 Subject: [PATCH 25/33] doc: join parts of disrupt section in cli.md Also eliminate some redundancy. PR-URL: https://github.com/nodejs/node/pull/30038 Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Colin Ihrig Reviewed-By: Yongsheng Zhang Reviewed-By: Rich Trott Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca --- doc/api/cli.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 13c0b102837af3..39172931a19bd6 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -237,7 +237,8 @@ added: v12.0.0 --> Enables a signal handler that causes the Node.js process to write a heap dump -when the specified signal is received. +when the specified signal is received. `signal` must be a valid signal name. +Disabled by default. ```console $ node --heapsnapshot-signal=SIGUSR2 index.js & @@ -300,9 +301,6 @@ added: v12.4.0 Specify the file name of the heap profile generated by `--heap-prof`. -Generates a heap snapshot each time the process receives the specified signal. -`signal` must be a valid signal name. Disabled by default. - ### `--icu-data-dir=file`