diff --git a/.eslintrc.js b/.eslintrc.js
index 0b4c170813d0a7..23ddc3c95cd39d 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -17,7 +17,10 @@ Module._findPath = (request, paths, isMain) => {
if (!r && hacks.includes(request)) {
try {
return require.resolve(`./tools/node_modules/${request}`);
- } catch {
+ // Keep the variable in place to ensure that ESLint started by older Node.js
+ // versions work as expected.
+ // eslint-disable-next-line no-unused-vars
+ } catch (e) {
return require.resolve(
`./tools/node_modules/eslint/node_modules/${request}`);
}
diff --git a/.travis.yml b/.travis.yml
index e496919579b2f8..3de388e838436f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,4 @@
language: cpp
-sudo: false
cache: ccache
os: linux
matrix:
diff --git a/BUILDING.md b/BUILDING.md
index 63ddf8e7f4ff2a..50f2984d679274 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -253,6 +253,16 @@ $ ./node ./test/parallel/test-stream2-transform.js
Remember to recompile with `make -j4` in between test runs if you change code in
the `lib` or `src` directories.
+The tests attempt to detect support for IPv6 and exclude IPv6 tests if
+appropriate. If your main interface has IPv6 addresses, then your
+loopback interface must also have '::1' enabled. For some default installations
+on Ubuntu that does not seem to be the case. To enable '::1' on the
+loopback interface on Ubuntu:
+
+```bash
+sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
+```
+
#### Running Coverage
It's good practice to ensure any code you add or change is covered by tests.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 78308184b6e8ec..ec9307646c0bc2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,7 +28,8 @@ release.
-11.3.0
+11.4.0
+11.3.0
11.2.0
11.1.0
11.0.0
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md
index ec3b0a8bf503fb..d270903c2eadc3 100644
--- a/COLLABORATOR_GUIDE.md
+++ b/COLLABORATOR_GUIDE.md
@@ -50,84 +50,71 @@ request. See [Who to CC in the issue tracker](#who-to-cc-in-the-issue-tracker).
### Welcoming First-Time Contributors
-Courtesy should always be shown to individuals submitting issues and pull
-requests to the Node.js project. Be welcoming to first-time contributors,
-identified by the GitHub ![First-time contributor](./doc/first_timer_badge.png)
-badge.
+Always show courtesy to individuals submitting issues and pull requests. Be
+welcoming to first-time contributors, identified by the GitHub
+![First-time contributor](./doc/first_timer_badge.png) badge.
-For first-time contributors, check if the commit author is the same as the
-pull request author, and ask if they have configured their git
+For first-time contributors, check if the commit author is the same as the pull
+request author. This way, once their pull request lands, GitHub will show them
+as a _Contributor_. Ask if they have configured their git
[username][git-username] and [email][git-email] to their liking.
-This is to make sure they would be promoted to "contributor" once their
-pull request lands.
### Closing Issues and Pull Requests
-Collaborators may close any issue or pull request they believe is
-not relevant for the future of the Node.js project. Where this is
-unclear, the issue should be left open for several days to allow for
-additional discussion. Where this does not yield input from Node.js
-Collaborators or additional evidence that the issue has relevance, the
-issue may be closed. Remember that issues can always be re-opened if
-necessary.
+Collaborators may close any issue or pull request that is not relevant to the
+future of the Node.js project. Where this is unclear, leave the issue or pull
+request open for several days to allow for discussion. Where this does not yield
+evidence that the issue or pull request has relevance, close it. Remember that
+issues and pull requests can always be re-opened if necessary.
### Author ready pull requests
-A pull request that is still awaiting the minimum review time is considered
-_author ready_ as soon as the CI has been started, it has at least two approvals
-(one Collaborator approval is enough if the pull request has been open for more
-than 7 days), and it has no outstanding review comments. Please always make sure
-to add the `author ready` label to the PR in that case and remove it again as
-soon as that condition is not met anymore.
+A pull request is _author ready_ when:
+
+* There is a CI run in progress or completed.
+* There are at least two Collaborator approvals, or at least one approval if the
+ pull request is older than 7 days.
+* There are no outstanding review comments.
+
+Please always add the `author ready` label to the pull request in that case.
+Please always remove it again as soon as the conditions are not met anymore.
### Handling own pull requests
-When you open a pull request, it is recommended to start a CI right away (see
-[testing and CI](#testing-and-ci) for instructions) and to post the link to it
-in a comment in the pull request. Starting a new CI after each update is also
-recommended (for example, after an additional code change or after rebasing).
+When you open a pull request, [start a CI](#testing-and-ci) right away and post
+the link to it in a comment in the pull request. Later, after new code changes
+or rebasing, start a new CI.
-As soon as the PR is ready to land, please do so. Landing your own pull requests
-allows other Collaborators to focus on other pull requests. If your pull request
-is still awaiting the [minimum time to land](#waiting-for-approvals), add the
-`author ready` label so other Collaborators know it can land as soon as the time
-ends. If instead you wish to land the PR yourself, indicate this intent by using
-the "assign yourself" button, to self-assign the PR.
+As soon as the pull request is ready to land, please do so. This allows other
+Collaborators to focus on other pull requests. If your pull request is not ready
+to land but is [author ready](#author-ready-pull-requests), add the
+`author ready` label. If you wish to land the pull request yourself, use the
+"assign yourself" link to self-assign it.
## Accepting Modifications
-All modifications to the Node.js code and documentation should be performed via
-GitHub pull requests, including modifications by Collaborators and TSC members.
-A pull request must be reviewed, and must also be tested with CI, before being
-landed into the codebase. There may be exceptions to the latter (the changed
-code cannot be tested with a CI or similar). If that is the case, please leave a
-comment that explains why the PR does not require a CI run.
+Contributors propose modifications to Node.js using GitHub pull requests. This
+includes modifications proposed by TSC members and other Collaborators. A pull
+request must pass code review and CI before landing into the codebase.
### Code Reviews
At least two Collaborators must approve a pull request before the pull request
-lands. (One Collaborator approval is enough if the pull request has been open
-for more than 7 days.) Approving a pull request indicates that the Collaborator
-accepts responsibility for the change. Approval must be from Collaborators who
-are not authors of the change.
+lands. One Collaborator approval is enough if the pull request has been open
+for more than seven days.
+
+Approving a pull request indicates that the Collaborator accepts responsibility
+for the change.
+
+Approval must be from Collaborators who are not authors of the change.
In some cases, it may be necessary to summon a GitHub team to a pull request for
review by @-mention.
See [Who to CC in the issue tracker](#who-to-cc-in-the-issue-tracker).
-If you are unsure about the modification and are not prepared to take
-full responsibility for the change, defer to another Collaborator.
-
If you are the first Collaborator to approve a pull request that has no CI yet,
-please start one (see [testing and CI](#testing-and-ci) for further information
-on how to do that) and post the link to the CI in the PR. Please also start a
-new CI in case the PR creator pushed new code since the last CI run (due to
-e.g., an addressed review comment or a rebase).
-
-In case there are already enough approvals (`LGTM`), a CI run, and the PR is
-open longer than the minimum waiting time without any open comments, please do
-not (only) add another approval. Instead go ahead and land the PR after checking
-the CI outcome.
+please [start one](#testing-and-ci). Post the link to the CI in the PR. Please
+also start a new CI if the PR creator pushed new code since the last CI run.
### Consensus Seeking
@@ -154,8 +141,9 @@ the TSC meeting agenda.
#### Helpful resources
-* How to respectfully and usefully review code, part [one](https://mtlynch.io/human-code-reviews-1/) and [two](https://mtlynch.io/human-code-reviews-2/)
-* [How to write a positive code review](https://css-tricks.com/code-review-etiquette/)
+* [How to Do Code Reviews Like a Human (Part One)](https://mtlynch.io/human-code-reviews-1/)
+* [How to Do Code Reviews Like a Human (Part Two)](https://mtlynch.io/human-code-reviews-2/)
+* [Code Review Etiquette](https://css-tricks.com/code-review-etiquette/)
### Waiting for Approvals
@@ -794,8 +782,8 @@ TSC for further discussion.
#### How are LTS Branches Managed?
-There are multiple LTS branches, e.g. `v8.x` and `v6.x`. Each of these is paired
-with a staging branch: `v8.x-staging` and `v6.x-staging`.
+There are multiple LTS branches, e.g. `v10.x` and `v8.x`. Each of these is
+paired with a staging branch: `v10.x-staging` and `v8.x-staging`.
As commits land on the master branch, they are cherry-picked back to each
staging branch as appropriate. If the commit applies only to the LTS branch, the
@@ -804,9 +792,8 @@ pulled from the staging branch into the LTS branch only when a release is
being prepared and may be pulled into the LTS branch in a different order
than they were landed in staging.
-Any Collaborator may land commits into a staging branch, but only the release
-team should land commits into the LTS branch while preparing a new
-LTS release.
+Only the members of the @nodejs/backporters team should land commits onto
+LTS staging branches.
#### How can I help?
@@ -817,14 +804,18 @@ on backporting, please see the [backporting guide][].
Several LTS related issue and PR labels have been provided:
-* `lts-watch-v6.x` - tells the LTS WG that the issue/PR needs to be considered
- for landing in the `v6.x-staging` branch.
-* `lts-watch-v4.x` - tells the LTS WG that the issue/PR needs to be considered
- for landing in the `v4.x-staging` branch.
+* `lts-watch-v10.x` - tells the LTS WG that the issue/PR needs to be
+ considered for landing in the `v10.x-staging` branch.
+* `lts-watch-v8.x` - tells the LTS WG that the issue/PR needs to be
+ considered for landing in the `v8.x-staging` branch.
+* `lts-watch-v6.x` - tells the LTS WG that the issue/PR needs to be
+ considered for landing in the `v6.x-staging` branch.
+* `land-on-v10.x` - tells the release team that the commit should be landed
+ in a future v10.x release.
+* `land-on-v8.x` - tells the release team that the commit should be landed
+ in a future v8.x release.
* `land-on-v6.x` - tells the release team that the commit should be landed
- in a future v6.x release
-* `land-on-v4.x` - tells the release team that the commit should be landed
- in a future v4.x release
+ in a future v6.x release.
Any Collaborator can attach these labels to any PR/issue. As commits are
landed into the staging branches, the `lts-watch-` label will be removed.
diff --git a/CPP_STYLE_GUIDE.md b/CPP_STYLE_GUIDE.md
index 5099f34ea866c9..b82ed7cc190ec8 100644
--- a/CPP_STYLE_GUIDE.md
+++ b/CPP_STYLE_GUIDE.md
@@ -21,6 +21,7 @@
* [Use explicit pointer comparisons](#use-explicit-pointer-comparisons)
* [Ownership and Smart Pointers](#ownership-and-smart-pointers)
* [Avoid non-const references](#avoid-non-const-references)
+ * [Use AliasedBuffers to manipulate TypedArrays](#use-aliasedbuffers-to-manipulate-typedarrays)
* [Others](#others)
* [Type casting](#type-casting)
* [Using `auto`](#using-auto)
@@ -257,6 +258,21 @@ class ExampleClass {
};
```
+### Use AliasedBuffers to manipulate TypedArrays
+
+When working with typed arrays that involve direct data modification
+from C++, use an `AliasedBuffer` when possible. The API abstraction and
+the usage scope of `AliasedBuffer` are documented in [aliased_buffer.h][].
+
+```c++
+// Create an AliasedBuffer.
+AliasedBuffer data;
+...
+
+// Modify the data through natural operator semantics.
+data[0] = 12345;
+```
+
## Others
### Type casting
@@ -382,3 +398,4 @@ even `try` and `catch` **will** break.
[Run Time Type Information]: https://en.wikipedia.org/wiki/Run-time_type_information
[cppref_auto_ptr]: https://en.cppreference.com/w/cpp/memory/auto_ptr
[without C++ exception handling]: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html#intro.using.exception.no
+[aliased_buffer.h]: https://github.com/nodejs/node/blob/master/src/aliased_buffer.h#L12
diff --git a/Makefile b/Makefile
index 7c2afde30a3d28..6dfc1de6af5833 100644
--- a/Makefile
+++ b/Makefile
@@ -270,7 +270,7 @@ v8:
tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS)
.PHONY: jstest
-jstest: build-addons build-addons-napi ## Runs addon tests and JS tests
+jstest: build-addons build-js-native-api-tests build-node-api-tests ## Runs addon tests and JS tests
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \
--skip-tests=$(CI_SKIP_TESTS) \
$(CI_JS_SUITES) \
@@ -281,21 +281,24 @@ jstest: build-addons build-addons-napi ## Runs addon tests and JS tests
test: all ## Runs default tests, linters, and builds docs.
$(MAKE) -s test-doc
$(MAKE) -s build-addons
- $(MAKE) -s build-addons-napi
+ $(MAKE) -s build-js-native-api-tests
+ $(MAKE) -s build-node-api-tests
$(MAKE) -s cctest
$(MAKE) -s jstest
.PHONY: test-only
test-only: all ## For a quick test, does not run linter or build docs.
$(MAKE) build-addons
- $(MAKE) build-addons-napi
+ $(MAKE) build-js-native-api-tests
+ $(MAKE) build-node-api-tests
$(MAKE) cctest
$(MAKE) jstest
# Used by `make coverage-test`
test-cov: all
$(MAKE) build-addons
- $(MAKE) build-addons-napi
+ $(MAKE) build-js-native-api-tests
+ $(MAKE) build-node-api-tests
# $(MAKE) cctest
CI_SKIP_TESTS=core_line_numbers.js $(MAKE) jstest
@@ -381,29 +384,55 @@ test/addons/.buildstamp: $(ADDONS_PREREQS) \
# TODO(bnoordhuis) Force rebuild after gyp update.
build-addons: | $(NODE_EXE) test/addons/.buildstamp
-ADDONS_NAPI_BINDING_GYPS := \
- $(filter-out test/addons-napi/??_*/binding.gyp, \
- $(wildcard test/addons-napi/*/binding.gyp))
+JS_NATIVE_API_BINDING_GYPS := \
+ $(filter-out test/js-native-api/??_*/binding.gyp, \
+ $(wildcard test/js-native-api/*/binding.gyp))
-ADDONS_NAPI_BINDING_SOURCES := \
- $(filter-out test/addons-napi/??_*/*.c, $(wildcard test/addons-napi/*/*.c)) \
- $(filter-out test/addons-napi/??_*/*.cc, $(wildcard test/addons-napi/*/*.cc)) \
- $(filter-out test/addons-napi/??_*/*.h, $(wildcard test/addons-napi/*/*.h))
+JS_NATIVE_API_BINDING_SOURCES := \
+ $(filter-out test/js-native-api/??_*/*.c, $(wildcard test/js-native-api/*/*.c)) \
+ $(filter-out test/js-native-api/??_*/*.cc, $(wildcard test/js-native-api/*/*.cc)) \
+ $(filter-out test/js-native-api/??_*/*.h, $(wildcard test/js-native-api/*/*.h))
-# Implicitly depends on $(NODE_EXE), see the build-addons-napi rule for rationale.
-test/addons-napi/.buildstamp: $(ADDONS_PREREQS) \
- $(ADDONS_NAPI_BINDING_GYPS) $(ADDONS_NAPI_BINDING_SOURCES) \
- src/node_api.h src/node_api_types.h
- @$(call run_build_addons,"$$PWD/test/addons-napi",$@)
+# Implicitly depends on $(NODE_EXE), see the build-js-native-api-tests rule for rationale.
+test/js-native-api/.buildstamp: $(ADDONS_PREREQS) \
+ $(JS_NATIVE_API_BINDING_GYPS) $(JS_NATIVE_API_BINDING_SOURCES) \
+ src/node_api.h src/node_api_types.h src/js_native_api.h \
+ src/js_native_api_types.h src/js_native_api_v8.h src/js_native_api_v8_internals.h
+ @$(call run_build_addons,"$$PWD/test/js-native-api",$@)
-.PHONY: build-addons-napi
+.PHONY: build-js-native-api-tests
# .buildstamp needs $(NODE_EXE) but cannot depend on it
# directly because it calls make recursively. The parent make cannot know
# if the subprocess touched anything so it pessimistically assumes that
# .buildstamp is out of date and need a rebuild.
# Just goes to show that recursive make really is harmful...
# TODO(bnoordhuis) Force rebuild after gyp or node-gyp update.
-build-addons-napi: | $(NODE_EXE) test/addons-napi/.buildstamp
+build-js-native-api-tests: | $(NODE_EXE) test/js-native-api/.buildstamp
+
+NODE_API_BINDING_GYPS := \
+ $(filter-out test/node-api/??_*/binding.gyp, \
+ $(wildcard test/node-api/*/binding.gyp))
+
+NODE_API_BINDING_SOURCES := \
+ $(filter-out test/node-api/??_*/*.c, $(wildcard test/node-api/*/*.c)) \
+ $(filter-out test/node-api/??_*/*.cc, $(wildcard test/node-api/*/*.cc)) \
+ $(filter-out test/node-api/??_*/*.h, $(wildcard test/node-api/*/*.h))
+
+# Implicitly depends on $(NODE_EXE), see the build-node-api-tests rule for rationale.
+test/node-api/.buildstamp: $(ADDONS_PREREQS) \
+ $(NODE_API_BINDING_GYPS) $(NODE_API_BINDING_SOURCES) \
+ src/node_api.h src/node_api_types.h src/js_native_api.h \
+ src/js_native_api_types.h src/js_native_api_v8.h src/js_native_api_v8_internals.h
+ @$(call run_build_addons,"$$PWD/test/node-api",$@)
+
+.PHONY: build-node-api-tests
+# .buildstamp needs $(NODE_EXE) but cannot depend on it
+# directly because it calls make recursively. The parent make cannot know
+# if the subprocess touched anything so it pessimistically assumes that
+# .buildstamp is out of date and need a rebuild.
+# Just goes to show that recursive make really is harmful...
+# TODO(bnoordhuis) Force rebuild after gyp or node-gyp update.
+build-node-api-tests: | $(NODE_EXE) test/node-api/.buildstamp
.PHONY: clear-stalled
clear-stalled:
@@ -414,9 +443,11 @@ clear-stalled:
echo $${PS_OUT} | xargs kill -9; \
fi
-test-build: | all build-addons build-addons-napi
+test-build: | all build-addons build-js-native-api-tests build-node-api-tests
+
+test-build-js-native-api: all build-js-native-api-tests
-test-build-addons-napi: all build-addons-napi
+test-build-node-api: all build-node-api-tests
.PHONY: test-all
test-all: test-build ## Run everything in test/.
@@ -425,7 +456,7 @@ test-all: test-build ## Run everything in test/.
test-all-valgrind: test-build
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=debug,release --valgrind
-CI_NATIVE_SUITES ?= addons addons-napi
+CI_NATIVE_SUITES ?= addons js-native-api node-api
CI_JS_SUITES ?= default
CI_DOC := doctool
@@ -433,7 +464,7 @@ CI_DOC := doctool
# Build and test addons without building anything else
# Related CI job: node-test-commit-arm-fanned
test-ci-native: LOGLEVEL := info
-test-ci-native: | test/addons/.buildstamp test/addons-napi/.buildstamp
+test-ci-native: | test/addons/.buildstamp test/js-native-api/.buildstamp test/node-api/.buildstamp
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
$(TEST_CI_ARGS) $(CI_NATIVE_SUITES)
@@ -455,7 +486,7 @@ test-ci-js: | clear-stalled
.PHONY: test-ci
# Related CI jobs: most CI tests, excluding node-test-commit-arm-fanned
test-ci: LOGLEVEL := info
-test-ci: | clear-stalled build-addons build-addons-napi doc-only bench-addons-build
+test-ci: | clear-stalled build-addons build-js-native-api-tests build-node-api-tests doc-only
out/Release/cctest --gtest_output=tap:cctest.tap
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
@@ -538,17 +569,26 @@ test-npm: $(NODE_EXE) ## Run the npm test suite on deps/npm.
test-npm-publish: $(NODE_EXE)
npm_package_config_publishtest=true $(NODE) deps/npm/test/run.js
-.PHONY: test-addons-napi
-test-addons-napi: test-build-addons-napi
- $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) addons-napi
+.PHONY: test-js-native-api
+test-js-native-api: test-build-js-native-api
+ $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) js-native-api
+
+.PHONY: test-js-native-api-clean
+test-js-native-api-clean:
+ $(RM) -r test/js-native-api/*/build
+ $(RM) test/js-native-api/.buildstamp
-.PHONY: test-addons-napi-clean
-test-addons-napi-clean:
- $(RM) -r test/addons-napi/*/build
- $(RM) test/addons-napi/.buildstamp
+.PHONY: test-node-api
+test-node-api: test-build-node-api
+ $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) node-api
+
+.PHONY: test-node-api-clean
+test-node-api-clean:
+ $(RM) -r test/node-api/*/build
+ $(RM) test/node-api/.buildstamp
.PHONY: test-addons
-test-addons: test-build test-addons-napi
+test-addons: test-build test-js-native-api test-node-api
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) addons
.PHONY: test-addons-clean
@@ -556,14 +596,16 @@ test-addons-clean:
$(RM) -r test/addons/??_*/
$(RM) -r test/addons/*/build
$(RM) test/addons/.buildstamp test/addons/.docbuildstamp
- $(MAKE) test-addons-napi-clean
+ $(MAKE) test-js-native-api-clean
+ $(MAKE) test-node-api-clean
test-async-hooks:
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) async-hooks
test-with-async-hooks:
$(MAKE) build-addons
- $(MAKE) build-addons-napi
+ $(MAKE) build-js-native-api-tests
+ $(MAKE) build-node-api-tests
$(MAKE) cctest
NODE_TEST_WITH_ASYNC_HOOKS=1 $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \
$(CI_JS_SUITES) \
@@ -809,19 +851,34 @@ BINARYNAME=$(TARNAME)-$(PLATFORM)-$(ARCH)
endif
BINARYTAR=$(BINARYNAME).tar
# OSX doesn't have xz installed by default, http://macpkg.sourceforge.net/
-XZ=$(shell which xz > /dev/null 2>&1; echo $$?)
+HAS_XZ ?= $(shell which xz > /dev/null 2>&1; [ $$? -eq 0 ] && echo 1 || echo 0)
+# Supply SKIP_XZ=1 to explicitly skip .tar.xz creation
+SKIP_XZ ?= 0
+XZ = $(shell [ $(HAS_XZ) -eq 1 -a $(SKIP_XZ) -eq 0 ] && echo 1 || echo 0)
XZ_COMPRESSION ?= 9e
PKG=$(TARNAME).pkg
MACOSOUTDIR=out/macos
+ifeq ($(SKIP_XZ), 1)
+check-xz:
+ @echo "SKIP_XZ=1 supplied, skipping .tar.xz creation"
+else
+ifeq ($(HAS_XZ), 1)
+check-xz:
+else
+check-xz:
+ @echo "No xz command, cannot continue"
+ @exit 1
+endif
+endif
+
.PHONY: release-only
-release-only:
- @if [ "$(DISTTYPE)" != "nightly" ] && [ "$(DISTTYPE)" != "next-nightly" ] && \
- `grep -q REPLACEME doc/api/*.md`; then \
+release-only: check-xz
+ @if [ "$(DISTTYPE)" = "release" ] && `grep -q REPLACEME doc/api/*.md`; then \
echo 'Please update REPLACEME in Added: tags in doc/api/*.md (See doc/releases.md)' ; \
exit 1 ; \
fi
- @if [ "$(DISTTYPE)" != "nightly" ] && [ "$(DISTTYPE)" != "next-nightly" ] && \
+ @if [ "$(DISTTYPE)" = "release" ] && \
`grep -q DEP...X doc/api/deprecations.md`; then \
echo 'Please update DEP...X in doc/api/deprecations.md (See doc/releases.md)' ; \
exit 1 ; \
@@ -942,7 +999,7 @@ $(TARBALL): release-only $(NODE_EXE) doc
tar -cf $(TARNAME).tar $(TARNAME)
$(RM) -r $(TARNAME)
gzip -c -f -9 $(TARNAME).tar > $(TARNAME).tar.gz
-ifeq ($(XZ), 0)
+ifeq ($(XZ), 1)
xz -c -f -$(XZ_COMPRESSION) $(TARNAME).tar > $(TARNAME).tar.xz
endif
$(RM) $(TARNAME).tar
@@ -956,7 +1013,7 @@ tar-upload: tar
chmod 664 $(TARNAME).tar.gz
scp -p $(TARNAME).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz.done"
-ifeq ($(XZ), 0)
+ifeq ($(XZ), 1)
chmod 664 $(TARNAME).tar.xz
scp -p $(TARNAME).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz.done"
@@ -982,7 +1039,7 @@ $(TARBALL)-headers: release-only
tar -cf $(TARNAME)-headers.tar $(TARNAME)
$(RM) -r $(TARNAME)
gzip -c -f -9 $(TARNAME)-headers.tar > $(TARNAME)-headers.tar.gz
-ifeq ($(XZ), 0)
+ifeq ($(XZ), 1)
xz -c -f -$(XZ_COMPRESSION) $(TARNAME)-headers.tar > $(TARNAME)-headers.tar.xz
endif
$(RM) $(TARNAME)-headers.tar
@@ -994,7 +1051,7 @@ tar-headers-upload: tar-headers
chmod 664 $(TARNAME)-headers.tar.gz
scp -p $(TARNAME)-headers.tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz.done"
-ifeq ($(XZ), 0)
+ifeq ($(XZ), 1)
chmod 664 $(TARNAME)-headers.tar.xz
scp -p $(TARNAME)-headers.tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz.done"
@@ -1019,7 +1076,7 @@ endif
tar -cf $(BINARYNAME).tar $(BINARYNAME)
$(RM) -r $(BINARYNAME)
gzip -c -f -9 $(BINARYNAME).tar > $(BINARYNAME).tar.gz
-ifeq ($(XZ), 0)
+ifeq ($(XZ), 1)
xz -c -f -$(XZ_COMPRESSION) $(BINARYNAME).tar > $(BINARYNAME).tar.xz
endif
$(RM) $(BINARYNAME).tar
@@ -1034,7 +1091,7 @@ binary-upload: binary
chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done"
-ifeq ($(XZ), 0)
+ifeq ($(XZ), 1)
chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done"
@@ -1060,13 +1117,11 @@ bench-addons-clean:
.PHONY: lint-md-rollup
lint-md-rollup:
- cd tools/node-lint-md-cli-rollup/remark-preset-lint-node && npm up
- cd tools/node-lint-md-cli-rollup && npm up
+ cd tools/node-lint-md-cli-rollup && npm install
cd tools/node-lint-md-cli-rollup && npm run build-node
.PHONY: lint-md-clean
lint-md-clean:
- $(RM) -r tools/node-lint-md-cli-rollup/remark-preset-lint-node/node_modules
$(RM) -r tools/node-lint-md-cli-rollup/node_modules
$(RM) tools/.*mdlintstamp
@@ -1085,7 +1140,7 @@ tools/.docmdlintstamp: $(LINT_MD_DOC_FILES)
LINT_MD_TARGETS = src lib benchmark test tools/doc tools/icu
LINT_MD_ROOT_DOCS := $(wildcard *.md)
LINT_MD_MISC_FILES := $(shell find $(LINT_MD_TARGETS) -type f \
- -not -path '*node_modules*' -not -path 'test/fixtures/*' -name '*.md') \
+ ! -path '*node_modules*' ! -path 'test/fixtures/*' -name '*.md') \
$(LINT_MD_ROOT_DOCS)
run-lint-misc-md = tools/lint-md.js -q -f $(LINT_MD_MISC_FILES)
# Lint other changed markdown files maintained by us
@@ -1138,7 +1193,7 @@ LINT_CPP_ADDON_DOC_FILES = $(wildcard $(LINT_CPP_ADDON_DOC_FILES_GLOB))
LINT_CPP_EXCLUDE ?=
LINT_CPP_EXCLUDE += src/node_root_certs.h
LINT_CPP_EXCLUDE += $(LINT_CPP_ADDON_DOC_FILES)
-LINT_CPP_EXCLUDE += $(wildcard test/addons-napi/??_*/*.cc test/addons-napi/??_*/*.h)
+LINT_CPP_EXCLUDE += $(wildcard test/js-native-api/??_*/*.cc test/js-native-api/??_*/*.h test/node-api/??_*/*.cc test/node-api/??_*/*.h)
# These files were copied more or less verbatim from V8.
LINT_CPP_EXCLUDE += src/tracing/trace_event.h src/tracing/trace_event_common.h
@@ -1154,8 +1209,10 @@ LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \
test/addons/*/*.h \
test/cctest/*.cc \
test/cctest/*.h \
- test/addons-napi/*/*.cc \
- test/addons-napi/*/*.h \
+ test/js-native-api/*/*.cc \
+ test/js-native-api/*/*.h \
+ test/node-api/*/*.cc \
+ test/node-api/*/*.h \
tools/icu/*.cc \
tools/icu/*.h \
))
@@ -1229,7 +1286,7 @@ ifneq ("","$(wildcard tools/pip/site-packages)")
lint-py:
PYTHONPATH=tools/pip $(PYTHON) -m flake8 . \
--count --show-source --statistics --select=E901,E999,F821,F822,F823 \
- --exclude=deps,lib,src,tools/*_macros.py,tools/gyp,tools/jinja2,tools/pip
+ --exclude=.git,deps,lib,src,tools/*_macros.py,tools/gyp,tools/jinja2,tools/pip
else
lint-py:
@echo "Python linting with flake8 is not avalible"
diff --git a/README.md b/README.md
index 533b36bf8dbd58..1835c51cc6e252 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ The open source license grants you the freedom to use Node.js. It does not
guarantee commitments of other people's time. Please be respectful and manage
your expectations.
-## Release Types
+## Release Types
* **Current**: Under active development. Code for the Current release is in the
branch for its major version number (for example,
@@ -83,7 +83,7 @@ your expectations.
Current and LTS releases follow [Semantic Versioning](https://semver.org). A
member of the Release Team [signs](#release-keys) each Current and LTS release.
For more information, see the
-[Release README](https://github.com/nodejs/Release).
+[Release README](https://github.com/nodejs/Release#readme).
### Download
@@ -203,10 +203,6 @@ For information about the governance of the Node.js project, see
**Michaël Zasso** <targos@protonmail.com> (he/him)
* [thefourtheye](https://github.com/thefourtheye) -
**Sakthipriyan Vairamani** <thechargingvolcano@gmail.com> (he/him)
-* [TimothyGu](https://github.com/TimothyGu) -
-**Tiancheng "Timothy" Gu** <timothygu99@gmail.com> (he/him)
-* [Trott](https://github.com/Trott) -
-**Rich Trott** <rtrott@gmail.com> (he/him)
### TSC Emeriti
@@ -234,8 +230,12 @@ For information about the governance of the Node.js project, see
**Bert Belder** <bertbelder@gmail.com>
* [shigeki](https://github.com/shigeki) -
**Shigeki Ohtsu** <ohtsu@ohtsu.org> (he/him)
+* [TimothyGu](https://github.com/TimothyGu) -
+**Tiancheng "Timothy" Gu** <timothygu99@gmail.com> (he/him)
* [trevnorris](https://github.com/trevnorris) -
**Trevor Norris** <trev.norris@gmail.com>
+* [Trott](https://github.com/Trott) -
+**Rich Trott** <rtrott@gmail.com> (he/him)
### Collaborators
@@ -249,6 +249,8 @@ For information about the governance of the Node.js project, see
**Andreas Madsen** <amwebdk@gmail.com> (he/him)
* [AnnaMag](https://github.com/AnnaMag) -
**Anna M. Kedzierska** <anna.m.kedzierska@gmail.com>
+* [antsmartian](https://github.com/antsmartian) -
+**Anto Aravinth** <anto.aravinth.cse@gmail.com> (he/him)
* [apapirovski](https://github.com/apapirovski) -
**Anatoli Papirovski** <apapirovski@mac.com> (he/him)
* [aqrln](https://github.com/aqrln) -
@@ -530,6 +532,8 @@ maintaining the Node.js project.
GPG keys used to sign Node.js releases:
+* **Beth Griggs** <bethany.griggs@uk.ibm.com>
+`4ED778F539E3634C779C87C6D7062848A1AB005C`
* **Colin Ihrig** <cjihrig@gmail.com>
`94AE36675C464D64BAFA68DD7434390BDBE9B9C5`
* **Evan Lucas** <evanlucas@me.com>
@@ -546,10 +550,13 @@ GPG keys used to sign Node.js releases:
`C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8`
* **Rod Vagg** <rod@vagg.org>
`DD8F2338BAE7501E3DD5AC78C273792F7D83545D`
+* **Ruben Bridgewater** <ruben@bridgewater.de>
+`A48C2BEE680E841632CD4E44F07496B3EB3C1762`
To import the full set of trusted release keys:
```shell
+gpg --keyserver pool.sks-keyservers.net --recv-keys 4ED778F539E3634C779C87C6D7062848A1AB005C
gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5
gpg --keyserver pool.sks-keyservers.net --recv-keys B9AE9905FFD7803F25714661B63B535A4C206CA9
gpg --keyserver pool.sks-keyservers.net --recv-keys 77984A986EBC2AA786BC0F66B01FBB92821C587A
@@ -558,6 +565,7 @@ gpg --keyserver pool.sks-keyservers.net --recv-keys FD3A5288F042B6850C66B31F09FE
gpg --keyserver pool.sks-keyservers.net --recv-keys 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600
gpg --keyserver pool.sks-keyservers.net --recv-keys C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8
gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D
+gpg --keyserver pool.sks-keyservers.net --recv-keys A48C2BEE680E841632CD4E44F07496B3EB3C1762
```
See the section above on [Verifying Binaries](#verifying-binaries) for how to
diff --git a/benchmark/common.js b/benchmark/common.js
index c76831b573dde6..d5e0494c16e826 100644
--- a/benchmark/common.js
+++ b/benchmark/common.js
@@ -254,3 +254,95 @@ exports.binding = function(bindingName) {
return process.binding(bindingName);
}
};
+
+const urls = {
+ long: 'http://nodejs.org:89/docs/latest/api/foo/bar/qua/13949281/0f28b/' +
+ '/5d49/b3020/url.html#test?payload1=true&payload2=false&test=1' +
+ '&benchmark=3&foo=38.38.011.293&bar=1234834910480&test=19299&3992&' +
+ 'key=f5c65e1e98fe07e648249ad41e1cfdb0',
+ short: 'https://nodejs.org/en/blog/',
+ idn: 'http://你好你好.在线',
+ auth: 'https://user:pass@example.com/path?search=1',
+ file: 'file:///foo/bar/test/node.js',
+ ws: 'ws://localhost:9229/f46db715-70df-43ad-a359-7f9949f39868',
+ javascript: 'javascript:alert("node is awesome");',
+ percent: 'https://%E4%BD%A0/foo',
+ dot: 'https://example.org/./a/../b/./c'
+};
+exports.urls = urls;
+
+const searchParams = {
+ noencode: 'foo=bar&baz=quux&xyzzy=thud',
+ multicharsep: 'foo=bar&&&&&&&&&&baz=quux&&&&&&&&&&xyzzy=thud',
+ encodefake: 'foo=%©ar&baz=%A©uux&xyzzy=%©ud',
+ encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d',
+ encodelast: 'foo=bar&baz=quux&xyzzy=thu%64',
+ multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz',
+ multivaluemany: 'foo=bar&foo=baz&foo=quux&quuy=quuz&foo=abc&foo=def&' +
+ 'foo=ghi&foo=jkl&foo=mno&foo=pqr&foo=stu&foo=vwxyz',
+ manypairs: 'a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z',
+ manyblankpairs: '&&&&&&&&&&&&&&&&&&&&&&&&',
+ altspaces: 'foo+bar=baz+quux&xyzzy+thud=quuy+quuz&abc=def+ghi'
+};
+exports.searchParams = searchParams;
+
+function getUrlData(withBase) {
+ const data = require('../test/fixtures/wpt/url/resources/urltestdata.json');
+ const result = [];
+ for (const item of data) {
+ if (item.failure || !item.input) continue;
+ if (withBase) {
+ result.push([item.input, item.base]);
+ } else if (item.base !== 'about:blank') {
+ result.push(item.base);
+ }
+ }
+ return result;
+}
+
+exports.urlDataTypes = Object.keys(urls).concat(['wpt']);
+
+/**
+ * Generate an array of data for URL benchmarks to use.
+ * The size of the resulting data set is the original data size * 2 ** `e`.
+ * The 'wpt' type contains about 400 data points when `withBase` is true,
+ * and 200 data points when `withBase` is false.
+ * Other types contain 200 data points with or without base.
+ *
+ * @param {string} type Type of the data, 'wpt' or a key of `urls`
+ * @param {number} e The repetition of the data, as exponent of 2
+ * @param {boolean} withBase Whether to include a base URL
+ * @param {boolean} asUrl Whether to return the results as URL objects
+ * @return {string[] | string[][] | URL[]}
+ */
+function bakeUrlData(type, e = 0, withBase = false, asUrl = false) {
+ let result = [];
+ if (type === 'wpt') {
+ result = getUrlData(withBase);
+ } else if (urls[type]) {
+ const input = urls[type];
+ const item = withBase ? [input, 'about:blank'] : input;
+ // Roughly the size of WPT URL test data
+ result = new Array(200).fill(item);
+ } else {
+ throw new Error(`Unknown url data type ${type}`);
+ }
+
+ if (typeof e !== 'number') {
+ throw new Error(`e must be a number, received ${e}`);
+ }
+
+ for (let i = 0; i < e; ++i) {
+ result = result.concat(result);
+ }
+
+ if (asUrl) {
+ if (withBase) {
+ result = result.map(([input, base]) => new URL(input, base));
+ } else {
+ result = result.map((input) => new URL(input));
+ }
+ }
+ return result;
+}
+exports.bakeUrlData = bakeUrlData;
diff --git a/benchmark/fixtures/url-inputs.js b/benchmark/fixtures/url-inputs.js
deleted file mode 100644
index 7b1983f6faa590..00000000000000
--- a/benchmark/fixtures/url-inputs.js
+++ /dev/null
@@ -1,30 +0,0 @@
-'use strict';
-
-exports.urls = {
- long: 'http://nodejs.org:89/docs/latest/api/foo/bar/qua/13949281/0f28b/' +
- '/5d49/b3020/url.html#test?payload1=true&payload2=false&test=1' +
- '&benchmark=3&foo=38.38.011.293&bar=1234834910480&test=19299&3992&' +
- 'key=f5c65e1e98fe07e648249ad41e1cfdb0',
- short: 'https://nodejs.org/en/blog/',
- idn: 'http://你好你好.在线',
- auth: 'https://user:pass@example.com/path?search=1',
- file: 'file:///foo/bar/test/node.js',
- ws: 'ws://localhost:9229/f46db715-70df-43ad-a359-7f9949f39868',
- javascript: 'javascript:alert("node is awesome");',
- percent: 'https://%E4%BD%A0/foo',
- dot: 'https://example.org/./a/../b/./c'
-};
-
-exports.searchParams = {
- noencode: 'foo=bar&baz=quux&xyzzy=thud',
- multicharsep: 'foo=bar&&&&&&&&&&baz=quux&&&&&&&&&&xyzzy=thud',
- encodefake: 'foo=%©ar&baz=%A©uux&xyzzy=%©ud',
- encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d',
- encodelast: 'foo=bar&baz=quux&xyzzy=thu%64',
- multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz',
- multivaluemany: 'foo=bar&foo=baz&foo=quux&quuy=quuz&foo=abc&foo=def&' +
- 'foo=ghi&foo=jkl&foo=mno&foo=pqr&foo=stu&foo=vwxyz',
- manypairs: 'a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z',
- manyblankpairs: '&&&&&&&&&&&&&&&&&&&&&&&&',
- altspaces: 'foo+bar=baz+quux&xyzzy+thud=quuy+quuz&abc=def+ghi'
-};
diff --git a/benchmark/http/create-clientrequest.js b/benchmark/http/create-clientrequest.js
index 97316a7e800419..76468a49aa0835 100644
--- a/benchmark/http/create-clientrequest.js
+++ b/benchmark/http/create-clientrequest.js
@@ -2,19 +2,49 @@
const common = require('../common.js');
const ClientRequest = require('http').ClientRequest;
-
+const types = Object.keys(common.urls)
+ .filter((i) => common.urls[i]
+ .startsWith('http://'));
const bench = common.createBenchmark(main, {
- len: [1, 8, 16, 32, 64, 128],
- n: [1e6]
+ // Use 'url' to avoid name clash with other http benchmark
+ url: types.concat(['wpt']),
+ arg: ['URL', 'string', 'options'],
+ e: [1]
});
-function main({ len, n }) {
- const path = '/'.repeat(len);
- const opts = { path: path, createConnection: function() {} };
+function noop() {}
- bench.start();
- for (var i = 0; i < n; i++) {
- new ClientRequest(opts);
+function main({ url: type, arg, e }) {
+ e = +e;
+ const data = common.bakeUrlData(type, e, false, false)
+ .filter((i) => i.startsWith('http://'));
+ const len = data.length;
+ var result;
+ var i;
+ if (arg === 'options') {
+ const options = data.map((i) => ({
+ path: new URL(i).path, createConnection: noop
+ }));
+ bench.start();
+ for (i = 0; i < len; i++) {
+ result = new ClientRequest(options[i]);
+ }
+ bench.end(len);
+ } else if (arg === 'URL') {
+ const options = data.map((i) => new URL(i));
+ bench.start();
+ for (i = 0; i < len; i++) {
+ result = new ClientRequest(options[i], { createConnection: noop });
+ }
+ bench.end(len);
+ } else if (arg === 'string') {
+ bench.start();
+ for (i = 0; i < len; i++) {
+ result = new ClientRequest(data[i], { createConnection: noop });
+ }
+ bench.end(len);
+ } else {
+ throw new Error(`Unknown arg type ${arg}`);
}
- bench.end(n);
+ require('assert').ok(result);
}
diff --git a/benchmark/querystring/querystring-parse.js b/benchmark/querystring/querystring-parse.js
index db650165eb9cda..ca4dca13bc14eb 100644
--- a/benchmark/querystring/querystring-parse.js
+++ b/benchmark/querystring/querystring-parse.js
@@ -1,7 +1,7 @@
'use strict';
const common = require('../common.js');
const querystring = require('querystring');
-const inputs = require('../fixtures/url-inputs.js').searchParams;
+const inputs = common.searchParams;
const bench = common.createBenchmark(main, {
type: Object.keys(inputs),
diff --git a/benchmark/url/legacy-vs-whatwg-url-get-prop.js b/benchmark/url/legacy-vs-whatwg-url-get-prop.js
index 2cc3ab8c75e65c..59bb4724f42ef3 100644
--- a/benchmark/url/legacy-vs-whatwg-url-get-prop.js
+++ b/benchmark/url/legacy-vs-whatwg-url-get-prop.js
@@ -3,20 +3,15 @@ const common = require('../common.js');
const url = require('url');
const URL = url.URL;
const assert = require('assert');
-const inputs = require('../fixtures/url-inputs.js').urls;
const bench = common.createBenchmark(main, {
- type: Object.keys(inputs),
+ type: common.urlDataTypes,
method: ['legacy', 'whatwg'],
- n: [1e5]
+ e: [1]
});
-// At the time of writing, when using a passed property name to index
-// the object, Crankshaft would generate a LoadKeyedGeneric even when it
-// remains a constant in the function, so here we must use the literal
-// instead to get a LoadNamedField.
-function useLegacy(n, input) {
- const obj = url.parse(input);
+function useLegacy(data) {
+ const obj = url.parse(data[0]);
const noDead = {
protocol: obj.protocol,
auth: obj.auth,
@@ -27,10 +22,12 @@ function useLegacy(n, input) {
search: obj.search,
hash: obj.hash
};
+ const len = data.length;
// It's necessary to assign the values to an object
// to avoid loop invariant code motion.
bench.start();
- for (var i = 0; i < n; i += 1) {
+ for (var i = 0; i < len; i++) {
+ const obj = data[i];
noDead.protocol = obj.protocol;
noDead.auth = obj.auth;
noDead.host = obj.host;
@@ -40,12 +37,12 @@ function useLegacy(n, input) {
noDead.search = obj.search;
noDead.hash = obj.hash;
}
- bench.end(n);
+ bench.end(len);
return noDead;
}
-function useWHATWG(n, input) {
- const obj = new URL(input);
+function useWHATWG(data) {
+ const obj = new URL(data[0]);
const noDead = {
protocol: obj.protocol,
auth: `${obj.username}:${obj.password}`,
@@ -56,8 +53,10 @@ function useWHATWG(n, input) {
search: obj.search,
hash: obj.hash
};
+ const len = data.length;
bench.start();
- for (var i = 0; i < n; i += 1) {
+ for (var i = 0; i < len; i++) {
+ const obj = data[i];
noDead.protocol = obj.protocol;
noDead.auth = `${obj.username}:${obj.password}`;
noDead.host = obj.host;
@@ -67,23 +66,22 @@ function useWHATWG(n, input) {
noDead.search = obj.search;
noDead.hash = obj.hash;
}
- bench.end(n);
+ bench.end(len);
return noDead;
}
-function main({ type, n, method }) {
- const input = inputs[type];
- if (!input) {
- throw new Error(`Unknown input type "${type}"`);
- }
-
+function main({ type, method, e }) {
+ e = +e;
+ var data;
var noDead; // Avoid dead code elimination.
switch (method) {
case 'legacy':
- noDead = useLegacy(n, input);
+ data = common.bakeUrlData(type, e, false, false);
+ noDead = useLegacy(data.map((i) => url.parse(i)));
break;
case 'whatwg':
- noDead = useWHATWG(n, input);
+ data = common.bakeUrlData(type, e, false, true);
+ noDead = useWHATWG(data);
break;
default:
throw new Error(`Unknown method "${method}"`);
diff --git a/benchmark/url/legacy-vs-whatwg-url-parse.js b/benchmark/url/legacy-vs-whatwg-url-parse.js
index 2be55e17cc354b..e4af2e0b7c2db5 100644
--- a/benchmark/url/legacy-vs-whatwg-url-parse.js
+++ b/benchmark/url/legacy-vs-whatwg-url-parse.js
@@ -3,47 +3,61 @@ const common = require('../common.js');
const url = require('url');
const URL = url.URL;
const assert = require('assert');
-const inputs = require('../fixtures/url-inputs.js').urls;
const bench = common.createBenchmark(main, {
- type: Object.keys(inputs),
- method: ['legacy', 'whatwg'],
- n: [1e5]
+ withBase: ['true', 'false'],
+ type: common.urlDataTypes,
+ e: [1],
+ method: ['legacy', 'whatwg']
});
-function useLegacy(n, input) {
- var noDead = url.parse(input);
+function useLegacy(data) {
+ const len = data.length;
+ var result = url.parse(data[0]); // avoid dead code elimination
bench.start();
- for (var i = 0; i < n; i += 1) {
- noDead = url.parse(input);
+ for (var i = 0; i < len; ++i) {
+ result = url.parse(data[i]);
}
- bench.end(n);
- return noDead;
+ bench.end(len);
+ return result;
}
-function useWHATWG(n, input) {
- var noDead = new URL(input);
+function useWHATWGWithBase(data) {
+ const len = data.length;
+ var result = new URL(data[0][0], data[0][1]); // avoid dead code elimination
bench.start();
- for (var i = 0; i < n; i += 1) {
- noDead = new URL(input);
+ for (var i = 0; i < len; ++i) {
+ const item = data[i];
+ result = new URL(item[0], item[1]);
}
- bench.end(n);
- return noDead;
+ bench.end(len);
+ return result;
}
-function main({ type, n, method }) {
- const input = inputs[type];
- if (!input) {
- throw new Error(`Unknown input type "${type}"`);
+function useWHATWGWithoutBase(data) {
+ const len = data.length;
+ var result = new URL(data[0]); // avoid dead code elimination
+ bench.start();
+ for (var i = 0; i < len; ++i) {
+ result = new URL(data[i]);
}
+ bench.end(len);
+ return result;
+}
+function main({ e, method, type, withBase }) {
+ e = +e;
+ withBase = withBase === 'true';
var noDead; // Avoid dead code elimination.
+ var data;
switch (method) {
case 'legacy':
- noDead = useLegacy(n, input);
+ data = common.bakeUrlData(type, e, false, false);
+ noDead = useLegacy(data);
break;
case 'whatwg':
- noDead = useWHATWG(n, input);
+ data = common.bakeUrlData(type, e, withBase, false);
+ noDead = withBase ? useWHATWGWithBase(data) : useWHATWGWithoutBase(data);
break;
default:
throw new Error(`Unknown method ${method}`);
diff --git a/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js b/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js
index 6b054d0b2a1f1a..81b5b6dc16ce24 100644
--- a/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js
+++ b/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js
@@ -2,7 +2,7 @@
const common = require('../common.js');
const { URLSearchParams } = require('url');
const querystring = require('querystring');
-const searchParams = require('../fixtures/url-inputs.js').searchParams;
+const searchParams = common.searchParams;
const bench = common.createBenchmark(main, {
searchParam: Object.keys(searchParams),
diff --git a/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js b/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js
index 54fdd956544886..f97961decf5069 100644
--- a/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js
+++ b/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js
@@ -2,7 +2,7 @@
const common = require('../common.js');
const { URLSearchParams } = require('url');
const querystring = require('querystring');
-const searchParams = require('../fixtures/url-inputs.js').searchParams;
+const searchParams = common.searchParams;
const bench = common.createBenchmark(main, {
searchParam: Object.keys(searchParams),
diff --git a/benchmark/url/legacy-vs-whatwg-url-serialize.js b/benchmark/url/legacy-vs-whatwg-url-serialize.js
index 017ec4328c590b..e4c821cb2e2c1b 100644
--- a/benchmark/url/legacy-vs-whatwg-url-serialize.js
+++ b/benchmark/url/legacy-vs-whatwg-url-serialize.js
@@ -3,49 +3,48 @@ const common = require('../common.js');
const url = require('url');
const URL = url.URL;
const assert = require('assert');
-const inputs = require('../fixtures/url-inputs.js').urls;
const bench = common.createBenchmark(main, {
- type: Object.keys(inputs),
+ type: common.urlDataTypes,
method: ['legacy', 'whatwg'],
- n: [1e5]
+ e: [1]
});
-function useLegacy(n, input, prop) {
- const obj = url.parse(input);
+function useLegacy(data) {
+ const obj = url.parse(data[0]);
+ const len = data.length;
var noDead = url.format(obj);
bench.start();
- for (var i = 0; i < n; i += 1) {
- noDead = url.format(obj);
+ for (var i = 0; i < len; i++) {
+ noDead = data[i].toString();
}
- bench.end(n);
+ bench.end(len);
return noDead;
}
-function useWHATWG(n, input, prop) {
- const obj = new URL(input);
+function useWHATWG(data) {
+ const obj = new URL(data[0]);
+ const len = data.length;
var noDead = obj.toString();
bench.start();
- for (var i = 0; i < n; i += 1) {
- noDead = obj.toString();
+ for (var i = 0; i < len; i++) {
+ noDead = data[i].toString();
}
- bench.end(n);
+ bench.end(len);
return noDead;
}
-function main({ type, n, method }) {
- const input = inputs[type];
- if (!input) {
- throw new Error(`Unknown input type "${type}"`);
- }
+function main({ type, e, method }) {
+ e = +e;
+ const data = common.bakeUrlData(type, e, false, false);
var noDead; // Avoid dead code elimination.
switch (method) {
case 'legacy':
- noDead = useLegacy(n, input);
+ noDead = useLegacy(data);
break;
case 'whatwg':
- noDead = useWHATWG(n, input);
+ noDead = useWHATWG(data);
break;
default:
throw new Error(`Unknown method ${method}`);
diff --git a/benchmark/url/url-resolve.js b/benchmark/url/url-resolve.js
index 48978574ea24ec..bd584c6f6090e9 100644
--- a/benchmark/url/url-resolve.js
+++ b/benchmark/url/url-resolve.js
@@ -1,7 +1,7 @@
'use strict';
const common = require('../common.js');
const url = require('url');
-const hrefs = require('../fixtures/url-inputs.js').urls;
+const hrefs = common.urls;
hrefs.noscheme = 'some.ran/dom/url.thing?oh=yes#whoo';
const paths = {
diff --git a/benchmark/url/url-searchparams-sort.js b/benchmark/url/url-searchparams-sort.js
index fe152bf823468f..6720b66dca366f 100644
--- a/benchmark/url/url-searchparams-sort.js
+++ b/benchmark/url/url-searchparams-sort.js
@@ -3,6 +3,7 @@ const common = require('../common.js');
const URLSearchParams = require('url').URLSearchParams;
const inputs = {
+ wpt: 'wpt', // to work around tests
empty: '',
sorted: 'a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z',
almostsorted: 'a&b&c&d&e&f&g&i&h&j&k&l&m&n&o&p&q&r&s&t&u&w&v&x&y&z',
diff --git a/benchmark/url/whatwg-url-properties.js b/benchmark/url/whatwg-url-properties.js
index f526c07f139be9..6961fec49e5fee 100644
--- a/benchmark/url/whatwg-url-properties.js
+++ b/benchmark/url/whatwg-url-properties.js
@@ -1,55 +1,42 @@
'use strict';
const common = require('../common.js');
-const URL = require('url').URL;
-const inputs = require('../fixtures/url-inputs.js').urls;
const bench = common.createBenchmark(main, {
- input: Object.keys(inputs),
+ withBase: ['true', 'false'],
+ type: ['wpt'], // Too many combinations - just use WPT by default
+ e: [1],
prop: ['href', 'origin', 'protocol',
'username', 'password', 'host', 'hostname', 'port',
- 'pathname', 'search', 'searchParams', 'hash'],
- n: [3e5]
+ 'pathname', 'search', 'searchParams', 'hash']
});
-function setAndGet(n, url, prop, alternative) {
- const old = url[prop];
+function setAndGet(data, prop) {
+ const len = data.length;
+ var result = data[0][prop];
bench.start();
- for (var i = 0; i < n; i += 1) {
- url[prop] = n % 2 === 0 ? alternative : old; // set
- url[prop]; // get
+ for (var i = 0; i < len; ++i) {
+ result = data[i][prop];
+ data[i][prop] = result;
}
- bench.end(n);
+ bench.end(len);
+ return result;
}
-function get(n, url, prop) {
+function get(data, prop) {
+ const len = data.length;
+ var result = data[0][prop];
bench.start();
- for (var i = 0; i < n; i += 1) {
- url[prop]; // get
+ for (var i = 0; i < len; ++i) {
+ result = data[i][prop]; // get
}
- bench.end(n);
+ bench.end(len);
+ return result;
}
-const alternatives = {
- href: 'http://user:pass@foo.bar.com:21/aaa/zzz?l=25#test',
- protocol: 'https:',
- username: 'user2',
- password: 'pass2',
- host: 'foo.bar.net:22',
- hostname: 'foo.bar.org',
- port: '23',
- pathname: '/aaa/bbb',
- search: '?k=99',
- hash: '#abcd'
-};
-
-function getAlternative(prop) {
- return alternatives[prop];
-}
-
-function main({ n, input, prop }) {
- const value = inputs[input];
- const url = new URL(value);
-
+function main({ e, type, prop, withBase }) {
+ e = +e;
+ withBase = withBase === 'true';
+ const data = common.bakeUrlData(type, e, withBase, true);
switch (prop) {
case 'protocol':
case 'username':
@@ -61,11 +48,11 @@ function main({ n, input, prop }) {
case 'search':
case 'hash':
case 'href':
- setAndGet(n, url, prop, getAlternative(prop));
+ setAndGet(data, prop);
break;
case 'origin':
case 'searchParams':
- get(n, url, prop);
+ get(data, prop);
break;
default:
throw new Error('Unknown prop');
diff --git a/common.gypi b/common.gypi
index 4b732704ba2618..c26203064fe09b 100644
--- a/common.gypi
+++ b/common.gypi
@@ -30,7 +30,7 @@
# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
- 'v8_embedder_string': '-node.11',
+ 'v8_embedder_string': '-node.13',
# Enable disassembler for `--print-code` v8 options
'v8_enable_disassembler': 1,
diff --git a/configure.py b/configure.py
index 065e31fd9cac51..1bef01baef5fbc 100755
--- a/configure.py
+++ b/configure.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
import json
import sys
import errno
@@ -185,7 +187,7 @@
parser.add_option('--experimental-http-parser',
action='store_true',
dest='experimental_http_parser',
- help='use llhttp instead of http_parser')
+ help='use llhttp instead of http_parser by default')
shared_optgroup.add_option('--shared-http-parser',
action='store_true',
@@ -434,7 +436,7 @@
dest='with_icu_source',
help='Intl mode: optional local path to icu/ dir, or path/URL of '
'the icu4c source archive. '
- 'v%d.x or later recommended.' % icu_versions["minimum_icu"])
+ 'v%d.x or later recommended.' % icu_versions['minimum_icu'])
parser.add_option('--with-ltcg',
action='store_true',
@@ -609,7 +611,7 @@ def print_verbose(x):
if not options.verbose:
return
if type(x) is str:
- print x
+ print(x)
else:
pprint.pprint(x, indent=2)
@@ -622,9 +624,13 @@ def b(value):
def pkg_config(pkg):
+ """Run pkg-config on the specified package
+ Returns ("-l flags", "-I flags", "-L flags", "version")
+ otherwise (None, None, None, None)"""
pkg_config = os.environ.get('PKG_CONFIG', 'pkg-config')
retval = ()
- for flag in ['--libs-only-l', '--cflags-only-I', '--libs-only-L']:
+ for flag in ['--libs-only-l', '--cflags-only-I',
+ '--libs-only-L', '--modversion']:
try:
proc = subprocess.Popen(
shlex.split(pkg_config) + ['--silence-errors', flag, pkg],
@@ -632,7 +638,7 @@ def pkg_config(pkg):
val = proc.communicate()[0].strip()
except OSError as e:
if e.errno != errno.ENOENT: raise e # Unexpected error.
- return (None, None, None) # No pkg-config/pkgconf installed.
+ return (None, None, None, None) # No pkg-config/pkgconf installed.
retval += (val,)
return retval
@@ -1119,7 +1125,7 @@ def configure_library(lib, output):
output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib))
if getattr(options, shared_lib):
- (pkg_libs, pkg_cflags, pkg_libpath) = pkg_config(lib)
+ (pkg_libs, pkg_cflags, pkg_libpath, pkg_modversion) = pkg_config(lib)
if options.__dict__[shared_lib + '_includes']:
output['include_dirs'] += [options.__dict__[shared_lib + '_includes']]
@@ -1354,7 +1360,12 @@ def write_config(data, name):
if pkgicu[0] is None:
error('''Could not load pkg-config data for "icu-i18n".
See above errors or the README.md.''')
- (libs, cflags, libpath) = pkgicu
+ (libs, cflags, libpath, icuversion) = pkgicu
+ icu_ver_major = icuversion.split('.')[0]
+ o['variables']['icu_ver_major'] = icu_ver_major
+ if int(icu_ver_major) < icu_versions['minimum_icu']:
+ error('icu4c v%s is too old, v%d.x or later is required.' %
+ (icuversion, icu_versions['minimum_icu']))
# libpath provides linker path which may contain spaces
if libpath:
o['libraries'] += [libpath]
@@ -1473,9 +1484,9 @@ def write_config(data, name):
icu_ver_major = m.group(1)
if not icu_ver_major:
error('Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h)
- elif int(icu_ver_major) < icu_versions["minimum_icu"]:
- error('icu4c v%d.x is too old, v%d.x or later is required.' % (int(icu_ver_major),
- icu_versions["minimum_icu"]))
+ elif int(icu_ver_major) < icu_versions['minimum_icu']:
+ error('icu4c v%s.x is too old, v%d.x or later is required.' %
+ (icu_ver_major, icu_versions['minimum_icu']))
icu_endianness = sys.byteorder[0];
o['variables']['icu_ver_major'] = icu_ver_major
o['variables']['icu_endianness'] = icu_endianness
diff --git a/deps/llhttp/include/llhttp.h b/deps/llhttp/include/llhttp.h
index c114d11ffa9353..26aa46e1e78a4b 100644
--- a/deps/llhttp/include/llhttp.h
+++ b/deps/llhttp/include/llhttp.h
@@ -3,7 +3,7 @@
#define LLHTTP_VERSION_MAJOR 1
#define LLHTTP_VERSION_MINOR 0
-#define LLHTTP_VERSION_PATCH 0
+#define LLHTTP_VERSION_PATCH 1
#ifndef INCLUDE_LLHTTP_ITSELF_H_
#define INCLUDE_LLHTTP_ITSELF_H_
diff --git a/deps/llhttp/src/llhttp.c b/deps/llhttp/src/llhttp.c
index cb12c8dfd0f182..7db9b2fdc107f0 100644
--- a/deps/llhttp/src/llhttp.c
+++ b/deps/llhttp/src/llhttp.c
@@ -6037,6 +6037,7 @@ int llhttp__internal_execute(llhttp__internal_t* state, const char* p, const cha
if (error != 0) {
state->error = error;
state->error_pos = endp;
+ return error;
}
}
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 2fdfbcd5322e5e..2f93bd8dffefa4 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -352,3 +352,7 @@ Andy Zhang
dmabupt
Ryan Liptak
Ali Ijaz Sheikh
+hitesh
+Svante Signell
+Samuel Thibault
+Jeremy Studer
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index 6a631a87c1cb39..8cd862715aef9d 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -13,6 +13,7 @@ endif()
set(uv_sources
src/fs-poll.c
+ src/idna.c
src/inet.c
src/threadpool.c
src/timer.c
@@ -64,6 +65,7 @@ set(uv_test_sources
test/test-homedir.c
test/test-hrtime.c
test/test-idle.c
+ test/test-idna.c
test/test-ip4-addr.c
test/test-ip6-addr.c
test/test-ip6-addr.c
@@ -260,7 +262,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD")
- list(APPEND uv_sources src/unix/posix-hrtime.c)
+ list(APPEND uv_sources src/unix/posix-hrtime.c src/unix/bsd-proctitle.c)
list(APPEND uv_libraries kvm)
endif()
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 7cb675238d3e08..3376481d62d1f0 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,60 @@
+2018.11.14, Version 1.24.0 (Stable), 2d427ee0083d1baf995df4ebf79a3f8890e9a3e1
+
+Changes since version 1.23.2:
+
+* unix: do not require PATH_MAX to be defined (Brad King)
+
+* win,doc: path encoding in uv_fs_XX is UTF-8 (hitesh)
+
+* unix: add missing link dependency on kFreeBSD (Svante Signell)
+
+* unix: add support for GNU/Hurd (Samuel Thibault)
+
+* test: avoid memory leak for test_output (Carlo Marcelo Arenas Belón)
+
+* zos: avoid UB with NULL pointer arithmetic (Carlo Marcelo Arenas Belón)
+
+* doc: add vtjnash to maintainers (Jameson Nash)
+
+* unix: restore skipping of phys_addr copy (cjihrig)
+
+* unix,win: make uv_interface_addresses() consistent (cjihrig)
+
+* unix: remove unnecessary linebreaks (cjihrig)
+
+* unix,win: handle zero-sized allocations uniformly (Ben Noordhuis)
+
+* unix: remove unused uv__dup() function (Ben Noordhuis)
+
+* core,bsd: refactor process_title functions (Santiago Gimeno)
+
+* win: Redefine NSIG to consider SIGWINCH (Jeremy Studer)
+
+* test: make sure that reading a directory fails (Sakthipriyan Vairamani)
+
+* win, tty: remove zero-size read callbacks (Bartosz Sosnowski)
+
+* test: fix test runner getenv async-signal-safety (Ben Noordhuis)
+
+* test: fix test runner execvp async-signal-safety (Ben Noordhuis)
+
+* test,unix: fix race in test runner (Ben Noordhuis)
+
+* unix,win: support IDNA 2008 in uv_getaddrinfo() (Ben Noordhuis)
+
+* win, tcp: avoid starving the loop (Bartosz Sosnowski)
+
+* win, dl: proper error messages on some systems (Bartosz Sosnowski)
+
+* win,fs: retry if uv_fs_rename fails (Bartosz Sosnowski)
+
+* darwin: speed up uv_set_process_title() (Ben Noordhuis)
+
+* aix: fix race in uv_get_process_title() (Gireesh Punathil)
+
+* win: support more fine-grained windows hiding (Bartosz Sosnowski)
+
+
2018.10.09, Version 1.23.2 (Stable), 34c12788d2e7308f3ac506c0abcbf74c0d6abd20
Changes since version 1.23.1:
diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md
index 543dc3cda7bce2..a5a11c8dfff16c 100644
--- a/deps/uv/MAINTAINERS.md
+++ b/deps/uv/MAINTAINERS.md
@@ -15,6 +15,7 @@ libuv is currently managed by the following individuals:
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq))
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
+* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
* **John Barboza** ([@jbarz](https://github.com/jbarz))
* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 2381425403c376..098d2f57931d18 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -29,6 +29,7 @@ libuv_la_CFLAGS = @CFLAGS@
libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
libuv_la_SOURCES = src/fs-poll.c \
src/heap-inl.h \
+ src/idna.c \
src/inet.c \
src/queue.h \
src/threadpool.c \
@@ -189,6 +190,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-homedir.c \
test/test-hrtime.c \
test/test-idle.c \
+ test/test-idna.c \
test/test-ip4-addr.c \
test/test-ip6-addr.c \
test/test-ipc-heavy-traffic-deadlock-bug.c \
@@ -374,6 +376,7 @@ endif
if DRAGONFLY
uvinclude_HEADERS += include/uv/bsd.h
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
@@ -383,12 +386,20 @@ endif
if FREEBSD
uvinclude_HEADERS += include/uv/bsd.h
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
test_run_tests_LDFLAGS += -lutil
endif
+if HURD
+uvinclude_HEADERS += include/uv/posix.h
+libuv_la_SOURCES += src/unix/no-fsevents.c \
+ src/unix/posix-hrtime.c \
+ src/unix/posix-poll.c
+endif
+
if LINUX
uvinclude_HEADERS += include/uv/linux.h
libuv_la_CFLAGS += -D_GNU_SOURCE
@@ -419,6 +430,7 @@ endif
if NETBSD
uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
+ src/unix/bsd-proctitle.c \
src/unix/kqueue.c \
src/unix/netbsd.c \
src/unix/posix-hrtime.c
@@ -428,6 +440,7 @@ endif
if OPENBSD
uvinclude_HEADERS += include/uv/bsd.h
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
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 0d9066bb0225a5..68939c699e4a32 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.23.2], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.24.0], [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])
@@ -56,6 +56,7 @@ AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])
AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])])
AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])])
+AM_CONDITIONAL([HURD], [AS_CASE([$host_os],[gnu*], [true], [false])])
AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
AM_CONDITIONAL([MSYS], [AS_CASE([$host_os],[msys*], [true], [false])])
AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])])
@@ -67,6 +68,9 @@ AS_CASE([$host_os],[mingw*], [
LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32"
])
AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])])
+AS_CASE([$host_os], [kfreebsd*], [
+ LIBS="$LIBS -lfreebsd-glue"
+])
AC_CHECK_HEADERS([sys/ahafs_evProds.h])
AC_CONFIG_FILES([Makefile libuv.pc])
AC_OUTPUT
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index fcf70a35a1f66d..21f9e27cb40727 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -12,6 +12,8 @@ otherwise it will be performed asynchronously.
All file operations are run on the threadpool. See :ref:`threadpool` for information
on the threadpool size.
+.. note::
+ On Windows `uv_fs_*` functions use utf-8 encoding.
Data types
----------
@@ -231,6 +233,15 @@ API
Equivalent to :man:`rename(2)`.
+ .. note::
+ On Windows if this function fails with ``UV_EBUSY``, ``UV_EPERM`` or
+ ``UV_EACCES``, it will retry to rename the file up to four times with
+ 250ms wait between attempts before giving up. If both `path` and
+ `new_path` are existing directories this function will work only if
+ target directory is empty.
+
+ .. versionchanged:: 1.24.0 Added retrying and directory move support on Windows.
+
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
Equivalent to :man:`fsync(2)`.
diff --git a/deps/uv/docs/src/process.rst b/deps/uv/docs/src/process.rst
index bc968554e149f2..f2b3be219bf299 100644
--- a/deps/uv/docs/src/process.rst
+++ b/deps/uv/docs/src/process.rst
@@ -70,11 +70,22 @@ Data types
*/
UV_PROCESS_DETACHED = (1 << 3),
/*
- * Hide the subprocess console window that would normally be created. This
+ * Hide the subprocess window that would normally be created. This option is
+ * only meaningful on Windows systems. On Unix it is silently ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE = (1 << 4),
+ /*
+ * Hide the subprocess console window that would normally be created. This
+ * option is only meaningful on Windows systems. On Unix it is silently
+ * ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5),
+ /*
+ * Hide the subprocess GUI window that would normally be created. This
* option is only meaningful on Windows systems. On Unix it is silently
* ignored.
*/
- UV_PROCESS_WINDOWS_HIDE = (1 << 4)
+ UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6)
};
.. c:type:: uv_stdio_container_t
@@ -217,6 +228,9 @@ API
setgid specified, or not having enough memory to allocate for the new
process.
+ .. versionchanged:: 1.24.0 Added `UV_PROCESS_WINDOWS_HIDE_CONSOLE` and
+ `UV_PROCESS_WINDOWS_HIDE_GUI` flags.
+
.. c:function:: int uv_process_kill(uv_process_t* handle, int signum)
Sends the specified signal to the given process handle. Check the documentation
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 717c2e570b9eb9..86a2ecc2d74469 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -963,11 +963,22 @@ enum uv_process_flags {
*/
UV_PROCESS_DETACHED = (1 << 3),
/*
- * Hide the subprocess console window that would normally be created. This
+ * Hide the subprocess window that would normally be created. This option is
+ * only meaningful on Windows systems. On Unix it is silently ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE = (1 << 4),
+ /*
+ * Hide the subprocess console window that would normally be created. This
+ * option is only meaningful on Windows systems. On Unix it is silently
+ * ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5),
+ /*
+ * Hide the subprocess GUI window that would normally be created. This
* option is only meaningful on Windows systems. On Unix it is silently
* ignored.
*/
- UV_PROCESS_WINDOWS_HIDE = (1 << 4)
+ UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6)
};
/*
diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h
index 7208557b560ce8..9de9efecff14c4 100644
--- a/deps/uv/include/uv/unix.h
+++ b/deps/uv/include/uv/unix.h
@@ -64,6 +64,8 @@
# include "uv/bsd.h"
#elif defined(__CYGWIN__) || defined(__MSYS__)
# include "uv/posix.h"
+#elif defined(__GNU__)
+# include "uv/posix.h"
#endif
#ifndef NI_MAXHOST
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index cc064e2fd87ce8..105e9a2615f4a6 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 23
-#define UV_VERSION_PATCH 2
+#define UV_VERSION_MINOR 24
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/include/uv/win.h b/deps/uv/include/uv/win.h
index d6b8b3a7f7b9a2..bb9477c8346bdc 100644
--- a/deps/uv/include/uv/win.h
+++ b/deps/uv/include/uv/win.h
@@ -86,6 +86,14 @@ typedef struct pollfd {
#define SIGKILL 9
#define SIGWINCH 28
+/* Redefine NSIG to take SIGWINCH into consideration */
+#if defined(NSIG) && NSIG <= SIGWINCH
+# undef NSIG
+#endif
+#ifndef NSIG
+# define NSIG SIGWINCH + 1
+#endif
+
/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like
* platforms. However MinGW doesn't define it, so we do. */
#ifndef SIGABRT_COMPAT
diff --git a/deps/uv/src/idna.c b/deps/uv/src/idna.c
new file mode 100644
index 00000000000000..13ffac6be8142d
--- /dev/null
+++ b/deps/uv/src/idna.c
@@ -0,0 +1,291 @@
+/* Copyright (c) 2011, 2018 Ben Noordhuis
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Derived from https://github.com/bnoordhuis/punycode
+ * but updated to support IDNA 2008.
+ */
+
+#include "uv.h"
+#include "idna.h"
+#include
+
+static unsigned uv__utf8_decode1_slow(const char** p,
+ const char* pe,
+ unsigned a) {
+ unsigned b;
+ unsigned c;
+ unsigned d;
+ unsigned min;
+
+ if (a > 0xF7)
+ return -1;
+
+ switch (*p - pe) {
+ default:
+ if (a > 0xEF) {
+ min = 0x10000;
+ a = a & 7;
+ b = (unsigned char) *(*p)++;
+ c = (unsigned char) *(*p)++;
+ d = (unsigned char) *(*p)++;
+ break;
+ }
+ /* Fall through. */
+ case 2:
+ if (a > 0xDF) {
+ min = 0x800;
+ b = 0x80 | (a & 15);
+ c = (unsigned char) *(*p)++;
+ d = (unsigned char) *(*p)++;
+ a = 0;
+ break;
+ }
+ /* Fall through. */
+ case 1:
+ if (a > 0xBF) {
+ min = 0x80;
+ b = 0x80;
+ c = 0x80 | (a & 31);
+ d = (unsigned char) *(*p)++;
+ a = 0;
+ break;
+ }
+ return -1; /* Invalid continuation byte. */
+ }
+
+ if (0x80 != (0xC0 & (b ^ c ^ d)))
+ return -1; /* Invalid sequence. */
+
+ b &= 63;
+ c &= 63;
+ d &= 63;
+ a = (a << 18) | (b << 12) | (c << 6) | d;
+
+ if (a < min)
+ return -1; /* Overlong sequence. */
+
+ if (a > 0x10FFFF)
+ return -1; /* Four-byte sequence > U+10FFFF. */
+
+ if (a >= 0xD800 && a <= 0xDFFF)
+ return -1; /* Surrogate pair. */
+
+ return a;
+}
+
+unsigned uv__utf8_decode1(const char** p, const char* pe) {
+ unsigned a;
+
+ a = (unsigned char) *(*p)++;
+
+ if (a < 128)
+ return a; /* ASCII, common case. */
+
+ return uv__utf8_decode1_slow(p, pe, a);
+}
+
+#define foreach_codepoint(c, p, pe) \
+ for (; (void) (*p <= pe && (c = uv__utf8_decode1(p, pe))), *p <= pe;)
+
+static int uv__idna_toascii_label(const char* s, const char* se,
+ char** d, char* de) {
+ static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
+ const char* ss;
+ unsigned c;
+ unsigned h;
+ unsigned k;
+ unsigned n;
+ unsigned m;
+ unsigned q;
+ unsigned t;
+ unsigned x;
+ unsigned y;
+ unsigned bias;
+ unsigned delta;
+ unsigned todo;
+ int first;
+
+ h = 0;
+ ss = s;
+ todo = 0;
+
+ foreach_codepoint(c, &s, se) {
+ if (c < 128)
+ h++;
+ else if (c == (unsigned) -1)
+ return UV_EINVAL;
+ else
+ todo++;
+ }
+
+ if (todo > 0) {
+ if (*d < de) *(*d)++ = 'x';
+ if (*d < de) *(*d)++ = 'n';
+ if (*d < de) *(*d)++ = '-';
+ if (*d < de) *(*d)++ = '-';
+ }
+
+ x = 0;
+ s = ss;
+ foreach_codepoint(c, &s, se) {
+ if (c > 127)
+ continue;
+
+ if (*d < de)
+ *(*d)++ = c;
+
+ if (++x == h)
+ break; /* Visited all ASCII characters. */
+ }
+
+ if (todo == 0)
+ return h;
+
+ /* Only write separator when we've written ASCII characters first. */
+ if (h > 0)
+ if (*d < de)
+ *(*d)++ = '-';
+
+ n = 128;
+ bias = 72;
+ delta = 0;
+ first = 1;
+
+ while (todo > 0) {
+ m = -1;
+ s = ss;
+ foreach_codepoint(c, &s, se)
+ if (c >= n)
+ if (c < m)
+ m = c;
+
+ x = m - n;
+ y = h + 1;
+
+ if (x > ~delta / y)
+ return UV_E2BIG; /* Overflow. */
+
+ delta += x * y;
+ n = m;
+
+ s = ss;
+ foreach_codepoint(c, &s, se) {
+ if (c < n)
+ if (++delta == 0)
+ return UV_E2BIG; /* Overflow. */
+
+ if (c != n)
+ continue;
+
+ for (k = 36, q = delta; /* empty */; k += 36) {
+ t = 1;
+
+ if (k > bias)
+ t = k - bias;
+
+ if (t > 26)
+ t = 26;
+
+ if (q < t)
+ break;
+
+ /* TODO(bnoordhuis) Since 1 <= t <= 26 and therefore
+ * 10 <= y <= 35, we can optimize the long division
+ * into a table-based reciprocal multiplication.
+ */
+ x = q - t;
+ y = 36 - t; /* 10 <= y <= 35 since 1 <= t <= 26. */
+ q = x / y;
+ t = t + x % y; /* 1 <= t <= 35 because of y. */
+
+ if (*d < de)
+ *(*d)++ = alphabet[t];
+ }
+
+ if (*d < de)
+ *(*d)++ = alphabet[q];
+
+ delta /= 2;
+
+ if (first) {
+ delta /= 350;
+ first = 0;
+ }
+
+ /* No overflow check is needed because |delta| was just
+ * divided by 2 and |delta+delta >= delta + delta/h|.
+ */
+ h++;
+ delta += delta / h;
+
+ for (bias = 0; delta > 35 * 26 / 2; bias += 36)
+ delta /= 35;
+
+ bias += 36 * delta / (delta + 38);
+ delta = 0;
+ todo--;
+ }
+
+ delta++;
+ n++;
+ }
+
+ return 0;
+}
+
+#undef foreach_codepoint
+
+long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
+ const char* si;
+ const char* st;
+ unsigned c;
+ char* ds;
+ int rc;
+
+ ds = d;
+
+ for (si = s; si < se; /* empty */) {
+ st = si;
+ c = uv__utf8_decode1(&si, se);
+
+ if (c != '.')
+ if (c != 0x3002) /* 。 */
+ if (c != 0xFF0E) /* . */
+ if (c != 0xFF61) /* 。 */
+ continue;
+
+ rc = uv__idna_toascii_label(s, st, &d, de);
+
+ if (rc < 0)
+ return rc;
+
+ if (d < de)
+ *d++ = '.';
+
+ s = si;
+ }
+
+ if (s < se) {
+ rc = uv__idna_toascii_label(s, se, &d, de);
+
+ if (rc < 0)
+ return rc;
+ }
+
+ if (d < de)
+ *d++ = '\0';
+
+ return d - ds; /* Number of bytes written. */
+}
diff --git a/deps/uv/src/idna.h b/deps/uv/src/idna.h
new file mode 100644
index 00000000000000..8e0c592fe139e5
--- /dev/null
+++ b/deps/uv/src/idna.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2011, 2018 Ben Noordhuis
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef UV_SRC_IDNA_H_
+#define UV_SRC_IDNA_H_
+
+/* Decode a single codepoint. Returns the codepoint or UINT32_MAX on error.
+ * |p| is updated on success _and_ error, i.e., bad multi-byte sequences are
+ * skipped in their entirety, not just the first bad byte.
+ */
+unsigned uv__utf8_decode1(const char** p, const char* pe);
+
+/* Convert a UTF-8 domain name to IDNA 2008 / Punycode. A return value >= 0
+ * is the number of bytes written to |d|, including the trailing nul byte.
+ * A return value < 0 is a libuv error code. |s| and |d| can not overlap.
+ */
+long uv__idna_toascii(const char* s, const char* se, char* d, char* de);
+
+#endif /* UV_SRC_IDNA_H_ */
diff --git a/deps/uv/src/unix/aix-common.c b/deps/uv/src/unix/aix-common.c
index e17e449481836a..63ac16a03431e6 100644
--- a/deps/uv/src/unix/aix-common.c
+++ b/deps/uv/src/unix/aix-common.c
@@ -166,8 +166,7 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
}
-int uv_interface_addresses(uv_interface_address_t** addresses,
- int* count) {
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int sockfd, inet6, size = 1;
struct ifconf ifc;
@@ -175,6 +174,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
struct sockaddr_dl* sa_addr;
*count = 0;
+ *addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
return UV__ERR(errno);
@@ -217,6 +217,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
(*count)++;
}
+ if (*count == 0) {
+ uv__close(sockfd);
+ return 0;
+ }
+
/* Alloc the return interface structs */
*addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
if (!(*addresses)) {
@@ -289,4 +294,4 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
}
uv__free(addresses);
-}
\ No newline at end of file
+}
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index 92de8148341e10..baac8e6c0067d7 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -886,16 +886,20 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
size_t len;
- len = strlen(process_argv[0]);
if (buffer == NULL || size == 0)
return UV_EINVAL;
- else if (size <= len)
- return UV_ENOBUFS;
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
uv_mutex_lock(&process_title_mutex);
- memcpy(buffer, process_argv[0], len + 1);
+ len = strlen(process_argv[0]);
+ if (size <= len) {
+ uv_mutex_unlock(&process_title_mutex);
+ return UV_ENOBUFS;
+ }
+
+ memcpy(buffer, process_argv[0], len);
+ buffer[len] = '\0';
uv_mutex_unlock(&process_title_mutex);
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index 9825b1c4db4865..2f2201f9ed024a 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -69,11 +69,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int i;
+ *count = 0;
+ *addresses = NULL;
+
if (getifaddrs(&addrs) != 0)
return UV__ERR(errno);
- *count = 0;
-
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
@@ -81,6 +82,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
+ if (*count == 0) {
+ freeifaddrs(addrs);
+ return 0;
+ }
+
*addresses = uv__malloc(*count * sizeof(**addresses));
if (*addresses == NULL) {
@@ -119,14 +125,19 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
continue;
address = *addresses;
- memset(address->phys_addr, 0, sizeof(address->phys_addr));
for (i = 0; i < *count; i++) {
+#if defined(__CYGWIN__) || defined(__MSYS__)
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
+#else
if (strcmp(address->name, ent->ifa_name) == 0) {
struct sockaddr_dl* sa_addr;
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ } else {
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
}
+#endif
address++;
}
}
diff --git a/deps/uv/src/unix/bsd-proctitle.c b/deps/uv/src/unix/bsd-proctitle.c
new file mode 100644
index 00000000000000..0ce47c8f64e25d
--- /dev/null
+++ b/deps/uv/src/unix/bsd-proctitle.c
@@ -0,0 +1,93 @@
+/* Copyright libuv project 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_mutex_t process_title_mutex;
+static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
+static char* process_title;
+
+
+static void init_process_title_mutex_once(void) {
+ if (uv_mutex_init(&process_title_mutex))
+ abort();
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ char* new_title;
+
+ new_title = uv__strdup(title);
+ if (new_title == NULL)
+ return UV_ENOMEM;
+
+ uv_once(&process_title_mutex_once, init_process_title_mutex_once);
+ uv_mutex_lock(&process_title_mutex);
+
+ uv__free(process_title);
+ process_title = new_title;
+ setproctitle("%s", title);
+
+ uv_mutex_unlock(&process_title_mutex);
+
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return UV_EINVAL;
+
+ uv_once(&process_title_mutex_once, init_process_title_mutex_once);
+ uv_mutex_lock(&process_title_mutex);
+
+ if (process_title != NULL) {
+ len = strlen(process_title) + 1;
+
+ if (size < len) {
+ uv_mutex_unlock(&process_title_mutex);
+ return UV_ENOBUFS;
+ }
+
+ memcpy(buffer, process_title, len);
+ } else {
+ len = 0;
+ }
+
+ uv_mutex_unlock(&process_title_mutex);
+
+ buffer[len] = '\0';
+
+ return 0;
+}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index f92446ff42b86b..0830c74a168e92 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -636,27 +636,6 @@ int uv__cloexec_fcntl(int fd, int set) {
}
-/* This function is not execve-safe, there is a race window
- * between the call to dup() and fcntl(FD_CLOEXEC).
- */
-int uv__dup(int fd) {
- int err;
-
- fd = dup(fd);
-
- if (fd == -1)
- return UV__ERR(errno);
-
- err = uv__cloexec(fd, 1);
- if (err) {
- uv__close(fd);
- return err;
- }
-
- return fd;
-}
-
-
ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
struct cmsghdr* cmsg;
ssize_t rc;
diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c
index dabde2239ccab3..92d46b7466d43b 100644
--- a/deps/uv/src/unix/darwin-proctitle.c
+++ b/deps/uv/src/unix/darwin-proctitle.c
@@ -33,61 +33,56 @@
# 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);
+static int (*dynamic_pthread_setname_np)(const char* name);
+#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 OSStatus (*pSetApplicationIsDaemon)(int);
+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;
- OSStatus (*pSetApplicationIsDaemon)(int);
- CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
- void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
- void*);
- CFTypeRef asn;
- int err;
-
- err = UV_ENOENT;
+void uv__set_process_title_platform_init(void) {
+ /* 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 !TARGET_OS_IPHONE
application_services_handle = dlopen("/System/Library/Frameworks/"
"ApplicationServices.framework/"
"Versions/A/ApplicationServices",
@@ -116,8 +111,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 +141,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 +162,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;
-
- pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
-
- /* Check into process manager?! */
- pLSApplicationCheckIn(-2,
- pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
-
- asn = pLSGetCurrentApplicationASN();
-
- err = UV_EINVAL;
- if (pLSSetApplicationInformationItem(-2, /* Magic value. */
- asn,
- *display_name_key,
- S(title),
- NULL) != noErr) {
- goto out;
- }
-
- uv__pthread_setname_np(title); /* Don't care if it fails. */
- err = 0;
+ return;
out:
- if (core_foundation_handle != NULL)
- dlclose(core_foundation_handle);
+ uv__set_process_title_platform_fini();
+#endif /* !TARGET_OS_IPHONE */
+}
- if (application_services_handle != NULL)
- dlclose(application_services_handle);
- return err;
+void uv__set_process_title(const char* title) {
+#if !TARGET_OS_IPHONE
+ if (core_foundation_handle != NULL && pSetApplicationIsDaemon(1) != noErr) {
+ CFTypeRef asn;
+ pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
+ pLSApplicationCheckIn(/* Magic value */ -2,
+ pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
+ asn = pLSGetCurrentApplicationASN();
+ pLSSetApplicationInformationItem(/* Magic value */ -2, asn,
+ *display_name_key, S(title), NULL);
+ }
#endif /* !TARGET_OS_IPHONE */
+
+ if (dynamic_pthread_setname_np != NULL) {
+ char namebuf[64]; /* MAXTHREADNAMESIZE */
+ strncpy(namebuf, title, sizeof(namebuf) - 1);
+ namebuf[sizeof(namebuf) - 1] = '\0';
+ dynamic_pthread_setname_np(namebuf);
+ }
}
diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c
index 70ccb13042fddb..0f729cfd4776a6 100644
--- a/deps/uv/src/unix/freebsd.c
+++ b/deps/uv/src/unix/freebsd.c
@@ -47,15 +47,6 @@
# define CP_INTR 4
#endif
-static uv_mutex_t process_title_mutex;
-static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
-static char *process_title;
-
-
-static void init_process_title_mutex_once(void) {
- uv_mutex_init(&process_title_mutex);
-}
-
int uv__platform_loop_init(uv_loop_t* loop) {
return uv__kqueue_init(loop);
@@ -159,76 +150,6 @@ void uv_loadavg(double avg[3]) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? uv__strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-int uv_set_process_title(const char* title) {
- int oid[4];
- char* new_title;
-
- new_title = uv__strdup(title);
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title == NULL) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOMEM;
- }
-
- uv__free(process_title);
- process_title = new_title;
-
- oid[0] = CTL_KERN;
- oid[1] = KERN_PROC;
- oid[2] = KERN_PROC_ARGS;
- oid[3] = getpid();
-
- sysctl(oid,
- ARRAY_SIZE(oid),
- NULL,
- NULL,
- process_title,
- strlen(process_title) + 1);
-
- uv_mutex_unlock(&process_title_mutex);
-
- return 0;
-}
-
-
-int uv_get_process_title(char* buffer, size_t size) {
- size_t len;
-
- if (buffer == NULL || size == 0)
- return UV_EINVAL;
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title) {
- len = strlen(process_title) + 1;
-
- if (size < len) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOBUFS;
- }
-
- memcpy(buffer, process_title, len);
- } else {
- len = 0;
- }
-
- uv_mutex_unlock(&process_title_mutex);
-
- buffer[len] = '\0';
-
- return 0;
-}
-
int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size;
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 3db5f89c9503d2..9068d4b115b646 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -358,19 +358,22 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) {
return n;
}
+#if defined(_POSIX_PATH_MAX)
+# define UV__FS_PATH_MAX _POSIX_PATH_MAX
+#elif defined(PATH_MAX)
+# define UV__FS_PATH_MAX PATH_MAX
+#else
+# define UV__FS_PATH_MAX_FALLBACK 8192
+# define UV__FS_PATH_MAX UV__FS_PATH_MAX_FALLBACK
+#endif
static ssize_t uv__fs_pathmax_size(const char* path) {
ssize_t pathmax;
pathmax = pathconf(path, _PC_PATH_MAX);
- if (pathmax == -1) {
-#if defined(PATH_MAX)
- return PATH_MAX;
-#else
-#error "PATH_MAX undefined in the current platform"
-#endif
- }
+ if (pathmax == -1)
+ pathmax = UV__FS_PATH_MAX;
return pathmax;
}
@@ -381,7 +384,28 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
char* buf;
char* newbuf;
+#if defined(UV__FS_PATH_MAX_FALLBACK)
+ /* We may not have a real PATH_MAX. Read size of link. */
+ struct stat st;
+ int ret;
+ ret = lstat(req->path, &st);
+ if (ret != 0)
+ return -1;
+ if (!S_ISLNK(st.st_mode)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ maxlen = st.st_size;
+
+ /* According to readlink(2) lstat can report st_size == 0
+ for some symlinks, such as those in /proc or /sys. */
+ if (maxlen == 0)
+ maxlen = uv__fs_pathmax_size(req->path);
+#else
maxlen = uv__fs_pathmax_size(req->path);
+#endif
+
buf = uv__malloc(maxlen);
if (buf == NULL) {
@@ -419,9 +443,15 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
}
static ssize_t uv__fs_realpath(uv_fs_t* req) {
- ssize_t len;
char* buf;
+#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L
+ buf = realpath(req->path, NULL);
+ if (buf == NULL)
+ return -1;
+#else
+ ssize_t len;
+
len = uv__fs_pathmax_size(req->path);
buf = uv__malloc(len + 1);
@@ -434,6 +464,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) {
uv__free(buf);
return -1;
}
+#endif
req->ptr = buf;
diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c
index 25827c1feeb6b3..6d23fbe02a8df3 100644
--- a/deps/uv/src/unix/getaddrinfo.c
+++ b/deps/uv/src/unix/getaddrinfo.c
@@ -27,6 +27,7 @@
#include "uv.h"
#include "internal.h"
+#include "idna.h"
#include
#include /* NULL */
@@ -141,15 +142,34 @@ int uv_getaddrinfo(uv_loop_t* loop,
const char* hostname,
const char* service,
const struct addrinfo* hints) {
+ char hostname_ascii[256];
size_t hostname_len;
size_t service_len;
size_t hints_len;
size_t len;
char* buf;
+ long rc;
if (req == NULL || (hostname == NULL && service == NULL))
return UV_EINVAL;
+ /* FIXME(bnoordhuis) IDNA does not seem to work z/OS,
+ * probably because it uses EBCDIC rather than ASCII.
+ */
+#ifdef __MVS__
+ (void) &hostname_ascii;
+#else
+ if (hostname != NULL) {
+ rc = uv__idna_toascii(hostname,
+ hostname + strlen(hostname),
+ hostname_ascii,
+ hostname_ascii + sizeof(hostname_ascii));
+ if (rc < 0)
+ return rc;
+ hostname = hostname_ascii;
+ }
+#endif
+
hostname_len = hostname ? strlen(hostname) + 1 : 0;
service_len = service ? strlen(service) + 1 : 0;
hints_len = hints ? sizeof(*hints) : 0;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index cd79037102013e..72d8da8a508b88 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -185,7 +185,6 @@ int uv__nonblock_fcntl(int fd, int set);
int uv__close(int fd); /* preserves errno */
int uv__close_nocheckstdio(int fd);
int uv__socket(int domain, int type, int protocol);
-int uv__dup(int fd);
ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
void uv__make_close_pending(uv_handle_t* handle);
int uv__getiovmax(void);
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 75362eb76d7f5d..991d1c60aee3dc 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -826,9 +826,10 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
return !exclude_type;
}
-int uv_interface_addresses(uv_interface_address_t** addresses,
- int* count) {
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
#ifndef HAVE_IFADDRS_H
+ *count = 0;
+ *addresses = NULL;
return UV_ENOSYS;
#else
struct ifaddrs *addrs, *ent;
@@ -836,12 +837,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
int i;
struct sockaddr_ll *sll;
- if (getifaddrs(&addrs))
- return UV__ERR(errno);
-
*count = 0;
*addresses = NULL;
+ if (getifaddrs(&addrs))
+ return UV__ERR(errno);
+
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
@@ -850,8 +851,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
(*count)++;
}
- if (*count == 0)
+ if (*count == 0) {
+ freeifaddrs(addrs);
return 0;
+ }
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
@@ -890,12 +893,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
continue;
address = *addresses;
- memset(address->phys_addr, 0, sizeof(address->phys_addr));
for (i = 0; i < (*count); i++) {
if (strcmp(address->name, ent->ifa_name) == 0) {
sll = (struct sockaddr_ll*)ent->ifa_addr;
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
+ } else {
+ memset(address->phys_addr, 0, sizeof(address->phys_addr));
}
address++;
}
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index 2605c114bca72d..4cfde1a586444c 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -40,15 +40,6 @@
#include
#include
-static uv_mutex_t process_title_mutex;
-static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
-static char *process_title;
-
-
-static void init_process_title_mutex_once(void) {
- uv_mutex_init(&process_title_mutex);
-}
-
int uv__platform_loop_init(uv_loop_t* loop) {
return uv__kqueue_init(loop);
@@ -134,65 +125,6 @@ uint64_t uv_get_total_memory(void) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? uv__strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-int uv_set_process_title(const char* title) {
- char* new_title;
-
- new_title = uv__strdup(title);
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title == NULL) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOMEM;
- }
-
- uv__free(process_title);
- process_title = new_title;
- setproctitle("%s", title);
-
- uv_mutex_unlock(&process_title_mutex);
-
- return 0;
-}
-
-
-int uv_get_process_title(char* buffer, size_t size) {
- size_t len;
-
- if (buffer == NULL || size == 0)
- return UV_EINVAL;
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title) {
- len = strlen(process_title) + 1;
-
- if (size < len) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOBUFS;
- }
-
- memcpy(buffer, process_title, len);
- } else {
- len = 0;
- }
-
- uv_mutex_unlock(&process_title_mutex);
-
- buffer[len] = '\0';
-
- return 0;
-}
-
-
int uv_resident_set_memory(size_t* rss) {
kvm_t *kd = NULL;
struct kinfo_proc2 *kinfo = NULL;
diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c
index ce937cd3efec25..bffb58bcd9ff00 100644
--- a/deps/uv/src/unix/openbsd.c
+++ b/deps/uv/src/unix/openbsd.c
@@ -36,16 +36,6 @@
#include
-static uv_mutex_t process_title_mutex;
-static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
-static char *process_title;
-
-
-static void init_process_title_mutex_once(void) {
- uv_mutex_init(&process_title_mutex);
-}
-
-
int uv__platform_loop_init(uv_loop_t* loop) {
return uv__kqueue_init(loop);
}
@@ -146,65 +136,6 @@ uint64_t uv_get_total_memory(void) {
}
-char** uv_setup_args(int argc, char** argv) {
- process_title = argc ? uv__strdup(argv[0]) : NULL;
- return argv;
-}
-
-
-int uv_set_process_title(const char* title) {
- char* new_title;
-
- new_title = uv__strdup(title);
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title == NULL) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOMEM;
- }
-
- uv__free(process_title);
- process_title = new_title;
- setproctitle("%s", title);
-
- uv_mutex_unlock(&process_title_mutex);
-
- return 0;
-}
-
-
-int uv_get_process_title(char* buffer, size_t size) {
- size_t len;
-
- if (buffer == NULL || size == 0)
- return UV_EINVAL;
-
- uv_once(&process_title_mutex_once, init_process_title_mutex_once);
- uv_mutex_lock(&process_title_mutex);
-
- if (process_title) {
- len = strlen(process_title) + 1;
-
- if (size < len) {
- uv_mutex_unlock(&process_title_mutex);
- return UV_ENOBUFS;
- }
-
- memcpy(buffer, process_title, len);
- } else {
- len = 0;
- }
-
- uv_mutex_unlock(&process_title_mutex);
-
- buffer[len] = '\0';
-
- return 0;
-}
-
-
int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size = getpagesize();
diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c
index 65e9b708303668..b43aebfc926940 100644
--- a/deps/uv/src/unix/os390.c
+++ b/deps/uv/src/unix/os390.c
@@ -357,13 +357,11 @@ uint64_t uv_get_total_memory(void) {
int uv_resident_set_memory(size_t* rss) {
- char* psa;
char* ascb;
char* rax;
size_t nframes;
- psa = PSA_PTR;
- ascb = *(char* __ptr32 *)(psa + PSAAOLD);
+ ascb = *(char* __ptr32 *)(PSA_PTR + PSAAOLD);
rax = *(char* __ptr32 *)(ascb + ASCBRSME);
nframes = *(unsigned int*)(rax + RAXFMCT);
@@ -531,12 +529,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifreq* p;
int count_v6;
+ *count = 0;
+ *addresses = NULL;
+
/* get the ipv6 addresses first */
uv_interface_address_t* addresses_v6;
uv__interface_addresses_v6(&addresses_v6, &count_v6);
/* now get the ipv4 addresses */
- *count = 0;
/* Assume maximum buffer size allowable */
maxsize = 16384;
@@ -578,6 +578,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
+ if (*count == 0) {
+ uv__close(sockfd);
+ return 0;
+ }
+
/* Alloc the return interface structs */
*addresses = uv__malloc((*count + count_v6) *
sizeof(uv_interface_address_t));
@@ -752,7 +757,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
sizeof(handle->rfis_rftok));
- /*
+ /*
* This call will take "/" as the path argument in case we
* don't care to supply the correct path. The system will simply
* ignore it.
@@ -988,7 +993,7 @@ void uv__set_process_title(const char* title) {
}
int uv__io_fork(uv_loop_t* loop) {
- /*
+ /*
Nullify the msg queue but don't close it because
it is still being used by the parent.
*/
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/sunos.c b/deps/uv/src/unix/sunos.c
index b6b3dfea77a8d7..ec5ecd7d3ce6b9 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -692,6 +692,8 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
#ifdef SUNOS_NO_IFADDRS
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ *count = 0;
+ *addresses = NULL;
return UV_ENOSYS;
}
#else /* SUNOS_NO_IFADDRS */
@@ -758,11 +760,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifaddrs* addrs;
struct ifaddrs* ent;
+ *count = 0;
+ *addresses = NULL;
+
if (getifaddrs(&addrs))
return UV__ERR(errno);
- *count = 0;
-
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent))
@@ -770,6 +773,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
+ if (*count == 0) {
+ freeifaddrs(addrs);
+ return 0;
+ }
+
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
freeifaddrs(addrs);
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index f0aec452606cb8..71d100a162f4ca 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -72,7 +72,9 @@ char* uv__strndup(const char* s, size_t n) {
}
void* uv__malloc(size_t size) {
- return uv__allocator.local_malloc(size);
+ if (size > 0)
+ return uv__allocator.local_malloc(size);
+ return NULL;
}
void uv__free(void* ptr) {
@@ -91,7 +93,10 @@ void* uv__calloc(size_t count, size_t size) {
}
void* uv__realloc(void* ptr, size_t size) {
- return uv__allocator.local_realloc(ptr, size);
+ if (size > 0)
+ return uv__allocator.local_realloc(ptr, size);
+ uv__free(ptr);
+ return NULL;
}
int uv_replace_allocator(uv_malloc_func malloc_func,
diff --git a/deps/uv/src/win/dl.c b/deps/uv/src/win/dl.c
index 97ac1c1ad10012..5b84555ca4d57f 100644
--- a/deps/uv/src/win/dl.c
+++ b/deps/uv/src/win/dl.c
@@ -107,7 +107,8 @@ static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno) {
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR) &lib->errmsg, 0, NULL);
- if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
+ if (!res && (GetLastError() == ERROR_MUI_FILE_NOT_FOUND ||
+ GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND)) {
res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 812c1a6de583d2..7ad0d077a6440b 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -42,6 +42,8 @@
#define UV_FS_FREE_PTR 0x0008
#define UV_FS_CLEANEDUP 0x0010
+#define UV__RENAME_RETRIES 4
+#define UV__RENAME_WAIT 250
#define INIT(subtype) \
do { \
@@ -1329,12 +1331,78 @@ static void fs__fstat(uv_fs_t* req) {
static void fs__rename(uv_fs_t* req) {
- if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
+ int tries;
+ int sys_errno;
+ int result;
+ int try_rmdir;
+ WCHAR* src, *dst;
+ DWORD src_attrib, dst_attrib;
+
+ src = req->file.pathw;
+ dst = req->fs.info.new_pathw;
+ try_rmdir = 0;
+
+ /* Do some checks to fail early. */
+ src_attrib = GetFileAttributesW(src);
+ if (src_attrib == INVALID_FILE_ATTRIBUTES) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
+ dst_attrib = GetFileAttributesW(dst);
+ if (dst_attrib != INVALID_FILE_ATTRIBUTES) {
+ if (dst_attrib & FILE_ATTRIBUTE_READONLY) {
+ req->result = UV_EPERM;
+ return;
+ }
+ /* Renaming folder to a folder name that already exist will fail on
+ * Windows. We will try to delete target folder first.
+ */
+ if (src_attrib & FILE_ATTRIBUTE_DIRECTORY &&
+ dst_attrib & FILE_ATTRIBUTE_DIRECTORY)
+ try_rmdir = 1;
+ }
- SET_REQ_RESULT(req, 0);
+ /* Sometimes an antivirus or indexing software can lock the target or the
+ * source file/directory. This is annoying for users, in such cases we will
+ * retry couple of times with some delay before failing.
+ */
+ for (tries = 0; tries < UV__RENAME_RETRIES; ++tries) {
+ if (tries > 0)
+ Sleep(UV__RENAME_WAIT);
+
+ if (try_rmdir) {
+ result = _wrmdir(dst) == 0 ? 0 : uv_translate_sys_error(_doserrno);
+ switch (result)
+ {
+ case 0:
+ case UV_ENOENT:
+ /* Folder removed or did not exist at all. */
+ try_rmdir = 0;
+ break;
+ case UV_ENOTEMPTY:
+ /* Non-empty target folder, fail instantly. */
+ SET_REQ_RESULT(req, -1);
+ return;
+ default:
+ /* All other errors - try to move file anyway and handle the error
+ * there, retrying folder deletion next time around.
+ */
+ break;
+ }
+ }
+
+ if (MoveFileExW(src, dst, MOVEFILE_REPLACE_EXISTING) != 0) {
+ SET_REQ_RESULT(req, 0);
+ return;
+ }
+
+ sys_errno = GetLastError();
+ result = uv_translate_sys_error(sys_errno);
+ if (result != UV_EBUSY && result != UV_EPERM && result != UV_EACCES)
+ break;
+ }
+ req->sys_errno_ = sys_errno;
+ req->result = result;
}
diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c
index 614ea8e376e8af..dfab860a735e47 100644
--- a/deps/uv/src/win/getaddrinfo.c
+++ b/deps/uv/src/win/getaddrinfo.c
@@ -24,6 +24,7 @@
#include "uv.h"
#include "internal.h"
#include "req-inl.h"
+#include "idna.h"
/* EAI_* constants. */
#include
@@ -259,11 +260,13 @@ int uv_getaddrinfo(uv_loop_t* loop,
const char* node,
const char* service,
const struct addrinfo* hints) {
+ char hostname_ascii[256];
int nodesize = 0;
int servicesize = 0;
int hintssize = 0;
char* alloc_ptr = NULL;
int err;
+ long rc;
if (req == NULL || (node == NULL && service == NULL)) {
return UV_EINVAL;
@@ -277,12 +280,19 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* calculate required memory size for all input values */
if (node != NULL) {
- nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, node, -1, NULL, 0) *
- sizeof(WCHAR));
+ rc = uv__idna_toascii(node,
+ node + strlen(node),
+ hostname_ascii,
+ hostname_ascii + sizeof(hostname_ascii));
+ if (rc < 0)
+ return rc;
+ nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, hostname_ascii,
+ -1, NULL, 0) * sizeof(WCHAR));
if (nodesize == 0) {
err = GetLastError();
goto error;
}
+ node = hostname_ascii;
}
if (service != NULL) {
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index b47f203e9d9c7f..e7cccd9c80123f 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -964,6 +964,8 @@ int uv_spawn(uv_loop_t* loop,
UV_PROCESS_SETGID |
UV_PROCESS_SETUID |
UV_PROCESS_WINDOWS_HIDE |
+ UV_PROCESS_WINDOWS_HIDE_CONSOLE |
+ UV_PROCESS_WINDOWS_HIDE_GUI |
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
err = uv_utf8_to_utf16_alloc(options->file, &application);
@@ -1065,7 +1067,8 @@ int uv_spawn(uv_loop_t* loop,
process_flags = CREATE_UNICODE_ENVIRONMENT;
- if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
+ if ((options->flags & UV_PROCESS_WINDOWS_HIDE_CONSOLE) ||
+ (options->flags & UV_PROCESS_WINDOWS_HIDE)) {
/* Avoid creating console window if stdio is not inherited. */
for (i = 0; i < options->stdio_count; i++) {
if (options->stdio[i].flags & UV_INHERIT_FD)
@@ -1073,7 +1076,9 @@ int uv_spawn(uv_loop_t* loop,
if (i == options->stdio_count - 1)
process_flags |= CREATE_NO_WINDOW;
}
-
+ }
+ if ((options->flags & UV_PROCESS_WINDOWS_HIDE_GUI) ||
+ (options->flags & UV_PROCESS_WINDOWS_HIDE)) {
/* Use SW_HIDE to avoid any potential process window. */
startup.wShowWindow = SW_HIDE;
} else {
diff --git a/deps/uv/src/win/signal.c b/deps/uv/src/win/signal.c
index 3d0b8a35b93ace..276dc609733320 100644
--- a/deps/uv/src/win/signal.c
+++ b/deps/uv/src/win/signal.c
@@ -190,7 +190,7 @@ int uv__signal_start(uv_signal_t* handle,
int signum,
int oneshot) {
/* Test for invalid signal values. */
- if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG))
+ if (signum <= 0 || signum >= NSIG)
return UV_EINVAL;
/* Short circuit: if the signal watcher is already watching {signum} don't go
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index 8b6f0a5c99bd70..3ce5548c0a4d4a 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -945,6 +945,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* req) {
DWORD bytes, flags, err;
uv_buf_t buf;
+ int count;
assert(handle->type == UV_TCP);
@@ -999,7 +1000,8 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
}
/* Do nonblocking reads until the buffer is empty */
- while (handle->flags & UV_HANDLE_READING) {
+ count = 32;
+ while ((handle->flags & UV_HANDLE_READING) && (count-- > 0)) {
buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
if (buf.base == NULL || buf.len == 0) {
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 32ccf74ca8cb6a..398288ec1de53b 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -941,20 +941,15 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
handle->read_cb((uv_stream_t*) handle,
uv_translate_sys_error(GET_REQ_ERROR(req)),
&buf);
- } else {
- /* The read was cancelled, or whatever we don't care */
- handle->read_cb((uv_stream_t*) handle, 0, &buf);
}
-
} else {
- if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) {
+ if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING) &&
+ req->u.io.overlapped.InternalHigh != 0) {
/* Read successful. TODO: read unicode, convert to utf-8 */
DWORD bytes = req->u.io.overlapped.InternalHigh;
handle->read_cb((uv_stream_t*) handle, bytes, &buf);
- } else {
- handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING;
- handle->read_cb((uv_stream_t*) handle, 0, &buf);
}
+ handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING;
}
/* Wait for more input events. */
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index c994984fe65a25..6e81c26165fbc0 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -816,6 +816,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
int is_vista_or_greater;
ULONG flags;
+ *addresses_ptr = NULL;
+ *count_ptr = 0;
+
is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0);
if (is_vista_or_greater) {
flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
diff --git a/deps/uv/test/echo-server.c b/deps/uv/test/echo-server.c
index bfed67675dd46a..a38e975d4841d6 100644
--- a/deps/uv/test/echo-server.c
+++ b/deps/uv/test/echo-server.c
@@ -340,6 +340,7 @@ HELPER_IMPL(tcp4_echo_server) {
if (tcp4_echo_start(TEST_PORT))
return 1;
+ notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -351,6 +352,7 @@ HELPER_IMPL(tcp6_echo_server) {
if (tcp6_echo_start(TEST_PORT))
return 1;
+ notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -362,6 +364,7 @@ HELPER_IMPL(pipe_echo_server) {
if (pipe_echo_start(TEST_PIPENAME))
return 1;
+ notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
@@ -373,6 +376,7 @@ HELPER_IMPL(udp4_echo_server) {
if (udp4_echo_start(TEST_PORT))
return 1;
+ notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index 9b8af0460877bd..42bde0bb96476d 100644
--- a/deps/uv/test/run-tests.c
+++ b/deps/uv/test/run-tests.c
@@ -109,20 +109,24 @@ static int maybe_run_test(int argc, char **argv) {
}
if (strcmp(argv[1], "spawn_helper1") == 0) {
+ notify_parent_process();
return 1;
}
if (strcmp(argv[1], "spawn_helper2") == 0) {
+ notify_parent_process();
printf("hello world\n");
return 1;
}
if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) {
+ notify_parent_process();
return spawn_tcp_server_helper();
}
if (strcmp(argv[1], "spawn_helper3") == 0) {
char buffer[256];
+ notify_parent_process();
ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
buffer[sizeof(buffer) - 1] = '\0';
fputs(buffer, stdout);
@@ -130,12 +134,14 @@ static int maybe_run_test(int argc, char **argv) {
}
if (strcmp(argv[1], "spawn_helper4") == 0) {
+ notify_parent_process();
/* Never surrender, never return! */
while (1) uv_sleep(10000);
}
if (strcmp(argv[1], "spawn_helper5") == 0) {
const char out[] = "fourth stdio!\n";
+ notify_parent_process();
#ifdef _WIN32
DWORD bytes;
WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
@@ -156,6 +162,8 @@ static int maybe_run_test(int argc, char **argv) {
if (strcmp(argv[1], "spawn_helper6") == 0) {
int r;
+ notify_parent_process();
+
r = fprintf(stdout, "hello world\n");
ASSERT(r > 0);
@@ -168,6 +176,9 @@ static int maybe_run_test(int argc, char **argv) {
if (strcmp(argv[1], "spawn_helper7") == 0) {
int r;
char *test;
+
+ notify_parent_process();
+
/* Test if the test value from the parent is still set */
test = getenv("ENV_TEST");
ASSERT(test != NULL);
@@ -181,6 +192,8 @@ static int maybe_run_test(int argc, char **argv) {
#ifndef _WIN32
if (strcmp(argv[1], "spawn_helper8") == 0) {
int fd;
+
+ notify_parent_process();
ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd)));
ASSERT(fd > 2);
ASSERT(-1 == write(fd, "x", 1));
@@ -190,6 +203,7 @@ static int maybe_run_test(int argc, char **argv) {
#endif /* !_WIN32 */
if (strcmp(argv[1], "spawn_helper9") == 0) {
+ notify_parent_process();
return spawn_stdin_stdout();
}
@@ -200,6 +214,7 @@ static int maybe_run_test(int argc, char **argv) {
ASSERT(uid == getuid());
ASSERT(gid == getgid());
+ notify_parent_process();
return 1;
}
diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c
index de0db0cc486d6a..432cf33d482cd9 100644
--- a/deps/uv/test/runner-unix.c
+++ b/deps/uv/test/runner-unix.c
@@ -40,6 +40,31 @@
#include
#include
+extern char** environ;
+
+static void closefd(int fd) {
+ if (close(fd) == 0 || errno == EINTR || errno == EINPROGRESS)
+ return;
+
+ perror("close");
+ abort();
+}
+
+
+void notify_parent_process(void) {
+ char* arg;
+ int fd;
+
+ arg = getenv("UV_TEST_RUNNER_FD");
+ if (arg == NULL)
+ return;
+
+ fd = atoi(arg);
+ assert(fd > STDERR_FILENO);
+ unsetenv("UV_TEST_RUNNER_FD");
+ closefd(fd);
+}
+
/* Do platform-specific initialization. */
int platform_init(int argc, char **argv) {
@@ -64,9 +89,31 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
int stdout_fd;
const char* arg;
char* args[16];
+ int pipefd[2];
+ char fdstr[8];
+ ssize_t rc;
int n;
pid_t pid;
+ arg = getenv("UV_USE_VALGRIND");
+ n = 0;
+
+ /* Disable valgrind for helpers, it complains about helpers leaking memory.
+ * They're killed after the test and as such never get a chance to clean up.
+ */
+ if (is_helper == 0 && arg != NULL && atoi(arg) != 0) {
+ args[n++] = "valgrind";
+ args[n++] = "--quiet";
+ args[n++] = "--leak-check=full";
+ args[n++] = "--show-reachable=yes";
+ args[n++] = "--error-exitcode=125";
+ }
+
+ args[n++] = executable_path;
+ args[n++] = name;
+ args[n++] = part;
+ args[n++] = NULL;
+
stdout_file = tmpfile();
stdout_fd = fileno(stdout_file);
if (!stdout_file) {
@@ -74,6 +121,19 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
return -1;
}
+ if (is_helper) {
+ if (pipe(pipefd)) {
+ perror("pipe");
+ return -1;
+ }
+
+ snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]);
+ if (setenv("UV_TEST_RUNNER_FD", fdstr, /* overwrite */ 1)) {
+ perror("setenv");
+ return -1;
+ }
+ }
+
p->terminated = 0;
p->status = 0;
@@ -86,29 +146,12 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
if (pid == 0) {
/* child */
- arg = getenv("UV_USE_VALGRIND");
- n = 0;
-
- /* Disable valgrind for helpers, it complains about helpers leaking memory.
- * They're killed after the test and as such never get a chance to clean up.
- */
- if (is_helper == 0 && arg != NULL && atoi(arg) != 0) {
- args[n++] = "valgrind";
- args[n++] = "--quiet";
- args[n++] = "--leak-check=full";
- args[n++] = "--show-reachable=yes";
- args[n++] = "--error-exitcode=125";
- }
-
- args[n++] = executable_path;
- args[n++] = name;
- args[n++] = part;
- args[n++] = NULL;
-
+ if (is_helper)
+ closefd(pipefd[0]);
dup2(stdout_fd, STDOUT_FILENO);
dup2(stdout_fd, STDERR_FILENO);
- execvp(args[0], args);
- perror("execvp()");
+ execve(args[0], args, environ);
+ perror("execve()");
_exit(127);
}
@@ -117,6 +160,28 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
p->name = strdup(name);
p->stdout_file = stdout_file;
+ if (!is_helper)
+ return 0;
+
+ closefd(pipefd[1]);
+ unsetenv("UV_TEST_RUNNER_FD");
+
+ do
+ rc = read(pipefd[0], &n, 1);
+ while (rc == -1 && errno == EINTR);
+
+ closefd(pipefd[0]);
+
+ if (rc == -1) {
+ perror("read");
+ return -1;
+ }
+
+ if (rc > 0) {
+ fprintf(stderr, "EOF expected but got data.\n");
+ return -1;
+ }
+
return 0;
}
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index aa52d7cc5aa9a6..e3e91a7b69ca62 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -76,6 +76,11 @@ int process_start(char *name, char *part, process_info_t *p, int is_helper) {
PROCESS_INFORMATION pi;
DWORD result;
+ if (!is_helper) {
+ /* Give the helpers time to settle. Race-y, fix this. */
+ uv_sleep(250);
+ }
+
if (GetTempPathW(sizeof(path) / sizeof(WCHAR), (WCHAR*)&path) == 0)
goto error;
if (GetTempFileNameW((WCHAR*)&path, L"uv", 0, (WCHAR*)&filename) == 0)
diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c
index f017902a04f7c8..aec560a59dbc5c 100644
--- a/deps/uv/test/runner.c
+++ b/deps/uv/test/runner.c
@@ -215,9 +215,6 @@ int run_test(const char* test,
process_count++;
}
- /* Give the helpers time to settle. Race-y, fix this. */
- uv_sleep(250);
-
/* Now start the test itself. */
for (task = TASKS; task->main; task++) {
if (strcmp(test, task->task_name) != 0) {
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 92a90a540be34f..282c02d50ce42d 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -181,6 +181,12 @@ extern int snprintf(char*, size_t, const char*, ...);
# define UNUSED
#endif
+#if defined(_WIN32)
+#define notify_parent_process() ((void) 0)
+#else
+extern void notify_parent_process(void);
+#endif
+
/* Fully close a loop */
static void close_walk_cb(uv_handle_t* handle, void* arg) {
if (!uv_is_closing(handle))
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 01f5a7b0236514..038d2dd6159245 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -3037,6 +3037,60 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
return 0;
}
+TEST_IMPL(fs_read_dir) {
+ int r;
+ char buf[2];
+ loop = uv_default_loop();
+
+ /* Setup */
+ rmdir("test_dir");
+ r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(mkdir_cb_count == 1);
+ /* Setup Done Here */
+
+ /* Get a file descriptor for the directory */
+ r = uv_fs_open(loop,
+ &open_req1,
+ "test_dir",
+ UV_FS_O_RDONLY | UV_FS_O_DIRECTORY,
+ S_IWUSR | S_IRUSR,
+ NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ /* Try to read data from the directory */
+ iov = uv_buf_init(buf, sizeof(buf));
+ r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL);
+#if defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__) || \
+ defined(__DragonFly__) || \
+ defined(_AIX) || \
+ defined(__sun) || \
+ defined(__MVS__)
+ /*
+ * As of now, these operating systems support reading from a directory,
+ * that too depends on the filesystem this temporary test directory is
+ * created on. That is why this assertion is a bit lenient.
+ */
+ ASSERT((r >= 0) || (r == UV_EISDIR));
+#else
+ ASSERT(r == UV_EISDIR);
+#endif
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ /* Cleanup */
+ rmdir("test_dir");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
#ifdef _WIN32
diff --git a/deps/uv/test/test-idna.c b/deps/uv/test/test-idna.c
new file mode 100644
index 00000000000000..b76853cb996ecc
--- /dev/null
+++ b/deps/uv/test/test-idna.c
@@ -0,0 +1,195 @@
+/* Copyright The libuv project and 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 "task.h"
+#include "../src/idna.c"
+#include
+
+TEST_IMPL(utf8_decode1) {
+ const char* p;
+ char b[32];
+ int i;
+
+ /* ASCII. */
+ p = b;
+ snprintf(b, sizeof(b), "%c\x7F", 0x00);
+ ASSERT(0 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 1);
+ ASSERT(127 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 2);
+
+ /* Two-byte sequences. */
+ p = b;
+ snprintf(b, sizeof(b), "\xC2\x80\xDF\xBF");
+ ASSERT(128 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 2);
+ ASSERT(0x7FF == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 4);
+
+ /* Three-byte sequences. */
+ p = b;
+ snprintf(b, sizeof(b), "\xE0\xA0\x80\xEF\xBF\xBF");
+ ASSERT(0x800 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 3);
+ ASSERT(0xFFFF == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 6);
+
+ /* Four-byte sequences. */
+ p = b;
+ snprintf(b, sizeof(b), "\xF0\x90\x80\x80\xF4\x8F\xBF\xBF");
+ ASSERT(0x10000 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 4);
+ ASSERT(0x10FFFF == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 8);
+
+ /* Four-byte sequences > U+10FFFF; disallowed. */
+ p = b;
+ snprintf(b, sizeof(b), "\xF4\x90\xC0\xC0\xF7\xBF\xBF\xBF");
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 4);
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 8);
+
+ /* Overlong; disallowed. */
+ p = b;
+ snprintf(b, sizeof(b), "\xC0\x80\xC1\x80");
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 2);
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 4);
+
+ /* Surrogate pairs; disallowed. */
+ p = b;
+ snprintf(b, sizeof(b), "\xED\xA0\x80\xED\xA3\xBF");
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 3);
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + 6);
+
+ /* Simply illegal. */
+ p = b;
+ snprintf(b, sizeof(b), "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
+
+ for (i = 1; i <= 8; i++) {
+ ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b)));
+ ASSERT(p == b + i);
+ }
+
+ return 0;
+}
+
+/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */
+#ifndef __MVS__
+
+#define F(input, err) \
+ do { \
+ char d[256] = {0}; \
+ static const char s[] = "" input ""; \
+ ASSERT(err == uv__idna_toascii(s, s + sizeof(s) - 1, d, d + sizeof(d))); \
+ } while (0)
+
+#define T(input, expected) \
+ do { \
+ long n; \
+ char d1[256] = {0}; \
+ char d2[256] = {0}; \
+ static const char s[] = "" input ""; \
+ n = uv__idna_toascii(s, s + sizeof(s) - 1, d1, d1 + sizeof(d1)); \
+ ASSERT(n == sizeof(expected)); \
+ ASSERT(0 == memcmp(d1, expected, n)); \
+ /* Sanity check: encoding twice should not change the output. */ \
+ n = uv__idna_toascii(d1, d1 + strlen(d1), d2, d2 + sizeof(d2)); \
+ ASSERT(n == sizeof(expected)); \
+ ASSERT(0 == memcmp(d2, expected, n)); \
+ ASSERT(0 == memcmp(d1, d2, sizeof(d2))); \
+ } while (0)
+
+TEST_IMPL(idna_toascii) {
+ /* Illegal inputs. */
+ F("\xC0\x80\xC1\x80", UV_EINVAL); /* Overlong UTF-8 sequence. */
+ F("\xC0\x80\xC1\x80.com", UV_EINVAL); /* Overlong UTF-8 sequence. */
+ /* No conversion. */
+ T("", "");
+ T(".", ".");
+ T(".com", ".com");
+ T("example", "example");
+ T("example-", "example-");
+ T("straße.de", "xn--strae-oqa.de");
+ /* Test cases adapted from punycode.js. Most are from RFC 3492. */
+ T("foo.bar", "foo.bar");
+ T("mañana.com", "xn--maana-pta.com");
+ T("example.com.", "example.com.");
+ T("bücher.com", "xn--bcher-kva.com");
+ T("café.com", "xn--caf-dma.com");
+ T("café.café.com", "xn--caf-dma.xn--caf-dma.com");
+ T("☃-⌘.com", "xn----dqo34k.com");
+ T("퐀☃-⌘.com", "xn----dqo34kn65z.com");
+ T("💩.la", "xn--ls8h.la");
+ T("mañana.com", "xn--maana-pta.com");
+ T("mañana。com", "xn--maana-pta.com");
+ T("mañana.com", "xn--maana-pta.com");
+ T("mañana。com", "xn--maana-pta.com");
+ T("ü", "xn--tda");
+ T(".ü", ".xn--tda");
+ T("ü.ü", "xn--tda.xn--tda");
+ T("ü.ü.", "xn--tda.xn--tda.");
+ T("üëäö♥", "xn--4can8av2009b");
+ T("Willst du die Blüthe des frühen, die Früchte des späteren Jahres",
+ "xn--Willst du die Blthe des frhen, "
+ "die Frchte des spteren Jahres-x9e96lkal");
+ T("ليهمابتكلموشعربي؟", "xn--egbpdaj6bu4bxfgehfvwxn");
+ T("他们为什么不说中文", "xn--ihqwcrb4cv8a8dqg056pqjye");
+ T("他們爲什麽不說中文", "xn--ihqwctvzc91f659drss3x8bo0yb");
+ T("Pročprostěnemluvíčesky", "xn--Proprostnemluvesky-uyb24dma41a");
+ T("למההםפשוטלאמדבריםעברית", "xn--4dbcagdahymbxekheh6e0a7fei0b");
+ T("यहलोगहिन्दीक्योंनहींबोलसकतेहैं",
+ "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd");
+ T("なぜみんな日本語を話してくれないのか",
+ "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa");
+ T("세계의모든사람들이한국어를이해한다면얼마나좋을까",
+ "xn--989aomsvi5e83db1d2a355cv1e0vak1d"
+ "wrv93d5xbh15a0dt30a5jpsd879ccm6fea98c");
+ T("почемужеонинеговорятпорусски", "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
+ T("PorquénopuedensimplementehablarenEspañol",
+ "xn--PorqunopuedensimplementehablarenEspaol-fmd56a");
+ T("TạisaohọkhôngthểchỉnóitiếngViệt",
+ "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g");
+ T("3年B組金八先生", "xn--3B-ww4c5e180e575a65lsy2b");
+ T("安室奈美恵-with-SUPER-MONKEYS",
+ "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n");
+ T("Hello-Another-Way-それぞれの場所",
+ "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b");
+ T("ひとつ屋根の下2", "xn--2-u9tlzr9756bt3uc0v");
+ T("MajiでKoiする5秒前", "xn--MajiKoi5-783gue6qz075azm5e");
+ T("パフィーdeルンバ", "xn--de-jg4avhby1noc0d");
+ T("そのスピードで", "xn--d9juau41awczczp");
+ T("-> $1.00 <-", "-> $1.00 <-");
+ /* Test cases from https://unicode.org/reports/tr46/ */
+ T("faß.de", "xn--fa-hia.de");
+ T("βόλος.com", "xn--nxasmm1c.com");
+ T("ශ්රී.com", "xn--10cl1a0b660p.com");
+ T("نامهای.com", "xn--mgba3gch31f060k.com");
+ return 0;
+}
+
+#undef T
+
+#endif /* __MVS__ */
diff --git a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
index 240fc64588b413..325305a6442fcf 100644
--- a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
+++ b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
@@ -150,6 +150,7 @@ int ipc_helper_heavy_traffic_deadlock_bug(void) {
r = uv_pipe_open(&pipe, 0);
ASSERT(r == 0);
+ notify_parent_process();
do_writes_and_reads((uv_stream_t*) &pipe);
uv_sleep(100);
diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c
index 3dedc86b8b0170..166225c01c6b52 100644
--- a/deps/uv/test/test-ipc-send-recv.c
+++ b/deps/uv/test/test-ipc-send-recv.c
@@ -397,6 +397,7 @@ int run_ipc_send_recv_helper(uv_loop_t* loop, int inprocess) {
send_recv_start();
}
+ notify_parent_process();
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c
index 200f68d6000a77..829d178d47fe7a 100644
--- a/deps/uv/test/test-ipc.c
+++ b/deps/uv/test/test-ipc.c
@@ -724,6 +724,7 @@ int ipc_helper(int listen_after_write) {
ASSERT(r == 0);
}
+ notify_parent_process();
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 1bd062da3d2e4b..46db4b2710138f 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -346,6 +346,7 @@ TEST_DECLARE (fs_partial_read)
TEST_DECLARE (fs_partial_write)
TEST_DECLARE (fs_file_pos_after_op_with_offset)
TEST_DECLARE (fs_null_req)
+TEST_DECLARE (fs_read_dir)
#ifdef _WIN32
TEST_DECLARE (fs_exclusive_sharing_mode)
TEST_DECLARE (fs_open_readonly_acl)
@@ -441,6 +442,9 @@ TEST_DECLARE (fork_threadpool_queue_work_simple)
#endif
#endif
+TEST_DECLARE (idna_toascii)
+TEST_DECLARE (utf8_decode1)
+
TASK_LIST_START
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
@@ -897,6 +901,7 @@ TASK_LIST_START
TEST_ENTRY (fs_read_write_null_arguments)
TEST_ENTRY (fs_file_pos_after_op_with_offset)
TEST_ENTRY (fs_null_req)
+ TEST_ENTRY (fs_read_dir)
#ifdef _WIN32
TEST_ENTRY (fs_exclusive_sharing_mode)
TEST_ENTRY (fs_open_readonly_acl)
@@ -944,6 +949,13 @@ TASK_LIST_START
#endif
#endif
+ TEST_ENTRY (utf8_decode1)
+
+/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */
+#ifndef __MVS__
+ TEST_ENTRY (idna_toascii)
+#endif
+
#if 0
/* These are for testing the test runner. */
TEST_ENTRY (fail_always)
diff --git a/deps/uv/test/test-process-title-threadsafe.c b/deps/uv/test/test-process-title-threadsafe.c
index cc3fd41a136833..c0dee48a79f22f 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-spawn.c b/deps/uv/test/test-spawn.c
index 4fcd905eed7500..594a64c60b8d5a 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -1172,6 +1172,7 @@ TEST_IMPL(argument_escaping) {
for (i = 0; i < count; ++i) {
free(test_output[i]);
}
+ free(test_output);
result = make_program_args(verbatim, 1, &verbatim_output);
ASSERT(result == 0);
diff --git a/deps/uv/test/test-stdio-over-pipes.c b/deps/uv/test/test-stdio-over-pipes.c
index 15744761049d84..a130ff6a9bc0c1 100644
--- a/deps/uv/test/test-stdio-over-pipes.c
+++ b/deps/uv/test/test-stdio-over-pipes.c
@@ -232,6 +232,7 @@ int stdio_over_pipes_helper(void) {
ASSERT(r == 0);
}
+ notify_parent_process();
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(after_write_called == 7);
diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp
index 855eda1c50003a..098512208c3cf8 100644
--- a/deps/uv/test/test.gyp
+++ b/deps/uv/test/test.gyp
@@ -46,6 +46,7 @@
'test-homedir.c',
'test-hrtime.c',
'test-idle.c',
+ 'test-idna.c',
'test-ip6-addr.c',
'test-ipc-heavy-traffic-deadlock-bug.c',
'test-ipc-send-recv.c',
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 5148a850ab4c15..746d1ed5416322 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -70,6 +70,8 @@
'include/uv/version.h',
'src/fs-poll.c',
'src/heap-inl.h',
+ 'src/idna.c',
+ 'src/idna.h',
'src/inet.c',
'src/queue.h',
'src/threadpool.c',
@@ -326,7 +328,10 @@
'sources': [ 'src/unix/netbsd.c' ],
}],
[ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', {
- 'sources': [ 'src/unix/posix-hrtime.c' ],
+ 'sources': [
+ 'src/unix/posix-hrtime.c',
+ 'src/unix/bsd-proctitle.c'
+ ],
}],
[ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', {
'sources': [
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 8f8aaf7bc628ac..5ac9aec0479277 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -7103,30 +7103,30 @@ i::Handle MapAsArray(i::Isolate* isolate, i::Object* table_obj,
i::Factory* factory = isolate->factory();
i::Handle table(i::OrderedHashMap::cast(table_obj),
isolate);
- if (offset >= table->NumberOfElements()) return factory->NewJSArray(0);
- int length = (table->NumberOfElements() - offset) *
- (kind == MapAsArrayKind::kEntries ? 2 : 1);
- i::Handle result = factory->NewFixedArray(length);
+ const bool collect_keys =
+ kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
+ const bool collect_values =
+ kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
+ int capacity = table->UsedCapacity();
+ int max_length =
+ (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
+ i::Handle result = factory->NewFixedArray(max_length);
int result_index = 0;
{
i::DisallowHeapAllocation no_gc;
- int capacity = table->UsedCapacity();
i::Oddball* the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
- for (int i = 0; i < capacity; ++i) {
+ for (int i = offset; i < capacity; ++i) {
i::Object* key = table->KeyAt(i);
if (key == the_hole) continue;
- if (offset-- > 0) continue;
- if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys) {
- result->set(result_index++, key);
- }
- if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues) {
- result->set(result_index++, table->ValueAt(i));
- }
+ if (collect_keys) result->set(result_index++, key);
+ if (collect_values) result->set(result_index++, table->ValueAt(i));
}
}
- DCHECK_EQ(result_index, result->length());
- DCHECK_EQ(result_index, length);
- return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
+ DCHECK_GE(max_length, result_index);
+ if (result_index == 0) return factory->NewJSArray(0);
+ result->Shrink(isolate, result_index);
+ return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
+ result_index);
}
} // namespace
@@ -7211,24 +7211,26 @@ i::Handle SetAsArray(i::Isolate* isolate, i::Object* table_obj,
i::Factory* factory = isolate->factory();
i::Handle table(i::OrderedHashSet::cast(table_obj),
isolate);
- int length = table->NumberOfElements() - offset;
- if (length <= 0) return factory->NewJSArray(0);
- i::Handle result = factory->NewFixedArray(length);
+ // Elements skipped by |offset| may already be deleted.
+ int capacity = table->UsedCapacity();
+ int max_length = capacity - offset;
+ if (max_length == 0) return factory->NewJSArray(0);
+ i::Handle result = factory->NewFixedArray(max_length);
int result_index = 0;
{
i::DisallowHeapAllocation no_gc;
- int capacity = table->UsedCapacity();
i::Oddball* the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
- for (int i = 0; i < capacity; ++i) {
+ for (int i = offset; i < capacity; ++i) {
i::Object* key = table->KeyAt(i);
if (key == the_hole) continue;
- if (offset-- > 0) continue;
result->set(result_index++, key);
}
}
- DCHECK_EQ(result_index, result->length());
- DCHECK_EQ(result_index, length);
- return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
+ DCHECK_GE(max_length, result_index);
+ if (result_index == 0) return factory->NewJSArray(0);
+ result->Shrink(isolate, result_index);
+ return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
+ result_index);
}
} // namespace
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index f7365c8f31a8c8..1b74ecfd70c655 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -28777,3 +28777,217 @@ TEST(TestSetWasmThreadsEnabledCallback) {
i::FLAG_experimental_wasm_threads = false;
CHECK(i_isolate->AreWasmThreadsEnabled(i_context));
}
+
+TEST(PreviewSetIteratorEntriesWithDeleted) {
+ LocalContext env;
+ v8::HandleScope handle_scope(env->GetIsolate());
+ v8::Local context = env.local();
+
+ {
+ // Create set, delete entry, create iterator, preview.
+ v8::Local iterator =
+ CompileRun("var set = new Set([1,2,3]); set.delete(1); set.keys()")
+ ->ToObject(context)
+ .ToLocalChecked();
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(2, entries->Length());
+ CHECK_EQ(2, entries->Get(context, 0)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ CHECK_EQ(3, entries->Get(context, 1)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ {
+ // Create set, create iterator, delete entry, preview.
+ v8::Local iterator =
+ CompileRun("var set = new Set([1,2,3]); set.keys()")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("set.delete(1);");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(2, entries->Length());
+ CHECK_EQ(2, entries->Get(context, 0)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ CHECK_EQ(3, entries->Get(context, 1)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ {
+ // Create set, create iterator, delete entry, iterate, preview.
+ v8::Local iterator =
+ CompileRun("var set = new Set([1,2,3]); var it = set.keys(); it")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("set.delete(1); it.next();");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(1, entries->Length());
+ CHECK_EQ(3, entries->Get(context, 0)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ {
+ // Create set, create iterator, delete entry, iterate until empty, preview.
+ v8::Local iterator =
+ CompileRun("var set = new Set([1,2,3]); var it = set.keys(); it")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("set.delete(1); it.next(); it.next();");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(0, entries->Length());
+ }
+ {
+ // Create set, create iterator, delete entry, iterate, trigger rehash,
+ // preview.
+ v8::Local iterator =
+ CompileRun("var set = new Set([1,2,3]); var it = set.keys(); it")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("set.delete(1); it.next();");
+ CompileRun("for (var i = 4; i < 20; i++) set.add(i);");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(17, entries->Length());
+ for (uint32_t i = 0; i < 17; i++) {
+ CHECK_EQ(i + 3, entries->Get(context, i)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ }
+}
+
+TEST(PreviewMapIteratorEntriesWithDeleted) {
+ LocalContext env;
+ v8::HandleScope handle_scope(env->GetIsolate());
+ v8::Local context = env.local();
+
+ {
+ // Create map, delete entry, create iterator, preview.
+ v8::Local iterator = CompileRun(
+ "var map = new Map();"
+ "var key = {}; map.set(key, 1);"
+ "map.set({}, 2); map.set({}, 3);"
+ "map.delete(key);"
+ "map.values()")
+ ->ToObject(context)
+ .ToLocalChecked();
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(2, entries->Length());
+ CHECK_EQ(2, entries->Get(context, 0)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ CHECK_EQ(3, entries->Get(context, 1)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ {
+ // Create map, create iterator, delete entry, preview.
+ v8::Local iterator = CompileRun(
+ "var map = new Map();"
+ "var key = {}; map.set(key, 1);"
+ "map.set({}, 2); map.set({}, 3);"
+ "map.values()")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("map.delete(key);");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(2, entries->Length());
+ CHECK_EQ(2, entries->Get(context, 0)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ CHECK_EQ(3, entries->Get(context, 1)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ {
+ // Create map, create iterator, delete entry, iterate, preview.
+ v8::Local iterator = CompileRun(
+ "var map = new Map();"
+ "var key = {}; map.set(key, 1);"
+ "map.set({}, 2); map.set({}, 3);"
+ "var it = map.values(); it")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("map.delete(key); it.next();");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(1, entries->Length());
+ CHECK_EQ(3, entries->Get(context, 0)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ {
+ // Create map, create iterator, delete entry, iterate until empty, preview.
+ v8::Local iterator = CompileRun(
+ "var map = new Map();"
+ "var key = {}; map.set(key, 1);"
+ "map.set({}, 2); map.set({}, 3);"
+ "var it = map.values(); it")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("map.delete(key); it.next(); it.next();");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(0, entries->Length());
+ }
+ {
+ // Create map, create iterator, delete entry, iterate, trigger rehash,
+ // preview.
+ v8::Local iterator = CompileRun(
+ "var map = new Map();"
+ "var key = {}; map.set(key, 1);"
+ "map.set({}, 2); map.set({}, 3);"
+ "var it = map.values(); it")
+ ->ToObject(context)
+ .ToLocalChecked();
+ CompileRun("map.delete(key); it.next();");
+ CompileRun("for (var i = 4; i < 20; i++) map.set({}, i);");
+ bool is_key;
+ v8::Local entries =
+ iterator->PreviewEntries(&is_key).ToLocalChecked();
+ CHECK(!is_key);
+ CHECK_EQ(17, entries->Length());
+ for (uint32_t i = 0; i < 17; i++) {
+ CHECK_EQ(i + 3, entries->Get(context, i)
+ .ToLocalChecked()
+ ->Int32Value(context)
+ .FromJust());
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index 851099607945e6..e08bec375e4a74 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -2545,6 +2545,21 @@ TEST(MultipleProfilers) {
profiler2->StopProfiling("2");
}
+int GetSourcePositionEntryCount(i::Isolate* isolate, const char* source) {
+ i::Handle function = i::Handle::cast(
+ v8::Utils::OpenHandle(*CompileRun(source)));
+ if (function->IsInterpreted()) return -1;
+ i::Handle code(function->code(), isolate);
+ i::SourcePositionTableIterator iterator(
+ ByteArray::cast(code->source_position_table()));
+ int count = 0;
+ while (!iterator.done()) {
+ count++;
+ iterator.Advance();
+ }
+ return count;
+}
+
UNINITIALIZED_TEST(DetailedSourcePositionAPI) {
i::FLAG_detailed_line_info = false;
i::FLAG_allow_natives_syntax = true;
diff --git a/doc/api/assert.md b/doc/api/assert.md
index e8249b0f321aca..4c4b2c4250f581 100644
--- a/doc/api/assert.md
+++ b/doc/api/assert.md
@@ -1245,8 +1245,8 @@ assert.throws(throwingFirst, /Second$/);
Due to the confusing notation, it is recommended not to use a string as the
second argument. This might lead to difficult-to-spot errors.
-[`ERR_INVALID_RETURN_VALUE`]: errors.html#errors_err_invalid_return_value
[`Class`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
+[`ERR_INVALID_RETURN_VALUE`]: errors.html#errors_err_invalid_return_value
[`Error.captureStackTrace`]: errors.html#errors_error_capturestacktrace_targetobject_constructoropt
[`Error`]: errors.html#errors_class_error
[`Map`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
@@ -1267,10 +1267,10 @@ second argument. This might lead to difficult-to-spot errors.
[`assert.throws()`]: #assert_assert_throws_fn_error_message
[`strict mode`]: #assert_strict_mode
[Abstract Equality Comparison]: https://tc39.github.io/ecma262/#sec-abstract-equality-comparison
+[Object wrappers]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
[SameValue Comparison]: https://tc39.github.io/ecma262/#sec-samevalue
[Strict Equality Comparison]: https://tc39.github.io/ecma262/#sec-strict-equality-comparison
[enumerable "own" properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
[mdn-equality-guide]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
[prototype-spec]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots
-[Object wrappers]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md
index 1529e33e474084..ad7a94736ff540 100644
--- a/doc/api/async_hooks.md
+++ b/doc/api/async_hooks.md
@@ -150,9 +150,9 @@ Because printing to the console is an asynchronous operation, `console.log()`
will cause the AsyncHooks callbacks to be called. Using `console.log()` or
similar asynchronous operations inside an AsyncHooks callback function will thus
cause an infinite recursion. An easy solution to this when debugging is to use a
-synchronous logging operation such as `fs.writeSync(process.stdout.fd, msg)`.
-This will print to stdout and will not invoke AsyncHooks recursively because it
-is synchronous.
+synchronous logging operation such as `fs.writeFileSync(file, msg, flag)`.
+This will print to the file and will not invoke AsyncHooks recursively because
+it is synchronous.
```js
const fs = require('fs');
@@ -160,7 +160,7 @@ const util = require('util');
function debug(...args) {
// use a function like this one when debugging inside an AsyncHooks callback
- fs.writeSync(process.stdout.fd, `${util.format(...args)}\n`);
+ fs.writeFileSync('log.out', `${util.format(...args)}\n`, { flag: 'a' });
}
```
@@ -330,17 +330,20 @@ async_hooks.createHook({
},
before(asyncId) {
const indentStr = ' '.repeat(indent);
- fs.writeSync(process.stdout.fd, `${indentStr}before: ${asyncId}\n`);
+ fs.writeFileSync('log.out',
+ `${indentStr}before: ${asyncId}\n`, { flag: 'a' });
indent += 2;
},
after(asyncId) {
indent -= 2;
const indentStr = ' '.repeat(indent);
- fs.writeSync(process.stdout.fd, `${indentStr}after: ${asyncId}\n`);
+ fs.writeFileSync('log.out',
+ `${indentStr}after: ${asyncId}\n`, { flag: 'a' });
},
destroy(asyncId) {
const indentStr = ' '.repeat(indent);
- fs.writeSync(process.stdout.fd, `${indentStr}destroy: ${asyncId}\n`);
+ fs.writeFileSync('log.out',
+ `${indentStr}destroy: ${asyncId}\n`, { flag: 'a' });
},
}).enable();
@@ -479,13 +482,12 @@ The ID returned from `executionAsyncId()` is related to execution timing, not
causality (which is covered by `triggerAsyncId()`):
```js
-const server = net.createServer(function onConnection(conn) {
+const server = net.createServer((conn) => {
// Returns the ID of the server, not of the new connection, because the
- // onConnection callback runs in the execution scope of the server's
- // MakeCallback().
+ // callback runs in the execution scope of the server's MakeCallback().
async_hooks.executionAsyncId();
-}).listen(port, function onListening() {
+}).listen(port, () => {
// Returns the ID of a TickObject (i.e. process.nextTick()) because all
// callbacks passed to .listen() are wrapped in a nextTick().
async_hooks.executionAsyncId();
@@ -711,6 +713,7 @@ never be called.
* Returns: {number} The same `triggerAsyncId` that is passed to the
`AsyncResource` constructor.
+[`Worker`]: worker_threads.html#worker_threads_class_worker
[`after` callback]: #async_hooks_after_asyncid
[`asyncResource.runInAsyncScope()`]: #async_hooks_asyncresource_runinasyncscope_fn_thisarg_args
[`before` callback]: #async_hooks_before_asyncid
@@ -719,4 +722,3 @@ never be called.
[Hook Callbacks]: #async_hooks_hook_callbacks
[PromiseHooks]: https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk/edit
[promise execution tracking]: #async_hooks_promise_execution_tracking
-[`Worker`]: worker_threads.html#worker_threads_class_worker
diff --git a/doc/api/buffer.md b/doc/api/buffer.md
index 1ad65494278b73..13267b710addcb 100644
--- a/doc/api/buffer.md
+++ b/doc/api/buffer.md
@@ -2672,9 +2672,9 @@ This value may depend on the JS engine that is being used.
[`buf.length`]: #buffer_buf_length
[`buf.slice()`]: #buffer_buf_slice_start_end
[`buf.values()`]: #buffer_buf_values
-[`buffer.kMaxLength`]: #buffer_buffer_kmaxlength
[`buffer.constants.MAX_LENGTH`]: #buffer_buffer_constants_max_length
[`buffer.constants.MAX_STRING_LENGTH`]: #buffer_buffer_constants_max_string_length
+[`buffer.kMaxLength`]: #buffer_buffer_kmaxlength
[`util.inspect()`]: util.html#util_util_inspect_object_options
[RFC1345]: https://tools.ietf.org/html/rfc1345
[RFC4648, Section 5]: https://tools.ietf.org/html/rfc4648#section-5
diff --git a/doc/api/child_process.md b/doc/api/child_process.md
index 7ba83b3528f8ef..e32568cd78e677 100644
--- a/doc/api/child_process.md
+++ b/doc/api/child_process.md
@@ -325,6 +325,9 @@ changes:
* `args` {string[]} List of string arguments.
* `options` {Object}
* `cwd` {string} Current working directory of the child process.
+ * `detached` {boolean} Prepare child to run independently of its parent
+ process. Specific behavior depends on the platform, see
+ [`options.detached`][]).
* `env` {Object} Environment key-value pairs.
* `execPath` {string} Executable used to create the child process.
* `execArgv` {string[]} List of string arguments passed to the executable.
@@ -617,8 +620,8 @@ pipes between the parent and child. The value is one of the following:
`'ignore'` will cause Node.js to open `/dev/null` and attach it to the
child's fd.
4. `'inherit'` - Pass through the corresponding stdio stream to/from the
- parent process. In the first three positions, this is equivalent to
- `process.stdin`, `process.stdout`, and `process.stderr`, respectively. In
+ parent process. In the first three positions, this is equivalent to
+ `process.stdin`, `process.stdout`, and `process.stderr`, respectively. In
any other position, equivalent to `'ignore'`.
5. {Stream} object - Share a readable or writable stream that refers to a tty,
file, socket, or a pipe with the child process. The stream's underlying
@@ -1433,13 +1436,6 @@ unavailable.
[`ChildProcess`]: #child_process_child_process
[`Error`]: errors.html#errors_class_error
[`EventEmitter`]: events.html#events_class_eventemitter
-[`subprocess.connected`]: #child_process_subprocess_connected
-[`subprocess.disconnect()`]: #child_process_subprocess_disconnect
-[`subprocess.kill()`]: #child_process_subprocess_kill_signal
-[`subprocess.send()`]: #child_process_subprocess_send_message_sendhandle_options_callback
-[`subprocess.stderr`]: #child_process_subprocess_stderr
-[`subprocess.stdin`]: #child_process_subprocess_stdin
-[`subprocess.stdout`]: #child_process_subprocess_stdout
[`child_process.exec()`]: #child_process_child_process_exec_command_options_callback
[`child_process.execFile()`]: #child_process_child_process_execfile_file_args_options_callback
[`child_process.execFileSync()`]: #child_process_child_process_execfilesync_file_args_options
@@ -1456,6 +1452,13 @@ unavailable.
[`process.execPath`]: process.html#process_process_execpath
[`process.send()`]: process.html#process_process_send_message_sendhandle_options_callback
[`stdio`]: #child_process_options_stdio
+[`subprocess.connected`]: #child_process_subprocess_connected
+[`subprocess.disconnect()`]: #child_process_subprocess_disconnect
+[`subprocess.kill()`]: #child_process_subprocess_kill_signal
+[`subprocess.send()`]: #child_process_subprocess_send_message_sendhandle_options_callback
+[`subprocess.stderr`]: #child_process_subprocess_stderr
+[`subprocess.stdin`]: #child_process_subprocess_stdin
+[`subprocess.stdout`]: #child_process_subprocess_stdout
[`util.promisify()`]: util.html#util_util_promisify_original
[Default Windows Shell]: #child_process_default_windows_shell
[Shell Requirements]: #child_process_shell_requirements
diff --git a/doc/api/cli.md b/doc/api/cli.md
index c970f4374aac6e..a4757c1d26ab60 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -119,6 +119,22 @@ added: v6.0.0
Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.)
(Same requirements as `--enable-fips`.)
+### `--http-parser=library`
+
+
+Chooses an HTTP parser library. Available values are:
+
+- `llhttp` for https://llhttp.org/
+- `legacy` for https://github.com/nodejs/http-parser
+
+The default is `legacy`, unless otherwise specified when building Node.js.
+
+This flag exists to aid in experimentation with the internal implementation of
+the Node.js http parser.
+This flag is likely to become a no-op and removed at some point in the future.
+
### `--icu-data-dir=file`
* `options` {Object} Available options are:
@@ -609,6 +612,9 @@ changes:
* `reuseAddr` {boolean} When `true` [`socket.bind()`][] will reuse the
address, even if another process has already bound a socket on it.
**Default:** `false`.
+ * `ipv6Only` {boolean} Setting `ipv6Only` to `true` will
+ disable dual-stack support, i.e., binding to address `::` won't make
+ `0.0.0.0` be bound. **Default:** `false`.
* `recvBufferSize` {number} - Sets the `SO_RCVBUF` socket value.
* `sendBufferSize` {number} - Sets the `SO_SNDBUF` socket value.
* `lookup` {Function} Custom lookup function. **Default:** [`dns.lookup()`][].
@@ -646,6 +652,7 @@ and `udp6` sockets). The bound address and port can be retrieved using
[`'close'`]: #dgram_event_close
[`Error`]: errors.html#errors_class_error
[`EventEmitter`]: events.html
+[`System Error`]: errors.html#errors_class_systemerror
[`close()`]: #dgram_socket_close_callback
[`cluster`]: cluster.html
[`dgram.Socket#bind()`]: #dgram_socket_bind_options_callback
@@ -654,7 +661,6 @@ and `udp6` sockets). The bound address and port can be retrieved using
[`socket.address().address`]: #dgram_socket_address
[`socket.address().port`]: #dgram_socket_address
[`socket.bind()`]: #dgram_socket_bind_port_address_callback
-[`System Error`]: errors.html#errors_class_systemerror
-[byte length]: buffer.html#buffer_class_method_buffer_bytelength_string_encoding
[IPv6 Zone Indices]: https://en.wikipedia.org/wiki/IPv6_address#Scoped_literal_IPv6_addresses
[RFC 4007]: https://tools.ietf.org/html/rfc4007
+[byte length]: buffer.html#buffer_class_method_buffer_bytelength_string_encoding
diff --git a/doc/api/documentation.md b/doc/api/documentation.md
index a1b0d5903b5130..440f21c7af08dc 100644
--- a/doc/api/documentation.md
+++ b/doc/api/documentation.md
@@ -86,7 +86,7 @@ sometimes impossible to replace Unix syscall semantics on Windows, see [Node.js
issue 4760](https://github.com/nodejs/node/issues/4760).
[`'warning'`]: process.html#process_event_warning
-[`stderr`]: process.html#process_process_stderr
[`fs.open()`]: fs.html#fs_fs_open_path_flags_mode_callback
+[`stderr`]: process.html#process_process_stderr
[submit an issue]: https://github.com/nodejs/node/issues/new
[the contributing guide]: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md
diff --git a/doc/api/errors.md b/doc/api/errors.md
index 500fb7801b61fd..1c16e05de84ac2 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -1655,6 +1655,17 @@ recommended to use 2048 bits or larger for stronger security.
A TLS/SSL handshake timed out. In this case, the server must also abort the
connection.
+
+### ERR_TLS_INVALID_PROTOCOL_VERSION
+
+Valid TLS protocol versions are `'TLSv1'`, `'TLSv1.1'`, or `'TLSv1.2'`.
+
+
+### ERR_TLS_PROTOCOL_VERSION_CONFLICT
+
+Attempting to set a TLS protocol `minVersion` or `maxVersion` conflicts with an
+attempt to set the `secureProtocol` explicitly. Use one mechanism or the other.
+
### ERR_TLS_RENEGOTIATE
@@ -1869,9 +1880,15 @@ Creation of a [`zlib`][] object failed due to incorrect configuration.
### HPE_HEADER_OVERFLOW
+
Too much HTTP header data was received. In order to protect against malicious or
-malconfigured clients, if more than 80KB of HTTP header data is received then
+malconfigured clients, if more than 8KB of HTTP header data is received then
HTTP parsing will abort without a request or response object being created, and
an `Error` with this code will be emitted.
diff --git a/doc/api/fs.md b/doc/api/fs.md
index ce054230e6dba7..fcd42fd19af1cd 100644
--- a/doc/api/fs.md
+++ b/doc/api/fs.md
@@ -1486,7 +1486,7 @@ closing naturally.
```js
const fs = require('fs');
-// Create a stream from some character device.
+// Create a stream from some character device.
const stream = fs.createReadStream('/dev/input/event0');
setTimeout(() => {
stream.close(); // This may not close the stream.
@@ -3528,6 +3528,13 @@ On Linux, positional writes don't work when the file is opened in append mode.
The kernel ignores the position argument and always appends the data to
the end of the file.
+On Windows, if the file descriptor is connected to the console (e.g. `fd == 1`
+or `stdout`) a string containing non-ASCII characters will not be rendered
+properly by default, regardless of the encoding used.
+It is possible to configure the console to render UTF-8 properly by changing the
+active codepage with the `chcp 65001` command. See the [chcp][] docs for more
+details.
+
## fs.writeFile(file, data[, options], callback)
+
+* `string` {string}
+* `position` {integer}
+* `encoding` {string} **Default:** `'utf8'`
+* Returns: {Promise}
+
+Write `string` to the file. If `string` is not a string, then
+the value will be coerced to one.
+
+The `Promise` is resolved with an object containing a `bytesWritten` property
+identifying the number of bytes written, and a `buffer` property containing
+a reference to the `string` written.
+
+`position` refers to the offset from the beginning of the file where this data
+should be written. If the type of `position` is not a `number` the data
+will be written at the current position. See pwrite(2).
+
+`encoding` is the expected string encoding.
+
+It is unsafe to use `filehandle.write()` multiple times on the same file
+without waiting for the `Promise` to be resolved (or rejected). For this
+scenario, [`fs.createWriteStream()`][] is strongly recommended.
+
+On Linux, positional writes do not work when the file is opened in append mode.
+The kernel ignores the position argument and always appends the data to
+the end of the file.
+
#### filehandle.writeFile(data, options)
+
+* {number} **Default:** `40000`
+
+Limit the amount of time the parser will wait to receive the complete HTTP
+headers.
+
+In case of inactivity, the rules defined in [`server.timeout`][] apply. However,
+that inactivity based timeout would still allow the connection to be kept open
+if the headers are being sent very slowly (by default, up to a byte per 2
+minutes). In order to prevent this, whenever header data arrives an additional
+check is made that more than `server.headersTimeout` milliseconds has not
+passed since the connection was established. If the check fails, a `'timeout'`
+event is emitted on the server object, and (by default) the socket is destroyed.
+See [`server.timeout`][] for more information on how timeout behavior can be
+customized.
+
### server.listen()
Starts the HTTP server listening for connections.
@@ -958,26 +978,6 @@ added: v0.7.0
Limits maximum incoming headers count. If set to 0, no limit will be applied.
-### server.headersTimeout
-
-
-* {number} **Default:** `40000`
-
-Limit the amount of time the parser will wait to receive the complete HTTP
-headers.
-
-In case of inactivity, the rules defined in [server.timeout][] apply. However,
-that inactivity based timeout would still allow the connection to be kept open
-if the headers are being sent very slowly (by default, up to a byte per 2
-minutes). In order to prevent this, whenever header data arrives an additional
-check is made that more than `server.headersTimeout` milliseconds has not
-passed since the connection was established. If the check fails, a `'timeout'`
-event is emitted on the server object, and (by default) the socket is destroyed.
-See [server.timeout][] for more information on how timeout behaviour can be
-customised.
-
### server.setTimeout([msecs][, callback])
* `callback` {Function}
-Stops the server from accepting new connections. See [`net.Server.close()`][].
+Stops the server from accepting new connections. See [`net.Server.close()`][].
Note that this is not analogous to restricting new requests since HTTP/2
connections are persistent. To achieve a similar graceful shutdown behavior,
@@ -1871,7 +1871,7 @@ added: v8.4.0
-->
* `callback` {Function}
-Stops the server from accepting new connections. See [`tls.Server.close()`][].
+Stops the server from accepting new connections. See [`tls.Server.close()`][].
Note that this is not analogous to restricting new requests since HTTP/2
connections are persistent. To achieve a similar graceful shutdown behavior,
@@ -2297,7 +2297,7 @@ For incoming headers:
`upgrade-insecure-requests`, `user-agent` or `x-content-type-options` are
discarded.
* `set-cookie` is always an array. Duplicates are added to the array.
-* `cookie`: the values are joined together with '; '.
+* For duplicate `cookie` headers, the values are joined together with '; '.
* For all other headers, the values are joined together with ', '.
```js
@@ -2531,7 +2531,7 @@ const server = http2.createServer({ settings });
Once the client receives the `SETTINGS` frame from the server indicating that
the extended CONNECT may be used, it may send `CONNECT` requests that use the
-`':protocol'` HTTP/2 pseudo-header:
+`':protocol'` HTTP/2 pseudo-header:
```js
const http2 = require('http2');
@@ -2654,6 +2654,16 @@ added: v10.1.0
The `request.aborted` property will be `true` if the request has
been aborted.
+#### request.authority
+
+
+* {string}
+
+The request authority pseudo header field. It can also be accessed via
+`req.headers[':authority']`.
+
#### request.destroy([error])
+
+* {string}
+
+The request scheme pseudo header field indicating the scheme
+portion of the target URL.
+
#### request.setTimeout(msecs, callback)
+- {number} **Default:** `40000`
+
+See [`http.Server#headersTimeout`][].
+
### server.listen()
Starts the HTTPS server listening for encrypted connections.
@@ -44,12 +52,6 @@ This method is identical to [`server.listen()`][] from [`net.Server`][].
See [`http.Server#maxHeadersCount`][].
-### server.headersTimeout
-
-- {number} **Default:** `40000`
-
-See [`http.Server#headersTimeout`][].
-
### server.setTimeout([msecs][, callback])
* `options` {Object} Required. Supports the following properties:
@@ -266,6 +270,9 @@ added: v0.11.14
for all users. **Default:** `false`
* `writableAll` {boolean} For IPC servers makes the pipe writable
for all users. **Default:** `false`
+ * `ipv6Only` {boolean} For TCP servers, setting `ipv6Only` to `true` will
+ disable dual-stack support, i.e., binding to host `::` won't make
+ `0.0.0.0` be bound. **Default:** `false`.
* `callback` {Function} Common parameter of [`server.listen()`][]
functions.
* Returns: {net.Server}
@@ -1167,6 +1174,7 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`.
[`net.createConnection(port, host)`]: #net_net_createconnection_port_host_connectlistener
[`net.createServer()`]: #net_net_createserver_options_connectionlistener
[`new net.Socket(options)`]: #net_new_net_socket_options
+[`readable.setEncoding()`]: stream.html#stream_readable_setencoding_encoding
[`server.close()`]: #net_server_close_callback
[`server.getConnections()`]: #net_server_getconnections_callback
[`server.listen()`]: #net_server_listen
@@ -1186,7 +1194,6 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`.
[`socket.setEncoding()`]: #net_socket_setencoding_encoding
[`socket.setTimeout()`]: #net_socket_settimeout_timeout_callback
[`socket.setTimeout(timeout)`]: #net_socket_settimeout_timeout_callback
-[`readable.setEncoding()`]: stream.html#stream_readable_setencoding_encoding
[IPC]: #net_ipc_support
[Identifying paths for IPC connections]: #net_identifying_paths_for_ipc_connections
[Readable Stream]: stream.html#stream_class_stream_readable
diff --git a/doc/api/os.md b/doc/api/os.md
index ad5736d7690016..27326c4ea31650 100644
--- a/doc/api/os.md
+++ b/doc/api/os.md
@@ -891,7 +891,7 @@ The following error constants are exported by `os.constants.errno`:
|