diff --git a/BUILDING.md b/BUILDING.md
index 50f2984d679274..7e39f50ba17ce0 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -281,7 +281,8 @@ the first command `./configure --coverage`).
_Generating a test coverage report can take several minutes._
To collect coverage for a subset of tests you can set the `CI_JS_SUITES` and
-`CI_NATIVE_SUITES` variables:
+`CI_NATIVE_SUITES` variables (to run specific suites, e.g., `child-process`, in
+isolation, unset the opposing `_SUITES` variable):
```text
$ CI_JS_SUITES=child-process CI_NATIVE_SUITES= make coverage
@@ -290,9 +291,15 @@ $ CI_JS_SUITES=child-process CI_NATIVE_SUITES= make coverage
The above command executes tests for the `child-process` subsystem and
outputs the resulting coverage report.
-The `make coverage` command downloads some tools to the project root directory
-and overwrites the `lib/` directory. To clean up after generating the coverage
-reports:
+Alternatively, you can run `make coverage-run-js`, to execute JavaScript tests
+independently of the C++ test suite:
+
+```text
+$ CI_JS_SUITES=fs CI_NATIVE_SUITES= make coverage-run-js
+```
+
+The `make coverage` command downloads some tools to the project root directory.
+To clean up after generating the coverage reports:
```console
$ make coverage-clean
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c13771d2ff88eb..cafba2ab601397 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,7 +28,8 @@ release.
-11.7.0
+11.8.0
+11.7.0
11.6.0
11.5.0
11.4.0
diff --git a/Makefile b/Makefile
index 9dd9b198491eb3..9fcf7e08701773 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ STAGINGSERVER ?= node-www
LOGLEVEL ?= silent
OSTYPE := $(shell uname -s | tr '[A-Z]' '[a-z]')
COVTESTS ?= test-cov
+COV_SKIP_TESTS ?= core_line_numbers.js,testFinalizer.js,test_function/test.js
GTEST_FILTER ?= "*"
GNUMAKEFLAGS += --no-print-directory
GCOV ?= gcov
@@ -181,7 +182,6 @@ coverage-clean:
$(RM) -r node_modules
$(RM) -r gcovr build
$(RM) -r out/$(BUILDTYPE)/.coverage
- $(RM) -r .cov_tmp
$(RM) out/$(BUILDTYPE)/obj.target/node/gen/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node/src/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda
@@ -201,9 +201,7 @@ coverage: coverage-test ## Run the tests and generate a coverage report.
.PHONY: coverage-build
coverage-build: all
- mkdir -p node_modules
- if [ ! -d node_modules/nyc ]; then \
- $(NODE) ./deps/npm install nyc@13 --no-save --no-package-lock; fi
+ -$(MAKE) coverage-build-js
if [ ! -d gcovr ]; then git clone -b 3.4 --depth=1 \
--single-branch https://github.com/gcovr/gcovr.git; fi
if [ ! -d build ]; then git clone --depth=1 \
@@ -211,38 +209,29 @@ coverage-build: all
if [ ! -f gcovr/scripts/gcovr.orig ]; then \
(cd gcovr && patch -N -p1 < \
"$(CURDIR)/build/jenkins/scripts/coverage/gcovr-patches-3.4.diff"); fi
- if [ -d lib_ ]; then $(RM) -r lib; mv lib_ lib; fi
- mv lib lib_
- NODE_DEBUG=nyc $(NODE) ./node_modules/.bin/nyc instrument --extension .js \
- --extension .mjs --exit-on-error lib_/ lib/
$(MAKE)
+.PHONY: coverage-build-js
+coverage-build-js:
+ mkdir -p node_modules
+ if [ ! -d node_modules/c8 ]; then \
+ $(NODE) ./deps/npm install c8@next --no-save --no-package-lock;\
+ fi
+
.PHONY: coverage-test
coverage-test: coverage-build
- $(RM) -r out/$(BUILDTYPE)/.coverage
- $(RM) -r .cov_tmp
$(RM) out/$(BUILDTYPE)/obj.target/node/gen/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node/src/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node_lib/gen/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node_lib/src/*.gcda
$(RM) out/$(BUILDTYPE)/obj.target/node_lib/src/tracing/*.gcda
- -$(MAKE) $(COVTESTS)
- mv lib lib__
- mv lib_ lib
- mkdir -p coverage .cov_tmp
- $(NODE) ./node_modules/.bin/nyc merge 'out/Release/.coverage' \
- .cov_tmp/libcov.json
- (cd lib && .$(NODE) ../node_modules/.bin/nyc report \
- --temp-dir "$(CURDIR)/.cov_tmp" \
- --report-dir "$(CURDIR)/coverage" \
- --reporter html)
+ -NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage $(MAKE) $(COVTESTS)
+ $(MAKE) coverage-report-js
-(cd out && "../gcovr/scripts/gcovr" --gcov-exclude='.*deps' \
--gcov-exclude='.*usr' -v -r Release/obj.target \
--html --html-detail -o ../coverage/cxxcoverage.html \
--gcov-executable="$(GCOV)")
- mv lib lib_
- mv lib__ lib
@echo -n "Javascript coverage %: "
@grep -B1 Lines coverage/index.html | head -n1 \
| sed 's/<[^>]*>//g'| sed 's/ //g'
@@ -250,6 +239,13 @@ coverage-test: coverage-build
@grep -A3 Lines coverage/cxxcoverage.html | grep style \
| sed 's/<[^>]*>//g'| sed 's/ //g'
+.PHONY: coverage-report-js
+coverage-report-js:
+ $(NODE) ./node_modules/.bin/c8 report --reporter=html \
+ --temp-directory=out/$(BUILDTYPE)/.coverage --omit-relative=false \
+ --resolve=./lib --exclude="deps/" --exclude="test/" --exclude="tools/" \
+ --wrapper-length=0
+
.PHONY: cctest
# Runs the C++ tests using the built `cctest` executable.
cctest: all
@@ -276,6 +272,14 @@ jstest: build-addons build-js-native-api-tests build-node-api-tests ## Runs addo
$(CI_JS_SUITES) \
$(CI_NATIVE_SUITES)
+.PHONY: coverage-run-js
+coverage-run-js:
+ $(RM) -r out/$(BUILDTYPE)/.coverage
+ $(MAKE) coverage-build-js
+ -NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage CI_SKIP_TESTS=$(COV_SKIP_TESTS) \
+ $(MAKE) jstest
+ $(MAKE) coverage-report-js
+
.PHONY: test
# This does not run tests of third-party libraries inside deps.
test: all ## Runs default tests, linters, and builds docs.
@@ -300,7 +304,7 @@ test-cov: all
$(MAKE) build-js-native-api-tests
$(MAKE) build-node-api-tests
# $(MAKE) cctest
- CI_SKIP_TESTS=core_line_numbers.js $(MAKE) jstest
+ CI_SKIP_TESTS=$(COV_SKIP_TESTS) $(MAKE) jstest
test-parallel: all
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) parallel
@@ -1290,7 +1294,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=.git,deps,lib,src,tools/*_macros.py,tools/gyp,tools/inspector_protocol,tools/jinja2,tools/markupsafe,tools/pip
+ --exclude=.git,deps,lib,src,test/fixtures,tools/*_macros.py,tools/gyp,tools/inspector_protocol,tools/jinja2,tools/markupsafe,tools/pip
else
lint-py:
@echo "Python linting with flake8 is not avalible"
diff --git a/README.md b/README.md
index 34d65f8f1f7a41..7bc71da80fbc4e 100644
--- a/README.md
+++ b/README.md
@@ -202,6 +202,8 @@ 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)
+* [Trott](https://github.com/Trott) -
+**Rich Trott** <rtrott@gmail.com> (he/him)
### TSC Emeriti
@@ -233,8 +235,6 @@ For information about the governance of the Node.js project, see
**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
diff --git a/common.gypi b/common.gypi
index 724d070c4caed7..9bad7d131c9192 100644
--- a/common.gypi
+++ b/common.gypi
@@ -116,28 +116,8 @@
'msvs_configuration_platform': 'x64',
}],
['OS=="aix"', {
- 'variables': {'real_os_name': '
Yuki Okumura
jBarz
jBarz
+ptlomholt
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index a8b50f6209d7a0..3317efeb1ac8af 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -362,3 +362,7 @@ Ashe Connor
Rick
Ivan Krylov
Michael Meier
+ptlomholt
+Victor Costan
+sid
+Kevin Adler
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index 9f1c0587a98060..fa268a13ed6661 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -167,6 +167,7 @@ set(uv_test_sources
test/test-udp-send-immediate.c
test/test-udp-send-unreachable.c
test/test-udp-try-send.c
+ test/test-uname.c
test/test-walk-handles.c
test/test-watcher-cross-stop.c)
@@ -211,7 +212,7 @@ if(WIN32)
else()
list(APPEND uv_defines _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
- # Android has pthread as part of its c library, not as a separate
+ # Android has pthread as part of its c library, not as a separate
# libpthread.so.
list(APPEND uv_libraries pthread)
endif()
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index f7881e6bbc4f92..3652829ce7790b 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,54 @@
+2019.01.19, Version 1.25.0 (Stable), 4a10a9d425863330af199e4b74bd688e62d945f1
+
+Changes since version 1.24.1:
+
+* Revert "win,fs: retry if uv_fs_rename fails" (Ben Noordhuis)
+
+* aix: manually trigger fs event monitoring (Gireesh Punathil)
+
+* unix: rename WRITE_RETRY_ON_ERROR macro (Ben Noordhuis)
+
+* darwin: DRY platform-specific error check (Ben Noordhuis)
+
+* unix: refactor uv__write() (Ben Noordhuis)
+
+* unix: don't send handle twice on partial write (Ben Noordhuis)
+
+* tty,win: fix Alt+key under WSL (Bartosz Sosnowski)
+
+* build: support running tests in out-of-tree builds (Jameson Nash)
+
+* fsevents: really watch files with fsevents on macos 10.7+ (Jameson Nash)
+
+* thread,mingw64: need intrin.h header for SSE2 MemoryBarrier (Jameson Nash)
+
+* win: fix sizeof-pointer-div warning (cjihrig)
+
+* unix,win: add uv_os_uname() (cjihrig)
+
+* win, tty: fix CreateFileW() return value check (Bartosz Sosnowski)
+
+* unix: enable IPv6 tests on OpenBSD (ptlomholt)
+
+* test: fix test-ipc spawn_helper exit_cb (Santiago Gimeno)
+
+* test: fix test-ipc tests (Santiago Gimeno)
+
+* unix: better handling of unsupported F_FULLFSYNC (Victor Costan)
+
+* win,test: de-flake fs_event_watch_dir_short_path (Refael Ackermann)
+
+* win: fix msvc warning (sid)
+
+* openbsd: switch to libuv's barrier implementation (ptlomholt)
+
+* unix,stream: fix zero byte writes (Santiago Gimeno)
+
+* ibmi: return EISDIR on read from directory fd (Kevin Adler)
+
+* build: wrap long lines in Makefile.am (cjihrig)
+
+
2018.12.17, Version 1.24.1 (Stable), 274f2bd3b70847cadd9a3965577a87e666ab9ac3
Changes since version 1.24.0:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index f9c9c9a05d14f3..d8a01574f3cf2c 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -20,7 +20,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \
include_HEADERS=include/uv.h
uvincludedir = $(includedir)/uv
-uvinclude_HEADERS=include/uv/errno.h include/uv/threadpool.h include/uv/version.h
+uvinclude_HEADERS = include/uv/errno.h \
+ include/uv/threadpool.h \
+ include/uv/version.h
CLEANFILES =
@@ -293,6 +295,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-udp-send-immediate.c \
test/test-udp-send-unreachable.c \
test/test-udp-try-send.c \
+ test/test-uname.c \
test/test-walk-handles.c \
test/test-watcher-cross-stop.c
test_run_tests_LDADD = libuv.la
@@ -306,7 +309,9 @@ test_run_tests_SOURCES += test/runner-unix.c \
endif
if AIX
-test_run_tests_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT
+test_run_tests_CFLAGS += -D_ALL_SOURCE \
+ -D_XOPEN_SOURCE=500 \
+ -D_LINUX_SOURCE_COMPAT
endif
if LINUX
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 35e7c1b7493acd..ab656c83d23502 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.24.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.25.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])
@@ -73,4 +73,6 @@ AS_CASE([$host_os], [kfreebsd*], [
])
AC_CHECK_HEADERS([sys/ahafs_evProds.h])
AC_CONFIG_FILES([Makefile libuv.pc])
+AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file])
+AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node])
AC_OUTPUT
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index 21f9e27cb40727..af97ec3a648882 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -233,15 +233,6 @@ 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/misc.rst b/deps/uv/docs/src/misc.rst
index cf4a7895cd147b..81c03a85303180 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -145,6 +145,19 @@ Data types
char* homedir;
} uv_passwd_t;
+.. c:type:: uv_utsname_t
+
+ Data type for operating system name and version information.
+
+ ::
+
+ typedef struct uv_utsname_s {
+ char sysname[256];
+ char release[256];
+ char version[256];
+ char machine[256];
+ } uv_utsname_t;
+
API
---
@@ -549,3 +562,12 @@ API
for others it will be silently reduced to `PRIORITY_HIGH`.
.. versionadded:: 1.23.0
+
+.. c:function:: int uv_os_uname(uv_utsname_t* buffer)
+
+ Retrieves system information in `buffer`. The populated data includes the
+ operating system name, release, version, and machine. On non-Windows
+ systems, `uv_os_uname()` is a thin wrapper around :man:`uname(3)`. Returns
+ zero on success, and a non-zero error value otherwise.
+
+ .. versionadded:: 1.25.0
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 86a2ecc2d74469..a46b229dfd166e 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -234,6 +234,7 @@ typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;
typedef struct uv_passwd_s uv_passwd_t;
+typedef struct uv_utsname_s uv_utsname_t;
typedef enum {
UV_LOOP_BLOCK_SIGNAL
@@ -968,13 +969,13 @@ enum uv_process_flags {
*/
UV_PROCESS_WINDOWS_HIDE = (1 << 4),
/*
- * Hide the subprocess console window that would normally be created. This
+ * 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
+ * Hide the subprocess GUI window that would normally be created. This
* option is only meaningful on Windows systems. On Unix it is silently
* ignored.
*/
@@ -1054,6 +1055,16 @@ struct uv_passwd_s {
char* homedir;
};
+struct uv_utsname_s {
+ char sysname[256];
+ char release[256];
+ char version[256];
+ char machine[256];
+ /* This struct does not contain the nodename and domainname fields present in
+ the utsname type. domainname is a GNU extension. Both fields are referred
+ to as meaningless in the docs. */
+};
+
typedef enum {
UV_DIRENT_UNKNOWN,
UV_DIRENT_FILE,
@@ -1135,6 +1146,8 @@ UV_EXTERN int uv_os_unsetenv(const char* name);
UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
+UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);
+
typedef enum {
UV_FS_UNKNOWN = -1,
diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h
index 9de9efecff14c4..d887d7211f1d1e 100644
--- a/deps/uv/include/uv/unix.h
+++ b/deps/uv/include/uv/unix.h
@@ -136,7 +136,9 @@ typedef pthread_cond_t uv_cond_t;
typedef pthread_key_t uv_key_t;
/* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */
-#if defined(_AIX) || !defined(PTHREAD_BARRIER_SERIAL_THREAD)
+#if defined(_AIX) || \
+ defined(__OpenBSD__) || \
+ !defined(PTHREAD_BARRIER_SERIAL_THREAD)
/* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */
struct _uv_barrier {
uv_mutex_t mutex;
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index 3bc023700ef002..136772128ab35a 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 24
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 25
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index 44c9cf5b639c31..337e58e0adc02f 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -555,7 +555,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) {
sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1");
rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1);
- if (rc < 0)
+ if (rc < 0 && errno != EBUSY)
return UV__ERR(errno);
return 0;
@@ -728,10 +728,16 @@ int uv_fs_event_start(uv_fs_event_t* handle,
char cwd[PATH_MAX];
char absolute_path[PATH_MAX];
char readlink_cwd[PATH_MAX];
+ struct timeval zt;
+ fd_set pollfd;
/* Figure out whether filename is absolute or not */
- if (filename[0] == '/') {
+ if (filename[0] == '\0') {
+ /* Missing a pathname */
+ return UV_ENOENT;
+ }
+ else if (filename[0] == '/') {
/* We have absolute pathname */
/* TODO(bnoordhuis) Check uv__strscpy() return value. */
uv__strscpy(absolute_path, filename, sizeof(absolute_path));
@@ -768,6 +774,15 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
+ /* AHAFS wants someone to poll for it to start mointoring.
+ * so kick-start it so that we don't miss an event in the
+ * eventuality of an event that occurs in the current loop. */
+ do {
+ memset(&zt, 0, sizeof(zt));
+ FD_ZERO(&pollfd);
+ FD_SET(fd, &pollfd);
+ rc = select(fd + 1, &pollfd, NULL, NULL, &zt);
+ } while (rc == -1 && errno == EINTR);
return 0;
#else
return UV_ENOSYS;
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index 2f2201f9ed024a..3c2253f0c9c952 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -52,13 +52,10 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
*/
if (ent->ifa_addr->sa_family == AF_LINK)
return 1;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
if (ent->ifa_addr->sa_family != PF_INET &&
ent->ifa_addr->sa_family != PF_INET6)
return 1;
-#elif defined(__OpenBSD__)
- if (ent->ifa_addr->sa_family != PF_INET)
- return 1;
#endif
return 0;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 0830c74a168e92..cd57ce20ba2edb 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -40,6 +40,7 @@
#include /* writev */
#include /* getrusage */
#include
+#include
#ifdef __sun
# include /* MAXHOSTNAMELEN on Solaris */
@@ -1357,3 +1358,59 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
return 0;
}
+
+
+int uv_os_uname(uv_utsname_t* buffer) {
+ struct utsname buf;
+ int r;
+
+ if (buffer == NULL)
+ return UV_EINVAL;
+
+ if (uname(&buf) == -1) {
+ r = UV__ERR(errno);
+ goto error;
+ }
+
+ r = uv__strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname));
+ if (r == UV_E2BIG)
+ goto error;
+
+#ifdef _AIX
+ r = snprintf(buffer->release,
+ sizeof(buffer->release),
+ "%s.%s",
+ buf.version,
+ buf.release);
+ if (r >= sizeof(buffer->release)) {
+ r = UV_E2BIG;
+ goto error;
+ }
+#else
+ r = uv__strscpy(buffer->release, buf.release, sizeof(buffer->release));
+ if (r == UV_E2BIG)
+ goto error;
+#endif
+
+ r = uv__strscpy(buffer->version, buf.version, sizeof(buffer->version));
+ if (r == UV_E2BIG)
+ goto error;
+
+#if defined(_AIX) || defined(__PASE__)
+ r = uv__strscpy(buffer->machine, "ppc64", sizeof(buffer->machine));
+#else
+ r = uv__strscpy(buffer->machine, buf.machine, sizeof(buffer->machine));
+#endif
+
+ if (r == UV_E2BIG)
+ goto error;
+
+ return 0;
+
+error:
+ buffer->sysname[0] = '\0';
+ buffer->release[0] = '\0';
+ buffer->version[0] = '\0';
+ buffer->machine[0] = '\0';
+ return r;
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index d22c70f0c293d4..91bb82f725e884 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -155,7 +155,7 @@ static ssize_t uv__fs_fsync(uv_fs_t* req) {
int r;
r = fcntl(req->file, F_FULLFSYNC);
- if (r != 0 && errno == ENOTTY)
+ if (r != 0)
r = fsync(req->file);
return r;
#else
@@ -317,6 +317,18 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
req->bufs = NULL;
req->nbufs = 0;
+#ifdef __PASE__
+ /* PASE returns EOPNOTSUPP when reading a directory, convert to EISDIR */
+ if (result == -1 && errno == EOPNOTSUPP) {
+ struct stat buf;
+ ssize_t rc;
+ rc = fstat(req->file, &buf);
+ if (rc == 0 && S_ISDIR(buf.st_mode)) {
+ errno = EISDIR;
+ }
+ }
+#endif
+
return result;
}
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index ee45299b791294..c430562b37298a 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -255,42 +255,55 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
path = paths[i];
len = strlen(path);
+ if (handle->realpath_len == 0)
+ continue; /* This should be unreachable */
+
/* Filter out paths that are outside handle's request */
- if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
+ if (len < handle->realpath_len)
+ continue;
+
+ if (handle->realpath_len != len &&
+ path[handle->realpath_len] != '/')
+ /* Make sure that realpath actually named a directory,
+ * or that we matched the whole string */
continue;
- if (handle->realpath_len > 1 || *handle->realpath != '/') {
+ if (memcmp(path, handle->realpath, handle->realpath_len) != 0)
+ continue;
+
+ if (!(handle->realpath_len == 1 && handle->realpath[0] == '/')) {
+ /* Remove common prefix, unless the watched folder is "/" */
path += handle->realpath_len;
len -= handle->realpath_len;
- /* Skip forward slash */
- if (*path != '\0') {
+ /* Ignore events with path equal to directory itself */
+ if (len <= 1 && (flags & kFSEventStreamEventFlagItemIsDir))
+ continue;
+
+ if (len == 0) {
+ /* Since we're using fsevents to watch the file itself,
+ * realpath == path, and we now need to get the basename of the file back
+ * (for commonality with other codepaths and platforms). */
+ while (len < handle->realpath_len && path[-1] != '/') {
+ path--;
+ len++;
+ }
+ /* Created and Removed seem to be always set, but don't make sense */
+ flags &= ~kFSEventsRenamed;
+ } else {
+ /* Skip forward slash */
path++;
len--;
}
}
-#ifdef MAC_OS_X_VERSION_10_7
- /* Ignore events with path equal to directory itself */
- if (len == 0)
- continue;
-#else
- if (len == 0 && (flags & kFSEventStreamEventFlagItemIsDir))
- continue;
-#endif /* MAC_OS_X_VERSION_10_7 */
-
/* Do not emit events from subdirectories (without option set) */
- if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
+ if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != '\0') {
pos = strchr(path + 1, '/');
if (pos != NULL)
continue;
}
-#ifndef MAC_OS_X_VERSION_10_7
- path = "";
- len = 0;
-#endif /* MAC_OS_X_VERSION_10_7 */
-
event = uv__malloc(sizeof(*event) + len);
if (event == NULL)
break;
@@ -299,22 +312,11 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
memcpy(event->path, path, len + 1);
event->events = UV_RENAME;
-#ifdef MAC_OS_X_VERSION_10_7
- if (0 != (flags & kFSEventsModified) &&
- 0 == (flags & kFSEventsRenamed)) {
- event->events = UV_CHANGE;
- }
-#else
- if (0 != (flags & kFSEventsModified) &&
- 0 != (flags & kFSEventStreamEventFlagItemIsDir) &&
- 0 == (flags & kFSEventStreamEventFlagItemRenamed)) {
- event->events = UV_CHANGE;
- }
- if (0 == (flags & kFSEventStreamEventFlagItemIsDir) &&
- 0 == (flags & kFSEventStreamEventFlagItemRenamed)) {
- event->events = UV_CHANGE;
+ if (0 == (flags & kFSEventsRenamed)) {
+ if (0 != (flags & kFSEventsModified) ||
+ 0 == (flags & kFSEventStreamEventFlagItemIsDir))
+ event->events = UV_CHANGE;
}
-#endif /* MAC_OS_X_VERSION_10_7 */
QUEUE_INSERT_TAIL(&head, &event->member);
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 72d8da8a508b88..c059893a46e992 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -284,24 +284,6 @@ int uv__fsevents_init(uv_fs_event_t* handle);
int uv__fsevents_close(uv_fs_event_t* handle);
void uv__fsevents_loop_delete(uv_loop_t* loop);
-/* OSX < 10.7 has no file events, polyfill them */
-#ifndef MAC_OS_X_VERSION_10_7
-
-static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
-static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
-static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
-static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
-static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
-static const int kFSEventStreamEventFlagItemModified = 0x00001000;
-static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
-static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
-static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
-static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
-static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
-static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
-
-#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
-
#endif /* defined(__APPLE__) */
UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 930f2da7126a5d..c24f96e1399c69 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -452,49 +452,48 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb,
const char* path,
unsigned int flags) {
-#if defined(__APPLE__)
- struct stat statbuf;
-#endif /* defined(__APPLE__) */
int fd;
if (uv__is_active(handle))
return UV_EINVAL;
- /* TODO open asynchronously - but how do we report back errors? */
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return UV__ERR(errno);
-
- uv__handle_start(handle);
- uv__io_init(&handle->event_watcher, uv__fs_event, fd);
- handle->path = uv__strdup(path);
- handle->cb = cb;
-
#if defined(__APPLE__)
- if (uv__has_forked_with_cfrunloop)
- goto fallback;
-
/* Nullify field to perform checks later */
handle->cf_cb = NULL;
handle->realpath = NULL;
handle->realpath_len = 0;
handle->cf_flags = flags;
- if (fstat(fd, &statbuf))
- goto fallback;
- /* FSEvents works only with directories */
- if (!(statbuf.st_mode & S_IFDIR))
- goto fallback;
-
- /* The fallback fd is no longer needed */
- uv__close(fd);
- handle->event_watcher.fd = -1;
-
- return uv__fsevents_init(handle);
-
-fallback:
+ if (!uv__has_forked_with_cfrunloop) {
+ int r;
+ /* The fallback fd is not used */
+ handle->event_watcher.fd = -1;
+ handle->path = uv__strdup(path);
+ if (handle->path == NULL)
+ return UV_ENOMEM;
+ handle->cb = cb;
+ r = uv__fsevents_init(handle);
+ if (r == 0) {
+ uv__handle_start(handle);
+ } else {
+ uv__free(handle->path);
+ handle->path = NULL;
+ }
+ return r;
+ }
#endif /* defined(__APPLE__) */
+ /* TODO open asynchronously - but how do we report back errors? */
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return UV__ERR(errno);
+
+ handle->path = uv__strdup(path);
+ if (handle->path == NULL)
+ return UV_ENOMEM;
+ handle->cb = cb;
+ uv__handle_start(handle);
+ uv__io_init(&handle->event_watcher, uv__fs_event, fd);
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
return 0;
@@ -502,29 +501,29 @@ int uv_fs_event_start(uv_fs_event_t* handle,
int uv_fs_event_stop(uv_fs_event_t* handle) {
+ int r;
+ r = 0;
+
if (!uv__is_active(handle))
return 0;
uv__handle_stop(handle);
#if defined(__APPLE__)
- if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle))
-#endif /* defined(__APPLE__) */
- {
- uv__io_close(handle->loop, &handle->event_watcher);
- }
-
- uv__free(handle->path);
- handle->path = NULL;
+ if (!uv__has_forked_with_cfrunloop)
+ r = uv__fsevents_close(handle);
+#endif
if (handle->event_watcher.fd != -1) {
- /* When FSEvents is used, we don't use the event_watcher's fd under certain
- * confitions. (see uv_fs_event_start) */
+ uv__io_close(handle->loop, &handle->event_watcher);
uv__close(handle->event_watcher.fd);
handle->event_watcher.fd = -1;
}
- return 0;
+ uv__free(handle->path);
+ handle->path = NULL;
+
+ return r;
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 2e84eeeb82877e..7e4d5fc7ffd429 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -58,11 +58,19 @@ struct uv__stream_select_s {
fd_set* swrite;
size_t swrite_sz;
};
-# define WRITE_RETRY_ON_ERROR(send_handle) \
+
+/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
+ * EPROTOTYPE can be returned while trying to write to a socket that is
+ * shutting down. If we retry the write, we should get the expected EPIPE
+ * instead.
+ */
+# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE)
+# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
(errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \
- (errno == EMSGSIZE && send_handle))
+ (errno == EMSGSIZE && send_handle != NULL))
#else
-# define WRITE_RETRY_ON_ERROR(send_handle) \
+# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR)
+# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
(errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
#endif /* defined(__APPLE__) */
@@ -700,6 +708,14 @@ static void uv__drain(uv_stream_t* stream) {
}
+static ssize_t uv__writev(int fd, struct iovec* vec, size_t n) {
+ if (n == 1)
+ return write(fd, vec->iov_base, vec->iov_len);
+ else
+ return writev(fd, vec, n);
+}
+
+
static size_t uv__write_req_size(uv_write_t* req) {
size_t size;
@@ -712,6 +728,37 @@ static size_t uv__write_req_size(uv_write_t* req) {
}
+/* Returns 1 if all write request data has been written, or 0 if there is still
+ * more data to write.
+ *
+ * Note: the return value only says something about the *current* request.
+ * There may still be other write requests sitting in the queue.
+ */
+static int uv__write_req_update(uv_stream_t* stream,
+ uv_write_t* req,
+ size_t n) {
+ uv_buf_t* buf;
+ size_t len;
+
+ assert(n <= stream->write_queue_size);
+ stream->write_queue_size -= n;
+
+ buf = req->bufs + req->write_index;
+
+ do {
+ len = n < buf->len ? n : buf->len;
+ buf->base += len;
+ buf->len -= len;
+ buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */
+ n -= len;
+ } while (n > 0);
+
+ req->write_index = buf - req->bufs;
+
+ return req->write_index == req->nbufs;
+}
+
+
static void uv__write_req_finish(uv_write_t* req) {
uv_stream_t* stream = req->handle;
@@ -832,102 +879,32 @@ static void uv__write(uv_stream_t* stream) {
*pi = fd_to_send;
}
- do {
+ do
n = sendmsg(uv__stream_fd(stream), &msg, 0);
- }
-#if defined(__APPLE__)
- /*
- * Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
- * EPROTOTYPE can be returned while trying to write to a socket that is
- * shutting down. If we retry the write, we should get the expected EPIPE
- * instead.
- */
- while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
-#else
- while (n == -1 && errno == EINTR);
-#endif
- } else {
- do {
- if (iovcnt == 1) {
- n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len);
- } else {
- n = writev(uv__stream_fd(stream), iov, iovcnt);
- }
- }
-#if defined(__APPLE__)
- /*
- * Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
- * EPROTOTYPE can be returned while trying to write to a socket that is
- * shutting down. If we retry the write, we should get the expected EPIPE
- * instead.
- */
- while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
-#else
- while (n == -1 && errno == EINTR);
-#endif
- }
+ while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
- if (n < 0) {
- if (!WRITE_RETRY_ON_ERROR(req->send_handle)) {
- err = UV__ERR(errno);
- goto error;
- } else if (stream->flags & UV_HANDLE_BLOCKING_WRITES) {
- /* If this is a blocking stream, try again. */
- goto start;
- }
+ /* Ensure the handle isn't sent again in case this is a partial write. */
+ if (n >= 0)
+ req->send_handle = NULL;
} else {
- /* Successful write */
-
- while (n >= 0) {
- uv_buf_t* buf = &(req->bufs[req->write_index]);
- size_t len = buf->len;
-
- assert(req->write_index < req->nbufs);
-
- if ((size_t)n < len) {
- buf->base += n;
- buf->len -= n;
- stream->write_queue_size -= n;
- n = 0;
-
- /* There is more to write. */
- if (stream->flags & UV_HANDLE_BLOCKING_WRITES) {
- /*
- * If we're blocking then we should not be enabling the write
- * watcher - instead we need to try again.
- */
- goto start;
- } else {
- /* Break loop and ensure the watcher is pending. */
- break;
- }
-
- } else {
- /* Finished writing the buf at index req->write_index. */
- req->write_index++;
-
- assert((size_t)n >= len);
- n -= len;
-
- assert(stream->write_queue_size >= len);
- stream->write_queue_size -= len;
+ do
+ n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
+ while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
+ }
- if (req->write_index == req->nbufs) {
- /* Then we're done! */
- assert(n == 0);
- uv__write_req_finish(req);
- /* TODO: start trying to write the next request. */
- return;
- }
- }
- }
+ if (n == -1 && !IS_TRANSIENT_WRITE_ERROR(errno, req->send_handle)) {
+ err = UV__ERR(errno);
+ goto error;
}
- /* Either we've counted n down to zero or we've got EAGAIN. */
- assert(n == 0 || n == -1);
+ if (n >= 0 && uv__write_req_update(stream, req, n)) {
+ uv__write_req_finish(req);
+ return; /* TODO(bnoordhuis) Start trying to write the next request. */
+ }
- /* Only non-blocking streams should use the write_watcher. */
- assert(!(stream->flags & UV_HANDLE_BLOCKING_WRITES));
+ /* If this is a blocking stream, try again. */
+ if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
+ goto start;
/* We're not done. */
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index 29004707a41947..8bcb857610fa98 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -48,8 +48,10 @@
STATIC_ASSERT(sizeof(uv_barrier_t) == sizeof(pthread_barrier_t));
#endif
-/* Note: guard clauses should match uv_barrier_t's in include/uv/uv-unix.h. */
-#if defined(_AIX) || !defined(PTHREAD_BARRIER_SERIAL_THREAD)
+/* Note: guard clauses should match uv_barrier_t's in include/uv/unix.h. */
+#if defined(_AIX) || \
+ defined(__OpenBSD__) || \
+ !defined(PTHREAD_BARRIER_SERIAL_THREAD)
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
struct _uv_barrier* b;
int rc;
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index e6668a012c5c27..ec337ec8b8dfc2 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -760,14 +760,16 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
* IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX) || defined(__MVS__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
&ttl,
sizeof(ttl));
-#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
+#endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
@@ -783,14 +785,16 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
* IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX) || defined(__MVS__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
&on,
sizeof(on));
-#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
+#endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) ||
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 1244967a78dacb..acf8e1107e9786 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -230,8 +230,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
*/
/* Convert to short path. */
- short_path = short_path_buffer;
- if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
+ if (GetShortPathNameW(pathw,
+ short_path_buffer,
+ ARRAY_SIZE(short_path_buffer))) {
+ short_path = short_path_buffer;
+ } else {
short_path = NULL;
}
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 0716ecca1221e6..65d936bf08f555 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -42,8 +42,6 @@
#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 { \
@@ -1360,78 +1358,12 @@ static void fs__fstat(uv_fs_t* req) {
static void fs__rename(uv_fs_t* req) {
- 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) {
+ if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
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;
- }
-
- /* 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;
+ SET_REQ_RESULT(req, 0);
}
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index e303cc8a2331e7..277f6497a25234 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -1310,7 +1310,6 @@ static int uv__pipe_write_data(uv_loop_t* loop,
uv_pipe_t* handle,
const uv_buf_t bufs[],
size_t nbufs,
- uv_stream_t* send_handle,
uv_write_cb cb,
int copy_always) {
int err;
@@ -1321,7 +1320,7 @@ static int uv__pipe_write_data(uv_loop_t* loop,
UV_REQ_INIT(req, UV_WRITE);
req->handle = (uv_stream_t*) handle;
- req->send_handle = send_handle;
+ req->send_handle = NULL;
req->cb = cb;
/* Private fields. */
req->coalesced = 0;
@@ -1558,8 +1557,7 @@ int uv__pipe_write_ipc(uv_loop_t* loop,
/* Write buffers. We set the `always_copy` flag, so it is not a problem that
* some of the written data lives on the stack. */
- err = uv__pipe_write_data(
- loop, req, handle, bufs, buf_count, send_handle, cb, 1);
+ err = uv__pipe_write_data(loop, req, handle, bufs, buf_count, cb, 1);
/* If we had to heap-allocate the bufs array, free it now. */
if (bufs != stack_bufs) {
@@ -1583,8 +1581,7 @@ int uv__pipe_write(uv_loop_t* loop,
} else {
/* Non-IPC pipe write: put data on the wire directly. */
assert(send_handle == NULL);
- return uv__pipe_write_data(
- loop, req, handle, bufs, nbufs, NULL, cb, 0);
+ return uv__pipe_write_data(loop, req, handle, bufs, nbufs, cb, 0);
}
}
diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c
index 56ca41aab0b759..fd4b7c98688f69 100644
--- a/deps/uv/src/win/thread.c
+++ b/deps/uv/src/win/thread.c
@@ -23,6 +23,12 @@
#include
#include
+#if defined(__MINGW64_VERSION_MAJOR)
+/* MemoryBarrier expands to __mm_mfence in some cases (x86+sse2), which may
+ * require this header in some versions of mingw64. */
+#include
+#endif
+
#include "uv.h"
#include "internal.h"
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 45bbe9689aea1d..f38e9a88636e4b 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -164,7 +164,7 @@ void uv_console_init(void) {
OPEN_EXISTING,
0,
0);
- if (uv__tty_console_handle != NULL) {
+ if (uv__tty_console_handle != INVALID_HANDLE_VALUE) {
QueueUserWorkItem(uv__tty_console_resize_message_loop_thread,
NULL,
WT_EXECUTELONGFUNCTION);
@@ -360,6 +360,8 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
}
} else {
was_reading = 0;
+ alloc_cb = NULL;
+ read_cb = NULL;
}
uv_sem_wait(&uv_tty_output_lock);
@@ -733,8 +735,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Ignore keyup events, unless the left alt key was held and a valid
* unicode character was emitted. */
- if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
- KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
+ if (!KEV.bKeyDown &&
+ KEV.wVirtualKeyCode != VK_MENU &&
+ KEV.uChar.UnicodeChar != 0) {
continue;
}
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 6e81c26165fbc0..923789129e92e0 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -1627,3 +1627,120 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
CloseHandle(handle);
return r;
}
+
+
+int uv_os_uname(uv_utsname_t* buffer) {
+ /* Implementation loosely based on
+ https://github.com/gagern/gnulib/blob/master/lib/uname.c */
+ OSVERSIONINFOW os_info;
+ SYSTEM_INFO system_info;
+ int processor_level;
+ int r;
+
+ if (buffer == NULL)
+ return UV_EINVAL;
+
+ uv__once_init();
+ os_info.dwOSVersionInfoSize = sizeof(os_info);
+ os_info.szCSDVersion[0] = L'\0';
+
+ /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx()
+ if RtlGetVersion() is not available. */
+ if (pRtlGetVersion) {
+ pRtlGetVersion(&os_info);
+ } else {
+ /* Silence GetVersionEx() deprecation warning. */
+ #pragma warning(suppress : 4996)
+ if (GetVersionExW(&os_info) == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto error;
+ }
+ }
+
+ /* Populate the version field. */
+ if (WideCharToMultiByte(CP_UTF8,
+ 0,
+ os_info.szCSDVersion,
+ -1,
+ buffer->version,
+ sizeof(buffer->version),
+ NULL,
+ NULL) == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto error;
+ }
+
+ /* Populate the sysname field. */
+#ifdef __MINGW32__
+ r = snprintf(buffer->sysname,
+ sizeof(buffer->sysname),
+ "MINGW32_NT-%u.%u",
+ (unsigned int) os_info.dwMajorVersion,
+ (unsigned int) os_info.dwMinorVersion);
+ assert(r < sizeof(buffer->sysname));
+#else
+ uv__strscpy(buffer->sysname, "Windows_NT", sizeof(buffer->sysname));
+#endif
+
+ /* Populate the release field. */
+ r = snprintf(buffer->release,
+ sizeof(buffer->release),
+ "%d.%d.%d",
+ (unsigned int) os_info.dwMajorVersion,
+ (unsigned int) os_info.dwMinorVersion,
+ (unsigned int) os_info.dwBuildNumber);
+ assert(r < sizeof(buffer->release));
+
+ /* Populate the machine field. */
+ GetSystemInfo(&system_info);
+
+ switch (system_info.wProcessorArchitecture) {
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ uv__strscpy(buffer->machine, "x86_64", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_IA64:
+ uv__strscpy(buffer->machine, "ia64", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ uv__strscpy(buffer->machine, "i386", sizeof(buffer->machine));
+
+ if (system_info.wProcessorLevel > 3) {
+ processor_level = system_info.wProcessorLevel < 6 ?
+ system_info.wProcessorLevel : 6;
+ buffer->machine[1] = '0' + processor_level;
+ }
+
+ break;
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+ uv__strscpy(buffer->machine, "i686", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ uv__strscpy(buffer->machine, "mips", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ case PROCESSOR_ARCHITECTURE_ALPHA64:
+ uv__strscpy(buffer->machine, "alpha", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_PPC:
+ uv__strscpy(buffer->machine, "powerpc", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_SHX:
+ uv__strscpy(buffer->machine, "sh", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_ARM:
+ uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
+ break;
+ default:
+ uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
+ break;
+ }
+
+ return 0;
+
+error:
+ buffer->sysname[0] = '\0';
+ buffer->release[0] = '\0';
+ buffer->version[0] = '\0';
+ buffer->machine[0] = '\0';
+ return r;
+}
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
index 2c09b448a95c01..fbbbceed95ebcf 100644
--- a/deps/uv/src/win/winapi.c
+++ b/deps/uv/src/win/winapi.c
@@ -26,6 +26,7 @@
/* Ntdll function pointers */
+sRtlGetVersion pRtlGetVersion;
sRtlNtStatusToDosError pRtlNtStatusToDosError;
sNtDeviceIoControlFile pNtDeviceIoControlFile;
sNtQueryInformationFile pNtQueryInformationFile;
@@ -55,6 +56,9 @@ void uv_winapi_init(void) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");
}
+ pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module,
+ "RtlGetVersion");
+
pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
ntdll_module,
"RtlNtStatusToDosError");
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 2a8adf6b262463..82c5ed46711d2f 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4519,6 +4519,9 @@ typedef VOID (NTAPI *PIO_APC_ROUTINE)
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved);
+typedef NTSTATUS (NTAPI *sRtlGetVersion)
+ (PRTL_OSVERSIONINFOW lpVersionInformation);
+
typedef ULONG (NTAPI *sRtlNtStatusToDosError)
(NTSTATUS Status);
@@ -4707,6 +4710,7 @@ typedef HWINEVENTHOOK (WINAPI *sSetWinEventHook)
/* Ntdll function pointers */
+extern sRtlGetVersion pRtlGetVersion;
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
extern sNtQueryInformationFile pNtQueryInformationFile;
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index 2a699f46dcb0ff..eba28ecb9aa0a5 100644
--- a/deps/uv/test/run-tests.c
+++ b/deps/uv/test/run-tests.c
@@ -42,6 +42,7 @@ int ipc_helper_tcp_connection(void);
int ipc_helper_closed_handle(void);
int ipc_send_recv_helper(void);
int ipc_helper_bind_twice(void);
+int ipc_helper_send_zero(void);
int stdio_over_pipes_helper(void);
int spawn_stdin_stdout(void);
int spawn_tcp_server_helper(void);
@@ -104,6 +105,10 @@ static int maybe_run_test(int argc, char **argv) {
return ipc_helper_bind_twice();
}
+ if (strcmp(argv[1], "ipc_helper_send_zero") == 0) {
+ return ipc_helper_send_zero();
+ }
+
if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
return stdio_over_pipes_helper();
}
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index 5ddccffd0a98e9..ea34bd63a70625 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -480,6 +480,8 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
#ifdef _WIN32
TEST_IMPL(fs_event_watch_dir_short_path) {
uv_loop_t* loop;
+ uv_fs_t req;
+ int has_shortnames;
int r;
/* Setup */
@@ -489,26 +491,37 @@ TEST_IMPL(fs_event_watch_dir_short_path) {
create_dir("watch_dir");
create_file("watch_dir/file1");
- r = uv_fs_event_init(loop, &fs_event);
- ASSERT(r == 0);
- r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
- ASSERT(r == 0);
- r = uv_timer_init(loop, &timer);
- ASSERT(r == 0);
- r = uv_timer_start(&timer, timer_cb_file, 100, 0);
- ASSERT(r == 0);
+ /* Newer version of Windows ship with
+ HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation
+ not equal to 0. So we verify the files we created are addressable by a 8.3
+ short name */
+ has_shortnames = uv_fs_stat(NULL, &req, "watch_~1", NULL) != UV_ENOENT;
+ if (has_shortnames) {
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
+ ASSERT(r == 0);
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, timer_cb_file, 100, 0);
+ ASSERT(r == 0);
- uv_run(loop, UV_RUN_DEFAULT);
+ uv_run(loop, UV_RUN_DEFAULT);
- ASSERT(fs_event_cb_called == 1);
- ASSERT(timer_cb_called == 1);
- ASSERT(close_cb_called == 1);
+ ASSERT(fs_event_cb_called == 1);
+ ASSERT(timer_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+ }
/* Cleanup */
remove("watch_dir/file1");
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
+
+ if (!has_shortnames)
+ RETURN_SKIP("Was not able to address files with 8.3 short name.");
+
return 0;
}
#endif
@@ -576,6 +589,14 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
create_dir("watch_dir");
create_file("watch_dir/file.js");
create_file("watch_dir/file.jsx");
+#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_12)
+ /* Empirically, FSEvents seems to (reliably) report the preceeding
+ * create_file events prior to macOS 10.11.6 in the subsequent fs_watch
+ * creation, but that behavior hasn't been observed to occur on newer
+ * versions. Give a long delay here to let the system settle before running
+ * the test. */
+ uv_sleep(1100);
+#endif
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -648,7 +669,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
- r = uv_timer_start(&timer, timer_cb_touch, 100, 0);
+ r = uv_timer_start(&timer, timer_cb_touch, 1100, 0);
ASSERT(r == 0);
ASSERT(timer_cb_touch_called == 0);
@@ -936,32 +957,48 @@ TEST_IMPL(fs_event_getpath) {
RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
+ unsigned i;
int r;
char buf[1024];
size_t len;
+ const char* const watch_dir[] = {
+ "watch_dir",
+ "watch_dir/",
+ "watch_dir///",
+ "watch_dir/subfolder/..",
+ "watch_dir//subfolder//..//",
+ };
create_dir("watch_dir");
+ create_dir("watch_dir/subfolder");
- r = uv_fs_event_init(loop, &fs_event);
- ASSERT(r == 0);
- len = sizeof buf;
- r = uv_fs_event_getpath(&fs_event, buf, &len);
- ASSERT(r == UV_EINVAL);
- r = uv_fs_event_start(&fs_event, fail_cb, "watch_dir", 0);
- ASSERT(r == 0);
- len = sizeof buf;
- r = uv_fs_event_getpath(&fs_event, buf, &len);
- ASSERT(r == 0);
- ASSERT(buf[len - 1] != 0);
- ASSERT(buf[len] == '\0');
- ASSERT(memcmp(buf, "watch_dir", len) == 0);
- r = uv_fs_event_stop(&fs_event);
- ASSERT(r == 0);
- uv_close((uv_handle_t*) &fs_event, close_cb);
- uv_run(loop, UV_RUN_DEFAULT);
+ for (i = 0; i < ARRAY_SIZE(watch_dir); i++) {
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ len = sizeof buf;
+ r = uv_fs_event_getpath(&fs_event, buf, &len);
+ ASSERT(r == UV_EINVAL);
+ r = uv_fs_event_start(&fs_event, fail_cb, watch_dir[i], 0);
+ ASSERT(r == 0);
+ len = 0;
+ r = uv_fs_event_getpath(&fs_event, buf, &len);
+ ASSERT(r == UV_ENOBUFS);
+ ASSERT(len < sizeof buf); /* sanity check */
+ ASSERT(len == strlen(watch_dir[i]) + 1);
+ r = uv_fs_event_getpath(&fs_event, buf, &len);
+ ASSERT(r == 0);
+ ASSERT(len == strlen(watch_dir[i]));
+ ASSERT(strcmp(buf, watch_dir[i]) == 0);
+ r = uv_fs_event_stop(&fs_event);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &fs_event, close_cb);
- ASSERT(close_cb_called == 1);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+ close_cb_called = 0;
+ }
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
@@ -1082,6 +1119,9 @@ TEST_IMPL(fs_event_watch_invalid_path) {
r = uv_fs_event_start(&fs_event, fs_event_cb_file, "<:;", 0);
ASSERT(r != 0);
ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_file, "", 0);
+ ASSERT(r != 0);
+ ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
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 325305a6442fcf..753fb7b7c209e7 100644
--- a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
+++ b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
@@ -55,7 +55,7 @@ static void write_cb(uv_write_t* req, int status) {
}
static void shutdown_cb(uv_shutdown_t* req, int status) {
- ASSERT(status == 0);
+ ASSERT(status == 0 || status == UV_ENOTCONN);
uv_close((uv_handle_t*) req->handle, NULL);
}
diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c
index 166225c01c6b52..12d4e33221f4cf 100644
--- a/deps/uv/test/test-ipc-send-recv.c
+++ b/deps/uv/test/test-ipc-send-recv.c
@@ -149,7 +149,6 @@ static void connect_cb(uv_connect_t* req, int status) {
&ctx.send.stream,
NULL);
ASSERT(r == 0);
- ASSERT(ctx.write_req.send_handle == &ctx.send.stream);
/* Perform two writes to the same pipe to make sure that on Windows we are
* not running into issue 505:
@@ -161,7 +160,6 @@ static void connect_cb(uv_connect_t* req, int status) {
&ctx.send2.stream,
NULL);
ASSERT(r == 0);
- ASSERT(ctx.write_req2.send_handle == &ctx.send2.stream);
r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb);
ASSERT(r == 0);
@@ -346,7 +344,6 @@ static void read_cb(uv_stream_t* handle,
&recv->stream,
write2_cb);
ASSERT(r == 0);
- ASSERT(write_req->send_handle == &recv->stream);
} while (uv_pipe_pending_count(pipe) > 0);
}
diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c
index 829d178d47fe7a..88d04ba143cff4 100644
--- a/deps/uv/test/test-ipc.c
+++ b/deps/uv/test/test-ipc.c
@@ -39,12 +39,15 @@ static int local_conn_accepted;
static int remote_conn_accepted;
static int tcp_server_listening;
static uv_write_t write_req;
+static uv_write_t write_req2;
static uv_write_t conn_notify_req;
static int close_cb_called;
static int connection_accepted;
static int tcp_conn_read_cb_called;
static int tcp_conn_write_cb_called;
static int closed_handle_data_read;
+static int closed_handle_write;
+static int send_zero_write;
typedef struct {
uv_connect_t conn_req;
@@ -54,7 +57,15 @@ typedef struct {
#define CONN_COUNT 100
#define BACKLOG 128
-#define LARGE_SIZE 1000000
+#define LARGE_SIZE 100000
+
+static uv_buf_t large_buf;
+static char buffer[LARGE_SIZE];
+static uv_write_t write_reqs[300];
+static int write_reqs_completed;
+
+static unsigned int write_until_data_queued(void);
+static void send_handle_and_close(void);
static void close_server_conn_cb(uv_handle_t* handle) {
@@ -92,6 +103,7 @@ static void exit_cb(uv_process_t* process,
printf("exit_cb\n");
exit_cb_called++;
ASSERT(exit_status == 0);
+ ASSERT(term_signal == 0);
uv_close((uv_handle_t*)process, NULL);
}
@@ -420,6 +432,14 @@ static void on_read_closed_handle(uv_stream_t* handle,
#endif
+static void on_read_send_zero(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ ASSERT(nread == 0 || nread == UV_EOF);
+ free(buf->base);
+}
+
+
static int run_ipc_test(const char* helper, uv_read_cb read_cb) {
uv_process_t process;
int r;
@@ -544,6 +564,13 @@ TEST_IMPL(ipc_listen_after_bind_twice) {
}
#endif
+TEST_IMPL(ipc_send_zero) {
+ int r;
+ r = run_ipc_test("ipc_helper_send_zero", on_read_send_zero);
+ ASSERT(r == 0);
+ return 0;
+}
+
/* Everything here runs in a child process. */
@@ -573,14 +600,25 @@ static void tcp_connection_write_cb(uv_write_t* req, int status) {
static void closed_handle_large_write_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
ASSERT(closed_handle_data_read = LARGE_SIZE);
+ if (++write_reqs_completed == ARRAY_SIZE(write_reqs)) {
+ write_reqs_completed = 0;
+ if (write_until_data_queued() > 0)
+ send_handle_and_close();
+ }
}
static void closed_handle_write_cb(uv_write_t* req, int status) {
ASSERT(status == UV_EBADF);
+ closed_handle_write = 1;
}
+static void send_zero_write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ send_zero_write++;
+}
+
static void on_tcp_child_process_read(uv_stream_t* tcp,
ssize_t nread,
const uv_buf_t* buf) {
@@ -688,7 +726,6 @@ int ipc_helper(int listen_after_write) {
* over which a handle will be transmitted.
*/
struct sockaddr_in addr;
- uv_write_t write_req;
int r;
uv_buf_t buf;
@@ -788,26 +825,28 @@ int ipc_helper_tcp_connection(void) {
return 0;
}
-
-int ipc_helper_closed_handle(void) {
+static unsigned int write_until_data_queued() {
+ unsigned int i;
int r;
- struct sockaddr_in addr;
- uv_write_t write_req;
- uv_write_t write_req2;
- uv_buf_t buf;
- char buffer[LARGE_SIZE];
- r = uv_pipe_init(uv_default_loop(), &channel, 1);
- ASSERT(r == 0);
-
- uv_pipe_open(&channel, 0);
+ i = 0;
+ do {
+ r = uv_write(&write_reqs[i],
+ (uv_stream_t*)&channel,
+ &large_buf,
+ 1,
+ closed_handle_large_write_cb);
+ ASSERT(r == 0);
+ i++;
+ } while (((uv_stream_t*)&channel)->write_queue_size == 0 &&
+ i < ARRAY_SIZE(write_reqs));
- ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
- ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
- ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+ return ((uv_stream_t*)&channel)->write_queue_size;
+}
- memset(buffer, '.', LARGE_SIZE);
- buf = uv_buf_init(buffer, LARGE_SIZE);
+static void send_handle_and_close() {
+ int r;
+ struct sockaddr_in addr;
r = uv_tcp_init(uv_default_loop(), &tcp_server);
ASSERT(r == 0);
@@ -817,26 +856,40 @@ int ipc_helper_closed_handle(void) {
r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
- r = uv_write(&write_req,
- (uv_stream_t*)&channel,
- &buf,
- 1,
- closed_handle_large_write_cb);
- ASSERT(r == 0);
-
- r = uv_write2(&write_req2,
+ r = uv_write2(&write_req,
(uv_stream_t*)&channel,
- &buf,
+ &large_buf,
1,
(uv_stream_t*)&tcp_server,
closed_handle_write_cb);
ASSERT(r == 0);
uv_close((uv_handle_t*)&tcp_server, NULL);
+}
+
+int ipc_helper_closed_handle(void) {
+ int r;
+
+ memset(buffer, '.', LARGE_SIZE);
+ large_buf = uv_buf_init(buffer, LARGE_SIZE);
+
+ r = uv_pipe_init(uv_default_loop(), &channel, 1);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&channel, 0);
+
+ ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+ if (write_until_data_queued() > 0)
+ send_handle_and_close();
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
+ ASSERT(closed_handle_write == 1);
+
MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -848,8 +901,6 @@ int ipc_helper_bind_twice(void) {
* over which two handles will be transmitted.
*/
struct sockaddr_in addr;
- uv_write_t write_req;
- uv_write_t write_req2;
int r;
uv_buf_t buf;
@@ -889,3 +940,35 @@ int ipc_helper_bind_twice(void) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+int ipc_helper_send_zero(void) {
+ int r;
+ uv_buf_t zero_buf;
+
+ zero_buf = uv_buf_init(0, 0);
+
+ r = uv_pipe_init(uv_default_loop(), &channel, 0);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&channel, 0);
+
+ ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+ r = uv_write(&write_req,
+ (uv_stream_t*)&channel,
+ &zero_buf,
+ 1,
+ send_zero_write_cb);
+
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(send_zero_write == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
\ No newline at end of file
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index cc37bc039b15ba..53372c90f769f8 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -69,6 +69,7 @@ TEST_DECLARE (ipc_send_recv_pipe_inprocess)
TEST_DECLARE (ipc_send_recv_tcp)
TEST_DECLARE (ipc_send_recv_tcp_inprocess)
TEST_DECLARE (ipc_tcp_connection)
+TEST_DECLARE (ipc_send_zero)
#ifndef _WIN32
TEST_DECLARE (ipc_closed_handle)
#endif
@@ -436,9 +437,13 @@ TEST_DECLARE (fork_socketpair)
TEST_DECLARE (fork_socketpair_started)
TEST_DECLARE (fork_signal_to_child)
TEST_DECLARE (fork_signal_to_child_closed)
+#ifndef __APPLE__ /* This is forbidden in a fork child: The process has forked
+ and you cannot use this CoreFoundation functionality
+ safely. You MUST exec(). */
TEST_DECLARE (fork_fs_events_child)
TEST_DECLARE (fork_fs_events_child_dir)
TEST_DECLARE (fork_fs_events_file_parent_child)
+#endif
#ifndef __MVS__
TEST_DECLARE (fork_threadpool_queue_work_simple)
#endif
@@ -446,6 +451,7 @@ TEST_DECLARE (fork_threadpool_queue_work_simple)
TEST_DECLARE (idna_toascii)
TEST_DECLARE (utf8_decode1)
+TEST_DECLARE (uname)
TASK_LIST_START
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
@@ -510,6 +516,7 @@ TASK_LIST_START
TEST_ENTRY (ipc_send_recv_tcp)
TEST_ENTRY (ipc_send_recv_tcp_inprocess)
TEST_ENTRY (ipc_tcp_connection)
+ TEST_ENTRY (ipc_send_zero)
#ifndef _WIN32
TEST_ENTRY (ipc_closed_handle)
#endif
@@ -945,15 +952,18 @@ TASK_LIST_START
TEST_ENTRY (fork_socketpair_started)
TEST_ENTRY (fork_signal_to_child)
TEST_ENTRY (fork_signal_to_child_closed)
+#ifndef __APPLE__
TEST_ENTRY (fork_fs_events_child)
TEST_ENTRY (fork_fs_events_child_dir)
TEST_ENTRY (fork_fs_events_file_parent_child)
+#endif
#ifndef __MVS__
TEST_ENTRY (fork_threadpool_queue_work_simple)
#endif
#endif
TEST_ENTRY (utf8_decode1)
+ TEST_ENTRY (uname)
/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */
#ifndef __MVS__
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index 43ed119debfe69..e651e5c582956e 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -35,6 +35,7 @@ TEST_IMPL(platform_output) {
uv_cpu_info_t* cpus;
uv_interface_address_t* interfaces;
uv_passwd_t pwd;
+ uv_utsname_t uname;
int count;
int i;
int err;
@@ -153,5 +154,13 @@ TEST_IMPL(platform_output) {
ASSERT(ppid > 0);
printf("uv_os_getppid: %d\n", (int) ppid);
+ err = uv_os_uname(&uname);
+ ASSERT(err == 0);
+ printf("uv_os_uname:\n");
+ printf(" sysname: %s\n", uname.sysname);
+ printf(" release: %s\n", uname.release);
+ printf(" version: %s\n", uname.version);
+ printf(" machine: %s\n", uname.machine);
+
return 0;
}
diff --git a/deps/uv/test/test-uname.c b/deps/uv/test/test-uname.c
new file mode 100644
index 00000000000000..105a17fe67771a
--- /dev/null
+++ b/deps/uv/test/test-uname.c
@@ -0,0 +1,69 @@
+/* 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 "task.h"
+#include
+
+#ifndef _WIN32
+# include
+#endif
+
+TEST_IMPL(uname) {
+#ifndef _WIN32
+ struct utsname buf;
+#endif
+#ifdef _AIX
+ char temp[256];
+#endif
+ uv_utsname_t buffer;
+ int r;
+
+ /* Verify that NULL is handled properly. */
+ r = uv_os_uname(NULL);
+ ASSERT(r == UV_EINVAL);
+
+ /* Verify the happy path. */
+ r = uv_os_uname(&buffer);
+ ASSERT(r == 0);
+
+#ifndef _WIN32
+ ASSERT(uname(&buf) != -1);
+ ASSERT(strcmp(buffer.sysname, buf.sysname) == 0);
+ ASSERT(strcmp(buffer.version, buf.version) == 0);
+
+# ifdef _AIX
+ snprintf(temp, sizeof(temp), "%s.%s", buf.version, buf.release);
+ ASSERT(strcmp(buffer.release, temp) == 0);
+# else
+ ASSERT(strcmp(buffer.release, buf.release) == 0);
+# endif /* _AIX */
+
+# if defined(_AIX) || defined(__PASE__)
+ ASSERT(strcmp(buffer.machine, "ppc64") == 0);
+# else
+ ASSERT(strcmp(buffer.machine, buf.machine) == 0);
+# endif /* defined(_AIX) || defined(__PASE__) */
+
+#endif /* _WIN32 */
+
+ return 0;
+}
diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp
index ae7dc0d628f6e4..604925861e525a 100644
--- a/deps/uv/test/test.gyp
+++ b/deps/uv/test/test.gyp
@@ -154,6 +154,7 @@
'test-udp-multicast-interface.c',
'test-udp-multicast-interface6.c',
'test-udp-try-send.c',
+ 'test-uname.c',
],
'conditions': [
[ 'OS=="win"', {
diff --git a/doc/api/buffer.md b/doc/api/buffer.md
index 1bfd30b1943e42..a8e8dd376654ab 100644
--- a/doc/api/buffer.md
+++ b/doc/api/buffer.md
@@ -221,7 +221,7 @@ elements, and not as a byte array of the target type. That is,
`[0x1020304]` or `[0x4030201]`.
It is possible to create a new `Buffer` that shares the same allocated memory as
-a [`TypedArray`] instance by using the `TypeArray` object's `.buffer` property.
+a [`TypedArray`] instance by using the `TypedArray` object's `.buffer` property.
```js
const arr = new Uint16Array(2);
@@ -1238,7 +1238,9 @@ console.log(b.toString());
// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
```
-`value` is coerced to a `uint32` value if it is not a string or integer.
+`value` is coerced to a `uint32` value if it is not a string, `Buffer`, or
+integer. If the resulting integer is greater than `255` (decimal), `buf` will be
+filled with `value & 255`.
If the final write of a `fill()` operation falls on a multi-byte character,
then only the bytes of that character that fit into `buf` are written:
diff --git a/doc/api/child_process.md b/doc/api/child_process.md
index e32568cd78e677..cdfdab1a98d635 100644
--- a/doc/api/child_process.md
+++ b/doc/api/child_process.md
@@ -147,8 +147,9 @@ changes:
`'/bin/sh'` on UNIX, `process.env.ComSpec` on Windows.
* `timeout` {number} **Default:** `0`
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
- stderr. If exceeded, the child process is terminated. See caveat at
- [`maxBuffer` and Unicode][]. **Default:** `200 * 1024`.
+ stderr. If exceeded, the child process is terminated and any output is
+ truncated. See caveat at [`maxBuffer` and Unicode][].
+ **Default:** `200 * 1024`.
* `killSignal` {string|integer} **Default:** `'SIGTERM'`
* `uid` {number} Sets the user identity of the process (see setuid(2)).
* `gid` {number} Sets the group identity of the process (see setgid(2)).
@@ -245,8 +246,9 @@ changes:
* `encoding` {string} **Default:** `'utf8'`
* `timeout` {number} **Default:** `0`
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
- stderr. If exceeded, the child process is terminated. See caveat at
- [`maxBuffer` and Unicode][]. **Default:** `200 * 1024`.
+ stderr. If exceeded, the child process is terminated and any output is
+ truncated. See caveat at [`maxBuffer` and Unicode][].
+ **Default:** `200 * 1024`.
* `killSignal` {string|integer} **Default:** `'SIGTERM'`
* `uid` {number} Sets the user identity of the process (see setuid(2)).
* `gid` {number} Sets the group identity of the process (see setgid(2)).
@@ -779,8 +781,9 @@ changes:
* `killSignal` {string|integer} The signal value to be used when the spawned
process will be killed. **Default:** `'SIGTERM'`.
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
- stderr. If exceeded, the child process is terminated. See caveat at
- [`maxBuffer` and Unicode][]. **Default:** `200 * 1024`.
+ stderr. If exceeded, the child process is terminated and any output is
+ truncated. See caveat at [`maxBuffer` and Unicode][].
+ **Default:** `200 * 1024`.
* `encoding` {string} The encoding used for all stdio inputs and outputs.
**Default:** `'buffer'`.
* `windowsHide` {boolean} Hide the subprocess console window that would
@@ -842,8 +845,9 @@ changes:
* `killSignal` {string|integer} The signal value to be used when the spawned
process will be killed. **Default:** `'SIGTERM'`.
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
- stderr. If exceeded, the child process is terminated. See caveat at
- [`maxBuffer` and Unicode][]. **Default:** `200 * 1024`.
+ stderr. If exceeded, the child process is terminated and any output is
+ truncated. See caveat at [`maxBuffer` and Unicode][].
+ **Default:** `200 * 1024`.
* `encoding` {string} The encoding used for all stdio inputs and outputs.
**Default:** `'buffer'`.
* `shell` {boolean|string} If `true`, runs `command` inside of a shell. Uses
diff --git a/doc/api/cli.md b/doc/api/cli.md
index c2c8a59ced2033..9cc52d077535dd 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -75,6 +75,64 @@ $ node --completion-bash > node_bash_completion
$ source node_bash_completion
```
+### `--diagnostic-report-directory=directory`
+
+
+Location at which the report will be generated.
+
+### `--diagnostic-report-filename=filename`
+
+
+Name of the file to which the report will be written.
+
+### `--diagnostic-report-on-fatalerror`
+
+
+Enables the report to be triggered on fatal errors (internal errors within
+the Node.js runtime such as out of memory) that lead to termination of the
+application, if `--experimental-report` is enabled. Useful to inspect various
+diagnostic data elements such as heap, stack, event loop state, resource
+consumption etc. to reason about the fatal error.
+
+### `--diagnostic-report-on-signal`
+
+
+Enables report to be generated upon receiving the specified (or predefined)
+signal to the running Node.js process, if `--experimental-report` is enabled.
+The signal to trigger the report is specified through `--diagnostic-report-signal`.
+
+### `--diagnostic-report-signal=signal`
+
+
+Sets or resets the signal for report generation (not supported on Windows).
+Default signal is `SIGUSR2`.
+
+### `--diagnostic-report-uncaught-exception`
+
+
+Enables report to be generated on un-caught exceptions, if
+`--experimental-report` is enabled. Useful when inspecting JavaScript stack in
+conjunction with native stack and other runtime environment data.
+
+### `--diagnostic-report-verbose`
+
+
+Flag that enables additional information to be printed during report generation.
+
### `--enable-fips`
+
+Use the specified file as a security policy.
+
### `--experimental-repl-await`
+
+Enable experimental diagnostic report feature.
+
### `--experimental-vm-modules`
+
+
+> Stability: 1 - Experimental
+
+
+
+Node.js contains experimental support for creating policies on loading code.
+
+Policies are a security feature intended to allow guarantees
+about what code Node.js is able to load. The use of policies assumes
+safe practices for the policy files such as ensuring that policy
+files cannot be overwritten by the Node.js application by using
+file permissions.
+
+A best practice would be to ensure that the policy manifest is read only for
+the running Node.js application, and that the file cannot be changed
+by the running Node.js application in any way. A typical setup would be to
+create the policy file as a different user id than the one running Node.js
+and granting read permissions to the user id running Node.js.
+
+## Enabling
+
+
+
+The `--experimental-policy` flag can be used to enable features for policies
+when loading modules.
+
+Once this has been set, all modules must conform to a policy manifest file
+passed to the flag:
+
+```sh
+node --experimental-policy=policy.json app.js
+```
+
+The policy manifest will be used to enforce constraints on code loaded by
+Node.js.
+
+## Features
+
+### Error Behavior
+
+When a policy check fails, Node.js by default will throw an error.
+It is possible to change the error behavior to one of a few possibilities
+by defining an "onerror" field in a policy manifest. The following values are
+available to change the behavior:
+
+* `"exit"` - will exit the process immediately.
+ No cleanup code will be allowed to run.
+* `"log"` - will log the error at the site of the failure.
+* `"throw"` (default) - will throw a JS error at the site of the failure.
+
+```json
+{
+ "onerror": "log",
+ "resources": {
+ "./app/checked.js": {
+ "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
+ }
+ }
+}
+```
+
+### Integrity Checks
+
+Policy files must use integrity checks with Subresource Integrity strings
+compatible with the browser
+[integrity attribute](https://www.w3.org/TR/SRI/#the-integrity-attribute)
+associated with absolute URLs.
+
+When using `require()` all resources involved in loading are checked for
+integrity if a policy manifest has been specified. If a resource does not match
+the integrity listed in the manifest, an error will be thrown.
+
+An example policy file that would allow loading a file `checked.js`:
+
+```json
+{
+ "resources": {
+ "./app/checked.js": {
+ "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
+ }
+ }
+}
+```
+
+Each resource listed in the policy manifest can be of one the following
+formats to determine its location:
+
+1. A [relative url string][] to a resource from the manifest such as `./resource.js`, `../resource.js`, or `/resource.js`.
+2. A complete url string to a resource such as `file:///resource.js`.
+
+When loading resources the entire URL must match including search parameters
+and hash fragment. `./a.js?b` will not be used when attempting to load
+`./a.js` and vice versa.
+
+In order to generate integrity strings, a script such as
+`printf "sha384-$(cat checked.js | openssl dgst -sha384 -binary | base64)"`
+can be used.
+
+
+[relative url string]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
diff --git a/doc/api/process.md b/doc/api/process.md
index 28ed9734f55144..60d3d1af1b66b0 100644
--- a/doc/api/process.md
+++ b/doc/api/process.md
@@ -1658,6 +1658,109 @@ In custom builds from non-release versions of the source tree, only the
`name` property may be present. The additional properties should not be
relied upon to exist.
+## process.report
+
+### process.report.getReport([err])
+
+
+* `err` {Object}
+* Returns: {Object} Returns the diagnostics report as an `Object`.
+
+Generates a JSON-formatted diagnostic report summary of the running process.
+The report includes JavaScript and native stack traces, heap statistics,
+platform information, resource usage etc.
+
+```js
+const data = process.report.getReport();
+console.log(data);
+```
+
+Additional documentation on diagnostic report is available
+at [report documentation][].
+
+### process.report.setDiagnosticReportOptions([options]);
+
+
+Set the runtime configuration of diagnostic report data capture. Upon invocation
+of this function, the runtime is reconfigured to generate report based on
+the new input.
+
+* `options` {Object}
+ * `events` {string[]}
+ * `signal`: generate a report in response to a signal raised on the process.
+ * `exception`: generate a report on unhandled exceptions.
+ * `fatalerror`: generate a report on internal fault
+ (such as out of memory errors or native assertions).
+ * `signal` {string} sets or resets the signal for report generation
+ (not supported on Windows). **Default:** `'SIGUSR2'`.
+ * `filename` {string} name of the file to which the report will be written.
+ * `path` {string} drectory at which the report will be generated.
+ **Default:** the current working directory of the Node.js process.
+ * `verbose` {boolean} flag that controls additional verbose information on
+ report generation. **Default:** `false`.
+
+```js
+// Trigger a report upon uncaught exceptions or fatal erros.
+process.report.setDiagnosticReportOptions(
+ { events: ['exception', 'fatalerror'] });
+
+// Change the default path and filename of the report.
+process.report.setDiagnosticReportOptions(
+ { filename: 'foo.json', path: '/home' });
+
+// Produce the report onto stdout, when generated. Special meaning is attached
+// to `stdout` and `stderr`. Usage of these will result in report being written
+// to the associated standard streams. URLs are not supported.
+process.report.setDiagnosticReportOptions(
+ { filename: 'stdout' });
+
+// Enable verbose option on report generation.
+process.report.setDiagnosticReportOptions(
+ { verbose: true });
+
+```
+
+Signal based report generation is not supported on Windows.
+
+Additional documentation on diagnostic report is available
+at [report documentation][].
+
+### process.report.triggerReport([filename][, err])
+
+
+* `filename` {string} The file to write into. The `filename` should be
+a relative path, that will be appended to the directory specified by
+`process.report.setDiagnosticReportOptions`, or current working directory
+of the Node.js process, if unspecified.
+* `err` {Object} A custom object which will be used for reporting
+JavsScript stack.
+
+* Returns: {string} Returns the filename of the generated report.
+
+If both `filename` and `err` object are passed to `triggerReport()` the
+`err` object must be the second parameter.
+
+Triggers and produces the report (a JSON-formatted file with the internal
+state of Node.js runtime) synchronously, and writes into a file.
+
+```js
+process.report.triggerReport();
+```
+
+When a report is triggered, start and end messages are issued to stderr and the
+filename of the report is returned to the caller. The default filename includes
+the date, time, PID and a sequence number. Alternatively, a filename and error
+object can be specified as parameters on the `triggerReport()` call.
+
+Additional documentation on diagnostic report is available
+at [report documentation][].
+
## process.send(message[, sendHandle[, options]][, callback])
The default curve name to use for ECDH key agreement in a tls server. The
@@ -1539,6 +1553,7 @@ where `secureSocket` has the same API as `pair.cleartext`.
[`server.getTicketKeys()`]: #tls_server_getticketkeys
[`server.listen()`]: net.html#net_server_listen
[`server.setTicketKeys()`]: #tls_server_setticketkeys_keys
+[`socket.setTimeout(timeout)`]: #net_socket_settimeout_timeout_callback
[`tls.DEFAULT_ECDH_CURVE`]: #tls_tls_default_ecdh_curve
[`tls.Server`]: #tls_class_tls_server
[`tls.TLSSocket.getPeerCertificate()`]: #tls_tlssocket_getpeercertificate_detailed
diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md
index 78f35412c32a65..05cafa9cb178e7 100644
--- a/doc/api/worker_threads.md
+++ b/doc/api/worker_threads.md
@@ -316,13 +316,16 @@ if (isMainThread) {
occur as described in the [HTML structured clone algorithm][], and an error
will be thrown if the object cannot be cloned (e.g. because it contains
`function`s).
- * stdin {boolean} If this is set to `true`, then `worker.stdin` will
+ * `stdin` {boolean} If this is set to `true`, then `worker.stdin` will
provide a writable stream whose contents will appear as `process.stdin`
inside the Worker. By default, no data is provided.
- * stdout {boolean} If this is set to `true`, then `worker.stdout` will
+ * `stdout` {boolean} If this is set to `true`, then `worker.stdout` will
not automatically be piped through to `process.stdout` in the parent.
- * stderr {boolean} If this is set to `true`, then `worker.stderr` will
+ * `stderr` {boolean} If this is set to `true`, then `worker.stderr` will
not automatically be piped through to `process.stderr` in the parent.
+ * `execArgv` {string[]} List of node CLI options passed to the worker.
+ V8 options (such as `--max-old-space-size`) and options that affect the
+ process (such as `--title`) are not supported.
### Event: 'error'
|