diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000000000..c29ea07ce66841
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,4 @@
+lib/punycode.js
+test/fixtures
+test/**/node_modules
+test/parallel/test-fs-non-number-arguments-throw.js
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 00000000000000..e023327fbb7d00
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,96 @@
+env:
+ node: true
+
+# enable ECMAScript features
+ecmaFeatures:
+ blockBindings: true
+ templateStrings: true
+ octalLiterals: true
+ binaryLiterals: true
+ generators: true
+ forOf: true
+
+rules:
+ # Possible Errors
+ # list: https://github.com/eslint/eslint/tree/master/docs/rules#possible-errors
+ ## check debugger sentence
+ no-debugger: 2
+ ## check duplicate arguments
+ no-dupe-args: 2
+ ## check duplicate object keys
+ no-dupe-keys: 2
+ ## check duplicate switch-case
+ no-duplicate-case: 2
+ ## disallow assignment of exceptional params
+ no-ex-assign: 2
+ ## disallow use of reserved words as keys like enum, class
+ no-reserved-keys: 2
+ ## disallow unreachable code
+ no-unreachable: 2
+ ## require valid typeof compared string like typeof foo === 'strnig'
+ valid-typeof: 2
+
+ # Best Practices
+ # list: https://github.com/eslint/eslint/tree/master/docs/rules#best-practices
+ ## require falls through comment on switch-case
+ no-fallthrough: 2
+
+ # Stylistic Issues
+ # list: https://github.com/eslint/eslint/tree/master/docs/rules#stylistic-issues
+ ## use single quote, we can use double quote when escape chars
+ quotes:
+ - 2
+ - "single"
+ - "avoid-escape"
+ ## 2 space indentation
+ indent:
+ - 2
+ - 2
+ ## add space after comma
+ ## set to 'warn' because of https://github.com/eslint/eslint/issues/2408
+ comma-spacing: 1
+ ## put semi-colon
+ semi: 2
+ ## require spaces operator like var sum = 1 + 1;
+ space-infix-ops: 2
+ ## require spaces return, throw, case
+ space-return-throw-case: 2
+ ## no space before function, eg. 'function()'
+ space-before-function-paren: [2, "never"]
+ ## require space before blocks, eg 'function() {'
+ space-before-blocks: [2, "always"]
+ ## require parens for Constructor
+ new-parens: 2
+ ## max 80 length
+ max-len:
+ - 2
+ - 80
+ - 2
+
+ # Strict Mode
+ # list: https://github.com/eslint/eslint/tree/master/docs/rules#strict-mode
+ ## 'use strict' on top
+ strict:
+ - 2
+ - "global"
+
+# Global scoped method and vars
+globals:
+ DTRACE_HTTP_CLIENT_REQUEST: true
+ LTTNG_HTTP_CLIENT_REQUEST: true
+ COUNTER_HTTP_CLIENT_REQUEST: true
+ DTRACE_HTTP_CLIENT_RESPONSE: true
+ LTTNG_HTTP_CLIENT_RESPONSE: true
+ COUNTER_HTTP_CLIENT_RESPONSE: true
+ DTRACE_HTTP_SERVER_REQUEST: true
+ LTTNG_HTTP_SERVER_REQUEST: true
+ COUNTER_HTTP_SERVER_REQUEST: true
+ DTRACE_HTTP_SERVER_RESPONSE: true
+ LTTNG_HTTP_SERVER_RESPONSE: true
+ COUNTER_HTTP_SERVER_RESPONSE: true
+ DTRACE_NET_STREAM_END: true
+ LTTNG_NET_STREAM_END: true
+ COUNTER_NET_SERVER_CONNECTION_CLOSE: true
+ DTRACE_NET_SERVER_CONNECTION: true
+ LTTNG_NET_SERVER_CONNECTION: true
+ COUNTER_NET_SERVER_CONNECTION: true
diff --git a/.gitignore b/.gitignore
index 19fb3840039160..ebb9a7bc56375c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,3 +76,7 @@ deps/zlib/zlib.target.mk
tools/faketime
icu_config.gypi
test.tap
+
+# Xcode workspaces and project folders
+*.xcodeproj
+*.xcworkspace
diff --git a/Makefile b/Makefile
index 8fc67d604e91b0..94f130f5fb3287 100644
--- a/Makefile
+++ b/Makefile
@@ -138,19 +138,7 @@ test-debugger: all
$(PYTHON) tools/test.py debugger
test-npm: $(NODE_EXE)
- rm -rf npm-cache npm-tmp npm-prefix
- mkdir npm-cache npm-tmp npm-prefix
- cd deps/npm ; npm_config_cache="$(shell pwd)/npm-cache" \
- npm_config_prefix="$(shell pwd)/npm-prefix" \
- npm_config_tmp="$(shell pwd)/npm-tmp" \
- ../../$(NODE_EXE) cli.js install --ignore-scripts
- cd deps/npm ; npm_config_cache="$(shell pwd)/npm-cache" \
- npm_config_prefix="$(shell pwd)/npm-prefix" \
- npm_config_tmp="$(shell pwd)/npm-tmp" \
- ../../$(NODE_EXE) cli.js run-script test-all && \
- ../../$(NODE_EXE) cli.js prune --prod && \
- cd ../.. && \
- rm -rf npm-cache npm-tmp npm-prefix
+ NODE_EXE=$(NODE_EXE) tools/test-npm.sh
test-npm-publish: $(NODE_EXE)
npm_package_config_publishtest=true ./$(NODE_EXE) deps/npm/test/run.js
@@ -386,11 +374,8 @@ bench-idle:
sleep 1
./$(NODE_EXE) benchmark/idle_clients.js &
-jslintfix:
- PYTHONPATH=tools/closure_linter/:tools/gflags/ $(PYTHON) tools/closure_linter/closure_linter/fixjsstyle.py --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
-
jslint:
- PYTHONPATH=tools/closure_linter/:tools/gflags/ $(PYTHON) tools/closure_linter/closure_linter/gjslint.py --unix_mode --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
+ ./$(NODE_EXE) tools/eslint/bin/eslint.js src lib test --reset --quiet
CPPLINT_EXCLUDE ?=
CPPLINT_EXCLUDE += src/node_lttng.cc
diff --git a/benchmark/misc/next-tick-breadth-args.js b/benchmark/misc/next-tick-breadth-args.js
new file mode 100644
index 00000000000000..e617fcfc824f7f
--- /dev/null
+++ b/benchmark/misc/next-tick-breadth-args.js
@@ -0,0 +1,37 @@
+'use strict';
+
+var common = require('../common.js');
+var bench = common.createBenchmark(main, {
+ millions: [2]
+});
+
+function main(conf) {
+ var N = +conf.millions * 1e6;
+ var n = 0;
+
+ function cb1(arg1) {
+ n++;
+ if (n === N)
+ bench.end(n / 1e6);
+ }
+ function cb2(arg1, arg2) {
+ n++;
+ if (n === N)
+ bench.end(n / 1e6);
+ }
+ function cb3(arg1, arg2, arg3) {
+ n++;
+ if (n === N)
+ bench.end(n / 1e6);
+ }
+
+ bench.start();
+ for (var i = 0; i < N; i++) {
+ if (i % 3 === 0)
+ process.nextTick(cb3, 512, true, null);
+ else if (i % 2 === 0)
+ process.nextTick(cb2, false, 5.1);
+ else
+ process.nextTick(cb1, 0);
+ }
+}
diff --git a/benchmark/misc/next-tick-depth-args.js b/benchmark/misc/next-tick-depth-args.js
new file mode 100644
index 00000000000000..066b4837856f60
--- /dev/null
+++ b/benchmark/misc/next-tick-depth-args.js
@@ -0,0 +1,48 @@
+'use strict';
+
+var common = require('../common.js');
+var bench = common.createBenchmark(main, {
+ millions: [2]
+});
+
+process.maxTickDepth = Infinity;
+
+function main(conf) {
+ var n = +conf.millions * 1e6;
+
+ function cb3(arg1, arg2, arg3) {
+ if (--n) {
+ if (n % 3 === 0)
+ process.nextTick(cb3, 512, true, null);
+ else if (n % 2 === 0)
+ process.nextTick(cb2, false, 5.1);
+ else
+ process.nextTick(cb1, 0);
+ } else
+ bench.end(+conf.millions);
+ }
+ function cb2(arg1, arg2) {
+ if (--n) {
+ if (n % 3 === 0)
+ process.nextTick(cb3, 512, true, null);
+ else if (n % 2 === 0)
+ process.nextTick(cb2, false, 5.1);
+ else
+ process.nextTick(cb1, 0);
+ } else
+ bench.end(+conf.millions);
+ }
+ function cb1(arg1) {
+ if (--n) {
+ if (n % 3 === 0)
+ process.nextTick(cb3, 512, true, null);
+ else if (n % 2 === 0)
+ process.nextTick(cb2, false, 5.1);
+ else
+ process.nextTick(cb1, 0);
+ } else
+ bench.end(+conf.millions);
+ }
+ bench.start();
+ process.nextTick(cb1, true);
+}
diff --git a/configure b/configure
index 8a19a5313cd67e..4a30973a3720ab 100755
--- a/configure
+++ b/configure
@@ -31,6 +31,16 @@ valid_arm_float_abi = ('soft', 'softfp', 'hard')
valid_mips_arch = ('loongson', 'r1', 'r2', 'r6', 'rx')
valid_mips_fpu = ('fp32', 'fp64', 'fpxx')
valid_mips_float_abi = ('soft', 'hard')
+valid_intl_modes = ('none', 'small-icu', 'full-icu', 'system-icu')
+
+# create option groups
+shared_optgroup = optparse.OptionGroup(parser, "Shared libraries",
+ "Flags that allows you to control whether you want to build against "
+ "built-in dependencies or its shared representations. If necessary, "
+ "provide multiple libraries with comma.")
+intl_optgroup = optparse.OptionGroup(parser, "Internationalization",
+ "Flags that lets you enable i18n features in io.js as well as which "
+ "library you want to build against.")
# Options should be in alphabetical order but keep --prefix at the top,
# that's arguably the one people will be looking for most.
@@ -78,90 +88,92 @@ parser.add_option("--openssl-no-asm",
dest="openssl_no_asm",
help="Do not build optimized assembly for OpenSSL")
-parser.add_option('--shared-http-parser',
+shared_optgroup.add_option('--shared-http-parser',
action='store_true',
dest='shared_http_parser',
help='link to a shared http_parser DLL instead of static linking')
-parser.add_option('--shared-http-parser-includes',
+shared_optgroup.add_option('--shared-http-parser-includes',
action='store',
dest='shared_http_parser_includes',
help='directory containing http_parser header files')
-parser.add_option('--shared-http-parser-libname',
+shared_optgroup.add_option('--shared-http-parser-libname',
action='store',
dest='shared_http_parser_libname',
default='http_parser',
help='alternative lib name to link to [default: %default]')
-parser.add_option('--shared-http-parser-libpath',
+shared_optgroup.add_option('--shared-http-parser-libpath',
action='store',
dest='shared_http_parser_libpath',
help='a directory to search for the shared http_parser DLL')
-parser.add_option('--shared-libuv',
+shared_optgroup.add_option('--shared-libuv',
action='store_true',
dest='shared_libuv',
help='link to a shared libuv DLL instead of static linking')
-parser.add_option('--shared-libuv-includes',
+shared_optgroup.add_option('--shared-libuv-includes',
action='store',
dest='shared_libuv_includes',
help='directory containing libuv header files')
-parser.add_option('--shared-libuv-libname',
+shared_optgroup.add_option('--shared-libuv-libname',
action='store',
dest='shared_libuv_libname',
default='uv',
help='alternative lib name to link to [default: %default]')
-parser.add_option('--shared-libuv-libpath',
+shared_optgroup.add_option('--shared-libuv-libpath',
action='store',
dest='shared_libuv_libpath',
help='a directory to search for the shared libuv DLL')
-parser.add_option('--shared-openssl',
+shared_optgroup.add_option('--shared-openssl',
action='store_true',
dest='shared_openssl',
help='link to a shared OpenSSl DLL instead of static linking')
-parser.add_option('--shared-openssl-includes',
+shared_optgroup.add_option('--shared-openssl-includes',
action='store',
dest='shared_openssl_includes',
help='directory containing OpenSSL header files')
-parser.add_option('--shared-openssl-libname',
+shared_optgroup.add_option('--shared-openssl-libname',
action='store',
dest='shared_openssl_libname',
default='crypto,ssl',
help='alternative lib name to link to [default: %default]')
-parser.add_option('--shared-openssl-libpath',
+shared_optgroup.add_option('--shared-openssl-libpath',
action='store',
dest='shared_openssl_libpath',
help='a directory to search for the shared OpenSSL DLLs')
-parser.add_option('--shared-zlib',
+shared_optgroup.add_option('--shared-zlib',
action='store_true',
dest='shared_zlib',
help='link to a shared zlib DLL instead of static linking')
-parser.add_option('--shared-zlib-includes',
+shared_optgroup.add_option('--shared-zlib-includes',
action='store',
dest='shared_zlib_includes',
help='directory containing zlib header files')
-parser.add_option('--shared-zlib-libname',
+shared_optgroup.add_option('--shared-zlib-libname',
action='store',
dest='shared_zlib_libname',
default='z',
help='alternative lib name to link to [default: %default]')
-parser.add_option('--shared-zlib-libpath',
+shared_optgroup.add_option('--shared-zlib-libpath',
action='store',
dest='shared_zlib_libpath',
help='a directory to search for the shared zlib DLL')
+parser.add_option_group(shared_optgroup)
+
# TODO document when we've decided on what the tracing API and its options will
# look like
parser.add_option('--systemtap-includes',
@@ -225,33 +237,38 @@ parser.add_option('--with-etw',
dest='with_etw',
help='build with ETW (default is true on Windows)')
-parser.add_option('--download',
+intl_optgroup.add_option('--with-intl',
action='store',
- dest='download_list',
- help=nodedownload.help())
+ dest='with_intl',
+ default='none',
+ choices=valid_intl_modes,
+ help='Intl mode (valid choices: {0}) [default: %default]'.format(
+ ', '.join(valid_intl_modes)))
-parser.add_option('--with-icu-path',
+intl_optgroup.add_option('--with-icu-path',
action='store',
dest='with_icu_path',
help='Path to icu.gyp (ICU i18n, Chromium version only.)')
-parser.add_option('--with-icu-locales',
+intl_optgroup.add_option('--with-icu-locales',
action='store',
dest='with_icu_locales',
default='root,en',
help='Comma-separated list of locales for "small-icu". "root" is assumed. '
'[default: %default]')
-parser.add_option('--with-intl',
- action='store',
- dest='with_intl',
- help='Intl mode: none, full-icu, small-icu [default: none]')
-
-parser.add_option('--with-icu-source',
+intl_optgroup.add_option('--with-icu-source',
action='store',
dest='with_icu_source',
help='Intl mode: optional local path to icu/ dir, or path/URL of icu source archive.')
+intl_optgroup.add_option('--download',
+ action='store',
+ dest='download_list',
+ help=nodedownload.help())
+
+parser.add_option_group(intl_optgroup)
+
parser.add_option('--with-perfctr',
action='store_true',
dest='with_perfctr',
@@ -277,15 +294,15 @@ parser.add_option('--without-perfctr',
dest='without_perfctr',
help='build without performance counters')
+# Dummy option for backwards compatibility
parser.add_option('--with-snapshot',
action='store_true',
- dest='with_snapshot',
+ dest='unused_with_snapshot',
help=optparse.SUPPRESS_HELP)
-# Dummy option for backwards compatibility.
parser.add_option('--without-snapshot',
action='store_true',
- dest='unused_without_snapshot',
+ dest='without_snapshot',
help=optparse.SUPPRESS_HELP)
parser.add_option('--without-ssl',
@@ -326,17 +343,28 @@ def b(value):
def pkg_config(pkg):
- cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
- libs = cmd.readline().strip()
- ret = cmd.close()
- if (ret): return None
-
- cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
- cflags = cmd.readline().strip()
- ret = cmd.close()
- if (ret): return None
-
- return (libs, cflags)
+ pkg_config = os.environ.get('PKG_CONFIG', 'pkg-config')
+ args = '--silence-errors'
+ retval = ()
+ for flag in ['--libs-only-l', '--cflags-only-I', '--libs-only-L']:
+ try:
+ val = subprocess.check_output([pkg_config, args, flag, pkg])
+ # check_output returns bytes
+ val = val.encode().strip().rstrip('\n')
+ except subprocess.CalledProcessError:
+ # most likely missing a .pc-file
+ val = None
+ except OSError:
+ # no pkg-config/pkgconf installed
+ return (None, None, None)
+ retval += (val,)
+ return retval
+
+
+def format_libraries(list):
+ """Returns string of space separated libraries"""
+ libraries = list.split(',')
+ return ' '.join('-l{0}'.format(i) for i in libraries)
def try_check_compiler(cc, lang):
@@ -562,10 +590,6 @@ def configure_arm(o):
o['variables']['arm_fpu'] = 'vfpv3'
o['variables']['arm_version'] = '7'
- # Print warning when snapshot is enabled and building on armv6
- if is_arch_armv6() and options.with_snapshot:
- warn('when building on ARMv6, don\'t use --with-snapshot')
-
def configure_mips(o):
can_use_fpu_instructions = (options.mips_float_abi != 'soft')
@@ -587,10 +611,10 @@ def configure_node(o):
o['variables']['host_arch'] = host_arch
o['variables']['target_arch'] = target_arch
- if target_arch != host_arch and options.with_snapshot:
- o['variables']['want_separate_host_toolset'] = 1
- else:
- o['variables']['want_separate_host_toolset'] = 0
+ cross_compiling = target_arch != host_arch
+ want_snapshots = not options.without_snapshot
+ o['variables']['want_separate_host_toolset'] = int(
+ cross_compiling and want_snapshots)
if target_arch == 'arm':
configure_arm(o)
@@ -655,40 +679,30 @@ def configure_node(o):
o['variables']['node_target_type'] = 'static_library'
-def configure_libz(o):
- o['variables']['node_shared_zlib'] = b(options.shared_zlib)
-
- if options.shared_zlib:
- o['libraries'] += ['-l%s' % options.shared_zlib_libname]
- if options.shared_zlib_libpath:
- o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
- if options.shared_zlib_includes:
- o['include_dirs'] += [options.shared_zlib_includes]
-
-
-def configure_http_parser(o):
- o['variables']['node_shared_http_parser'] = b(options.shared_http_parser)
-
- if options.shared_http_parser:
- o['libraries'] += ['-l%s' % options.shared_http_parser_libname]
- if options.shared_http_parser_libpath:
- o['libraries'] += ['-L%s' % options.shared_http_parser_libpath]
- if options.shared_http_parser_includes:
- o['include_dirs'] += [options.shared_http_parser_includes]
-
-
-def configure_libuv(o):
- o['variables']['node_shared_libuv'] = b(options.shared_libuv)
-
- if options.shared_libuv:
- o['libraries'] += ['-l%s' % options.shared_libuv_libname]
- if options.shared_libuv_libpath:
- o['libraries'] += ['-L%s' % options.shared_libuv_libpath]
- else:
- o['variables']['uv_library'] = 'static_library'
-
- if options.shared_libuv_includes:
- o['include_dirs'] += [options.shared_libuv_includes]
+def configure_library(lib, output):
+ shared_lib = 'shared_' + lib
+ output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib))
+
+ if getattr(options, shared_lib):
+ default_cflags = getattr(options, shared_lib + '_includes')
+ default_lib = format_libraries(getattr(options, shared_lib + '_libname'))
+ default_libpath = getattr(options, shared_lib + '_libpath')
+ if default_libpath:
+ default_libpath = '-L' + default_libpath
+ (pkg_libs, pkg_cflags, pkg_libpath) = pkg_config(lib)
+ cflags = pkg_cflags.split('-I') if pkg_cflags else default_cflags
+ libs = pkg_libs if pkg_libs else default_lib
+ libpath = pkg_libpath if pkg_libpath else default_libpath
+
+ # libpath needs to be provided ahead libraries
+ if libpath:
+ output['libraries'] += [libpath]
+ if libs:
+ # libs passed to the linker cannot contain spaces.
+ # (libpath on the other hand can)
+ output['libraries'] += libs.split()
+ if cflags:
+ output['include_dirs'] += [cflags]
def configure_v8(o):
@@ -696,30 +710,16 @@ def configure_v8(o):
o['variables']['v8_no_strict_aliasing'] = 1 # Work around compiler bugs.
o['variables']['v8_optimized_debug'] = 0 # Compile with -O0 in debug builds.
o['variables']['v8_random_seed'] = 0 # Use a random seed for hash tables.
- o['variables']['v8_use_snapshot'] = b(options.with_snapshot)
+ o['variables']['v8_use_snapshot'] = 0 if options.without_snapshot else 1
def configure_openssl(o):
o['variables']['node_use_openssl'] = b(not options.without_ssl)
o['variables']['node_shared_openssl'] = b(options.shared_openssl)
- o['variables']['openssl_no_asm'] = (
- 1 if options.openssl_no_asm else 0)
+ o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0
if options.without_ssl:
return
-
- if options.shared_openssl:
- (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
-
- libnames = options.shared_openssl_libname.split(',')
- o['libraries'] += ['-l%s' % s for s in libnames]
-
- if options.shared_openssl_libpath:
- o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
-
- if options.shared_openssl_includes:
- o['include_dirs'] += [options.shared_openssl_includes]
- else:
- o['cflags'] += cflags.split()
+ configure_library('openssl', o)
def configure_fullystatic(o):
@@ -812,7 +812,7 @@ def configure_intl(o):
with_intl = options.with_intl
with_icu_source = options.with_icu_source
have_icu_path = bool(options.with_icu_path)
- if have_icu_path and with_intl:
+ if have_icu_path and with_intl != 'none':
print 'Error: Cannot specify both --with-icu-path and --with-intl'
sys.exit(1)
elif have_icu_path:
@@ -840,21 +840,19 @@ def configure_intl(o):
# ICU from pkg-config.
o['variables']['v8_enable_i18n_support'] = 1
pkgicu = pkg_config('icu-i18n')
- if not pkgicu:
+ if pkgicu[0] is None:
print 'Error: could not load pkg-config data for "icu-i18n".'
print 'See above errors or the README.md.'
sys.exit(1)
- (libs, cflags) = pkgicu
+ (libs, cflags, libpath) = pkgicu
+ # libpath provides linker path which may contain spaces
+ o['libraries'] += [libpath]
+ # safe to split, cannot contain spaces
o['libraries'] += libs.split()
o['cflags'] += cflags.split()
# use the "system" .gyp
o['variables']['icu_gyp_path'] = 'tools/icu/icu-system.gyp'
return
- else:
- print 'Error: unknown value --with-intl=%s' % with_intl
- sys.exit(1)
- # Note: non-ICU implementations could use other 'with_intl'
- # values.
# this is just the 'deps' dir. Used for unpacking.
icu_parent_path = os.path.join(root_dir, 'deps')
@@ -1008,9 +1006,9 @@ if (options.dest_os):
flavor = GetFlavor(flavor_params)
configure_node(output)
-configure_libz(output)
-configure_http_parser(output)
-configure_libuv(output)
+configure_library('zlib', output)
+configure_library('http_parser', output)
+configure_library('libuv', output)
configure_v8(output)
configure_openssl(output)
configure_winsdk(output)
diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp
index dfa35a25ef5e56..8fd8662e1bdf6f 100644
--- a/deps/cares/cares.gyp
+++ b/deps/cares/cares.gyp
@@ -26,7 +26,6 @@
'direct_dependent_settings': {
'include_dirs': [ 'include' ]
},
- 'defines': [ 'HAVE_CONFIG_H' ],
'sources': [
'common.gypi',
'include/ares.h',
@@ -96,7 +95,6 @@
'src/inet_ntop.c',
'src/ares_inet_net_pton.h',
'src/setup_once.h',
- 'src/windows_port.c'
],
'conditions': [
[ 'library=="static_library"', {
@@ -107,7 +105,7 @@
[ 'OS=="win"', {
'include_dirs': [ 'config/win32' ],
'sources': [
- 'config/win32/ares_config.h',
+ 'src/config-win32.h',
'src/windows_port.c',
'src/ares_getenv.c',
'src/ares_iphlpapi.h',
@@ -126,6 +124,7 @@
'-Wextra',
'-Wno-unused-parameter'
],
+ 'defines': [ 'HAVE_CONFIG_H' ],
}],
[ 'OS not in "win android"', {
'cflags': [
diff --git a/deps/cares/config/win32/ares_config.h b/deps/cares/config/win32/ares_config.h
deleted file mode 100644
index 6ded638093f8f7..00000000000000
--- a/deps/cares/config/win32/ares_config.h
+++ /dev/null
@@ -1,369 +0,0 @@
-#ifndef __ARES_CONFIG_WIN32_H
-#define __ARES_CONFIG_WIN32_H
-
-/* when building c-ares library */
-#define CARES_BUILDING_LIBRARY 1
-
-/* Copyright (C) 2004 - 2008 by Daniel Stenberg et al
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#define ARES_
-
-/* ================================================================ */
-/* ares/config-win32.h - Hand crafted config file for Windows */
-/* ================================================================ */
-
-/* ---------------------------------------------------------------- */
-/* HEADER FILES */
-/* ---------------------------------------------------------------- */
-
-/* Define if you have the header file. */
-#if defined(__MINGW32__) || defined(__POCC__)
-#define HAVE_GETOPT_H 1
-#endif
-
-/* Define if you have the header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define if you have the header file. */
-#ifndef __SALFORDC__
-#define HAVE_PROCESS_H 1
-#endif
-
-/* Define if you have the header file. */
-#define HAVE_SIGNAL_H 1
-
-/* Define if you have the header file */
-#if defined(__MINGW32__)
-#define HAVE_SYS_TIME_H 1
-#endif
-
-/* Define if you have the header file. */
-#define HAVE_TIME_H 1
-
-/* Define if you have the header file. */
-#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
- defined(__POCC__)
-#define HAVE_UNISTD_H 1
-#endif
-
-/* Define if you have the windows.h header file. */
-#define HAVE_WINDOWS_H 1
-
-/* Define if you have the header file. */
-#define HAVE_WINSOCK_H 1
-
-/* Define if you have the header file. */
-#ifndef __SALFORDC__
-#define HAVE_WINSOCK2_H 1
-#endif
-
-/* Define if you have the header file. */
-#ifndef __SALFORDC__
-#define HAVE_WS2TCPIP_H 1
-#endif
-
-/* ---------------------------------------------------------------- */
-/* OTHER HEADER INFO */
-/* ---------------------------------------------------------------- */
-
-/* Define if sig_atomic_t is an available typedef. */
-#define HAVE_SIG_ATOMIC_T 1
-
-/* Define if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if you can safely include both and . */
-/* #define TIME_WITH_SYS_TIME 1 */
-
-/* ---------------------------------------------------------------- */
-/* FUNCTIONS */
-/* ---------------------------------------------------------------- */
-
-/* Define if you have the closesocket function. */
-#define HAVE_CLOSESOCKET 1
-
-/* Define if you have the gethostname function. */
-#define HAVE_GETHOSTNAME 1
-
-/* Define if you have the ioctlsocket function. */
-#define HAVE_IOCTLSOCKET 1
-
-/* Define if you have a working ioctlsocket FIONBIO function. */
-#define HAVE_IOCTLSOCKET_FIONBIO 1
-
-/* Define if you have the strcasecmp function. */
-/* #define HAVE_STRCASECMP 1 */
-
-/* Define if you have the getenv function. */
-#define HAVE_GETENV 1
-
-/* Define if you have the strdup function. */
-#define HAVE_STRDUP 1
-
-/* Define if you have the stricmp function. */
-#define HAVE_STRICMP 1
-
-/* Define if you have the strncasecmp function. */
-/* #define HAVE_STRNCASECMP 1 */
-
-/* Define if you have the strnicmp function. */
-#define HAVE_STRNICMP 1
-
-/* Define if you have the recv function. */
-#define HAVE_RECV 1
-
-/* Define to the type of arg 1 for recv. */
-#define RECV_TYPE_ARG1 SOCKET
-
-/* Define to the type of arg 2 for recv. */
-#define RECV_TYPE_ARG2 char *
-
-/* Define to the type of arg 3 for recv. */
-#define RECV_TYPE_ARG3 int
-
-/* Define to the type of arg 4 for recv. */
-#define RECV_TYPE_ARG4 int
-
-/* Define to the function return type for recv. */
-#define RECV_TYPE_RETV int
-
-/* Define if you have the recvfrom function. */
-#define HAVE_RECVFROM 1
-
-/* Define to the type of arg 1 for recvfrom. */
-#define RECVFROM_TYPE_ARG1 SOCKET
-
-/* Define to the type pointed by arg 2 for recvfrom. */
-#define RECVFROM_TYPE_ARG2 char
-
-/* Define to the type of arg 3 for recvfrom. */
-#define RECVFROM_TYPE_ARG3 int
-
-/* Define to the type of arg 4 for recvfrom. */
-#define RECVFROM_TYPE_ARG4 int
-
-/* Define to the type pointed by arg 5 for recvfrom. */
-#define RECVFROM_TYPE_ARG5 struct sockaddr
-
-/* Define to the type pointed by arg 6 for recvfrom. */
-#define RECVFROM_TYPE_ARG6 int
-
-/* Define to the function return type for recvfrom. */
-#define RECVFROM_TYPE_RETV int
-
-/* Define if you have the send function. */
-#define HAVE_SEND 1
-
-/* Define to the type of arg 1 for send. */
-#define SEND_TYPE_ARG1 SOCKET
-
-/* Define to the type qualifier of arg 2 for send. */
-#define SEND_QUAL_ARG2 const
-
-/* Define to the type of arg 2 for send. */
-#define SEND_TYPE_ARG2 char *
-
-/* Define to the type of arg 3 for send. */
-#define SEND_TYPE_ARG3 int
-
-/* Define to the type of arg 4 for send. */
-#define SEND_TYPE_ARG4 int
-
-/* Define to the function return type for send. */
-#define SEND_TYPE_RETV int
-
-/* Specifics for the Watt-32 tcp/ip stack */
-#ifdef WATT32
- #define SOCKET int
- #define NS_INADDRSZ 4
- #define HAVE_ARPA_NAMESER_H 1
- #define HAVE_ARPA_INET_H 1
- #define HAVE_NETDB_H 1
- #define HAVE_NETINET_IN_H 1
- #define HAVE_SYS_SOCKET_H 1
- #define HAVE_NETINET_TCP_H 1
- #define HAVE_AF_INET6 1
- #define HAVE_PF_INET6 1
- #define HAVE_STRUCT_IN6_ADDR 1
- #define HAVE_STRUCT_SOCKADDR_IN6 1
- #undef HAVE_WINSOCK_H
- #undef HAVE_WINSOCK2_H
- #undef HAVE_WS2TCPIP_H
-#endif
-
-/* ---------------------------------------------------------------- */
-/* TYPEDEF REPLACEMENTS */
-/* ---------------------------------------------------------------- */
-
-/* Define this if in_addr_t is not an available 'typedefed' type */
-#define in_addr_t unsigned long
-
-/* Define as the return type of signal handlers (int or void). */
-#define RETSIGTYPE void
-
-/* Define ssize_t if it is not an available 'typedefed' type */
-#ifndef _SSIZE_T_DEFINED
-# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
- defined(__POCC__) || \
- defined(__MINGW32__)
-# elif defined(_WIN64)
-# define _SSIZE_T_DEFINED
-# define ssize_t __int64
-# else
-# define _SSIZE_T_DEFINED
-# define ssize_t int
-# endif
-#endif
-
-/* ---------------------------------------------------------------- */
-/* TYPE SIZES */
-/* ---------------------------------------------------------------- */
-
-/* The size of `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of `short', as computed by sizeof. */
-#define SIZEOF_SHORT 2
-
-/* The size of `size_t', as computed by sizeof. */
-#if defined(_WIN64)
-# define SIZEOF_SIZE_T 8
-#else
-# define SIZEOF_SIZE_T 4
-#endif
-
-/* ---------------------------------------------------------------- */
-/* STRUCT RELATED */
-/* ---------------------------------------------------------------- */
-
-/* Define this if you have struct addrinfo */
-#define HAVE_STRUCT_ADDRINFO 1
-
-/* Define this if you have struct sockaddr_storage */
-#ifndef __SALFORDC__
-#define HAVE_STRUCT_SOCKADDR_STORAGE 1
-#endif
-
-/* Define this if you have struct timeval */
-#define HAVE_STRUCT_TIMEVAL 1
-
-/* ---------------------------------------------------------------- */
-/* COMPILER SPECIFIC */
-/* ---------------------------------------------------------------- */
-
-/* Define to avoid VS2005 complaining about portable C functions */
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define _CRT_SECURE_NO_DEPRECATE 1
-#define _CRT_NONSTDC_NO_DEPRECATE 1
-#endif
-
-/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows
- 2000 as a supported build target. VS2008 default installations provide an
- embedded Windows SDK v6.0A along with the claim that Windows 2000 is a
- valid build target for VS2008. Popular belief is that binaries built using
- Windows SDK versions 6.X and Windows 2000 as a build target are functional */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500)
-# define VS2008_MINIMUM_TARGET 0x0500
-#endif
-
-/* When no build target is specified VS2008 default build target is Windows
- Vista, which leaves out even Winsows XP. If no build target has been given
- for VS2008 we will target the minimum Officially supported build target,
- which happens to be Windows XP. */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500)
-# define VS2008_DEFAULT_TARGET 0x0501
-#endif
-
-/* VS2008 default target settings and minimum build target check */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500)
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT VS2008_DEFAULT_TARGET
-# endif
-# ifndef WINVER
-# define WINVER VS2008_DEFAULT_TARGET
-# endif
-# if (_WIN32_WINNT < VS2008_MINIMUM_TARGET) || (WINVER < VS2008_MINIMUM_TARGET)
-# error VS2008 does not support Windows build targets prior to Windows 2000
-# endif
-#endif
-
-/* When no build target is specified Pelles C 5.00 and later default build
- target is Windows Vista. We override default target to be Windows 2000. */
-#if defined(__POCC__) && (__POCC__ >= 500)
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0500
-# endif
-# ifndef WINVER
-# define WINVER 0x0500
-# endif
-#endif
-
-/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is
- quite convoluted, compiler dependent and even build target dependent. */
-#if defined(HAVE_WS2TCPIP_H)
-# if defined(__POCC__)
-# define HAVE_FREEADDRINFO 1
-# define HAVE_GETADDRINFO 1
-# define HAVE_GETNAMEINFO 1
-# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
-# define HAVE_FREEADDRINFO 1
-# define HAVE_GETADDRINFO 1
-# define HAVE_GETNAMEINFO 1
-# elif defined(_MSC_VER) && (_MSC_VER >= 1200)
-# define HAVE_FREEADDRINFO 1
-# define HAVE_GETADDRINFO 1
-# define HAVE_GETNAMEINFO 1
-# endif
-#endif
-
-#if defined(__POCC__)
-# ifndef _MSC_VER
-# error Microsoft extensions /Ze compiler option is required
-# endif
-# ifndef __POCC__OLDNAMES
-# error Compatibility names /Go compiler option is required
-# endif
-#endif
-
-/* ---------------------------------------------------------------- */
-/* IPV6 COMPATIBILITY */
-/* ---------------------------------------------------------------- */
-
-/* Define this if you have address family AF_INET6 */
-#ifdef HAVE_WINSOCK2_H
-#define HAVE_AF_INET6 1
-#endif
-
-/* Define this if you have protocol family PF_INET6 */
-#ifdef HAVE_WINSOCK2_H
-#define HAVE_PF_INET6 1
-#endif
-
-/* Define this if you have struct in6_addr */
-#ifdef HAVE_WS2TCPIP_H
-#define HAVE_STRUCT_IN6_ADDR 1
-#endif
-
-/* Define this if you have struct sockaddr_in6 */
-#ifdef HAVE_WS2TCPIP_H
-#define HAVE_STRUCT_SOCKADDR_IN6 1
-#endif
-
-/* Define this if you have sockaddr_in6 with scopeid */
-#ifdef HAVE_WS2TCPIP_H
-#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
-#endif
-
-
-#endif /* __ARES_CONFIG_WIN32_H */
diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h
index 3091064b5113b4..f9abe854d5846a 100644
--- a/deps/cares/include/ares.h
+++ b/deps/cares/include/ares.h
@@ -29,55 +29,8 @@
# define WIN32
#endif
-/*************************** libuv patch ***************/
-
-/*
- * We want to avoid autoconf altogether since there are a finite number of
- * operating systems and simply build c-ares. Therefore we do not want the
- * configurations provided by ares_build.h since we are always statically
- * linking c-ares into libuv. Having a system dependent ares_build.h forces
- * all users of ares.h to include the correct ares_build.h. We do not care
- * about the linking checks provided by ares_rules.h. This would complicate
- * the libuv build process.
- */
-
-
-#if defined(WIN32)
-/* Configure process defines this to 1 when it finds out that system */
-/* header file ws2tcpip.h must be included by the external interface. */
-/* #undef CARES_PULL_WS2TCPIP_H */
-# include
-# include
-# include
-
-#else /* Not Windows */
-
-# include
-# include
-# include
-#endif
-
-#if 0
-/* The size of `long', as computed by sizeof. */
-#define CARES_SIZEOF_LONG 4
-#endif
-
-/* Integral data type used for ares_socklen_t. */
-#define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
-
-#if 0
-/* The size of `ares_socklen_t', as computed by sizeof. */
-#define CARES_SIZEOF_ARES_SOCKLEN_T 4
-#endif
-
/* Data type definition of ares_socklen_t. */
-typedef int ares_socklen_t;
-
-#if 0 /* libuv disabled */
-#include "ares_rules.h" /* c-ares rules enforcement */
-#endif
-
-/*********************** end libuv patch ***************/
+typedef unsigned ares_socklen_t;
#include
diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h
index cdd49924cc4b80..2c9146d7d954a6 100644
--- a/deps/cares/include/ares_version.h
+++ b/deps/cares/include/ares_version.h
@@ -7,11 +7,11 @@
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 10
-#define ARES_VERSION_PATCH 0
+#define ARES_VERSION_PATCH 1
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
-#define ARES_VERSION_STR "1.10.0-DEV"
+#define ARES_VERSION_STR "1.10.1-DEV"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1
diff --git a/deps/cares/src/ares__read_line.c b/deps/cares/src/ares__read_line.c
index bd9504fc4f0be0..6ebd42fe6efb34 100644
--- a/deps/cares/src/ares__read_line.c
+++ b/deps/cares/src/ares__read_line.c
@@ -61,7 +61,10 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize)
/* Allocate more space. */
newbuf = realloc(*buf, *bufsize * 2);
if (!newbuf)
- return ARES_ENOMEM;
+ {
+ free(*buf);
+ return ARES_ENOMEM;
+ }
*buf = newbuf;
*bufsize *= 2;
}
diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/ares_gethostbyname.c
index 2b27b2e1048fcc..ba6b0f0f0c5661 100644
--- a/deps/cares/src/ares_gethostbyname.c
+++ b/deps/cares/src/ares_gethostbyname.c
@@ -188,8 +188,9 @@ static void host_callback(void *arg, int status, int timeouts,
else if (hquery->sent_family == AF_INET6)
{
status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
- if ((status == ARES_ENODATA || status == ARES_EBADRESP) &&
- hquery->want_family == AF_UNSPEC) {
+ if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
+ (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)) &&
+ hquery->want_family == AF_UNSPEC) {
/* The query returned something but either there were no AAAA
records (e.g. just CNAME) or the response was malformed. Try
looking up A instead. */
diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/ares_getnameinfo.c
index 5b9f6386b29e01..b0bc6da868cdda 100644
--- a/deps/cares/src/ares_getnameinfo.c
+++ b/deps/cares/src/ares_getnameinfo.c
@@ -281,6 +281,8 @@ static char *lookup_service(unsigned short port, int flags,
struct servent se;
#endif
char tmpbuf[4096];
+ char *name;
+ size_t name_len;
if (port)
{
@@ -323,14 +325,20 @@ static char *lookup_service(unsigned short port, int flags,
#endif
}
if (sep && sep->s_name)
- /* get service name */
- strcpy(tmpbuf, sep->s_name);
+ {
+ /* get service name */
+ name = sep->s_name;
+ }
else
- /* get port as a string */
- sprintf(tmpbuf, "%u", (unsigned int)ntohs(port));
- if (strlen(tmpbuf) < buflen)
+ {
+ /* get port as a string */
+ sprintf(tmpbuf, "%u", (unsigned int)ntohs(port));
+ name = tmpbuf;
+ }
+ name_len = strlen(name);
+ if (name_len < buflen)
/* return it if buffer big enough */
- strcpy(buf, tmpbuf);
+ memcpy(buf, name, name_len + 1);
else
/* avoid reusing previous one */
buf[0] = '\0';
diff --git a/deps/cares/src/ares_getsock.c b/deps/cares/src/ares_getsock.c
index 07d2854cfd1538..22d344679faa60 100644
--- a/deps/cares/src/ares_getsock.c
+++ b/deps/cares/src/ares_getsock.c
@@ -30,9 +30,7 @@ int ares_getsock(ares_channel channel,
/* Are there any active queries? */
int active_queries = !ares__is_list_empty(&(channel->all_queries));
- for (i = 0;
- (i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
- i++)
+ for (i = 0; i < channel->nservers; i++)
{
server = &channel->servers[i];
/* We only need to register interest in UDP sockets if we have
@@ -40,7 +38,7 @@ int ares_getsock(ares_channel channel,
*/
if (active_queries && server->udp_socket != ARES_SOCKET_BAD)
{
- if(sockindex >= numsocks)
+ if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM)
break;
socks[sockindex] = server->udp_socket;
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
@@ -52,7 +50,7 @@ int ares_getsock(ares_channel channel,
*/
if (server->tcp_socket != ARES_SOCKET_BAD)
{
- if(sockindex >= numsocks)
+ if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM)
break;
socks[sockindex] = server->tcp_socket;
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c
index 05bf70c3b6d80f..bd3336e5d63e46 100644
--- a/deps/cares/src/ares_init.c
+++ b/deps/cares/src/ares_init.c
@@ -266,7 +266,10 @@ int ares_dup(ares_channel *dest, ares_channel src)
which is most of them */
rc = ares_save_options(src, &opts, &optmask);
if(rc)
+ {
+ ares_destroy_options(&opts);
return rc;
+ }
/* Then create the new channel with those options */
rc = ares_init_options(dest, &opts, optmask);
@@ -1158,20 +1161,24 @@ static int init_by_resolv_conf(ares_channel channel)
FILE *fp;
size_t linesize;
int error;
+ int update_domains;
/* Don't read resolv.conf and friends if we don't have to */
if (ARES_CONFIG_CHECK(channel))
return ARES_SUCCESS;
+ /* Only update search domains if they're not already specified */
+ update_domains = (channel->ndomains == -1);
+
fp = fopen(PATH_RESOLV_CONF, "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
- if ((p = try_config(line, "domain", ';')))
+ if ((p = try_config(line, "domain", ';')) && update_domains)
status = config_domain(channel, p);
else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
status = config_lookup(channel, p, "bind", "file");
- else if ((p = try_config(line, "search", ';')))
+ else if ((p = try_config(line, "search", ';')) && update_domains)
status = set_search(channel, p);
else if ((p = try_config(line, "nameserver", ';')) &&
channel->nservers == -1)
@@ -1410,7 +1417,7 @@ static int init_by_defaults(ares_channel channel)
goto error;
}
- } WHILE_FALSE;
+ } while (res != 0);
dot = strchr(hostname, '.');
if (dot) {
diff --git a/deps/cares/src/ares_ipv6.h b/deps/cares/src/ares_ipv6.h
index 6f1022a76f5338..1830076a81092a 100644
--- a/deps/cares/src/ares_ipv6.h
+++ b/deps/cares/src/ares_ipv6.h
@@ -71,7 +71,7 @@ struct addrinfo
#endif
#endif
-/* Defined in ares_net_pton.c for no particular reason. */
+/* Defined in inet_net_pton.c for no particular reason. */
extern const struct ares_in6_addr ares_in6addr_any; /* :: */
diff --git a/deps/cares/src/ares_nowarn.c b/deps/cares/src/ares_nowarn.c
index 397e70b01844a1..d4bd272c6d9e8c 100644
--- a/deps/cares/src/ares_nowarn.c
+++ b/deps/cares/src/ares_nowarn.c
@@ -1,5 +1,5 @@
-/* Copyright (C) 2010-2012 by Daniel Stenberg
+/* Copyright (C) 2010-2013 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@@ -21,6 +21,10 @@
# include
#endif
+#ifdef HAVE_LIMITS_H
+#include
+#endif
+
#if defined(__INTEL_COMPILER) && defined(__unix__)
#ifdef HAVE_NETINET_IN_H
@@ -36,13 +40,43 @@
#include "ares_nowarn.h"
-#define CARES_MASK_USHORT (~(unsigned short) 0)
-#define CARES_MASK_UINT (~(unsigned int) 0)
-#define CARES_MASK_ULONG (~(unsigned long) 0)
+#if (SIZEOF_SHORT == 2)
+# define CARES_MASK_SSHORT 0x7FFF
+# define CARES_MASK_USHORT 0xFFFF
+#elif (SIZEOF_SHORT == 4)
+# define CARES_MASK_SSHORT 0x7FFFFFFF
+# define CARES_MASK_USHORT 0xFFFFFFFF
+#elif (SIZEOF_SHORT == 8)
+# define CARES_MASK_SSHORT 0x7FFFFFFFFFFFFFFF
+# define CARES_MASK_USHORT 0xFFFFFFFFFFFFFFFF
+#else
+# error "SIZEOF_SHORT not defined"
+#endif
-#define CARES_MASK_SSHORT (CARES_MASK_USHORT >> 1)
-#define CARES_MASK_SINT (CARES_MASK_UINT >> 1)
-#define CARES_MASK_SLONG (CARES_MASK_ULONG >> 1)
+#if (SIZEOF_INT == 2)
+# define CARES_MASK_SINT 0x7FFF
+# define CARES_MASK_UINT 0xFFFF
+#elif (SIZEOF_INT == 4)
+# define CARES_MASK_SINT 0x7FFFFFFF
+# define CARES_MASK_UINT 0xFFFFFFFF
+#elif (SIZEOF_INT == 8)
+# define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFF
+# define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFF
+#elif (SIZEOF_INT == 16)
+# define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+# define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#else
+# error "SIZEOF_INT not defined"
+#endif
+
+#ifndef HAVE_LIMITS_H
+/* systems without we guess have 32 bit longs */
+#define CARES_MASK_SLONG 0x7FFFFFFFL
+#define CARES_MASK_ULONG 0xFFFFFFFFUL
+#else
+#define CARES_MASK_ULONG ULONG_MAX
+#define CARES_MASK_SLONG LONG_MAX
+#endif
/*
** unsigned size_t to signed long
diff --git a/deps/cares/src/ares_options.c b/deps/cares/src/ares_options.c
index 76d82dfb94d0a8..cf88433a1b5ae4 100644
--- a/deps/cares/src/ares_options.c
+++ b/deps/cares/src/ares_options.c
@@ -158,6 +158,9 @@ int ares_set_servers_csv(ares_channel channel,
return ARES_SUCCESS; /* blank all servers */
csv = malloc(i + 2);
+ if (!csv)
+ return ARES_ENOMEM;
+
strcpy(csv, _csv);
if (csv[i-1] != ',') { /* make parsing easier by ensuring ending ',' */
csv[i] = ',';
diff --git a/deps/cares/src/ares_parse_soa_reply.c b/deps/cares/src/ares_parse_soa_reply.c
index da1c6dccaf13ee..9a578a1f19a226 100644
--- a/deps/cares/src/ares_parse_soa_reply.c
+++ b/deps/cares/src/ares_parse_soa_reply.c
@@ -86,7 +86,10 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
/* allocate result struct */
soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
if (!soa)
- return ARES_ENOMEM;
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
/* nsname */
status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len);
diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/ares_private.h
index ab5be5a58aa6c9..8f486a449a8ae2 100644
--- a/deps/cares/src/ares_private.h
+++ b/deps/cares/src/ares_private.h
@@ -310,12 +310,7 @@ struct ares_channeldata {
/* return true if now is exactly check time or later */
int ares__timedout(struct timeval *now,
struct timeval *check);
-/* add the specific number of milliseconds to the time in the first argument */
-int ares__timeadd(struct timeval *now,
- int millisecs);
-/* return time offset between now and (future) check, in milliseconds */
-long ares__timeoffset(struct timeval *now,
- struct timeval *check);
+
/* returns ARES_SUCCESS if library has been initialized */
int ares_library_initialized(void);
void ares__send_query(ares_channel channel, struct query *query,
diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c
index bbeca5e737e73f..020a1319e55ea4 100644
--- a/deps/cares/src/ares_process.c
+++ b/deps/cares/src/ares_process.c
@@ -102,8 +102,7 @@ int ares__timedout(struct timeval *now,
}
/* add the specific number of milliseconds to the time in the first argument */
-int ares__timeadd(struct timeval *now,
- int millisecs)
+static void timeadd(struct timeval *now, int millisecs)
{
now->tv_sec += millisecs/1000;
now->tv_usec += (millisecs%1000)*1000;
@@ -112,19 +111,8 @@ int ares__timeadd(struct timeval *now,
++(now->tv_sec);
now->tv_usec -= 1000000;
}
-
- return 0;
-}
-
-/* return time offset between now and (future) check, in milliseconds */
-long ares__timeoffset(struct timeval *now,
- struct timeval *check)
-{
- return (check->tv_sec - now->tv_sec)*1000 +
- (check->tv_usec - now->tv_usec)/1000;
}
-
/*
* generic process function
*/
@@ -831,8 +819,7 @@ void ares__send_query(ares_channel channel, struct query *query,
timeplus = channel->timeout << (query->try_count / channel->nservers);
timeplus = (timeplus * (9 + (rand () & 7))) / 16;
query->timeout = *now;
- ares__timeadd(&query->timeout,
- timeplus);
+ timeadd(&query->timeout, timeplus);
/* Keep track of queries bucketed by timeout, so we can process
* timeout events quickly.
*/
diff --git a/deps/cares/src/ares_rules.h b/deps/cares/src/ares_rules.h
index f94c5b59165e7a..44f08f807c3cb7 100644
--- a/deps/cares/src/ares_rules.h
+++ b/deps/cares/src/ares_rules.h
@@ -68,11 +68,6 @@
* Verify that some macros are actually defined.
*/
-#ifndef CARES_SIZEOF_LONG
-# error "CARES_SIZEOF_LONG definition is missing!"
- Error Compilation_aborted_CARES_SIZEOF_LONG_is_missing
-#endif
-
#ifndef CARES_TYPEOF_ARES_SOCKLEN_T
# error "CARES_TYPEOF_ARES_SOCKLEN_T definition is missing!"
Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_is_missing
@@ -91,15 +86,6 @@
#define CareschkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
-/*
- * Verify that the size previously defined and expected for long
- * is the same as the one reported by sizeof() at compile time.
- */
-
-typedef char
- __cares_rule_01__
- [CareschkszEQ(long, CARES_SIZEOF_LONG)];
-
/*
* Verify that the size previously defined and expected for
* ares_socklen_t is actually the the same as the one reported
diff --git a/deps/cares/src/ares_search.c b/deps/cares/src/ares_search.c
index ec076405adb7a1..f9558a9a50f463 100644
--- a/deps/cares/src/ares_search.c
+++ b/deps/cares/src/ares_search.c
@@ -239,7 +239,7 @@ static int single_domain(ares_channel channel, const char *name, char **s)
/* If the name contains a trailing dot, then the single query is the name
* sans the trailing dot.
*/
- if (name[len - 1] == '.')
+ if ((len > 0) && (name[len - 1] == '.'))
{
*s = strdup(name);
return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
diff --git a/deps/cares/src/ares_setup.h b/deps/cares/src/ares_setup.h
index 18e14557cde56d..dee3e6ba6e4c05 100644
--- a/deps/cares/src/ares_setup.h
+++ b/deps/cares/src/ares_setup.h
@@ -75,9 +75,9 @@
/* please, do it beyond the point further indicated in this file. */
/* ================================================================ */
-#if 1 /* libuv hack */
-#include /* needed on windows */
-#else
+#if 1
+# define SIZEOF_SHORT 2
+#else /* Disabled for the gyp-ified build. */
/*
* c-ares external interface definitions are also used internally,
* and might also include required system header files to define them.
@@ -90,7 +90,7 @@
*/
#include
-#endif /* libuv hack */
+#endif
/* ================================================================= */
/* No system header file shall be included in this file before this */
diff --git a/deps/cares/src/ares_timeout.c b/deps/cares/src/ares_timeout.c
index 0b5a435f510f4c..293e4af02161e8 100644
--- a/deps/cares/src/ares_timeout.c
+++ b/deps/cares/src/ares_timeout.c
@@ -23,6 +23,13 @@
#include "ares.h"
#include "ares_private.h"
+/* return time offset between now and (future) check, in milliseconds */
+static long timeoffset(struct timeval *now, struct timeval *check)
+{
+ return (check->tv_sec - now->tv_sec)*1000 +
+ (check->tv_usec - now->tv_usec)/1000;
+}
+
/* WARNING: Beware that this is linear in the number of outstanding
* requests! You are probably far better off just calling ares_process()
* once per second, rather than calling ares_timeout() to figure out
@@ -53,7 +60,7 @@ struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
query = list_node->data;
if (query->timeout.tv_sec == 0)
continue;
- offset = ares__timeoffset(&now, &query->timeout);
+ offset = timeoffset(&now, &query->timeout);
if (offset < 0)
offset = 0;
if (min_offset == -1 || offset < min_offset)
diff --git a/deps/cares/src/config-win32.h b/deps/cares/src/config-win32.h
new file mode 100644
index 00000000000000..1245ba2abbef89
--- /dev/null
+++ b/deps/cares/src/config-win32.h
@@ -0,0 +1,385 @@
+#ifndef HEADER_CARES_CONFIG_WIN32_H
+#define HEADER_CARES_CONFIG_WIN32_H
+
+/* Copyright (C) 2004 - 2011 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/* ================================================================ */
+/* c-ares/config-win32.h - Hand crafted config file for Windows */
+/* ================================================================ */
+
+/* ---------------------------------------------------------------- */
+/* HEADER FILES */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define if you have the header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the header file. */
+#if defined(__MINGW32__) || defined(__POCC__)
+#define HAVE_GETOPT_H 1
+#endif
+
+/* Define if you have the header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the header file. */
+#ifndef __SALFORDC__
+#define HAVE_PROCESS_H 1
+#endif
+
+/* Define if you have the header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the header file */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the header file. */
+#define HAVE_TIME_H 1
+
+/* Define if you have the header file. */
+#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
+ defined(__POCC__)
+#define HAVE_UNISTD_H 1
+#endif
+
+/* Define if you have the header file. */
+#define HAVE_WINDOWS_H 1
+
+/* Define if you have the header file. */
+#define HAVE_WINSOCK_H 1
+
+/* Define if you have the header file. */
+#ifndef __SALFORDC__
+#define HAVE_WINSOCK2_H 1
+#endif
+
+/* Define if you have the header file. */
+#ifndef __SALFORDC__
+#define HAVE_WS2TCPIP_H 1
+#endif
+
+/* ---------------------------------------------------------------- */
+/* OTHER HEADER INFO */
+/* ---------------------------------------------------------------- */
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both and . */
+/* #define TIME_WITH_SYS_TIME 1 */
+
+/* ---------------------------------------------------------------- */
+/* FUNCTIONS */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have the closesocket function. */
+#define HAVE_CLOSESOCKET 1
+
+/* Define if you have the getenv function. */
+#define HAVE_GETENV 1
+
+/* Define if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define if you have the ioctlsocket function. */
+#define HAVE_IOCTLSOCKET 1
+
+/* Define if you have a working ioctlsocket FIONBIO function. */
+#define HAVE_IOCTLSOCKET_FIONBIO 1
+
+/* Define if you have the strcasecmp function. */
+/* #define HAVE_STRCASECMP 1 */
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the stricmp function. */
+#define HAVE_STRICMP 1
+
+/* Define if you have the strncasecmp function. */
+/* #define HAVE_STRNCASECMP 1 */
+
+/* Define if you have the strnicmp function. */
+#define HAVE_STRNICMP 1
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 SOCKET
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 SOCKET
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 SOCKET
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* Specifics for the Watt-32 tcp/ip stack. */
+#ifdef WATT32
+ #define SOCKET int
+ #define NS_INADDRSZ 4
+ #define HAVE_ARPA_NAMESER_H 1
+ #define HAVE_ARPA_INET_H 1
+ #define HAVE_NETDB_H 1
+ #define HAVE_NETINET_IN_H 1
+ #define HAVE_SYS_SOCKET_H 1
+ #define HAVE_NETINET_TCP_H 1
+ #define HAVE_AF_INET6 1
+ #define HAVE_PF_INET6 1
+ #define HAVE_STRUCT_IN6_ADDR 1
+ #define HAVE_STRUCT_SOCKADDR_IN6 1
+ #undef HAVE_WINSOCK_H
+ #undef HAVE_WINSOCK2_H
+ #undef HAVE_WS2TCPIP_H
+#endif
+
+/* ---------------------------------------------------------------- */
+/* TYPEDEF REPLACEMENTS */
+/* ---------------------------------------------------------------- */
+
+/* Define if in_addr_t is not an available 'typedefed' type. */
+#define in_addr_t unsigned long
+
+/* Define to the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define if ssize_t is not an available 'typedefed' type. */
+#ifndef _SSIZE_T_DEFINED
+# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
+ defined(__POCC__) || \
+ defined(__MINGW32__)
+# elif defined(_WIN64)
+# define _SSIZE_T_DEFINED
+# define ssize_t __int64
+# else
+# define _SSIZE_T_DEFINED
+# define ssize_t int
+# endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/* TYPE SIZES */
+/* ---------------------------------------------------------------- */
+
+/* Define to the size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* Define to the size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* Define to the size of `size_t', as computed by sizeof. */
+#if defined(_WIN64)
+# define SIZEOF_SIZE_T 8
+#else
+# define SIZEOF_SIZE_T 4
+#endif
+
+/* ---------------------------------------------------------------- */
+/* STRUCT RELATED */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define if you have struct sockaddr_storage. */
+#if !defined(__SALFORDC__) && !defined(__BORLANDC__)
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+
+/* Define if you have struct timeval. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* ---------------------------------------------------------------- */
+/* COMPILER SPECIFIC */
+/* ---------------------------------------------------------------- */
+
+/* Define to avoid VS2005 complaining about portable C functions. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+# define _CRT_SECURE_NO_DEPRECATE 1
+# define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+
+/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows
+ 2000 as a supported build target. VS2008 default installations provide
+ an embedded Windows SDK v6.0A along with the claim that Windows 2000 is
+ a valid build target for VS2008. Popular belief is that binaries built
+ with VS2008 using Windows SDK versions 6.X and Windows 2000 as a build
+ target are functional. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+# define VS2008_MIN_TARGET 0x0500
+#endif
+
+/* When no build target is specified VS2008 default build target is Windows
+ Vista, which leaves out even Winsows XP. If no build target has been given
+ for VS2008 we will target the minimum Officially supported build target,
+ which happens to be Windows XP. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+# define VS2008_DEF_TARGET 0x0501
+#endif
+
+/* VS2008 default target settings and minimum build target check. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT VS2008_DEF_TARGET
+# endif
+# ifndef WINVER
+# define WINVER VS2008_DEF_TARGET
+# endif
+# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
+# error VS2008 does not support Windows build targets prior to Windows 2000
+# endif
+#endif
+
+/* When no build target is specified Pelles C 5.00 and later default build
+ target is Windows Vista. We override default target to be Windows 2000. */
+#if defined(__POCC__) && (__POCC__ >= 500)
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# endif
+# ifndef WINVER
+# define WINVER 0x0500
+# endif
+#endif
+
+/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is
+ quite convoluted, compiler dependent and even build target dependent. */
+#if defined(HAVE_WS2TCPIP_H)
+# if defined(__POCC__)
+# define HAVE_FREEADDRINFO 1
+# define HAVE_GETADDRINFO 1
+# define HAVE_GETNAMEINFO 1
+# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
+# define HAVE_FREEADDRINFO 1
+# define HAVE_GETADDRINFO 1
+# define HAVE_GETNAMEINFO 1
+# elif defined(_MSC_VER) && (_MSC_VER >= 1200)
+# define HAVE_FREEADDRINFO 1
+# define HAVE_GETADDRINFO 1
+# define HAVE_GETNAMEINFO 1
+# endif
+#endif
+
+#if defined(__POCC__)
+# ifndef _MSC_VER
+# error Microsoft extensions /Ze compiler option is required
+# endif
+# ifndef __POCC__OLDNAMES
+# error Compatibility names /Go compiler option is required
+# endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/* IPV6 COMPATIBILITY */
+/* ---------------------------------------------------------------- */
+
+/* Define if you have address family AF_INET6. */
+#ifdef HAVE_WINSOCK2_H
+#define HAVE_AF_INET6 1
+#endif
+
+/* Define if you have protocol family PF_INET6. */
+#ifdef HAVE_WINSOCK2_H
+#define HAVE_PF_INET6 1
+#endif
+
+/* Define if you have struct in6_addr. */
+#ifdef HAVE_WS2TCPIP_H
+#define HAVE_STRUCT_IN6_ADDR 1
+#endif
+
+/* Define if you have struct sockaddr_in6. */
+#ifdef HAVE_WS2TCPIP_H
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+
+/* Define if you have sockaddr_in6 with scopeid. */
+#ifdef HAVE_WS2TCPIP_H
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+#endif
+
+/* ---------------------------------------------------------------- */
+/* Win CE */
+/* ---------------------------------------------------------------- */
+
+/* FIXME: A proper config-win32ce.h should be created to hold these */
+
+/*
+ * System error codes for Windows CE
+ */
+
+#if defined(_WIN32_WCE) && !defined(HAVE_ERRNO_H)
+# define ENOENT ERROR_FILE_NOT_FOUND
+# define ESRCH ERROR_PATH_NOT_FOUND
+# define ENOMEM ERROR_NOT_ENOUGH_MEMORY
+# define ENOSPC ERROR_INVALID_PARAMETER
+#endif
+
+#endif /* HEADER_CARES_CONFIG_WIN32_H */
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 6929fff222cd91..a0e3dd46f092f4 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -181,3 +181,19 @@ Johan Bergström
Alex Mo
Luis Martinez de Bartolome
Michael Penick
+Michael
+Massimiliano Torromeo
+TomCrypto
+Brett Vickers
+Ole André Vadla Ravnås
+Kazuho Oku
+Ryan Phillips
+Brian Green
+Devchandra Meetei Leishangthem
+Corey Farrell
+Per Nilsson
+Alan Rogers
+Daryl Haresign
+Rui Abreu Ferreira
+João Reis
+farblue68
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 7bbe5027a7aa28..e5c79808d2e1cc 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,4 +1,108 @@
-2015.02.27, Version 1.4.2 (Stable)
+2015.05.07, Version 1.5.0 (Stable), 4e77f74c7b95b639b3397095db1bc5bcc016c203
+
+Changes since version 1.4.2:
+
+* doc: clarify that the thread pool primites are not thread safe (Andrius
+ Bentkus)
+
+* aix: always deregister closing fds from epoll (Michael)
+
+* unix: fix glibc-2.20+ macro incompatibility (Massimiliano Torromeo)
+
+* doc: add Sphinx plugin for generating links to man pages (Saúl Ibarra
+ Corretgé)
+
+* doc: link system and library calls to man pages (Saúl Ibarra Corretgé)
+
+* doc: document uv_getnameinfo_t.{host|service} (Saúl Ibarra Corretgé)
+
+* build: update the location of gyp (Stephen von Takach)
+
+* win: name all anonymous structs and unions (TomCrypto)
+
+* linux: work around epoll bug in kernels 3.10-3.19 (Ben Noordhuis)
+
+* darwin: fix size calculation in select() fallback (Ole André Vadla Ravnås)
+
+* solaris: fix setsockopt for multicast options (Julien Gilli)
+
+* test: fix race condition in multithreaded test (Ben Noordhuis)
+
+* doc: fix long lines in tty.rst (Ben Noordhuis)
+
+* test: use UV_TTY_MODE_* values in tty test (Ben Noordhuis)
+
+* unix: don't clobber errno in uv_tty_reset_mode() (Ben Noordhuis)
+
+* unix: reject non-tty fds in uv_tty_init() (Ben Noordhuis)
+
+* win: fix pipe blocking writes (Alexis Campailla)
+
+* build: fix cross-compiling for iOS (Steven Kabbes)
+
+* win: remove unnecessary malloc.h
+
+* include: use `extern "c++"` for defining C++ code (Kazuho Oku)
+
+* unix: reap child on execvp() failure (Ryan Phillips)
+
+* windows: fix handle leak on EMFILE (Brian Green)
+
+* test: fix tty_file, close handle if initialized (Saúl Ibarra Corretgé)
+
+* doc: clarify what uv_*_open accepts (Saúl Ibarra Corretgé)
+
+* doc: clarify that we don't maintain external doc resources (Saúl Ibarra
+ Corretgé)
+
+* build: add documentation for ninja support (Devchandra Meetei Leishangthem)
+
+* doc: document uv_buf_t members (Corey Farrell)
+
+* linux: fix epoll_pwait() fallback on arm64 (Ben Noordhuis)
+
+* android: fix compilation warning (Saúl Ibarra Corretgé)
+
+* unix: don't close the fds we just setup (Sam Roberts)
+
+* test: spawn child replacing std{out,err} to stderr (Saúl Ibarra Corretgé)
+
+* unix: fix swapping fds order in uv_spawn (Saúl Ibarra Corretgé)
+
+* unix: fix potential bug if dup2 fails in uv_spawn (Saúl Ibarra Corretgé)
+
+* test: remove LOG and LOGF variadic macros (Saúl Ibarra Corretgé)
+
+* win: fix uv_fs_access on directories (Saúl Ibarra Corretgé)
+
+* win: fix of double free in uv_uptime (Per Nilsson)
+
+* unix: open "/dev/null" instead of "/" for emfile_fd (Alan Rogers)
+
+* docs: add some missing words (Daryl Haresign)
+
+* unix: clean up uv_fs_open() O_CLOEXEC logic (Ben Noordhuis)
+
+* build: set SONAME for shared library in uv.gyp (Rui Abreu Ferreira)
+
+* windows: define snprintf replacement as inline instead of static (Rui Abreu
+ Ferreira)
+
+* win: fix unlink of readonly files (João Reis)
+
+* doc: fix uv_run(UV_RUN_DEFAULT) description (Ben Noordhuis)
+
+* linux: intercept syscall when running under memory sanitizer (Keno Fischer)
+
+* aix: fix uv_interface_addresses return value (farblue68)
+
+* windows: defer reporting TCP write failure until next tick (Saúl Ibarra
+ Corretgé)
+
+* test: add test for deferred TCP write failure (Saúl Ibarra Corretgé)
+
+
+2015.02.27, Version 1.4.2 (Stable), 1a7391348a11d5450c0f69c828d5302e2cb842eb
Changes since version 1.4.1:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 9c511db47a6c8f..b9fb80c6738b52 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -226,6 +226,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-write-to-half-open-connection.c \
test/test-tcp-write-after-connect.c \
test/test-tcp-writealot.c \
+ test/test-tcp-write-fail.c \
test/test-tcp-try-write.c \
test/test-tcp-write-queue-order.c \
test/test-thread-equal.c \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index a267f0d5b527e5..a7da8b898c581d 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -72,19 +72,23 @@ NOTE: Windows users need to use make.bat instead of plain 'make'.
Documentation can be browsed online [here](http://docs.libuv.org).
+The [tests and benchmarks](https://github.com/libuv/libuv/tree/master/test)
+also serve as API specification and usage examples.
+
### Other resources
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
— An overview of libuv with tutorials.
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
— High-level introductory talk about libuv.
- * [Tests and benchmarks](https://github.com/libuv/libuv/tree/master/test)
- — API specification and usage examples.
* [libuv-dox](https://github.com/thlorenz/libuv-dox)
— Documenting types and methods of libuv, mostly by reading uv.h.
* [learnuv](https://github.com/thlorenz/learnuv)
— Learn uv for fun and profit, a self guided workshop to libuv.
+These resources are not handled by libuv maintainers and might be out of
+date. Please verify it before opening new issues.
+
## Build Instructions
For GCC there are two build methods: via autotools or via [GYP][].
@@ -113,8 +117,6 @@ To have GYP generate build script for another system, checkout GYP into the
project tree manually:
$ git clone https://chromium.googlesource.com/external/gyp.git build/gyp
- OR
- $ svn co http://gyp.googlecode.com/svn/trunk build/gyp
### Unix
@@ -153,6 +155,15 @@ Run:
Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
+### Using Ninja
+
+To use ninja for build on ninja supported platforms, run:
+
+ $ ./gyp_uv.py -f ninja
+ $ ninja -C out/Debug #for debug build OR
+ $ ninja -C out/Release
+
+
### Running tests
Run:
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 9473d5ffcb09d2..71cb4704138c57 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.4.2], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.5.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])
diff --git a/deps/uv/docs/src/conf.py b/deps/uv/docs/src/conf.py
index f614fc5b434b24..b9eaa137432dea 100644
--- a/deps/uv/docs/src/conf.py
+++ b/deps/uv/docs/src/conf.py
@@ -38,7 +38,7 @@ def get_libuv_version():
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+sys.path.insert(0, os.path.abspath('sphinx-plugins'))
# -- General configuration ------------------------------------------------
@@ -48,7 +48,7 @@ def get_libuv_version():
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
-extensions = []
+extensions = ['manpage']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['templates']
diff --git a/deps/uv/docs/src/design.rst b/deps/uv/docs/src/design.rst
index 63141bedf58438..34c3cff68e54ca 100644
--- a/deps/uv/docs/src/design.rst
+++ b/deps/uv/docs/src/design.rst
@@ -40,7 +40,7 @@ The I/O loop
The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O
operations, and it's meant to be tied to a single thread. One can run multiple event loops
as long as each runs in a different thread. The libuv event loop (or any other API involving
-the loop or handles, for that matter) **is not thread-safe** except stated otherwise.
+the loop or handles, for that matter) **is not thread-safe** except where stated otherwise.
The event loop follows the rather usual single threaded asynchronous I/O approach: all (network)
I/O is performed on non-blocking sockets which are polled using the best mechanism available
@@ -113,7 +113,7 @@ stages of a loop iteration:
.. note::
While the polling mechanism is different, libuv makes the execution model consistent
- Unix systems and Windows.
+ across Unix systems and Windows.
File I/O
diff --git a/deps/uv/docs/src/dns.rst b/deps/uv/docs/src/dns.rst
index 3b15377f91e419..1d881580966315 100644
--- a/deps/uv/docs/src/dns.rst
+++ b/deps/uv/docs/src/dns.rst
@@ -51,6 +51,18 @@ Public members
Loop that started this getnameinfo request and where completion will be
reported. Readonly.
+.. c:member:: char[NI_MAXHOST] uv_getnameinfo_t.host
+
+ Char array containing the resulting host. It's null terminated.
+
+ .. versionchanged:: 1.3.0 the field is declared as public.
+
+.. c:member:: char[NI_MAXSERV] uv_getnameinfo_t.service
+
+ Char array containing the resulting service. It's null terminated.
+
+ .. versionchanged:: 1.3.0 the field is declared as public.
+
.. seealso:: The :c:type:`uv_req_t` members also apply.
@@ -59,7 +71,7 @@ API
.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints)
- Asynchronous ``getaddrinfo(3)``.
+ Asynchronous :man:`getaddrinfo(3)`.
Either node or service may be NULL but not both.
@@ -84,7 +96,7 @@ API
.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags)
- Asynchronous ``getnameinfo(3)``.
+ Asynchronous :man:`getnameinfo(3)`.
Returns 0 on success or an error code < 0 on failure. If successful, the
callback will get called sometime in the future with the lookup result.
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index cd535f756fc1c9..c2a3fc252a1ffe 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -162,46 +162,46 @@ API
.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
- Equivalent to ``close(2)``.
+ Equivalent to :man:`close(2)`.
.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
- Equivalent to ``open(2)``.
+ Equivalent to :man:`open(2)`.
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
- Equivalent to ``preadv(2)``.
+ Equivalent to :man:`preadv(2)`.
.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
- Equivalent to ``unlink(2)``.
+ Equivalent to :man:`unlink(2)`.
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
- Equivalent to ``pwritev(2)``.
+ Equivalent to :man:`pwritev(2)`.
.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
- Equivalent to ``mkdir(2)``.
+ Equivalent to :man:`mkdir(2)`.
.. note::
`mode` is currently not implemented on Windows.
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
- Equivalent to ``mkdtemp(3)``.
+ Equivalent to :man:`mkdtemp(3)`.
.. note::
The result can be found as a null terminated string at `req->path`.
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
- Equivalent to ``rmdir(2)``.
+ Equivalent to :man:`rmdir(2)`.
.. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
.. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent)
- Equivalent to ``scandir(3)``, with a slightly different API. Once the callback
+ Equivalent to :man:`scandir(3)`, with a slightly different API. Once the callback
for the request is called, the user can use :c:func:`uv_fs_scandir_next` to
get `ent` populated with the next directory entry data. When there are no
more entries ``UV_EOF`` will be returned.
@@ -210,49 +210,49 @@ API
.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
- Equivalent to ``(f/l)stat(2)``.
+ Equivalent to :man:`stat(2)`, :man:`fstat(2)` and :man:`fstat(2)` respectively.
.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
- Equivalent to ``rename(2)``.
+ Equivalent to :man:`rename(2)`.
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
- Equivalent to ``fsync(2)``.
+ Equivalent to :man:`fsync(2)`.
.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
- Equivalent to ``fdatasync(2)``.
+ Equivalent to :man:`fdatasync(2)`.
.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb)
- Equivalent to ``ftruncate(2)``.
+ Equivalent to :man:`ftruncate(2)`.
.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb)
- Limited equivalent to ``sendfile(2)``.
+ Limited equivalent to :man:`sendfile(2)`.
.. c:function:: int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
- Equivalent to ``access(2)`` on Unix. Windows uses ``GetFileAttributesW()``.
+ Equivalent to :man:`access(2)` on Unix. Windows uses ``GetFileAttributesW()``.
.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb)
- Equivalent to ``(f)chmod(2)``.
+ Equivalent to :man:`chmod(2)` and :man:`fchmod(2)` respectively.
.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb)
.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb)
- Equivalent to ``(f)utime(s)(2)``.
+ Equivalent to :man:`utime(2)` and :man:`futime(2)` respectively.
.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
- Equivalent to ``link(2)``.
+ Equivalent to :man:`link(2)`.
.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb)
- Equivalent to ``symlink(2)``.
+ Equivalent to :man:`symlink(2)`.
.. note::
On Windows the `flags` parameter can be specified to control how the symlink will
@@ -265,12 +265,12 @@ API
.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
- Equivalent to ``readlink(2)``.
+ Equivalent to :man:`readlink(2)`.
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
- Equivalent to ``(f)chown(2)``.
+ Equivalent to :man:`chown(2)` and :man:`fchown(2)` respectively.
.. note::
These functions are not implemented on Windows.
diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst
index 203672bd34f00a..2a01d796375e8e 100644
--- a/deps/uv/docs/src/loop.rst
+++ b/deps/uv/docs/src/loop.rst
@@ -92,7 +92,9 @@ API
specified mode:
- UV_RUN_DEFAULT: Runs the event loop until there are no more active and
- referenced handles or requests. Always returns zero.
+ referenced handles or requests. Returns non-zero if :c:func:`uv_stop`
+ was called and there are still active handles or requests. Returns
+ zero in all other cases.
- UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if
there are no pending callbacks. Returns zero when done (no active handles
or requests left), or non-zero if more callbacks are expected (meaning
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 10c349e9b736f3..bb97a260057fc8 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -15,6 +15,17 @@ Data types
Buffer data type.
+ .. c:member:: char* uv_buf_t.base
+
+ Pointer to the base of the buffer. Readonly.
+
+ .. c:member:: size_t uv_buf_t.len
+
+ Total bytes in the buffer. Readonly.
+
+ .. note::
+ On Windows this field is ULONG.
+
.. c:type:: uv_file
Cross platform representation of a file handle.
@@ -26,7 +37,7 @@ Data types
.. c:type:: uv_os_fd_t
Abstract representation of a file descriptor. On Unix systems this is a
- `typedef` of `int` and on Windows fa `HANDLE`.
+ `typedef` of `int` and on Windows a `HANDLE`.
.. c:type:: uv_rusage_t
@@ -101,7 +112,8 @@ API
descriptor. Usually this will be used during initialization to guess the
type of the stdio streams.
- For ``isatty()`` functionality use this function and test for ``UV_TTY``.
+ For :man:`isatty(3)` equivalent functionality use this function and test
+ for ``UV_TTY``.
.. c:function:: unsigned int uv_version(void)
@@ -195,8 +207,8 @@ API
.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size)
.. c:function:: int uv_inet_pton(int af, const char* src, void* dst)
- Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()``
- and ``inet_pton()`` functions. On success they return 0. In case of error
+ Cross-platform IPv6-capable implementation of :man:`inet_ntop(3)`
+ and :man:`inet_pton(3)`. On success they return 0. In case of error
the target `dst` pointer is unmodified.
.. c:function:: int uv_exepath(char* buffer, size_t* size)
diff --git a/deps/uv/docs/src/pipe.rst b/deps/uv/docs/src/pipe.rst
index 8f8402c29bbadd..df896a0583447f 100644
--- a/deps/uv/docs/src/pipe.rst
+++ b/deps/uv/docs/src/pipe.rst
@@ -40,6 +40,10 @@ API
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
+ .. note::
+ The passed file descriptor or HANDLE is not checked for its type, but
+ it's required that it represents a valid pipe.
+
.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name)
Bind the pipe to a file path (Unix) or a name (Windows).
diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst
index 907cb1a613dfbb..6dc41839ac1e92 100644
--- a/deps/uv/docs/src/poll.rst
+++ b/deps/uv/docs/src/poll.rst
@@ -5,7 +5,7 @@
===================================
Poll handles are used to watch file descriptors for readability and
-writability, similar to the purpose of poll(2).
+writability, similar to the purpose of :man:`poll(2)`.
The purpose of poll handles is to enable integrating external libraries that
rely on the event loop to signal it about the socket status changes, like
@@ -29,7 +29,7 @@ closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`.
.. note::
On windows only sockets can be polled with poll handles. On Unix any file
- descriptor that would be accepted by poll(2) can be used.
+ descriptor that would be accepted by :man:`poll(2)` can be used.
Data types
diff --git a/deps/uv/docs/src/sphinx-plugins/manpage.py b/deps/uv/docs/src/sphinx-plugins/manpage.py
new file mode 100644
index 00000000000000..1d1dc379f410ee
--- /dev/null
+++ b/deps/uv/docs/src/sphinx-plugins/manpage.py
@@ -0,0 +1,46 @@
+# encoding: utf-8
+
+#
+# Copyright (c) 2013 Dariusz Dwornikowski. All rights reserved.
+#
+# Adapted from https://github.com/tdi/sphinxcontrib-manpage
+# License: Apache 2
+#
+
+
+import re
+
+from docutils import nodes, utils
+from docutils.parsers.rst.roles import set_classes
+from string import Template
+
+
+def make_link_node(rawtext, app, name, manpage_num, options):
+ ref = app.config.man_url_regex
+ if not ref:
+ ref = "http://linux.die.net/man/%s/%s" % (manpage_num, name)
+ else:
+ s = Template(ref)
+ ref = s.substitute(num=manpage_num, topic=name)
+ set_classes(options)
+ node = nodes.reference(rawtext, "%s(%s)" % (name, manpage_num), refuri=ref, **options)
+ return node
+
+
+def man_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
+ app = inliner.document.settings.env.app
+ p = re.compile("([a-zA-Z0-9_\.-_]+)\((\d)\)")
+ m = p.match(text)
+
+ manpage_num = m.group(2)
+ name = m.group(1)
+ node = make_link_node(rawtext, app, name, manpage_num, options)
+ return [node], []
+
+
+def setup(app):
+ app.info('Initializing manpage plugin')
+ app.add_role('man', man_role)
+ app.add_config_value('man_url_regex', None, 'env')
+ return
+
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
index 1f6682adc1cfc2..880f0e2ebc75d3 100644
--- a/deps/uv/docs/src/stream.rst
+++ b/deps/uv/docs/src/stream.rst
@@ -104,7 +104,7 @@ API
.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb)
Start listening for incoming connections. `backlog` indicates the number of
- connections the kernel might queue, same as ``listen(2)``. When a new
+ connections the kernel might queue, same as :man:`listen(2)`. When a new
incoming connection is received the :c:type:`uv_connection_cb` callback is
called.
diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst
index 8baedde86c5c15..2b5d268ddd86e6 100644
--- a/deps/uv/docs/src/tcp.rst
+++ b/deps/uv/docs/src/tcp.rst
@@ -38,6 +38,10 @@ API
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
+ .. note::
+ The passed file descriptor or SOCKET is not checked for its type, but
+ it's required that it represents a valid stream socket.
+
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)
Enable / disable Nagle's algorithm.
diff --git a/deps/uv/docs/src/threadpool.rst b/deps/uv/docs/src/threadpool.rst
index 89f00844ef2c65..18949507e75004 100644
--- a/deps/uv/docs/src/threadpool.rst
+++ b/deps/uv/docs/src/threadpool.rst
@@ -18,6 +18,10 @@ libuv preallocates and initializes the maximum number of threads allowed by
``UV_THREADPOOL_SIZE``. This causes a relatively minor memory overhead
(~1MB for 128 threads) but increases the performance of threading at runtime.
+.. note::
+ Note that even though a global thread pool which is shared across all events
+ loops is used, the functions are not thread safe.
+
Data types
----------
diff --git a/deps/uv/docs/src/tty.rst b/deps/uv/docs/src/tty.rst
index 6c20c84bf75e58..18f34ef46d97b5 100644
--- a/deps/uv/docs/src/tty.rst
+++ b/deps/uv/docs/src/tty.rst
@@ -24,14 +24,14 @@ Data types
::
- typedef enum {
- /* Initial/normal terminal mode */
- UV_TTY_MODE_NORMAL,
- /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
- UV_TTY_MODE_RAW,
- /* Binary-safe I/O mode for IPC (Unix-only) */
- UV_TTY_MODE_IO
- } uv_tty_mode_t;
+ typedef enum {
+ /* Initial/normal terminal mode */
+ UV_TTY_MODE_NORMAL,
+ /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
+ UV_TTY_MODE_RAW,
+ /* Binary-safe I/O mode for IPC (Unix-only) */
+ UV_TTY_MODE_IO
+ } uv_tty_mode_t;
@@ -58,18 +58,22 @@ API
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with
this stream. stdin is readable, stdout is not.
- On Unix this function will try to open ``/dev/tty`` and use it if the passed file
- descriptor refers to a TTY. This lets libuv put the tty in non-blocking mode
- without affecting other processes that share the tty.
+ On Unix this function will try to open ``/dev/tty`` and use it if the passed
+ file descriptor refers to a TTY. This lets libuv put the tty in non-blocking
+ mode without affecting other processes that share the tty.
.. note::
- If opening ``/dev/tty`` fails, libuv falls back to blocking writes for non-readable
- TTY streams.
+ If opening ``/dev/tty`` fails, libuv falls back to blocking writes for
+ non-readable TTY streams.
+
+ .. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file
+ descriptor that refers to a file returns `UV_EINVAL`
+ on UNIX.
.. c:function:: int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode)
- .. versionchanged:: 1.2.0: the mode is specified as a :c:type:`uv_tty_mode_t`
- value.
+ .. versionchanged:: 1.2.0: the mode is specified as a
+ :c:type:`uv_tty_mode_t` value.
Set the TTY using the specified terminal mode.
diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst
index 9c4aa2102bdcfc..ec7ce56d38f52c 100644
--- a/deps/uv/docs/src/udp.rst
+++ b/deps/uv/docs/src/udp.rst
@@ -122,6 +122,10 @@ API
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
+ .. note::
+ The passed file descriptor or SOCKET is not checked for its type, but
+ it's required that it represents a valid datagram socket.
+
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
Bind the UDP handle to an IP address and port.
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index 836d399d774a32..0b4e6d781c35f6 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 4
-#define UV_VERSION_PATCH 2
+#define UV_VERSION_MINOR 5
+#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 24b22b31a9562b..fd844202b99a1a 100644
--- a/deps/uv/include/uv-win.h
+++ b/deps/uv/include/uv-win.h
@@ -43,16 +43,6 @@ typedef struct pollfd {
# define LOCALE_INVARIANT 0x007f
#endif
-#ifndef _malloca
-# if defined(_DEBUG)
-# define _malloca(size) malloc(size)
-# define _freea(ptr) free(ptr)
-# else
-# define _malloca(size) alloca(size)
-# define _freea(ptr)
-# endif
-#endif
-
#include
#include
#include
@@ -366,8 +356,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { \
OVERLAPPED overlapped; \
size_t queued_bytes; \
- }; \
- }; \
+ } io; \
+ } u; \
struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
@@ -419,9 +409,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
int activecnt; \
uv_read_t read_req; \
union { \
- struct { uv_stream_connection_fields }; \
- struct { uv_stream_server_fields }; \
- };
+ struct { uv_stream_connection_fields } conn; \
+ struct { uv_stream_server_fields } serv; \
+ } stream;
#define uv_tcp_server_fields \
uv_tcp_accept_t* accept_reqs; \
@@ -437,9 +427,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
SOCKET socket; \
int delayed_error; \
union { \
- struct { uv_tcp_server_fields }; \
- struct { uv_tcp_connection_fields }; \
- };
+ struct { uv_tcp_server_fields } serv; \
+ struct { uv_tcp_connection_fields } conn; \
+ } tcp;
#define UV_UDP_PRIVATE_FIELDS \
SOCKET socket; \
@@ -476,9 +466,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE handle; \
WCHAR* name; \
union { \
- struct { uv_pipe_server_fields }; \
- struct { uv_pipe_connection_fields }; \
- };
+ struct { uv_pipe_server_fields } serv; \
+ struct { uv_pipe_connection_fields } conn; \
+ } pipe;
/* TODO: put the parser states in an union - TTY handles are always */
/* half-duplex so read-state can safely overlap write-state. */
@@ -496,7 +486,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
unsigned char last_key_len; \
WCHAR last_utf16_high_surrogate; \
INPUT_RECORD last_input_record; \
- }; \
+ } rd; \
struct { \
/* Used for writable TTY handles */ \
/* utf8-to-utf16 conversion state */ \
@@ -510,8 +500,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
unsigned short ansi_csi_argv[4]; \
COORD saved_position; \
WORD saved_attributes; \
- }; \
- };
+ } wr; \
+ } tty;
#define UV_POLL_PRIVATE_FIELDS \
SOCKET socket; \
@@ -600,7 +590,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
/* TODO: remove me in 0.9. */ \
WCHAR* pathw; \
int fd; \
- }; \
+ } file; \
union { \
struct { \
int mode; \
@@ -611,12 +601,12 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
uv_buf_t* bufs; \
int64_t offset; \
uv_buf_t bufsml[4]; \
- }; \
+ } info; \
struct { \
double atime; \
double mtime; \
- }; \
- };
+ } time; \
+ } fs;
#define UV_WORK_PRIVATE_FIELDS \
struct uv__work work_req;
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 55f75218b58682..75b3a4a5d2f8bf 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -644,13 +644,13 @@ UV_EXTERN int uv_tty_reset_mode(void);
UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
#ifdef __cplusplus
-} /* extern "C" */
+extern "C++" {
inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
return uv_tty_set_mode(handle, static_cast(mode));
}
-extern "C" {
+}
#endif
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
@@ -799,6 +799,7 @@ struct uv_getnameinfo_s {
UV_REQ_FIELDS
/* read-only */
uv_loop_t* loop;
+ /* host and service are marked as private, but they really aren't. */
UV_GETNAMEINFO_PRIVATE_FIELDS
};
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index ec800c7a323f4b..e21a9cc78b6979 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -1111,19 +1111,19 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
*count = 0;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
- return -ENOSYS;
+ return -errno;
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
- uv__close(sockfd);
- return -ENOSYS;
+ SAVE_ERRNO(uv__close(sockfd));
+ return -errno;
}
ifc.ifc_req = (struct ifreq*)malloc(size);
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
- uv__close(sockfd);
- return -ENOSYS;
+ SAVE_ERRNO(uv__close(sockfd));
+ return -errno;
}
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
@@ -1141,8 +1141,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
- uv__close(sockfd);
- return -ENOSYS;
+ SAVE_ERRNO(uv__close(sockfd));
+ return -errno;
}
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -1218,16 +1218,23 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct pollfd* events;
uintptr_t i;
uintptr_t nfds;
+ struct poll_ctl pc;
assert(loop->watchers != NULL);
events = (struct pollfd*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
- if (events == NULL)
- return;
- /* Invalidate events with same file descriptor */
- for (i = 0; i < nfds; i++)
- if ((int) events[i].fd == fd)
- events[i].fd = -1;
+ if (events != NULL)
+ /* Invalidate events with same file descriptor */
+ for (i = 0; i < nfds; i++)
+ if ((int) events[i].fd == fd)
+ events[i].fd = -1;
+
+ /* Remove the file descriptor from the poll set */
+ pc.events = 0;
+ pc.cmd = PS_DELETE;
+ pc.fd = fd;
+ if(loop->backend_fd >= 0)
+ pollset_ctl(loop->backend_fd, &pc, 1);
}
diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c
index 3cda578dd1a94c..a99b0191d54808 100644
--- a/deps/uv/src/unix/android-ifaddrs.c
+++ b/deps/uv/src/unix/android-ifaddrs.c
@@ -24,6 +24,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "android-ifaddrs.h"
+#include "uv-common.h"
#include
#include
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index e7eee2f9abc4ed..7792801e9b6fd6 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -202,6 +202,44 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
}
+static ssize_t uv__fs_open(uv_fs_t* req) {
+ static int no_cloexec_support;
+ int r;
+
+ /* Try O_CLOEXEC before entering locks */
+ if (no_cloexec_support == 0) {
+#ifdef O_CLOEXEC
+ r = open(req->path, req->flags | O_CLOEXEC, req->mode);
+ if (r >= 0)
+ return r;
+ if (errno != EINVAL)
+ return r;
+ no_cloexec_support = 1;
+#endif /* O_CLOEXEC */
+ }
+
+ if (req->cb != NULL)
+ uv_rwlock_rdlock(&req->loop->cloexec_lock);
+
+ r = open(req->path, req->flags, req->mode);
+
+ /* In case of failure `uv__cloexec` will leave error in `errno`,
+ * so it is enough to just set `r` to `-1`.
+ */
+ if (r >= 0 && uv__cloexec(r, 1) != 0) {
+ r = uv__close(r);
+ if (r != 0 && r != -EINPROGRESS)
+ abort();
+ r = -1;
+ }
+
+ if (req->cb != NULL)
+ uv_rwlock_rdunlock(&req->loop->cloexec_lock);
+
+ return r;
+}
+
+
static ssize_t uv__fs_read(uv_fs_t* req) {
#if defined(__linux__)
static int no_preadv;
@@ -661,8 +699,22 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec;
dst->st_flags = src->st_flags;
dst->st_gen = src->st_gen;
-#elif !defined(_AIX) && \
- (defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE))
+#elif defined(__ANDROID__)
+ dst->st_atim.tv_sec = src->st_atime;
+ dst->st_atim.tv_nsec = src->st_atime_nsec;
+ dst->st_mtim.tv_sec = src->st_mtime;
+ dst->st_mtim.tv_nsec = src->st_mtime_nsec;
+ dst->st_ctim.tv_sec = src->st_ctime;
+ dst->st_ctim.tv_nsec = src->st_ctime_nsec;
+ dst->st_birthtim.tv_sec = src->st_ctime;
+ dst->st_birthtim.tv_nsec = src->st_ctime_nsec;
+ dst->st_flags = 0;
+ dst->st_gen = 0;
+#elif !defined(_AIX) && ( \
+ defined(_BSD_SOURCE) || \
+ defined(_SVID_SOURCE) || \
+ defined(_XOPEN_SOURCE) || \
+ defined(_DEFAULT_SOURCE))
dst->st_atim.tv_sec = src->st_atim.tv_sec;
dst->st_atim.tv_nsec = src->st_atim.tv_nsec;
dst->st_mtim.tv_sec = src->st_mtim.tv_sec;
@@ -729,9 +781,6 @@ static void uv__fs_work(struct uv__work* w) {
int retry_on_eintr;
uv_fs_t* req;
ssize_t r;
-#ifdef O_CLOEXEC
- static int no_cloexec_support;
-#endif /* O_CLOEXEC */
req = container_of(w, uv_fs_t, work_req);
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
@@ -760,6 +809,7 @@ static void uv__fs_work(struct uv__work* w) {
X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req));
+ X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(req));
X(READLINK, uv__fs_readlink(req));
@@ -771,41 +821,10 @@ static void uv__fs_work(struct uv__work* w) {
X(UNLINK, unlink(req->path));
X(UTIME, uv__fs_utime(req));
X(WRITE, uv__fs_write(req));
- case UV_FS_OPEN:
-#ifdef O_CLOEXEC
- /* Try O_CLOEXEC before entering locks */
- if (!no_cloexec_support) {
- r = open(req->path, req->flags | O_CLOEXEC, req->mode);
- if (r >= 0)
- break;
- if (errno != EINVAL)
- break;
- no_cloexec_support = 1;
- }
-#endif /* O_CLOEXEC */
- if (req->cb != NULL)
- uv_rwlock_rdlock(&req->loop->cloexec_lock);
- r = open(req->path, req->flags, req->mode);
-
- /*
- * In case of failure `uv__cloexec` will leave error in `errno`,
- * so it is enough to just set `r` to `-1`.
- */
- if (r >= 0 && uv__cloexec(r, 1) != 0) {
- r = uv__close(r);
- if (r != 0 && r != -EINPROGRESS)
- abort();
- r = -1;
- }
- if (req->cb != NULL)
- uv_rwlock_rdunlock(&req->loop->cloexec_lock);
- break;
default: abort();
}
-
#undef X
- }
- while (r == -1 && errno == EINTR && retry_on_eintr);
+ } while (r == -1 && errno == EINTR && retry_on_eintr);
if (r == -1)
req->result = -errno;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 101dc745499f8d..31db5e29ea68b8 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -55,6 +55,9 @@
#define ACCESS_ONCE(type, var) \
(*(volatile type*) &(var))
+#define ROUND_UP(a, b) \
+ ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a))
+
#define UNREACHABLE() \
do { \
assert(0 && "unreachable code"); \
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 33a735dc674f14..d07494dd654bb3 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -130,8 +130,13 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
*
* We pass in a dummy epoll_event, to work around a bug in old kernels.
*/
- if (loop->backend_fd >= 0)
+ if (loop->backend_fd >= 0) {
+ /* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
+ * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
+ */
+ memset(&dummy, 0, sizeof(dummy));
uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy);
+ }
}
diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c
index 7bf2c0f87dbea4..566e1f37cfed12 100644
--- a/deps/uv/src/unix/linux-syscalls.c
+++ b/deps/uv/src/unix/linux-syscalls.c
@@ -26,6 +26,13 @@
#include
#include
+#if defined(__has_feature)
+# if __has_feature(memory_sanitizer)
+# define MSAN_ACTIVE 1
+# include
+# endif
+#endif
+
#if defined(__i386__)
# ifndef __NR_socketcall
# define __NR_socketcall 102
@@ -310,7 +317,13 @@ int uv__epoll_wait(int epfd,
int nevents,
int timeout) {
#if defined(__NR_epoll_wait)
- return syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
+ int result;
+ result = syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
+#if MSAN_ACTIVE
+ if (result > 0)
+ __msan_unpoison(events, sizeof(events[0]) * result);
+#endif
+ return result;
#else
return errno = ENOSYS, -1;
#endif
@@ -323,13 +336,19 @@ int uv__epoll_pwait(int epfd,
int timeout,
uint64_t sigmask) {
#if defined(__NR_epoll_pwait)
- return syscall(__NR_epoll_pwait,
- epfd,
- events,
- nevents,
- timeout,
- &sigmask,
- sizeof(sigmask));
+ int result;
+ result = syscall(__NR_epoll_pwait,
+ epfd,
+ events,
+ nevents,
+ timeout,
+ &sigmask,
+ sizeof(sigmask));
+#if MSAN_ACTIVE
+ if (result > 0)
+ __msan_unpoison(events, sizeof(events[0]) * result);
+#endif
+ return result;
#else
return errno = ENOSYS, -1;
#endif
@@ -374,7 +393,13 @@ int uv__inotify_rm_watch(int fd, int32_t wd) {
int uv__pipe2(int pipefd[2], int flags) {
#if defined(__NR_pipe2)
- return syscall(__NR_pipe2, pipefd, flags);
+ int result;
+ result = syscall(__NR_pipe2, pipefd, flags);
+#if MSAN_ACTIVE
+ if (!result)
+ __msan_unpoison(pipefd, sizeof(int[2]));
+#endif
+ return result;
#else
return errno = ENOSYS, -1;
#endif
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index be283b480d6a23..380f3db1dce7f4 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -280,6 +280,21 @@ static void uv__process_child_init(const uv_process_options_t* options,
if (options->flags & UV_PROCESS_DETACHED)
setsid();
+ /* First duplicate low numbered fds, since it's not safe to duplicate them,
+ * they could get replaced. Example: swapping stdout and stderr; without
+ * this fd 2 (stderr) would be duplicated into fd 1, thus making both
+ * stdout and stderr go to the same fd, which was not the intention. */
+ for (fd = 0; fd < stdio_count; fd++) {
+ use_fd = pipes[fd][1];
+ if (use_fd < 0 || use_fd >= fd)
+ continue;
+ pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
+ if (pipes[fd][1] == -1) {
+ uv__write_int(error_fd, -errno);
+ _exit(127);
+ }
+ }
+
for (fd = 0; fd < stdio_count; fd++) {
close_fd = pipes[fd][0];
use_fd = pipes[fd][1];
@@ -304,7 +319,12 @@ static void uv__process_child_init(const uv_process_options_t* options,
if (fd == use_fd)
uv__cloexec(use_fd, 0);
else
- dup2(use_fd, fd);
+ fd = dup2(use_fd, fd);
+
+ if (fd == -1) {
+ uv__write_int(error_fd, -errno);
+ _exit(127);
+ }
if (fd <= 2)
uv__nonblock(fd, 0);
@@ -316,8 +336,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
for (fd = 0; fd < stdio_count; fd++) {
use_fd = pipes[fd][1];
- if (use_fd >= 0 && fd != use_fd)
- close(use_fd);
+ if (use_fd >= stdio_count)
+ uv__close(use_fd);
}
if (options->cwd != NULL && chdir(options->cwd)) {
@@ -367,6 +387,7 @@ int uv_spawn(uv_loop_t* loop,
int err;
int exec_errorno;
int i;
+ int status;
assert(options->file != NULL);
assert(!(options->flags & ~(UV_PROCESS_DETACHED |
@@ -453,11 +474,17 @@ int uv_spawn(uv_loop_t* loop,
if (r == 0)
; /* okay, EOF */
- else if (r == sizeof(exec_errorno))
- ; /* okay, read errorno */
- else if (r == -1 && errno == EPIPE)
- ; /* okay, got EPIPE */
- else
+ else if (r == sizeof(exec_errorno)) {
+ do
+ err = waitpid(pid, &status, 0); /* okay, read errorno */
+ while (err == -1 && errno == EINTR);
+ assert(err == pid);
+ } else if (r == -1 && errno == EPIPE) {
+ do
+ err = waitpid(pid, &status, 0); /* okay, got EPIPE */
+ while (err == -1 && errno == EINTR);
+ assert(err == pid);
+ } else
abort();
uv__close(signal_pipe[0]);
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 518a2fce0f2e46..48827b65d36dee 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -88,7 +88,12 @@ void uv__stream_init(uv_loop_t* loop,
stream->write_queue_size = 0;
if (loop->emfile_fd == -1) {
- err = uv__open_cloexec("/", O_RDONLY);
+ err = uv__open_cloexec("/dev/null", O_RDONLY);
+ if (err < 0)
+ /* In the rare case that "/dev/null" isn't mounted open "/"
+ * instead.
+ */
+ err = uv__open_cloexec("/", O_RDONLY);
if (err >= 0)
loop->emfile_fd = err;
}
@@ -301,7 +306,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
if (fds[1] > max_fd)
max_fd = fds[1];
- sread_sz = (max_fd + NBBY) / NBBY;
+ sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY;
swrite_sz = sread_sz;
s = malloc(sizeof(*s) + sread_sz + swrite_sz);
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index b1782df95b2010..7783548a6e987d 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -35,10 +35,19 @@ static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
+ uv_handle_type type;
int flags;
int newfd;
int r;
+ /* File descriptors that refer to files cannot be monitored with epoll.
+ * That restriction also applies to character devices like /dev/random
+ * (but obviously not /dev/tty.)
+ */
+ type = uv_guess_handle(fd);
+ if (type == UV_FILE || type == UV_UNKNOWN_HANDLE)
+ return -EINVAL;
+
flags = 0;
newfd = -1;
@@ -54,7 +63,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
* different struct file, hence changing its properties doesn't affect
* other processes.
*/
- if (isatty(fd)) {
+ if (type == UV_TTY) {
r = uv__open_cloexec("/dev/tty", O_RDWR);
if (r < 0) {
@@ -237,8 +246,10 @@ uv_handle_type uv_guess_handle(uv_file file) {
* critical section when the signal was raised.
*/
int uv_tty_reset_mode(void) {
+ int saved_errno;
int err;
+ saved_errno = errno;
if (!uv_spinlock_trylock(&termios_spinlock))
return -EBUSY; /* In uv_tty_set_mode(). */
@@ -248,5 +259,7 @@ int uv_tty_reset_mode(void) {
err = -errno;
uv_spinlock_unlock(&termios_spinlock);
+ errno = saved_errno;
+
return err;
}
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 941c0aec6e2f0b..22c2e1388e14ac 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -601,40 +601,47 @@ int uv_udp_set_membership(uv_udp_t* handle,
}
}
-
-static int uv__setsockopt_maybe_char(uv_udp_t* handle,
- int option4,
- int option6,
- int val) {
+static int uv__setsockopt(uv_udp_t* handle,
+ int option4,
+ int option6,
+ const void* val,
+ size_t size) {
int r;
-#if defined(__sun) || defined(_AIX)
- char arg = val;
-#else
- int arg = val;
-#endif
-
- if (val < 0 || val > 255)
- return -EINVAL;
if (handle->flags & UV_HANDLE_IPV6)
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IPV6,
option6,
- &arg,
- sizeof(arg));
+ val,
+ size);
else
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IP,
option4,
- &arg,
- sizeof(arg));
-
+ val,
+ size);
if (r)
return -errno;
return 0;
}
+static int uv__setsockopt_maybe_char(uv_udp_t* handle,
+ int option4,
+ int option6,
+ int val) {
+#if defined(__sun) || defined(_AIX)
+ char arg = val;
+#else
+ int arg = val;
+#endif
+
+ if (val < 0 || val > 255)
+ return -EINVAL;
+
+ return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
+}
+
int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
if (setsockopt(handle->io_watcher.fd,
@@ -653,6 +660,20 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return -EINVAL;
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
+ * so hardcode the size of these options on this platform,
+ * and use the general uv__setsockopt_maybe_char call on other platforms.
+ */
+#if defined(__sun)
+ return uv__setsockopt(handle,
+ IP_TTL,
+ IPV6_UNICAST_HOPS,
+ &ttl,
+ sizeof(ttl));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
@@ -661,6 +682,21 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for
+ * 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)
+ if (handle->flags & UV_HANDLE_IPV6)
+ return uv__setsockopt(handle,
+ IP_MULTICAST_TTL,
+ IPV6_MULTICAST_HOPS,
+ &ttl,
+ sizeof(ttl));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
@@ -669,6 +705,21 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for
+ * 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)
+ if (handle->flags & UV_HANDLE_IPV6)
+ return uv__setsockopt(handle,
+ IP_MULTICAST_LOOP,
+ IPV6_MULTICAST_LOOP,
+ &on,
+ sizeof(on));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 791c09b4e28e77..02341f8b95d9c0 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -379,15 +379,28 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
return 0;
}
+/* The windows implementation does not have the same structure layout as
+ * the unix implementation (nbufs is not directly inside req but is
+ * contained in a nested union/struct) so this function locates it.
+*/
+static unsigned int* uv__get_nbufs(uv_fs_t* req) {
+#ifdef _WIN32
+ return &req->fs.info.nbufs;
+#else
+ return &req->nbufs;
+#endif
+}
void uv__fs_scandir_cleanup(uv_fs_t* req) {
uv__dirent_t** dents;
+ unsigned int* nbufs = uv__get_nbufs(req);
+
dents = req->ptr;
- if (req->nbufs > 0 && req->nbufs != (unsigned int) req->result)
- req->nbufs--;
- for (; req->nbufs < (unsigned int) req->result; req->nbufs++)
- free(dents[req->nbufs]);
+ if (*nbufs > 0 && *nbufs != (unsigned int) req->result)
+ (*nbufs)--;
+ for (; *nbufs < (unsigned int) req->result; (*nbufs)++)
+ free(dents[*nbufs]);
}
@@ -395,20 +408,22 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
uv__dirent_t** dents;
uv__dirent_t* dent;
+ unsigned int* nbufs = uv__get_nbufs(req);
+
dents = req->ptr;
/* Free previous entity */
- if (req->nbufs > 0)
- free(dents[req->nbufs - 1]);
+ if (*nbufs > 0)
+ free(dents[*nbufs - 1]);
/* End was already reached */
- if (req->nbufs == (unsigned int) req->result) {
+ if (*nbufs == (unsigned int) req->result) {
free(dents);
req->ptr = NULL;
return UV_EOF;
}
- dent = dents[req->nbufs++];
+ dent = dents[(*nbufs)++];
ent->name = dent->d_name;
#ifdef HAVE_DIRENT_TYPES
@@ -522,6 +537,7 @@ void uv_loop_delete(uv_loop_t* loop) {
default_loop = default_loop_ptr;
err = uv_loop_close(loop);
+ (void) err; /* Squelch compiler warnings. */
assert(err == 0);
if (loop != default_loop)
free(loop);
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index a101159438341f..115449224f9651 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c
index 5c5514736e8304..a265a272dced19 100644
--- a/deps/uv/src/win/error.c
+++ b/deps/uv/src/win/error.c
@@ -21,7 +21,6 @@
#include
#include
-#include
#include
#include
#include
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 7ad99a88b1ebef..640651b6c9634b 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -20,7 +20,6 @@
*/
#include
-#include
#include
#include
#include
@@ -39,7 +38,8 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
assert(handle->dir_handle != INVALID_HANDLE_VALUE);
assert(!handle->req_pending);
- memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));
+ memset(&(handle->req.u.io.overlapped), 0,
+ sizeof(handle->req.u.io.overlapped));
if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer,
uv_directory_watcher_buffer_size,
@@ -53,7 +53,7 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
NULL,
- &handle->req.overlapped,
+ &handle->req.u.io.overlapped,
NULL)) {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(&handle->req, GetLastError());
@@ -232,7 +232,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
- memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));
+ memset(&(handle->req.u.io.overlapped), 0,
+ sizeof(handle->req.u.io.overlapped));
if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer,
@@ -247,7 +248,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
NULL,
- &handle->req.overlapped,
+ &handle->req.u.io.overlapped,
NULL)) {
last_error = GetLastError();
goto error;
@@ -349,7 +350,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
if (REQ_SUCCESS(req)) {
- if (req->overlapped.InternalHigh > 0) {
+ if (req->u.io.overlapped.InternalHigh > 0) {
do {
file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
assert(!filename);
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 33bc9da304054f..af7ec74276f995 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -21,7 +21,6 @@
#include
#include
-#include
#include
#include
#include
@@ -161,8 +160,8 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
if (buf_sz == 0) {
- req->pathw = NULL;
- req->new_pathw = NULL;
+ req->file.pathw = NULL;
+ req->fs.info.new_pathw = NULL;
req->path = NULL;
return 0;
}
@@ -182,10 +181,10 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
(WCHAR*) pos,
pathw_len);
assert(r == (DWORD) pathw_len);
- req->pathw = (WCHAR*) pos;
+ req->file.pathw = (WCHAR*) pos;
pos += r * sizeof(WCHAR);
} else {
- req->pathw = NULL;
+ req->file.pathw = NULL;
}
if (new_path != NULL) {
@@ -196,10 +195,10 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
(WCHAR*) pos,
new_pathw_len);
assert(r == (DWORD) new_pathw_len);
- req->new_pathw = (WCHAR*) pos;
+ req->fs.info.new_pathw = (WCHAR*) pos;
pos += r * sizeof(WCHAR);
} else {
- req->new_pathw = NULL;
+ req->fs.info.new_pathw = NULL;
}
if (!copy_path) {
@@ -388,7 +387,7 @@ void fs__open(uv_fs_t* req) {
DWORD attributes = 0;
HANDLE file;
int fd, current_umask;
- int flags = req->file_flags;
+ int flags = req->fs.info.file_flags;
/* Obtain the active umask. umask() never fails and returns the previous */
/* umask. */
@@ -450,7 +449,7 @@ void fs__open(uv_fs_t* req) {
attributes |= FILE_ATTRIBUTE_NORMAL;
if (flags & _O_CREAT) {
- if (!((req->mode & ~current_umask) & _S_IWRITE)) {
+ if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
attributes |= FILE_ATTRIBUTE_READONLY;
}
}
@@ -480,7 +479,7 @@ void fs__open(uv_fs_t* req) {
/* Setting this flag makes it possible to open a directory. */
attributes |= FILE_FLAG_BACKUP_SEMANTICS;
- file = CreateFileW(req->pathw,
+ file = CreateFileW(req->file.pathw,
access,
share,
NULL,
@@ -512,6 +511,7 @@ void fs__open(uv_fs_t* req) {
SET_REQ_WIN32_ERROR(req, GetLastError());
else
SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+ CloseHandle(file);
return;
}
@@ -523,7 +523,7 @@ void fs__open(uv_fs_t* req) {
}
void fs__close(uv_fs_t* req) {
- int fd = req->fd;
+ int fd = req->file.fd;
int result;
VERIFY_FD(fd, req);
@@ -534,8 +534,8 @@ void fs__close(uv_fs_t* req) {
void fs__read(uv_fs_t* req) {
- int fd = req->fd;
- int64_t offset = req->offset;
+ int fd = req->file.fd;
+ int64_t offset = req->fs.info.offset;
HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_;
@@ -572,13 +572,13 @@ void fs__read(uv_fs_t* req) {
}
result = ReadFile(handle,
- req->bufs[index].base,
- req->bufs[index].len,
+ req->fs.info.bufs[index].base,
+ req->fs.info.bufs[index].len,
&incremental_bytes,
overlapped_ptr);
bytes += incremental_bytes;
++index;
- } while (result && index < req->nbufs);
+ } while (result && index < req->fs.info.nbufs);
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
@@ -594,8 +594,8 @@ void fs__read(uv_fs_t* req) {
void fs__write(uv_fs_t* req) {
- int fd = req->fd;
- int64_t offset = req->offset;
+ int fd = req->file.fd;
+ int64_t offset = req->fs.info.offset;
HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_;
@@ -630,13 +630,13 @@ void fs__write(uv_fs_t* req) {
}
result = WriteFile(handle,
- req->bufs[index].base,
- req->bufs[index].len,
+ req->fs.info.bufs[index].base,
+ req->fs.info.bufs[index].len,
&incremental_bytes,
overlapped_ptr);
bytes += incremental_bytes;
++index;
- } while (result && index < req->nbufs);
+ } while (result && index < req->fs.info.nbufs);
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
@@ -647,13 +647,13 @@ void fs__write(uv_fs_t* req) {
void fs__rmdir(uv_fs_t* req) {
- int result = _wrmdir(req->pathw);
+ int result = _wrmdir(req->file.pathw);
SET_REQ_RESULT(req, result);
}
void fs__unlink(uv_fs_t* req) {
- const WCHAR* pathw = req->pathw;
+ const WCHAR* pathw = req->file.pathw;
HANDLE handle;
BY_HANDLE_FILE_INFORMATION info;
FILE_DISPOSITION_INFORMATION disposition;
@@ -661,7 +661,7 @@ void fs__unlink(uv_fs_t* req) {
NTSTATUS status;
handle = CreateFileW(pathw,
- FILE_READ_ATTRIBUTES | DELETE,
+ FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
@@ -703,6 +703,24 @@ void fs__unlink(uv_fs_t* req) {
}
}
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ /* Remove read-only attribute */
+ FILE_BASIC_INFORMATION basic = { 0 };
+
+ basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY);
+
+ status = pNtSetInformationFile(handle,
+ &iosb,
+ &basic,
+ sizeof basic,
+ FileBasicInformation);
+ if (!NT_SUCCESS(status)) {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+ CloseHandle(handle);
+ return;
+ }
+ }
+
/* Try to set the delete flag. */
disposition.DeleteFile = TRUE;
status = pNtSetInformationFile(handle,
@@ -722,7 +740,7 @@ void fs__unlink(uv_fs_t* req) {
void fs__mkdir(uv_fs_t* req) {
/* TODO: use req->mode. */
- int result = _wmkdir(req->pathw);
+ int result = _wmkdir(req->file.pathw);
SET_REQ_RESULT(req, result);
}
@@ -740,8 +758,8 @@ void fs__mkdtemp(uv_fs_t* req) {
uint64_t v;
BOOL released;
- len = wcslen(req->pathw);
- ep = req->pathw + len;
+ len = wcslen(req->file.pathw);
+ ep = req->file.pathw + len;
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return;
@@ -766,7 +784,7 @@ void fs__mkdtemp(uv_fs_t* req) {
v /= num_chars;
}
- if (_wmkdir(req->pathw) == 0) {
+ if (_wmkdir(req->file.pathw) == 0) {
len = strlen(req->path);
wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
SET_REQ_RESULT(req, 0);
@@ -810,7 +828,7 @@ void fs__scandir(uv_fs_t* req) {
/* Open the directory. */
dir_handle =
- CreateFileW(req->pathw,
+ CreateFileW(req->file.pathw,
FILE_LIST_DIRECTORY | SYNCHRONIZE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -956,7 +974,7 @@ void fs__scandir(uv_fs_t* req) {
SET_REQ_RESULT(req, dirents_used);
/* `nbufs` will be used as index by uv_fs_scandir_next. */
- req->nbufs = 0;
+ req->fs.info.nbufs = 0;
return;
@@ -1125,7 +1143,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
}
- handle = CreateFileW(req->pathw,
+ handle = CreateFileW(req->file.pathw,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -1159,19 +1177,19 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
static void fs__stat(uv_fs_t* req) {
- fs__stat_prepare_path(req->pathw);
+ fs__stat_prepare_path(req->file.pathw);
fs__stat_impl(req, 0);
}
static void fs__lstat(uv_fs_t* req) {
- fs__stat_prepare_path(req->pathw);
+ fs__stat_prepare_path(req->file.pathw);
fs__stat_impl(req, 1);
}
static void fs__fstat(uv_fs_t* req) {
- int fd = req->fd;
+ int fd = req->file.fd;
HANDLE handle;
VERIFY_FD(fd, req);
@@ -1194,7 +1212,7 @@ static void fs__fstat(uv_fs_t* req) {
static void fs__rename(uv_fs_t* req) {
- if (!MoveFileExW(req->pathw, req->new_pathw, MOVEFILE_REPLACE_EXISTING)) {
+ if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
@@ -1204,7 +1222,7 @@ static void fs__rename(uv_fs_t* req) {
INLINE static void fs__sync_impl(uv_fs_t* req) {
- int fd = req->fd;
+ int fd = req->file.fd;
int result;
VERIFY_FD(fd, req);
@@ -1229,7 +1247,7 @@ static void fs__fdatasync(uv_fs_t* req) {
static void fs__ftruncate(uv_fs_t* req) {
- int fd = req->fd;
+ int fd = req->file.fd;
HANDLE handle;
NTSTATUS status;
IO_STATUS_BLOCK io_status;
@@ -1239,7 +1257,7 @@ static void fs__ftruncate(uv_fs_t* req) {
handle = uv__get_osfhandle(fd);
- eof_info.EndOfFile.QuadPart = req->offset;
+ eof_info.EndOfFile.QuadPart = req->fs.info.offset;
status = pNtSetInformationFile(handle,
&io_status,
@@ -1256,9 +1274,9 @@ static void fs__ftruncate(uv_fs_t* req) {
static void fs__sendfile(uv_fs_t* req) {
- int fd_in = req->fd, fd_out = req->fd_out;
- size_t length = req->bufsml[0].len;
- int64_t offset = req->offset;
+ int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
+ size_t length = req->fs.info.bufsml[0].len;
+ int64_t offset = req->fs.info.offset;
const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size;
int n, result = 0;
@@ -1303,32 +1321,39 @@ static void fs__sendfile(uv_fs_t* req) {
static void fs__access(uv_fs_t* req) {
- DWORD attr = GetFileAttributesW(req->pathw);
+ DWORD attr = GetFileAttributesW(req->file.pathw);
if (attr == INVALID_FILE_ATTRIBUTES) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
- if ((req->flags & W_OK) &&
- ((attr & FILE_ATTRIBUTE_READONLY) ||
- (attr & FILE_ATTRIBUTE_DIRECTORY))) {
+ /*
+ * Access is possible if
+ * - write access wasn't requested,
+ * - or the file isn't read-only,
+ * - or it's a directory.
+ * (Directories cannot be read-only on Windows.)
+ */
+ if (!(req->flags & W_OK) ||
+ !(attr & FILE_ATTRIBUTE_READONLY) ||
+ (attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ SET_REQ_RESULT(req, 0);
+ } else {
SET_REQ_WIN32_ERROR(req, UV_EPERM);
- return;
}
- SET_REQ_RESULT(req, 0);
}
static void fs__chmod(uv_fs_t* req) {
- int result = _wchmod(req->pathw, req->mode);
+ int result = _wchmod(req->file.pathw, req->fs.info.mode);
SET_REQ_RESULT(req, result);
}
static void fs__fchmod(uv_fs_t* req) {
- int fd = req->fd;
+ int fd = req->file.fd;
HANDLE handle;
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
@@ -1349,7 +1374,7 @@ static void fs__fchmod(uv_fs_t* req) {
return;
}
- if (req->mode & _S_IWRITE) {
+ if (req->fs.info.mode & _S_IWRITE) {
file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
} else {
file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
@@ -1387,7 +1412,7 @@ INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
static void fs__utime(uv_fs_t* req) {
HANDLE handle;
- handle = CreateFileW(req->pathw,
+ handle = CreateFileW(req->file.pathw,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -1400,7 +1425,7 @@ static void fs__utime(uv_fs_t* req) {
return;
}
- if (fs__utime_handle(handle, req->atime, req->mtime) != 0) {
+ if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
CloseHandle(handle);
return;
@@ -1413,7 +1438,7 @@ static void fs__utime(uv_fs_t* req) {
static void fs__futime(uv_fs_t* req) {
- int fd = req->fd;
+ int fd = req->file.fd;
HANDLE handle;
VERIFY_FD(fd, req);
@@ -1424,7 +1449,7 @@ static void fs__futime(uv_fs_t* req) {
return;
}
- if (fs__utime_handle(handle, req->atime, req->mtime) != 0) {
+ if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
@@ -1434,7 +1459,7 @@ static void fs__futime(uv_fs_t* req) {
static void fs__link(uv_fs_t* req) {
- DWORD r = CreateHardLinkW(req->new_pathw, req->pathw, NULL);
+ DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL);
if (r == 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
} else {
@@ -1614,9 +1639,9 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
static void fs__symlink(uv_fs_t* req) {
- WCHAR* pathw = req->pathw;
- WCHAR* new_pathw = req->new_pathw;
- int flags = req->file_flags;
+ WCHAR* pathw = req->file.pathw;
+ WCHAR* new_pathw = req->fs.info.new_pathw;
+ int flags = req->fs.info.file_flags;
int result;
@@ -1640,7 +1665,7 @@ static void fs__symlink(uv_fs_t* req) {
static void fs__readlink(uv_fs_t* req) {
HANDLE handle;
- handle = CreateFileW(req->pathw,
+ handle = CreateFileW(req->file.pathw,
0,
0,
NULL,
@@ -1739,14 +1764,14 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
return;
if (req->flags & UV_FS_FREE_PATHS)
- free(req->pathw);
+ free(req->file.pathw);
if (req->flags & UV_FS_FREE_PTR)
free(req->ptr);
req->path = NULL;
- req->pathw = NULL;
- req->new_pathw = NULL;
+ req->file.pathw = NULL;
+ req->fs.info.new_pathw = NULL;
req->ptr = NULL;
req->flags |= UV_FS_CLEANEDUP;
@@ -1764,8 +1789,8 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
return uv_translate_sys_error(err);
}
- req->file_flags = flags;
- req->mode = mode;
+ req->fs.info.file_flags = flags;
+ req->fs.info.mode = mode;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -1779,7 +1804,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
- req->fd = fd;
+ req->file.fd = fd;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -1800,19 +1825,19 @@ int uv_fs_read(uv_loop_t* loop,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_READ, cb);
- req->fd = fd;
+ req->file.fd = fd;
- req->nbufs = nbufs;
- req->bufs = req->bufsml;
- if (nbufs > ARRAY_SIZE(req->bufsml))
- req->bufs = malloc(nbufs * sizeof(*bufs));
+ req->fs.info.nbufs = nbufs;
+ req->fs.info.bufs = req->fs.info.bufsml;
+ if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
+ req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
- if (req->bufs == NULL)
+ if (req->fs.info.bufs == NULL)
return UV_ENOMEM;
- memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
+ memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
- req->offset = offset;
+ req->fs.info.offset = offset;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -1833,19 +1858,19 @@ int uv_fs_write(uv_loop_t* loop,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
- req->fd = fd;
+ req->file.fd = fd;
- req->nbufs = nbufs;
- req->bufs = req->bufsml;
- if (nbufs > ARRAY_SIZE(req->bufsml))
- req->bufs = malloc(nbufs * sizeof(*bufs));
+ req->fs.info.nbufs = nbufs;
+ req->fs.info.bufs = req->fs.info.bufsml;
+ if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
+ req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
- if (req->bufs == NULL)
+ if (req->fs.info.bufs == NULL)
return UV_ENOMEM;
- memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
+ memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
- req->offset = offset;
+ req->fs.info.offset = offset;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -1889,7 +1914,7 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
return uv_translate_sys_error(err);
}
- req->mode = mode;
+ req->fs.info.mode = mode;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -1952,7 +1977,7 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
return uv_translate_sys_error(err);
}
- req->file_flags = flags;
+ req->fs.info.file_flags = flags;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -1996,7 +2021,7 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
return uv_translate_sys_error(err);
}
- req->file_flags = flags;
+ req->fs.info.file_flags = flags;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2106,7 +2131,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
- req->fd = fd;
+ req->file.fd = fd;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2141,7 +2166,7 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
- req->fd = fd;
+ req->file.fd = fd;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2155,7 +2180,7 @@ int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
- req->fd = fd;
+ req->file.fd = fd;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2171,8 +2196,8 @@ int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd,
int64_t offset, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
- req->fd = fd;
- req->offset = offset;
+ req->file.fd = fd;
+ req->fs.info.offset = offset;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2189,10 +2214,10 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
- req->fd = fd_in;
- req->fd_out = fd_out;
- req->offset = in_offset;
- req->bufsml[0].len = length;
+ req->file.fd = fd_in;
+ req->fs.info.fd_out = fd_out;
+ req->fs.info.offset = in_offset;
+ req->fs.info.bufsml[0].len = length;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2240,7 +2265,7 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
return uv_translate_sys_error(err);
}
- req->mode = mode;
+ req->fs.info.mode = mode;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2256,8 +2281,8 @@ int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb);
- req->fd = fd;
- req->mode = mode;
+ req->file.fd = fd;
+ req->fs.info.mode = mode;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2280,8 +2305,8 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
return uv_translate_sys_error(err);
}
- req->atime = atime;
- req->mtime = mtime;
+ req->fs.time.atime = atime;
+ req->fs.time.mtime = mtime;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@@ -2297,9 +2322,9 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
double mtime, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FUTIME, cb);
- req->fd = fd;
- req->atime = atime;
- req->mtime = mtime;
+ req->file.fd = fd;
+ req->fs.time.atime = atime;
+ req->fs.time.mtime = mtime;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c
index f103f5fbd3418a..f3802cd5829208 100644
--- a/deps/uv/src/win/getaddrinfo.c
+++ b/deps/uv/src/win/getaddrinfo.c
@@ -20,7 +20,6 @@
*/
#include
-#include
#include "uv.h"
#include "internal.h"
diff --git a/deps/uv/src/win/getnameinfo.c b/deps/uv/src/win/getnameinfo.c
index b1d045c79bd9db..66b64b883248e3 100644
--- a/deps/uv/src/win/getnameinfo.c
+++ b/deps/uv/src/win/getnameinfo.c
@@ -20,7 +20,6 @@
*/
#include
-#include
#include
#include "uv.h"
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 57fab065aa346b..5a0e5420847b12 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -95,15 +95,15 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
handle->reqs_pending = 0;
handle->handle = INVALID_HANDLE_VALUE;
handle->name = NULL;
- handle->ipc_pid = 0;
- handle->remaining_ipc_rawdata_bytes = 0;
- QUEUE_INIT(&handle->pending_ipc_info.queue);
- handle->pending_ipc_info.queue_len = 0;
+ handle->pipe.conn.ipc_pid = 0;
+ handle->pipe.conn.remaining_ipc_rawdata_bytes = 0;
+ QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue);
+ handle->pipe.conn.pending_ipc_info.queue_len = 0;
handle->ipc = ipc;
- handle->non_overlapped_writes_tail = NULL;
- handle->readfile_thread = NULL;
+ handle->pipe.conn.non_overlapped_writes_tail = NULL;
+ handle->pipe.conn.readfile_thread = NULL;
- uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
+ uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req);
return 0;
}
@@ -112,11 +112,11 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
static void uv_pipe_connection_init(uv_pipe_t* handle) {
uv_connection_init((uv_stream_t*) handle);
handle->read_req.data = handle;
- handle->eof_timer = NULL;
+ handle->pipe.conn.eof_timer = NULL;
assert(!(handle->flags & UV_HANDLE_PIPESERVER));
if (pCancelSynchronousIo &&
handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
- uv_mutex_init(&handle->readfile_mutex);
+ uv_mutex_init(&handle->pipe.conn.readfile_mutex);
handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
}
}
@@ -330,16 +330,16 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
- uv_mutex_destroy(&handle->readfile_mutex);
+ uv_mutex_destroy(&handle->pipe.conn.readfile_mutex);
}
if ((handle->flags & UV_HANDLE_CONNECTION) &&
- handle->shutdown_req != NULL &&
- handle->write_reqs_pending == 0) {
- req = handle->shutdown_req;
+ handle->stream.conn.shutdown_req != NULL &&
+ handle->stream.conn.write_reqs_pending == 0) {
+ req = handle->stream.conn.shutdown_req;
/* Clear the shutdown_req field so we don't go here again. */
- handle->shutdown_req = NULL;
+ handle->stream.conn.shutdown_req = NULL;
if (handle->flags & UV__HANDLE_CLOSING) {
UNREGISTER_HANDLE_REQ(loop, handle, req);
@@ -408,11 +408,11 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (handle->flags & UV_HANDLE_CONNECTION) {
/* Free pending sockets */
- while (!QUEUE_EMPTY(&handle->pending_ipc_info.queue)) {
+ while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) {
QUEUE* q;
SOCKET socket;
- q = QUEUE_HEAD(&handle->pending_ipc_info.queue);
+ q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue);
QUEUE_REMOVE(q);
item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
@@ -428,7 +428,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (socket != INVALID_SOCKET)
closesocket(socket);
}
- handle->pending_ipc_info.queue_len = 0;
+ handle->pipe.conn.pending_ipc_info.queue_len = 0;
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
@@ -443,9 +443,9 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}
if (handle->flags & UV_HANDLE_PIPESERVER) {
- assert(handle->accept_reqs);
- free(handle->accept_reqs);
- handle->accept_reqs = NULL;
+ assert(handle->pipe.serv.accept_reqs);
+ free(handle->pipe.serv.accept_reqs);
+ handle->pipe.serv.accept_reqs = NULL;
}
uv__handle_close(handle);
@@ -454,7 +454,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
- handle->pending_instances = count;
+ handle->pipe.serv.pending_instances = count;
handle->flags |= UV_HANDLE_PIPESERVER;
}
@@ -474,17 +474,17 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
- handle->pending_instances = default_pending_pipe_instances;
+ handle->pipe.serv.pending_instances = default_pending_pipe_instances;
}
- handle->accept_reqs = (uv_pipe_accept_t*)
- malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
- if (!handle->accept_reqs) {
+ handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
+ malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
+ if (!handle->pipe.serv.accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
- for (i = 0; i < handle->pending_instances; i++) {
- req = &handle->accept_reqs[i];
+ for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
+ req = &handle->pipe.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT;
req->data = handle;
@@ -508,13 +508,13 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
* Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
* If this fails then there's already a pipe server for the given pipe name.
*/
- handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
+ handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
- if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
+ if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */
@@ -524,12 +524,15 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
goto error;
}
- if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) {
+ if (uv_set_pipe_handle(loop,
+ handle,
+ handle->pipe.serv.accept_reqs[0].pipeHandle,
+ 0)) {
err = GetLastError();
goto error;
}
- handle->pending_accepts = NULL;
+ handle->pipe.serv.pending_accepts = NULL;
handle->flags |= UV_HANDLE_PIPESERVER;
handle->flags |= UV_HANDLE_BOUND;
@@ -541,9 +544,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
handle->name = NULL;
}
- if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
- CloseHandle(handle->accept_reqs[0].pipeHandle);
- handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
+ if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle);
+ handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
}
return uv_translate_sys_error(err);
@@ -677,15 +680,15 @@ void uv__pipe_pause_read(uv_pipe_t* handle) {
any access to a NamedPipe to deadlock if
any process has called ReadFile */
HANDLE h;
- uv_mutex_lock(&handle->readfile_mutex);
- h = handle->readfile_thread;
+ uv_mutex_lock(&handle->pipe.conn.readfile_mutex);
+ h = handle->pipe.conn.readfile_thread;
while (h) {
/* spinlock: we expect this to finish quickly,
or we are probably about to deadlock anyways
(in the kernel), so it doesn't matter */
pCancelSynchronousIo(h);
SwitchToThread(); /* yield thread control briefly */
- h = handle->readfile_thread;
+ h = handle->pipe.conn.readfile_thread;
}
}
}
@@ -693,7 +696,7 @@ void uv__pipe_pause_read(uv_pipe_t* handle) {
void uv__pipe_unpause_read(uv_pipe_t* handle) {
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- uv_mutex_unlock(&handle->readfile_mutex);
+ uv_mutex_unlock(&handle->pipe.conn.readfile_mutex);
}
}
@@ -719,11 +722,11 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
}
if (handle->flags & UV_HANDLE_PIPESERVER) {
- for (i = 0; i < handle->pending_instances; i++) {
- pipeHandle = handle->accept_reqs[i].pipeHandle;
+ for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
+ pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle;
if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle);
- handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
+ handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
}
}
}
@@ -796,9 +799,9 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
assert(req->pipeHandle != INVALID_HANDLE_VALUE);
/* Prepare the overlapped structure. */
- memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
- if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) &&
+ if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) &&
GetLastError() != ERROR_IO_PENDING) {
if (GetLastError() == ERROR_PIPE_CONNECTED) {
SET_REQ_SUCCESS(req);
@@ -826,14 +829,14 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
int err;
if (server->ipc) {
- if (QUEUE_EMPTY(&server->pending_ipc_info.queue)) {
+ if (QUEUE_EMPTY(&server->pipe.conn.pending_ipc_info.queue)) {
/* No valid pending sockets. */
return WSAEWOULDBLOCK;
}
- q = QUEUE_HEAD(&server->pending_ipc_info.queue);
+ q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue);
QUEUE_REMOVE(q);
- server->pending_ipc_info.queue_len--;
+ server->pipe.conn.pending_ipc_info.queue_len--;
item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
err = uv_tcp_import((uv_tcp_t*)client,
@@ -849,7 +852,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
/* Find a connection instance that has been connected, but not yet */
/* accepted. */
- req = server->pending_accepts;
+ req = server->pipe.serv.pending_accepts;
if (!req) {
/* No valid connections found, so we error out. */
@@ -862,7 +865,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
/* Prepare the req to pick up a new connection */
- server->pending_accepts = req->next_pending;
+ server->pipe.serv.pending_accepts = req->next_pending;
req->next_pending = NULL;
req->pipeHandle = INVALID_HANDLE_VALUE;
@@ -881,7 +884,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
int i;
if (handle->flags & UV_HANDLE_LISTENING) {
- handle->connection_cb = cb;
+ handle->stream.serv.connection_cb = cb;
}
if (!(handle->flags & UV_HANDLE_BOUND)) {
@@ -898,13 +901,13 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
handle->flags |= UV_HANDLE_LISTENING;
INCREASE_ACTIVE_COUNT(loop, handle);
- handle->connection_cb = cb;
+ handle->stream.serv.connection_cb = cb;
/* First pipe handle should have already been created in uv_pipe_bind */
- assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
+ assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
- for (i = 0; i < handle->pending_instances; i++) {
- uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
+ for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
+ uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0);
}
return 0;
@@ -919,7 +922,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
uv_loop_t* loop = handle->loop;
HANDLE hThread = NULL;
DWORD err;
- uv_mutex_t *m = &handle->readfile_mutex;
+ uv_mutex_t *m = &handle->pipe.conn.readfile_mutex;
assert(req != NULL);
assert(req->type == UV_READ);
@@ -930,7 +933,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &hThread,
0, TRUE, DUPLICATE_SAME_ACCESS)) {
- handle->readfile_thread = hThread;
+ handle->pipe.conn.readfile_thread = hThread;
} else {
hThread = NULL;
}
@@ -948,10 +951,10 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
if (handle->flags & UV_HANDLE_READING) {
/* just a brief break to do something else */
- handle->readfile_thread = NULL;
+ handle->pipe.conn.readfile_thread = NULL;
/* resume after it is finished */
uv_mutex_lock(m);
- handle->readfile_thread = hThread;
+ handle->pipe.conn.readfile_thread = hThread;
uv_mutex_unlock(m);
goto restart_readfile;
} else {
@@ -960,9 +963,9 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
}
}
if (hThread) {
- assert(hThread == handle->readfile_thread);
+ assert(hThread == handle->pipe.conn.readfile_thread);
/* mutex does not control clearing readfile_thread */
- handle->readfile_thread = NULL;
+ handle->pipe.conn.readfile_thread = NULL;
uv_mutex_lock(m);
/* only when we hold the mutex lock is it safe to
open or close the handle */
@@ -1017,9 +1020,9 @@ static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out)
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
- req->overlapped.InternalHigh,
+ req->u.io.overlapped.InternalHigh,
0,
- &req->overlapped)) {
+ &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
}
@@ -1036,9 +1039,9 @@ static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
- req->overlapped.InternalHigh,
+ req->u.io.overlapped.InternalHigh,
0,
- &req->overlapped)) {
+ &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
}
@@ -1064,9 +1067,9 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
goto error;
}
} else {
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
- req->overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
+ req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
}
/* Do 0-read */
@@ -1074,7 +1077,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
&uv_zero_,
0,
NULL,
- &req->overlapped);
+ &req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
/* Make this req pending reporting an error. */
@@ -1091,7 +1094,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
}
if (req->wait_handle == INVALID_HANDLE_VALUE) {
if (!RegisterWaitForSingleObject(&req->wait_handle,
- req->overlapped.hEvent, post_completion_read_wait, (void*) req,
+ req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req,
INFINITE, WT_EXECUTEINWAITTHREAD)) {
SET_REQ_ERROR(req, GetLastError());
goto error;
@@ -1135,14 +1138,14 @@ int uv_pipe_read_start(uv_pipe_t* handle,
static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle,
uv_write_t* req) {
req->next_req = NULL;
- if (handle->non_overlapped_writes_tail) {
+ if (handle->pipe.conn.non_overlapped_writes_tail) {
req->next_req =
- handle->non_overlapped_writes_tail->next_req;
- handle->non_overlapped_writes_tail->next_req = (uv_req_t*)req;
- handle->non_overlapped_writes_tail = req;
+ handle->pipe.conn.non_overlapped_writes_tail->next_req;
+ handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req;
+ handle->pipe.conn.non_overlapped_writes_tail = req;
} else {
req->next_req = (uv_req_t*)req;
- handle->non_overlapped_writes_tail = req;
+ handle->pipe.conn.non_overlapped_writes_tail = req;
}
}
@@ -1150,13 +1153,13 @@ static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle,
static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) {
uv_write_t* req;
- if (handle->non_overlapped_writes_tail) {
- req = (uv_write_t*)handle->non_overlapped_writes_tail->next_req;
+ if (handle->pipe.conn.non_overlapped_writes_tail) {
+ req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req;
- if (req == handle->non_overlapped_writes_tail) {
- handle->non_overlapped_writes_tail = NULL;
+ if (req == handle->pipe.conn.non_overlapped_writes_tail) {
+ handle->pipe.conn.non_overlapped_writes_tail = NULL;
} else {
- handle->non_overlapped_writes_tail->next_req =
+ handle->pipe.conn.non_overlapped_writes_tail->next_req =
req->next_req;
}
@@ -1213,7 +1216,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
req->ipc_header = 0;
req->event_handle = NULL;
req->wait_handle = INVALID_HANDLE_VALUE;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
if (handle->ipc) {
assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
@@ -1223,7 +1226,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
if (send_handle) {
tcp_send_handle = (uv_tcp_t*)send_handle;
- err = uv_tcp_duplicate_socket(tcp_send_handle, handle->ipc_pid,
+ err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid,
&ipc_frame.socket_info_ex.socket_info);
if (err) {
return err;
@@ -1255,8 +1258,8 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
* Try to use the preallocated write req if it's available.
* Otherwise allocate a new one.
*/
- if (handle->ipc_header_write_req.type != UV_WRITE) {
- ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req;
+ if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) {
+ ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req;
} else {
ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
if (!ipc_header_req) {
@@ -1272,12 +1275,13 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
}
/* Write the header or the whole frame. */
- memset(&ipc_header_req->overlapped, 0, sizeof(ipc_header_req->overlapped));
+ memset(&ipc_header_req->u.io.overlapped, 0,
+ sizeof(ipc_header_req->u.io.overlapped));
/* Using overlapped IO, but wait for completion before returning.
This write is blocking because ipc_frame is on stack. */
- ipc_header_req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
- if (!ipc_header_req->overlapped.hEvent) {
+ ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
+ if (!ipc_header_req->u.io.overlapped.hEvent) {
uv_fatal_error(GetLastError(), "CreateEvent");
}
@@ -1286,29 +1290,29 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
sizeof(ipc_frame) : sizeof(ipc_frame.header),
NULL,
- &ipc_header_req->overlapped);
+ &ipc_header_req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
err = GetLastError();
- CloseHandle(ipc_header_req->overlapped.hEvent);
+ CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
return err;
}
if (!result) {
/* Request not completed immediately. Wait for it.*/
- if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) !=
+ if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) {
err = GetLastError();
- CloseHandle(ipc_header_req->overlapped.hEvent);
+ CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
return err;
}
}
- ipc_header_req->queued_bytes = 0;
- CloseHandle(ipc_header_req->overlapped.hEvent);
- ipc_header_req->overlapped.hEvent = NULL;
+ ipc_header_req->u.io.queued_bytes = 0;
+ CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
+ ipc_header_req->u.io.overlapped.hEvent = NULL;
REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
handle->reqs_pending++;
- handle->write_reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
/* If we don't have any raw data to write - we're done. */
if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
@@ -1331,28 +1335,28 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
return err;
} else {
/* Request completed immediately. */
- req->queued_bytes = 0;
+ req->u.io.queued_bytes = 0;
}
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
- handle->write_reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
} else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
req->write_buffer = bufs[0];
uv_insert_non_overlapped_write_req(handle, req);
- if (handle->write_reqs_pending == 0) {
+ if (handle->stream.conn.write_reqs_pending == 0) {
uv_queue_non_overlapped_write(handle);
}
/* Request queued by the kernel. */
- req->queued_bytes = uv__count_bufs(bufs, nbufs);
- handle->write_queue_size += req->queued_bytes;
+ req->u.io.queued_bytes = bufs[0].len;
+ handle->write_queue_size += req->u.io.queued_bytes;
} else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
/* Using overlapped IO, but wait for completion before returning */
- req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
- if (!req->overlapped.hEvent) {
+ req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
+ if (!req->u.io.overlapped.hEvent) {
uv_fatal_error(GetLastError(), "CreateEvent");
}
@@ -1360,40 +1364,40 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
bufs[0].base,
bufs[0].len,
NULL,
- &req->overlapped);
+ &req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
err = GetLastError();
- CloseHandle(req->overlapped.hEvent);
+ CloseHandle(req->u.io.overlapped.hEvent);
return err;
}
if (result) {
/* Request completed immediately. */
- req->queued_bytes = 0;
+ req->u.io.queued_bytes = 0;
} else {
- assert(ipc_header_req != NULL);
/* Request queued by the kernel. */
- if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) !=
+ req->u.io.queued_bytes = bufs[0].len;
+ handle->write_queue_size += req->u.io.queued_bytes;
+ if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) {
err = GetLastError();
- CloseHandle(ipc_header_req->overlapped.hEvent);
+ CloseHandle(req->u.io.overlapped.hEvent);
return uv_translate_sys_error(err);
}
}
- CloseHandle(req->overlapped.hEvent);
+ CloseHandle(req->u.io.overlapped.hEvent);
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
- handle->write_reqs_pending++;
- POST_COMPLETION_FOR_REQ(loop, req);
+ handle->stream.conn.write_reqs_pending++;
return 0;
} else {
result = WriteFile(handle->handle,
bufs[0].base,
bufs[0].len,
NULL,
- &req->overlapped);
+ &req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
return GetLastError();
@@ -1401,11 +1405,11 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
if (result) {
/* Request completed immediately. */
- req->queued_bytes = 0;
+ req->u.io.queued_bytes = 0;
} else {
/* Request queued by the kernel. */
- req->queued_bytes = uv__count_bufs(bufs, nbufs);
- handle->write_queue_size += req->queued_bytes;
+ req->u.io.queued_bytes = bufs[0].len;
+ handle->write_queue_size += req->u.io.queued_bytes;
}
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
@@ -1414,7 +1418,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
uv_fatal_error(GetLastError(), "CreateEvent");
}
if (!RegisterWaitForSingleObject(&req->wait_handle,
- req->overlapped.hEvent, post_completion_write_wait, (void*) req,
+ req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req,
INFINITE, WT_EXECUTEINWAITTHREAD)) {
return GetLastError();
}
@@ -1423,7 +1427,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
- handle->write_reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
return 0;
}
@@ -1500,8 +1504,8 @@ void uv__pipe_insert_pending_socket(uv_pipe_t* handle,
memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex));
item->tcp_connection = tcp_connection;
- QUEUE_INSERT_TAIL(&handle->pending_ipc_info.queue, &item->member);
- handle->pending_ipc_info.queue_len++;
+ QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member);
+ handle->pipe.conn.pending_ipc_info.queue_len++;
}
@@ -1544,7 +1548,7 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
if (handle->ipc) {
/* Use the IPC framing protocol to read the incoming data. */
- if (handle->remaining_ipc_rawdata_bytes == 0) {
+ if (handle->pipe.conn.remaining_ipc_rawdata_bytes == 0) {
/* We're reading a new frame. First, read the header. */
assert(avail >= sizeof(ipc_frame.header));
@@ -1587,12 +1591,12 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
}
if (ipc_frame.header.flags & UV_IPC_RAW_DATA) {
- handle->remaining_ipc_rawdata_bytes =
+ handle->pipe.conn.remaining_ipc_rawdata_bytes =
ipc_frame.header.raw_data_length;
continue;
}
} else {
- avail = min(avail, (DWORD)handle->remaining_ipc_rawdata_bytes);
+ avail = min(avail, (DWORD)handle->pipe.conn.remaining_ipc_rawdata_bytes);
}
}
@@ -1610,9 +1614,9 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
NULL)) {
/* Successful read */
if (handle->ipc) {
- assert(handle->remaining_ipc_rawdata_bytes >= bytes);
- handle->remaining_ipc_rawdata_bytes =
- handle->remaining_ipc_rawdata_bytes - bytes;
+ assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes);
+ handle->pipe.conn.remaining_ipc_rawdata_bytes =
+ handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes;
}
handle->read_cb((uv_stream_t*)handle, bytes, &buf);
@@ -1643,8 +1647,8 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
assert(handle->type == UV_NAMED_PIPE);
- assert(handle->write_queue_size >= req->queued_bytes);
- handle->write_queue_size -= req->queued_bytes;
+ assert(handle->write_queue_size >= req->u.io.queued_bytes);
+ handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req);
@@ -1660,7 +1664,7 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
}
if (req->ipc_header) {
- if (req == &handle->ipc_header_write_req) {
+ if (req == &handle->pipe.conn.ipc_header_write_req) {
req->type = UV_UNKNOWN_REQ;
} else {
free(req);
@@ -1672,16 +1676,16 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
}
}
- handle->write_reqs_pending--;
+ handle->stream.conn.write_reqs_pending--;
if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE &&
- handle->non_overlapped_writes_tail) {
- assert(handle->write_reqs_pending > 0);
+ handle->pipe.conn.non_overlapped_writes_tail) {
+ assert(handle->stream.conn.write_reqs_pending > 0);
uv_queue_non_overlapped_write(handle);
}
- if (handle->shutdown_req != NULL &&
- handle->write_reqs_pending == 0) {
+ if (handle->stream.conn.shutdown_req != NULL &&
+ handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@@ -1704,11 +1708,11 @@ void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
if (REQ_SUCCESS(req)) {
assert(req->pipeHandle != INVALID_HANDLE_VALUE);
- req->next_pending = handle->pending_accepts;
- handle->pending_accepts = req;
+ req->next_pending = handle->pipe.serv.pending_accepts;
+ handle->pipe.serv.pending_accepts = req;
- if (handle->connection_cb) {
- handle->connection_cb((uv_stream_t*)handle, 0);
+ if (handle->stream.serv.connection_cb) {
+ handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
}
} else {
if (req->pipeHandle != INVALID_HANDLE_VALUE) {
@@ -1781,23 +1785,23 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
static void eof_timer_init(uv_pipe_t* pipe) {
int r;
- assert(pipe->eof_timer == NULL);
+ assert(pipe->pipe.conn.eof_timer == NULL);
assert(pipe->flags & UV_HANDLE_CONNECTION);
- pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer);
+ pipe->pipe.conn.eof_timer = (uv_timer_t*) malloc(sizeof *pipe->pipe.conn.eof_timer);
- r = uv_timer_init(pipe->loop, pipe->eof_timer);
+ r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer);
assert(r == 0); /* timers can't fail */
- pipe->eof_timer->data = pipe;
- uv_unref((uv_handle_t*) pipe->eof_timer);
+ pipe->pipe.conn.eof_timer->data = pipe;
+ uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer);
}
static void eof_timer_start(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION);
- if (pipe->eof_timer != NULL) {
- uv_timer_start(pipe->eof_timer, eof_timer_cb, eof_timeout, 0);
+ if (pipe->pipe.conn.eof_timer != NULL) {
+ uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0);
}
}
@@ -1805,8 +1809,8 @@ static void eof_timer_start(uv_pipe_t* pipe) {
static void eof_timer_stop(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION);
- if (pipe->eof_timer != NULL) {
- uv_timer_stop(pipe->eof_timer);
+ if (pipe->pipe.conn.eof_timer != NULL) {
+ uv_timer_stop(pipe->pipe.conn.eof_timer);
}
}
@@ -1829,7 +1833,7 @@ static void eof_timer_cb(uv_timer_t* timer) {
/* Therefore we check here if the read request has completed but will */
/* be processed later. */
if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
- HasOverlappedIoCompleted(&pipe->read_req.overlapped)) {
+ HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
return;
}
@@ -1850,9 +1854,9 @@ static void eof_timer_cb(uv_timer_t* timer) {
static void eof_timer_destroy(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION);
- if (pipe->eof_timer) {
- uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb);
- pipe->eof_timer = NULL;
+ if (pipe->pipe.conn.eof_timer) {
+ uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb);
+ pipe->pipe.conn.eof_timer = NULL;
}
}
@@ -1903,8 +1907,8 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
- pipe->ipc_pid = uv_parent_pid();
- assert(pipe->ipc_pid != -1);
+ pipe->pipe.conn.ipc_pid = uv_parent_pid();
+ assert(pipe->pipe.conn.ipc_pid != -1);
}
return 0;
}
@@ -2027,7 +2031,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
int uv_pipe_pending_count(uv_pipe_t* handle) {
if (!handle->ipc)
return 0;
- return handle->pending_ipc_info.queue_len;
+ return handle->pipe.conn.pending_ipc_info.queue_len;
}
@@ -2060,7 +2064,7 @@ int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
if (!handle->ipc)
return UV_UNKNOWN_HANDLE;
- if (handle->pending_ipc_info.queue_len == 0)
+ if (handle->pipe.conn.pending_ipc_info.queue_len == 0)
return UV_UNKNOWN_HANDLE;
else
return UV_TCP;
diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c
index 4d8e1f99f65cb5..ce861d6ffc41eb 100644
--- a/deps/uv/src/win/poll.c
+++ b/deps/uv/src/win/poll.c
@@ -112,12 +112,12 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL;
}
- memset(&req->overlapped, 0, sizeof req->overlapped);
+ memset(&req->u.io.overlapped, 0, sizeof req->u.io.overlapped);
result = uv_msafd_poll((SOCKET) handle->peer_socket,
afd_poll_info,
afd_poll_info,
- &req->overlapped);
+ &req->u.io.overlapped);
if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
/* Queue this req, reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
@@ -380,7 +380,7 @@ static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
}
SET_REQ_SUCCESS(req);
- req->overlapped.InternalHigh = (DWORD) reported_events;
+ req->u.io.overlapped.InternalHigh = (DWORD) reported_events;
POST_COMPLETION_FOR_REQ(handle->loop, req);
return 0;
@@ -442,7 +442,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
}
} else {
/* Got some events. */
- int events = req->overlapped.InternalHigh & handle->events & ~mask_events;
+ int events = req->u.io.overlapped.InternalHigh & handle->events & ~mask_events;
if (events != 0) {
handle->poll_cb(handle, 0, events);
}
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index 3a0106f82d63e3..887595f89cc9b6 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -707,7 +707,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
}
/* second pass: copy to UTF-16 environment block */
- dst_copy = _malloca(env_len * sizeof(WCHAR));
+ dst_copy = malloc(env_len * sizeof(WCHAR));
if (!dst_copy) {
return ERROR_OUTOFMEMORY;
}
@@ -725,7 +725,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
(int) (env_len - (ptr - dst_copy)));
if (len <= 0) {
DWORD err = GetLastError();
- _freea(dst_copy);
+ free(dst_copy);
return err;
}
*ptr_copy++ = ptr;
@@ -767,7 +767,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
/* final pass: copy, in sort order, and inserting required variables */
dst = malloc((1+env_len) * sizeof(WCHAR));
if (!dst) {
- _freea(dst_copy);
+ free(dst_copy);
return ERROR_OUTOFMEMORY;
}
@@ -812,7 +812,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
assert(env_len == (ptr - dst));
*ptr = L'\0';
- _freea(dst_copy);
+ free(dst_copy);
*dst_ptr = dst;
return 0;
}
@@ -1124,7 +1124,7 @@ int uv_spawn(uv_loop_t* loop,
if (fdopt->flags & UV_CREATE_PIPE &&
fdopt->data.stream->type == UV_NAMED_PIPE &&
((uv_pipe_t*) fdopt->data.stream)->ipc) {
- ((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId;
+ ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId;
}
}
diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h
index 46c7d9b106a869..b5e502eef5521a 100644
--- a/deps/uv/src/win/req-inl.h
+++ b/deps/uv/src/win/req-inl.h
@@ -29,7 +29,7 @@
#define SET_REQ_STATUS(req, status) \
- (req)->overlapped.Internal = (ULONG_PTR) (status)
+ (req)->u.io.overlapped.Internal = (ULONG_PTR) (status)
#define SET_REQ_ERROR(req, error) \
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
@@ -38,7 +38,7 @@
SET_REQ_STATUS((req), STATUS_SUCCESS)
#define GET_REQ_STATUS(req) \
- ((NTSTATUS) (req)->overlapped.Internal)
+ ((NTSTATUS) (req)->u.io.overlapped.Internal)
#define REQ_SUCCESS(req) \
(NT_SUCCESS(GET_REQ_STATUS((req))))
@@ -74,7 +74,7 @@
if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \
0, \
- &((req)->overlapped))) { \
+ &((req)->u.io.overlapped))) { \
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
}
@@ -86,13 +86,24 @@ INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
- return CONTAINING_RECORD(overlapped, uv_req_t, overlapped);
+ return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped);
}
INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (loop->pending_reqs_tail) {
+#ifdef _DEBUG
+ /* Ensure the request is not already in the queue, or the queue
+ * will get corrupted.
+ */
+ uv_req_t* current = loop->pending_reqs_tail;
+ do {
+ assert(req != current);
+ current = current->next_req;
+ } while(current != loop->pending_reqs_tail);
+#endif
+
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
diff --git a/deps/uv/src/win/stream-inl.h b/deps/uv/src/win/stream-inl.h
index 97a6b90b50560a..b7a3c11958c274 100644
--- a/deps/uv/src/win/stream-inl.h
+++ b/deps/uv/src/win/stream-inl.h
@@ -41,7 +41,7 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION;
- handle->write_reqs_pending = 0;
+ handle->stream.conn.write_reqs_pending = 0;
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
handle->read_req.event_handle = NULL;
@@ -49,7 +49,7 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->read_req.type = UV_READ;
handle->read_req.data = handle;
- handle->shutdown_req = NULL;
+ handle->stream.conn.shutdown_req = NULL;
}
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index 36d88d00bd9893..a2466e5e9db8ba 100644
--- a/deps/uv/src/win/stream.c
+++ b/deps/uv/src/win/stream.c
@@ -216,7 +216,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
req->cb = cb;
handle->flags &= ~UV_HANDLE_WRITABLE;
- handle->shutdown_req = req;
+ handle->stream.conn.shutdown_req = req;
handle->reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index c5ddbed08f75ae..8b0e18c7cf3256 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -149,13 +149,13 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
- handle->accept_reqs = NULL;
- handle->pending_accepts = NULL;
+ handle->tcp.serv.accept_reqs = NULL;
+ handle->tcp.serv.pending_accepts = NULL;
handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0;
- handle->func_acceptex = NULL;
- handle->func_connectex = NULL;
- handle->processed_accepts = 0;
+ handle->tcp.serv.func_acceptex = NULL;
+ handle->tcp.conn.func_connectex = NULL;
+ handle->tcp.serv.processed_accepts = 0;
handle->delayed_error = 0;
return 0;
@@ -168,10 +168,10 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv_tcp_accept_t* req;
if (handle->flags & UV_HANDLE_CONNECTION &&
- handle->shutdown_req != NULL &&
- handle->write_reqs_pending == 0) {
+ handle->stream.conn.shutdown_req != NULL &&
+ handle->stream.conn.write_reqs_pending == 0) {
- UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
+ UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
err = 0;
if (handle->flags & UV__HANDLE_CLOSING) {
@@ -180,12 +180,12 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
err = WSAGetLastError();
}
- if (handle->shutdown_req->cb) {
- handle->shutdown_req->cb(handle->shutdown_req,
+ if (handle->stream.conn.shutdown_req->cb) {
+ handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req,
uv_translate_sys_error(err));
}
- handle->shutdown_req = NULL;
+ handle->stream.conn.shutdown_req = NULL;
DECREASE_PENDING_REQ_COUNT(handle);
return;
}
@@ -200,10 +200,10 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
}
- if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) {
+ if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
- req = &handle->accept_reqs[i];
+ req = &handle->tcp.serv.accept_reqs[i];
if (req->wait_handle != INVALID_HANDLE_VALUE) {
UnregisterWait(req->wait_handle);
req->wait_handle = INVALID_HANDLE_VALUE;
@@ -215,8 +215,8 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
}
}
- free(handle->accept_reqs);
- handle->accept_reqs = NULL;
+ free(handle->tcp.serv.accept_reqs);
+ handle->tcp.serv.accept_reqs = NULL;
}
if (handle->flags & UV_HANDLE_CONNECTION &&
@@ -327,9 +327,9 @@ static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
- req->overlapped.InternalHigh,
+ req->u.io.overlapped.InternalHigh,
0,
- &req->overlapped)) {
+ &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
}
@@ -346,9 +346,9 @@ static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
- req->overlapped.InternalHigh,
+ req->u.io.overlapped.InternalHigh,
0,
- &req->overlapped)) {
+ &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
}
@@ -390,19 +390,19 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
}
/* Prepare the overlapped structure. */
- memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
- req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+ req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
}
- success = handle->func_acceptex(handle->socket,
- accept_socket,
- (void*)req->accept_buffer,
- 0,
- sizeof(struct sockaddr_storage),
- sizeof(struct sockaddr_storage),
- &bytes,
- &req->overlapped);
+ success = handle->tcp.serv.func_acceptex(handle->socket,
+ accept_socket,
+ (void*)req->accept_buffer,
+ 0,
+ sizeof(struct sockaddr_storage),
+ sizeof(struct sockaddr_storage),
+ &bytes,
+ &req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */
@@ -432,7 +432,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
closesocket(accept_socket);
/* Destroy the event handle */
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
- CloseHandle(req->overlapped.hEvent);
+ CloseHandle(req->u.io.overlapped.hEvent);
req->event_handle = NULL;
}
}
@@ -449,7 +449,7 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
assert(!(handle->flags & UV_HANDLE_READ_PENDING));
req = &handle->read_req;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
/*
* Preallocate a read buffer if the number of active streams is below
@@ -457,13 +457,13 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
*/
if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
handle->flags &= ~UV_HANDLE_ZERO_READ;
- handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer);
- if (handle->read_buffer.len == 0) {
- handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer);
+ handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer);
+ if (handle->tcp.conn.read_buffer.len == 0) {
+ handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer);
return;
}
- assert(handle->read_buffer.base != NULL);
- buf = handle->read_buffer;
+ assert(handle->tcp.conn.read_buffer.base != NULL);
+ buf = handle->tcp.conn.read_buffer;
} else {
handle->flags |= UV_HANDLE_ZERO_READ;
buf.base = (char*) &uv_zero_;
@@ -471,10 +471,10 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
}
/* Prepare the overlapped structure. */
- memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
assert(req->event_handle);
- req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+ req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
}
flags = 0;
@@ -483,13 +483,13 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
1,
&bytes,
&flags,
- &req->overlapped,
+ &req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
- req->overlapped.InternalHigh = bytes;
+ req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
@@ -522,7 +522,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
assert(backlog > 0);
if (handle->flags & UV_HANDLE_LISTENING) {
- handle->connection_cb = cb;
+ handle->stream.serv.connection_cb = cb;
}
if (handle->flags & UV_HANDLE_READING) {
@@ -544,8 +544,8 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
return handle->delayed_error;
}
- if (!handle->func_acceptex) {
- if (!uv_get_acceptex_function(handle->socket, &handle->func_acceptex)) {
+ if (!handle->tcp.serv.func_acceptex) {
+ if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) {
return WSAEAFNOSUPPORT;
}
}
@@ -556,21 +556,21 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
}
handle->flags |= UV_HANDLE_LISTENING;
- handle->connection_cb = cb;
+ handle->stream.serv.connection_cb = cb;
INCREASE_ACTIVE_COUNT(loop, handle);
simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
: uv_simultaneous_server_accepts;
- if(!handle->accept_reqs) {
- handle->accept_reqs = (uv_tcp_accept_t*)
+ if(!handle->tcp.serv.accept_reqs) {
+ handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*)
malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
- if (!handle->accept_reqs) {
+ if (!handle->tcp.serv.accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
for (i = 0; i < simultaneous_accepts; i++) {
- req = &handle->accept_reqs[i];
+ req = &handle->tcp.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*)req);
req->type = UV_ACCEPT;
req->accept_socket = INVALID_SOCKET;
@@ -593,7 +593,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
/* doesn't know how how many requests were initialized, so it will */
/* try to clean up {uv_simultaneous_server_accepts} requests. */
for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
- req = &handle->accept_reqs[i];
+ req = &handle->tcp.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT;
req->accept_socket = INVALID_SOCKET;
@@ -612,7 +612,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
int err = 0;
int family;
- uv_tcp_accept_t* req = server->pending_accepts;
+ uv_tcp_accept_t* req = server->tcp.serv.pending_accepts;
if (!req) {
/* No valid connections found, so we error out. */
@@ -643,7 +643,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
}
/* Prepare the req to pick up a new connection */
- server->pending_accepts = req->next_pending;
+ server->tcp.serv.pending_accepts = req->next_pending;
req->next_pending = NULL;
req->accept_socket = INVALID_SOCKET;
@@ -655,15 +655,15 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
/* We better be switching to a single pending accept. */
assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
- server->processed_accepts++;
+ server->tcp.serv.processed_accepts++;
- if (server->processed_accepts >= uv_simultaneous_server_accepts) {
- server->processed_accepts = 0;
+ if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) {
+ server->tcp.serv.processed_accepts = 0;
/*
* All previously queued accept requests are now processed.
* We now switch to queueing just a single accept.
*/
- uv_tcp_queue_accept(server, &server->accept_reqs[0]);
+ uv_tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]);
server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
}
@@ -732,8 +732,8 @@ static int uv_tcp_try_connect(uv_connect_t* req,
return handle->delayed_error;
}
- if (!handle->func_connectex) {
- if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) {
+ if (!handle->tcp.conn.func_connectex) {
+ if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) {
return WSAEAFNOSUPPORT;
}
}
@@ -742,15 +742,15 @@ static int uv_tcp_try_connect(uv_connect_t* req,
req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
- success = handle->func_connectex(handle->socket,
- addr,
- addrlen,
- NULL,
- 0,
- &bytes,
- &req->overlapped);
+ success = handle->tcp.conn.func_connectex(handle->socket,
+ addr,
+ addrlen,
+ NULL,
+ 0,
+ &bytes,
+ &req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */
@@ -828,13 +828,13 @@ int uv_tcp_write(uv_loop_t* loop,
req->cb = cb;
/* Prepare the overlapped structure. */
- memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
req->event_handle = CreateEvent(NULL, 0, 0, NULL);
if (!req->event_handle) {
uv_fatal_error(GetLastError(), "CreateEvent");
}
- req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+ req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
req->wait_handle = INVALID_HANDLE_VALUE;
}
@@ -843,23 +843,23 @@ int uv_tcp_write(uv_loop_t* loop,
nbufs,
&bytes,
0,
- &req->overlapped,
+ &req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Request completed immediately. */
- req->queued_bytes = 0;
+ req->u.io.queued_bytes = 0;
handle->reqs_pending++;
- handle->write_reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
uv_insert_pending_req(loop, (uv_req_t*) req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */
- req->queued_bytes = uv__count_bufs(bufs, nbufs);
+ req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
handle->reqs_pending++;
- handle->write_reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
- handle->write_queue_size += req->queued_bytes;
+ handle->write_queue_size += req->u.io.queued_bytes;
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
!RegisterWaitForSingleObject(&req->wait_handle,
req->event_handle, post_write_completion, (void*) req,
@@ -868,8 +868,13 @@ int uv_tcp_write(uv_loop_t* loop,
uv_insert_pending_req(loop, (uv_req_t*)req);
}
} else {
- /* Send failed due to an error. */
- return WSAGetLastError();
+ /* Send failed due to an error, report it later */
+ req->u.io.queued_bytes = 0;
+ handle->reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*) req);
}
return 0;
@@ -882,7 +887,7 @@ int uv__tcp_try_write(uv_tcp_t* handle,
int result;
DWORD bytes;
- if (handle->write_reqs_pending > 0)
+ if (handle->stream.conn.write_reqs_pending > 0)
return UV_EAGAIN;
result = WSASend(handle->socket,
@@ -916,7 +921,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
- uv_buf_init(NULL, 0) : handle->read_buffer;
+ uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer;
err = GET_REQ_SOCK_ERROR(req);
@@ -934,13 +939,13 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
} else {
if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
/* The read was done with a non-zero buffer length. */
- if (req->overlapped.InternalHigh > 0) {
+ if (req->u.io.overlapped.InternalHigh > 0) {
/* Successful read */
handle->read_cb((uv_stream_t*)handle,
- req->overlapped.InternalHigh,
- &handle->read_buffer);
+ req->u.io.overlapped.InternalHigh,
+ &handle->tcp.conn.read_buffer);
/* Read again only if bytes == buf.len */
- if (req->overlapped.InternalHigh < handle->read_buffer.len) {
+ if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) {
goto done;
}
} else {
@@ -953,7 +958,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
buf.base = 0;
buf.len = 0;
- handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->read_buffer);
+ handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer);
goto done;
}
}
@@ -1032,8 +1037,8 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
assert(handle->type == UV_TCP);
- assert(handle->write_queue_size >= req->queued_bytes);
- handle->write_queue_size -= req->queued_bytes;
+ assert(handle->write_queue_size >= req->u.io.queued_bytes);
+ handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req);
@@ -1057,9 +1062,9 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
req->cb(req, err);
}
- handle->write_reqs_pending--;
- if (handle->shutdown_req != NULL &&
- handle->write_reqs_pending == 0) {
+ handle->stream.conn.write_reqs_pending--;
+ if (handle->stream.conn.shutdown_req != NULL &&
+ handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@@ -1082,10 +1087,10 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING;
DECREASE_ACTIVE_COUNT(loop, handle);
- if (handle->connection_cb) {
+ if (handle->stream.serv.connection_cb) {
err = GET_REQ_SOCK_ERROR(req);
- handle->connection_cb((uv_stream_t*)handle,
- uv_translate_sys_error(err));
+ handle->stream.serv.connection_cb((uv_stream_t*)handle,
+ uv_translate_sys_error(err));
}
}
} else if (REQ_SUCCESS(req) &&
@@ -1094,12 +1099,12 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
SO_UPDATE_ACCEPT_CONTEXT,
(char*)&handle->socket,
sizeof(handle->socket)) == 0) {
- req->next_pending = handle->pending_accepts;
- handle->pending_accepts = req;
+ req->next_pending = handle->tcp.serv.pending_accepts;
+ handle->tcp.serv.pending_accepts = req;
/* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
- if (handle->connection_cb) {
- handle->connection_cb((uv_stream_t*)handle, 0);
+ if (handle->stream.serv.connection_cb) {
+ handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
}
} else {
/* Error related to accepted socket is ignored because the server */
@@ -1357,7 +1362,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
}
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
- tcp->accept_reqs != NULL) {
+ tcp->tcp.serv.accept_reqs != NULL) {
/* Under normal circumstances closesocket() will ensure that all pending */
/* accept reqs are canceled. However, when the socket is shared the */
/* presence of another reference to the socket in another process will */
@@ -1371,9 +1376,9 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
/* cause the connection to be aborted. */
unsigned int i;
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
- uv_tcp_accept_t* req = &tcp->accept_reqs[i];
+ uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
if (req->accept_socket != INVALID_SOCKET &&
- !HasOverlappedIoCompleted(&req->overlapped)) {
+ !HasOverlappedIoCompleted(&req->u.io.overlapped)) {
closesocket(req->accept_socket);
req->accept_socket = INVALID_SOCKET;
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 603421045cac58..7b1e4ba0557fca 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -142,28 +142,28 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
if (readable) {
/* Initialize TTY input specific fields. */
tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
- tty->read_line_handle = NULL;
- tty->read_line_buffer = uv_null_buf_;
- tty->read_raw_wait = NULL;
+ tty->tty.rd.read_line_handle = NULL;
+ tty->tty.rd.read_line_buffer = uv_null_buf_;
+ tty->tty.rd.read_raw_wait = NULL;
/* Init keycode-to-vt100 mapper state. */
- tty->last_key_len = 0;
- tty->last_key_offset = 0;
- tty->last_utf16_high_surrogate = 0;
- memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
+ tty->tty.rd.last_key_len = 0;
+ tty->tty.rd.last_key_offset = 0;
+ tty->tty.rd.last_utf16_high_surrogate = 0;
+ memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record);
} else {
/* TTY output specific fields. */
tty->flags |= UV_HANDLE_WRITABLE;
/* Init utf8-to-utf16 conversion state. */
- tty->utf8_bytes_left = 0;
- tty->utf8_codepoint = 0;
+ tty->tty.wr.utf8_bytes_left = 0;
+ tty->tty.wr.utf8_codepoint = 0;
/* Initialize eol conversion state */
- tty->previous_eol = 0;
+ tty->tty.wr.previous_eol = 0;
/* Init ANSI parser state. */
- tty->ansi_parser_state = ANSI_NORMAL;
+ tty->tty.wr.ansi_parser_state = ANSI_NORMAL;
}
return 0;
@@ -268,8 +268,8 @@ static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) {
handle = (uv_tty_t*) req->data;
loop = handle->loop;
- UnregisterWait(handle->read_raw_wait);
- handle->read_raw_wait = NULL;
+ UnregisterWait(handle->tty.rd.read_raw_wait);
+ handle->tty.rd.read_raw_wait = NULL;
SET_REQ_SUCCESS(req);
POST_COMPLETION_FOR_REQ(loop, req);
@@ -285,19 +285,19 @@ static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) {
assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
- handle->read_line_buffer = uv_null_buf_;
+ handle->tty.rd.read_line_buffer = uv_null_buf_;
req = &handle->read_req;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
- r = RegisterWaitForSingleObject(&handle->read_raw_wait,
+ r = RegisterWaitForSingleObject(&handle->tty.rd.read_raw_wait,
handle->handle,
uv_tty_post_raw_read,
(void*) req,
INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
if (!r) {
- handle->read_raw_wait = NULL;
+ handle->tty.rd.read_raw_wait = NULL;
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req(loop, (uv_req_t*)req);
}
@@ -321,12 +321,12 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
handle = (uv_tty_t*) req->data;
loop = handle->loop;
- assert(handle->read_line_buffer.base != NULL);
- assert(handle->read_line_buffer.len > 0);
+ assert(handle->tty.rd.read_line_buffer.base != NULL);
+ assert(handle->tty.rd.read_line_buffer.len > 0);
/* ReadConsole can't handle big buffers. */
- if (handle->read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
- bytes = handle->read_line_buffer.len;
+ if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
+ bytes = handle->tty.rd.read_line_buffer.len;
} else {
bytes = MAX_INPUT_BUFFER_LENGTH;
}
@@ -335,7 +335,7 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
/* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */
chars = bytes / 3;
- if (ReadConsoleW(handle->read_line_handle,
+ if (ReadConsoleW(handle->tty.rd.read_line_handle,
(void*) utf16,
chars,
&read_chars,
@@ -344,12 +344,12 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
0,
utf16,
read_chars,
- handle->read_line_buffer.base,
+ handle->tty.rd.read_line_buffer.base,
bytes,
NULL,
NULL);
SET_REQ_SUCCESS(req);
- req->overlapped.InternalHigh = read_bytes;
+ req->u.io.overlapped.InternalHigh = read_bytes;
} else {
SET_REQ_ERROR(req, GetLastError());
}
@@ -368,30 +368,30 @@ static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
req = &handle->read_req;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
- handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->read_line_buffer);
- if (handle->read_line_buffer.len == 0) {
+ handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer);
+ if (handle->tty.rd.read_line_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle,
UV_ENOBUFS,
- &handle->read_line_buffer);
+ &handle->tty.rd.read_line_buffer);
return;
}
- assert(handle->read_line_buffer.base != NULL);
+ assert(handle->tty.rd.read_line_buffer.base != NULL);
/* Duplicate the console handle, so if we want to cancel the read, we can */
/* just close this handle duplicate. */
- if (handle->read_line_handle == NULL) {
+ if (handle->tty.rd.read_line_handle == NULL) {
HANDLE this_process = GetCurrentProcess();
r = DuplicateHandle(this_process,
handle->handle,
this_process,
- &handle->read_line_handle,
+ &handle->tty.rd.read_line_handle,
0,
0,
DUPLICATE_SAME_ACCESS);
if (!r) {
- handle->read_line_handle = NULL;
+ handle->tty.rd.read_line_handle = NULL;
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req(loop, (uv_req_t*)req);
goto out;
@@ -489,8 +489,8 @@ static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl,
void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
uv_req_t* req) {
- /* Shortcut for handle->last_input_record.Event.KeyEvent. */
-#define KEV handle->last_input_record.Event.KeyEvent
+ /* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */
+#define KEV handle->tty.rd.last_input_record.Event.KeyEvent
DWORD records_left, records_read;
uv_buf_t buf;
@@ -531,12 +531,12 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
buf = uv_null_buf_;
buf_used = 0;
- while ((records_left > 0 || handle->last_key_len > 0) &&
+ while ((records_left > 0 || handle->tty.rd.last_key_len > 0) &&
(handle->flags & UV_HANDLE_READING)) {
- if (handle->last_key_len == 0) {
+ if (handle->tty.rd.last_key_len == 0) {
/* Read the next input record */
if (!ReadConsoleInputW(handle->handle,
- &handle->last_input_record,
+ &handle->tty.rd.last_input_record,
1,
&records_read)) {
handle->flags &= ~UV_HANDLE_READING;
@@ -551,7 +551,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* If the window was resized, recompute the virtual window size. This */
/* will trigger a SIGWINCH signal if the window size changed in an */
/* way that matters to libuv. */
- if (handle->last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+ if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
CONSOLE_SCREEN_BUFFER_INFO info;
EnterCriticalSection(&uv_tty_output_lock);
@@ -567,7 +567,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
}
/* Ignore other events that are not key or resize events. */
- if (handle->last_input_record.EventType != KEY_EVENT) {
+ if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
continue;
}
@@ -613,7 +613,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (KEV.uChar.UnicodeChar >= 0xD800 &&
KEV.uChar.UnicodeChar < 0xDC00) {
/* UTF-16 high surrogate */
- handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
+ handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
continue;
}
@@ -622,7 +622,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
&& !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
- handle->last_key[0] = '\033';
+ handle->tty.rd.last_key[0] = '\033';
prefix_len = 1;
} else {
prefix_len = 0;
@@ -631,14 +631,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (KEV.uChar.UnicodeChar >= 0xDC00 &&
KEV.uChar.UnicodeChar < 0xE000) {
/* UTF-16 surrogate pair */
- WCHAR utf16_buffer[2] = { handle->last_utf16_high_surrogate,
+ WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate,
KEV.uChar.UnicodeChar};
char_len = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
2,
- &handle->last_key[prefix_len],
- sizeof handle->last_key,
+ &handle->tty.rd.last_key[prefix_len],
+ sizeof handle->tty.rd.last_key,
NULL,
NULL);
} else {
@@ -647,14 +647,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
0,
&KEV.uChar.UnicodeChar,
1,
- &handle->last_key[prefix_len],
- sizeof handle->last_key,
+ &handle->tty.rd.last_key[prefix_len],
+ sizeof handle->tty.rd.last_key,
NULL,
NULL);
}
/* Whatever happened, the last character wasn't a high surrogate. */
- handle->last_utf16_high_surrogate = 0;
+ handle->tty.rd.last_utf16_high_surrogate = 0;
/* If the utf16 character(s) couldn't be converted something must */
/* be wrong. */
@@ -667,8 +667,8 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
goto out;
}
- handle->last_key_len = (unsigned char) (prefix_len + char_len);
- handle->last_key_offset = 0;
+ handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len);
+ handle->tty.rd.last_key_offset = 0;
continue;
} else {
@@ -690,23 +690,23 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Prefix with \x033 when the alt key was held. */
if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
- handle->last_key[0] = '\033';
+ handle->tty.rd.last_key[0] = '\033';
prefix_len = 1;
} else {
prefix_len = 0;
}
/* Copy the vt100 sequence to the handle buffer. */
- assert(prefix_len + vt100_len < sizeof handle->last_key);
- memcpy(&handle->last_key[prefix_len], vt100, vt100_len);
+ assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key);
+ memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len);
- handle->last_key_len = (unsigned char) (prefix_len + vt100_len);
- handle->last_key_offset = 0;
+ handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len);
+ handle->tty.rd.last_key_offset = 0;
continue;
}
} else {
/* Copy any bytes left from the last keypress to the user buffer. */
- if (handle->last_key_offset < handle->last_key_len) {
+ if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) {
/* Allocate a buffer if needed */
if (buf_used == 0) {
handle->alloc_cb((uv_handle_t*) handle, 1024, &buf);
@@ -717,7 +717,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
assert(buf.base != NULL);
}
- buf.base[buf_used++] = handle->last_key[handle->last_key_offset++];
+ buf.base[buf_used++] = handle->tty.rd.last_key[handle->tty.rd.last_key_offset++];
/* If the buffer is full, emit it */
if ((size_t) buf_used == buf.len) {
@@ -731,11 +731,11 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Apply dwRepeat from the last input record. */
if (--KEV.wRepeatCount > 0) {
- handle->last_key_offset = 0;
+ handle->tty.rd.last_key_offset = 0;
continue;
}
- handle->last_key_len = 0;
+ handle->tty.rd.last_key_len = 0;
continue;
}
}
@@ -766,15 +766,15 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
assert(handle->type == UV_TTY);
assert(handle->flags & UV_HANDLE_TTY_READABLE);
- buf = handle->read_line_buffer;
+ buf = handle->tty.rd.read_line_buffer;
handle->flags &= ~UV_HANDLE_READ_PENDING;
- handle->read_line_buffer = uv_null_buf_;
+ handle->tty.rd.read_line_buffer = uv_null_buf_;
if (!REQ_SUCCESS(req)) {
/* Read was not successful */
if ((handle->flags & UV_HANDLE_READING) &&
- handle->read_line_handle != NULL) {
+ handle->tty.rd.read_line_handle != NULL) {
/* Real error */
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
@@ -789,7 +789,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
} else {
/* Read successful */
/* TODO: read unicode, convert to utf-8 */
- DWORD bytes = req->overlapped.InternalHigh;
+ DWORD bytes = req->u.io.overlapped.InternalHigh;
handle->read_cb((uv_stream_t*) handle, bytes, &buf);
}
@@ -811,7 +811,7 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
/* If the read_line_buffer member is zero, it must have been an raw read. */
/* Otherwise it was a line-buffered read. */
/* FIXME: This is quite obscure. Use a flag or something. */
- if (handle->read_line_buffer.len == 0) {
+ if (handle->tty.rd.read_line_buffer.len == 0) {
uv_process_tty_read_raw_req(loop, handle, req);
} else {
uv_process_tty_read_line_req(loop, handle, req);
@@ -840,7 +840,7 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
/* Maybe the user stopped reading half-way while processing key events. */
/* Short-circuit if this could be the case. */
- if (handle->last_key_len > 0) {
+ if (handle->tty.rd.last_key_len > 0) {
SET_REQ_SUCCESS(&handle->read_req);
uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
return 0;
@@ -869,10 +869,10 @@ int uv_tty_read_stop(uv_tty_t* handle) {
}
/* Cancel line-buffered read */
- if (handle->read_line_handle != NULL) {
+ if (handle->tty.rd.read_line_handle != NULL) {
/* Closing this handle will cancel the ReadConsole operation */
- CloseHandle(handle->read_line_handle);
- handle->read_line_handle = NULL;
+ CloseHandle(handle->tty.rd.read_line_handle);
+ handle->tty.rd.read_line_handle = NULL;
}
@@ -1149,8 +1149,8 @@ static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen,
} while (0)
static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
- unsigned short argc = handle->ansi_csi_argc;
- unsigned short* argv = handle->ansi_csi_argv;
+ unsigned short argc = handle->tty.wr.ansi_csi_argc;
+ unsigned short* argv = handle->tty.wr.ansi_csi_argv;
int i;
CONSOLE_SCREEN_BUFFER_INFO info;
@@ -1319,12 +1319,12 @@ static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes,
uv_tty_update_virtual_window(&info);
- handle->saved_position.X = info.dwCursorPosition.X;
- handle->saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
+ handle->tty.wr.saved_position.X = info.dwCursorPosition.X;
+ handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
handle->flags |= UV_HANDLE_TTY_SAVED_POSITION;
if (save_attributes) {
- handle->saved_attributes = info.wAttributes &
+ handle->tty.wr.saved_attributes = info.wAttributes &
(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES;
}
@@ -1344,9 +1344,9 @@ static int uv_tty_restore_state(uv_tty_t* handle,
if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) {
if (uv_tty_move_caret(handle,
- handle->saved_position.X,
+ handle->tty.wr.saved_position.X,
0,
- handle->saved_position.Y,
+ handle->tty.wr.saved_position.Y,
0,
error) != 0) {
return -1;
@@ -1362,7 +1362,7 @@ static int uv_tty_restore_state(uv_tty_t* handle,
new_attributes = info.wAttributes;
new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
- new_attributes |= handle->saved_attributes;
+ new_attributes |= handle->tty.wr.saved_attributes;
if (!SetConsoleTextAttribute(handle->handle, new_attributes)) {
*error = GetLastError();
@@ -1412,10 +1412,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
} while (0)
/* Cache for fast access */
- unsigned char utf8_bytes_left = handle->utf8_bytes_left;
- unsigned int utf8_codepoint = handle->utf8_codepoint;
- unsigned char previous_eol = handle->previous_eol;
- unsigned char ansi_parser_state = handle->ansi_parser_state;
+ unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left;
+ unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint;
+ unsigned char previous_eol = handle->tty.wr.previous_eol;
+ unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state;
/* Store the error here. If we encounter an error, stop trying to do i/o */
/* but keep parsing the buffer so we leave the parser in a consistent */
@@ -1492,7 +1492,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 0233:
ansi_parser_state = ANSI_CSI;
- handle->ansi_csi_argc = 0;
+ handle->tty.wr.ansi_csi_argc = 0;
continue;
}
@@ -1500,7 +1500,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
switch (utf8_codepoint) {
case '[':
ansi_parser_state = ANSI_CSI;
- handle->ansi_csi_argc = 0;
+ handle->tty.wr.ansi_csi_argc = 0;
continue;
case '^':
@@ -1557,20 +1557,20 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* We were not currently parsing a number */
/* Check for too many arguments */
- if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) {
+ if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
ansi_parser_state |= ANSI_IGNORE;
continue;
}
ansi_parser_state |= ANSI_IN_ARG;
- handle->ansi_csi_argc++;
- handle->ansi_csi_argv[handle->ansi_csi_argc - 1] =
+ handle->tty.wr.ansi_csi_argc++;
+ handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
(unsigned short) utf8_codepoint - '0';
continue;
} else {
/* We were already parsing a number. Parse next digit. */
uint32_t value = 10 *
- handle->ansi_csi_argv[handle->ansi_csi_argc - 1];
+ handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1];
/* Check for overflow. */
if (value > UINT16_MAX) {
@@ -1578,7 +1578,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
continue;
}
- handle->ansi_csi_argv[handle->ansi_csi_argc - 1] =
+ handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
(unsigned short) value + (utf8_codepoint - '0');
continue;
}
@@ -1593,25 +1593,25 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* If ANSI_IN_ARG is not set, add another argument and */
/* default it to 0. */
/* Check for too many arguments */
- if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) {
+ if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
ansi_parser_state |= ANSI_IGNORE;
continue;
}
- handle->ansi_csi_argc++;
- handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = 0;
+ handle->tty.wr.ansi_csi_argc++;
+ handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0;
continue;
}
} else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) &&
- handle->ansi_csi_argc == 0) {
+ handle->tty.wr.ansi_csi_argc == 0) {
/* Ignores '?' if it is the first character after CSI[ */
/* This is an extension character from the VT100 codeset */
/* that is supported and used by most ANSI terminals today. */
continue;
} else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
- (handle->ansi_csi_argc > 0 || utf8_codepoint != '[')) {
+ (handle->tty.wr.ansi_csi_argc > 0 || utf8_codepoint != '[')) {
int x, y, d;
/* Command byte */
@@ -1619,50 +1619,50 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'A':
/* cursor up */
FLUSH_TEXT();
- y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1);
+ y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
uv_tty_move_caret(handle, 0, 1, y, 1, error);
break;
case 'B':
/* cursor down */
FLUSH_TEXT();
- y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1;
+ y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
uv_tty_move_caret(handle, 0, 1, y, 1, error);
break;
case 'C':
/* cursor forward */
FLUSH_TEXT();
- x = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1;
+ x = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
uv_tty_move_caret(handle, x, 1, 0, 1, error);
break;
case 'D':
/* cursor back */
FLUSH_TEXT();
- x = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1);
+ x = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
uv_tty_move_caret(handle, x, 1, 0, 1, error);
break;
case 'E':
/* cursor next line */
FLUSH_TEXT();
- y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1;
+ y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
uv_tty_move_caret(handle, 0, 0, y, 1, error);
break;
case 'F':
/* cursor previous line */
FLUSH_TEXT();
- y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1);
+ y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
uv_tty_move_caret(handle, 0, 0, y, 1, error);
break;
case 'G':
/* cursor horizontal move absolute */
FLUSH_TEXT();
- x = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0])
- ? handle->ansi_csi_argv[0] - 1 : 0;
+ x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
+ ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
uv_tty_move_caret(handle, x, 0, 0, 1, error);
break;
@@ -1670,17 +1670,17 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'f':
/* cursor move absolute */
FLUSH_TEXT();
- y = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0])
- ? handle->ansi_csi_argv[0] - 1 : 0;
- x = (handle->ansi_csi_argc >= 2 && handle->ansi_csi_argv[1])
- ? handle->ansi_csi_argv[1] - 1 : 0;
+ y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
+ ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
+ x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1])
+ ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0;
uv_tty_move_caret(handle, x, 0, y, 0, error);
break;
case 'J':
/* Erase screen */
FLUSH_TEXT();
- d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0;
+ d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
if (d >= 0 && d <= 2) {
uv_tty_clear(handle, d, 1, error);
}
@@ -1689,7 +1689,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'K':
/* Erase line */
FLUSH_TEXT();
- d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0;
+ d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
if (d >= 0 && d <= 2) {
uv_tty_clear(handle, d, 0, error);
}
@@ -1715,8 +1715,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'l':
/* Hide the cursor */
- if (handle->ansi_csi_argc == 1 &&
- handle->ansi_csi_argv[0] == 25) {
+ if (handle->tty.wr.ansi_csi_argc == 1 &&
+ handle->tty.wr.ansi_csi_argv[0] == 25) {
FLUSH_TEXT();
uv_tty_set_cursor_visibility(handle, 0, error);
}
@@ -1724,8 +1724,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'h':
/* Show the cursor */
- if (handle->ansi_csi_argc == 1 &&
- handle->ansi_csi_argv[0] == 25) {
+ if (handle->tty.wr.ansi_csi_argc == 1 &&
+ handle->tty.wr.ansi_csi_argv[0] == 25) {
FLUSH_TEXT();
uv_tty_set_cursor_visibility(handle, 1, error);
}
@@ -1830,10 +1830,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
FLUSH_TEXT();
/* Copy cached values back to struct. */
- handle->utf8_bytes_left = utf8_bytes_left;
- handle->utf8_codepoint = utf8_codepoint;
- handle->previous_eol = previous_eol;
- handle->ansi_parser_state = ansi_parser_state;
+ handle->tty.wr.utf8_bytes_left = utf8_bytes_left;
+ handle->tty.wr.utf8_codepoint = utf8_codepoint;
+ handle->tty.wr.previous_eol = previous_eol;
+ handle->tty.wr.ansi_parser_state = ansi_parser_state;
LeaveCriticalSection(&uv_tty_output_lock);
@@ -1861,10 +1861,10 @@ int uv_tty_write(uv_loop_t* loop,
req->cb = cb;
handle->reqs_pending++;
- handle->write_reqs_pending++;
+ handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
- req->queued_bytes = 0;
+ req->u.io.queued_bytes = 0;
if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) {
SET_REQ_SUCCESS(req);
@@ -1883,7 +1883,7 @@ int uv__tty_try_write(uv_tty_t* handle,
unsigned int nbufs) {
DWORD error;
- if (handle->write_reqs_pending > 0)
+ if (handle->stream.conn.write_reqs_pending > 0)
return UV_EAGAIN;
if (uv_tty_write_bufs(handle, bufs, nbufs, &error))
@@ -1897,7 +1897,7 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
uv_write_t* req) {
int err;
- handle->write_queue_size -= req->queued_bytes;
+ handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req);
if (req->cb) {
@@ -1905,9 +1905,9 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
req->cb(req, uv_translate_sys_error(err));
}
- handle->write_reqs_pending--;
- if (handle->shutdown_req != NULL &&
- handle->write_reqs_pending == 0) {
+ handle->stream.conn.write_reqs_pending--;
+ if (handle->stream.conn.shutdown_req != NULL &&
+ handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@@ -1933,20 +1933,20 @@ void uv_tty_close(uv_tty_t* handle) {
void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
if (!(handle->flags & UV_HANDLE_TTY_READABLE) &&
- handle->shutdown_req != NULL &&
- handle->write_reqs_pending == 0) {
- UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
+ handle->stream.conn.shutdown_req != NULL &&
+ handle->stream.conn.write_reqs_pending == 0) {
+ UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
/* TTY shutdown is really just a no-op */
- if (handle->shutdown_req->cb) {
+ if (handle->stream.conn.shutdown_req->cb) {
if (handle->flags & UV__HANDLE_CLOSING) {
- handle->shutdown_req->cb(handle->shutdown_req, UV_ECANCELED);
+ handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED);
} else {
- handle->shutdown_req->cb(handle->shutdown_req, 0);
+ handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0);
}
}
- handle->shutdown_req = NULL;
+ handle->stream.conn.shutdown_req = NULL;
DECREASE_PENDING_REQ_COUNT(handle);
return;
@@ -1957,12 +1957,12 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
/* The console handle duplicate used for line reading should be destroyed */
/* by uv_tty_read_stop. */
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
- handle->read_line_handle == NULL);
+ handle->tty.rd.read_line_handle == NULL);
/* The wait handle used for raw reading should be unregistered when the */
/* wait callback runs. */
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
- handle->read_raw_wait == NULL);
+ handle->tty.rd.read_raw_wait == NULL);
assert(!(handle->flags & UV_HANDLE_CLOSED));
uv__handle_close(handle);
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 73b5bd5e467b40..197e5d828f2ad4 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -244,7 +244,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
assert(!(handle->flags & UV_HANDLE_READ_PENDING));
req = &handle->recv_req;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
/*
* Preallocate a read buffer if the number of active streams is below
@@ -272,13 +272,13 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
&flags,
(struct sockaddr*) &handle->recv_from,
&handle->recv_from_len,
- &req->overlapped,
+ &req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
- req->overlapped.InternalHigh = bytes;
+ req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
@@ -304,13 +304,13 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
1,
&bytes,
&flags,
- &req->overlapped,
+ &req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
- req->overlapped.InternalHigh = bytes;
+ req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
@@ -384,7 +384,7 @@ static int uv__send(uv_udp_send_t* req,
req->type = UV_UDP_SEND;
req->handle = handle;
req->cb = cb;
- memset(&req->overlapped, 0, sizeof(req->overlapped));
+ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
result = WSASendTo(handle->socket,
(WSABUF*)bufs,
@@ -393,22 +393,22 @@ static int uv__send(uv_udp_send_t* req,
0,
addr,
addrlen,
- &req->overlapped,
+ &req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Request completed immediately. */
- req->queued_bytes = 0;
+ req->u.io.queued_bytes = 0;
handle->reqs_pending++;
- handle->send_queue_size += req->queued_bytes;
+ handle->send_queue_size += req->u.io.queued_bytes;
handle->send_queue_count++;
REGISTER_HANDLE_REQ(loop, handle, req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */
- req->queued_bytes = uv__count_bufs(bufs, nbufs);
+ req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
handle->reqs_pending++;
- handle->send_queue_size += req->queued_bytes;
+ handle->send_queue_size += req->u.io.queued_bytes;
handle->send_queue_count++;
REGISTER_HANDLE_REQ(loop, handle, req);
} else {
@@ -459,7 +459,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
/* Successful read */
partial = !REQ_SUCCESS(req);
handle->recv_cb(handle,
- req->overlapped.InternalHigh,
+ req->u.io.overlapped.InternalHigh,
&handle->recv_buffer,
(const struct sockaddr*) &handle->recv_from,
partial ? UV_UDP_PARTIAL : 0);
@@ -536,9 +536,9 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
assert(handle->type == UV_UDP);
- assert(handle->send_queue_size >= req->queued_bytes);
+ assert(handle->send_queue_size >= req->u.io.queued_bytes);
assert(handle->send_queue_count >= 1);
- handle->send_queue_size -= req->queued_bytes;
+ handle->send_queue_size -= req->u.io.queued_bytes;
handle->send_queue_count--;
UNREGISTER_HANDLE_REQ(loop, handle, req);
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 43d843ff5c42b5..3697d5aa6aaf20 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -535,14 +534,14 @@ int uv_uptime(double* uptime) {
return uv_translate_sys_error(result);
}
- free(malloced_buffer);
-
buffer_size *= 2;
/* Don't let the buffer grow infinitely. */
if (buffer_size > 1 << 20) {
goto internalError;
}
+ free(malloced_buffer);
+
buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
if (malloced_buffer == NULL) {
*uptime = 0;
diff --git a/deps/uv/test/benchmark-getaddrinfo.c b/deps/uv/test/benchmark-getaddrinfo.c
index c7f99a2fcb8720..1dbc23ddba009d 100644
--- a/deps/uv/test/benchmark-getaddrinfo.c
+++ b/deps/uv/test/benchmark-getaddrinfo.c
@@ -83,8 +83,9 @@ BENCHMARK_IMPL(getaddrinfo) {
ASSERT(calls_initiated == TOTAL_CALLS);
ASSERT(calls_completed == TOTAL_CALLS);
- LOGF("getaddrinfo: %.0f req/s\n",
- (double) calls_completed / (double) (end_time - start_time) * 1000.0);
+ fprintf(stderr, "getaddrinfo: %.0f req/s\n",
+ (double) calls_completed / (double) (end_time - start_time) * 1000.0);
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/benchmark-loop-count.c b/deps/uv/test/benchmark-loop-count.c
index 5cb813238d4f75..970a94c2fecb5c 100644
--- a/deps/uv/test/benchmark-loop-count.c
+++ b/deps/uv/test/benchmark-loop-count.c
@@ -62,10 +62,11 @@ BENCHMARK_IMPL(loop_count) {
ASSERT(ticks == NUM_TICKS);
- LOGF("loop_count: %d ticks in %.2fs (%.0f/s)\n",
- NUM_TICKS,
- ns / 1e9,
- NUM_TICKS / (ns / 1e9));
+ fprintf(stderr, "loop_count: %d ticks in %.2fs (%.0f/s)\n",
+ NUM_TICKS,
+ ns / 1e9,
+ NUM_TICKS / (ns / 1e9));
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
@@ -83,7 +84,8 @@ BENCHMARK_IMPL(loop_count_timed) {
uv_run(loop, UV_RUN_DEFAULT);
- LOGF("loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0);
+ fprintf(stderr, "loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0);
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/benchmark-million-timers.c b/deps/uv/test/benchmark-million-timers.c
index 6027d6088aa789..60a308bef13d40 100644
--- a/deps/uv/test/benchmark-million-timers.c
+++ b/deps/uv/test/benchmark-million-timers.c
@@ -75,10 +75,11 @@ BENCHMARK_IMPL(million_timers) {
ASSERT(close_cb_called == NUM_TIMERS);
free(timers);
- LOGF("%.2f seconds total\n", (after_all - before_all) / 1e9);
- LOGF("%.2f seconds init\n", (before_run - before_all) / 1e9);
- LOGF("%.2f seconds dispatch\n", (after_run - before_run) / 1e9);
- LOGF("%.2f seconds cleanup\n", (after_all - after_run) / 1e9);
+ fprintf(stderr, "%.2f seconds total\n", (after_all - before_all) / 1e9);
+ fprintf(stderr, "%.2f seconds init\n", (before_run - before_all) / 1e9);
+ fprintf(stderr, "%.2f seconds dispatch\n", (after_run - before_run) / 1e9);
+ fprintf(stderr, "%.2f seconds cleanup\n", (after_all - after_run) / 1e9);
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/benchmark-ping-pongs.c b/deps/uv/test/benchmark-ping-pongs.c
index bb560d7d21fd6b..646a7df9447036 100644
--- a/deps/uv/test/benchmark-ping-pongs.c
+++ b/deps/uv/test/benchmark-ping-pongs.c
@@ -80,7 +80,8 @@ static void pinger_close_cb(uv_handle_t* handle) {
pinger_t* pinger;
pinger = (pinger_t*)handle->data;
- LOGF("ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME);
+ fprintf(stderr, "ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME);
+ fflush(stderr);
free(pinger);
diff --git a/deps/uv/test/benchmark-pound.c b/deps/uv/test/benchmark-pound.c
index 587928549eac8a..79f36345037cd4 100644
--- a/deps/uv/test/benchmark-pound.c
+++ b/deps/uv/test/benchmark-pound.c
@@ -299,11 +299,12 @@ static int pound_it(int concurrency,
/* Number of fractional seconds it took to run the benchmark. */
secs = (double)(end_time - start_time) / NANOSEC;
- LOGF("%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
- type,
- concurrency,
- closed_streams / secs,
- conns_failed);
+ fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
+ type,
+ concurrency,
+ closed_streams / secs,
+ conns_failed);
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/benchmark-pump.c b/deps/uv/test/benchmark-pump.c
index d58f46a384b899..88f2dc5c658e27 100644
--- a/deps/uv/test/benchmark-pump.c
+++ b/deps/uv/test/benchmark-pump.c
@@ -90,9 +90,10 @@ static void show_stats(uv_timer_t* handle) {
int i;
#if PRINT_STATS
- LOGF("connections: %d, write: %.1f gbit/s\n",
- write_sockets,
- gbit(nsent, STATS_INTERVAL));
+ fprintf(stderr, "connections: %d, write: %.1f gbit/s\n",
+ write_sockets,
+ gbit(nsent, STATS_INTERVAL));
+ fflush(stderr);
#endif
/* Exit if the show is over */
@@ -101,10 +102,11 @@ static void show_stats(uv_timer_t* handle) {
uv_update_time(loop);
diff = uv_now(loop) - start_time;
- LOGF("%s_pump%d_client: %.1f gbit/s\n",
- type == TCP ? "tcp" : "pipe",
- write_sockets,
- gbit(nsent_total, diff));
+ fprintf(stderr, "%s_pump%d_client: %.1f gbit/s\n",
+ type == TCP ? "tcp" : "pipe",
+ write_sockets,
+ gbit(nsent_total, diff));
+ fflush(stderr);
for (i = 0; i < write_sockets; i++) {
if (type == TCP)
@@ -128,10 +130,11 @@ static void read_show_stats(void) {
uv_update_time(loop);
diff = uv_now(loop) - start_time;
- LOGF("%s_pump%d_server: %.1f gbit/s\n",
- type == TCP ? "tcp" : "pipe",
- max_read_sockets,
- gbit(nrecv_total, diff));
+ fprintf(stderr, "%s_pump%d_server: %.1f gbit/s\n",
+ type == TCP ? "tcp" : "pipe",
+ max_read_sockets,
+ gbit(nrecv_total, diff));
+ fflush(stderr);
}
@@ -213,7 +216,10 @@ static void do_write(uv_stream_t* stream) {
static void connect_cb(uv_connect_t* req, int status) {
int i;
- if (status) LOG(uv_strerror(status));
+ if (status) {
+ fprintf(stderr, "%s", uv_strerror(status));
+ fflush(stderr);
+ }
ASSERT(status == 0);
write_sockets++;
diff --git a/deps/uv/test/benchmark-sizes.c b/deps/uv/test/benchmark-sizes.c
index 8ccf10ee475fb1..9bf42f91537d58 100644
--- a/deps/uv/test/benchmark-sizes.c
+++ b/deps/uv/test/benchmark-sizes.c
@@ -24,22 +24,23 @@
BENCHMARK_IMPL(sizes) {
- LOGF("uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t));
- LOGF("uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t));
- LOGF("uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t));
- LOGF("uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t));
- LOGF("uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t));
- LOGF("uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t));
- LOGF("uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t));
- LOGF("uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t));
- LOGF("uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t));
- LOGF("uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t));
- LOGF("uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t));
- LOGF("uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t));
- LOGF("uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t));
- LOGF("uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t));
- LOGF("uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t));
- LOGF("uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t));
- LOGF("uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t));
+ fprintf(stderr, "uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t));
+ fprintf(stderr, "uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t));
+ fprintf(stderr, "uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t));
+ fprintf(stderr, "uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t));
+ fprintf(stderr, "uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t));
+ fprintf(stderr, "uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t));
+ fprintf(stderr, "uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t));
+ fprintf(stderr, "uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t));
+ fprintf(stderr, "uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t));
+ fprintf(stderr, "uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t));
+ fprintf(stderr, "uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t));
+ fprintf(stderr, "uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t));
+ fprintf(stderr, "uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t));
+ fprintf(stderr, "uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t));
+ fprintf(stderr, "uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t));
+ fprintf(stderr, "uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t));
+ fprintf(stderr, "uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t));
+ fflush(stderr);
return 0;
}
diff --git a/deps/uv/test/benchmark-spawn.c b/deps/uv/test/benchmark-spawn.c
index 9cae41a83afd61..ed9ad608f3790e 100644
--- a/deps/uv/test/benchmark-spawn.c
+++ b/deps/uv/test/benchmark-spawn.c
@@ -155,8 +155,9 @@ BENCHMARK_IMPL(spawn) {
uv_update_time(loop);
end_time = uv_now(loop);
- LOGF("spawn: %.0f spawns/s\n",
- (double) N / (double) (end_time - start_time) * 1000.0);
+ fprintf(stderr, "spawn: %.0f spawns/s\n",
+ (double) N / (double) (end_time - start_time) * 1000.0);
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/run-benchmarks.c b/deps/uv/test/run-benchmarks.c
index 8d4f549799e8b3..6e42623d54cdec 100644
--- a/deps/uv/test/run-benchmarks.c
+++ b/deps/uv/test/run-benchmarks.c
@@ -41,7 +41,8 @@ int main(int argc, char **argv) {
case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]);
default:
- LOGF("Too many arguments.\n");
+ fprintf(stderr, "Too many arguments.\n");
+ fflush(stderr);
return EXIT_FAILURE;
}
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index e92c93008e72ef..1f458745327398 100644
--- a/deps/uv/test/run-tests.c
+++ b/deps/uv/test/run-tests.c
@@ -56,7 +56,8 @@ int main(int argc, char **argv) {
case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]);
default:
- LOGF("Too many arguments.\n");
+ fprintf(stderr, "Too many arguments.\n");
+ fflush(stderr);
return EXIT_FAILURE;
}
diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c
index e896d43b7627df..e094defc7e7de5 100644
--- a/deps/uv/test/runner.c
+++ b/deps/uv/test/runner.c
@@ -43,13 +43,14 @@ static void log_progress(int total,
total = 1;
progress = 100 * (passed + failed + skipped + todos) / total;
- LOGF("[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
- progress,
- passed,
- failed,
- todos,
- skipped,
- name);
+ fprintf(stderr, "[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
+ progress,
+ passed,
+ failed,
+ todos,
+ skipped,
+ name);
+ fflush(stderr);
}
@@ -109,7 +110,8 @@ int run_tests(int benchmark_output) {
}
if (tap_output) {
- LOGF("1..%d\n", total);
+ fprintf(stderr, "1..%d\n", total);
+ fflush(stderr);
}
/* Run all tests. */
@@ -184,7 +186,8 @@ void log_tap_result(int test_count,
reason[0] = '\0';
}
- LOGF("%s %d - %s%s%s\n", result, test_count, test, directive, reason);
+ fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
+ fflush(stderr);
}
@@ -320,49 +323,55 @@ int run_test(const char* test,
/* Show error and output from processes if the test failed. */
if (status != 0 || task->show_output) {
if (tap_output) {
- LOGF("#");
+ fprintf(stderr, "#");
} else if (status == TEST_TODO) {
- LOGF("\n`%s` todo\n", test);
+ fprintf(stderr, "\n`%s` todo\n", test);
} else if (status == TEST_SKIP) {
- LOGF("\n`%s` skipped\n", test);
+ fprintf(stderr, "\n`%s` skipped\n", test);
} else if (status != 0) {
- LOGF("\n`%s` failed: %s\n", test, errmsg);
+ fprintf(stderr, "\n`%s` failed: %s\n", test, errmsg);
} else {
- LOGF("\n");
+ fprintf(stderr, "\n");
}
+ fflush(stderr);
for (i = 0; i < process_count; i++) {
switch (process_output_size(&processes[i])) {
case -1:
- LOGF("Output from process `%s`: (unavailable)\n",
- process_get_name(&processes[i]));
+ fprintf(stderr, "Output from process `%s`: (unavailable)\n",
+ process_get_name(&processes[i]));
+ fflush(stderr);
break;
case 0:
- LOGF("Output from process `%s`: (no output)\n",
- process_get_name(&processes[i]));
+ fprintf(stderr, "Output from process `%s`: (no output)\n",
+ process_get_name(&processes[i]));
+ fflush(stderr);
break;
default:
- LOGF("Output from process `%s`:\n", process_get_name(&processes[i]));
+ fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i]));
+ fflush(stderr);
process_copy_output(&processes[i], fileno(stderr));
break;
}
}
if (!tap_output) {
- LOG("=============================================================\n");
+ fprintf(stderr, "=============================================================\n");
}
/* In benchmark mode show concise output from the main process. */
} else if (benchmark_output) {
switch (process_output_size(main_proc)) {
case -1:
- LOGF("%s: (unavailable)\n", test);
+ fprintf(stderr, "%s: (unavailable)\n", test);
+ fflush(stderr);
break;
case 0:
- LOGF("%s: (no output)\n", test);
+ fprintf(stderr, "%s: (no output)\n", test);
+ fflush(stderr);
break;
default:
@@ -397,7 +406,8 @@ int run_test_part(const char* test, const char* part) {
}
}
- LOGF("No test part with that name: %s:%s\n", test, part);
+ fprintf(stderr, "No test part with that name: %s:%s\n", test, part);
+ fflush(stderr);
return 255;
}
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 07584c52996f8c..ea0503e8feefe4 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -76,19 +76,6 @@ typedef enum {
PIPE
} stream_type;
-/* Log to stderr. */
-#define LOG(...) \
- do { \
- fprintf(stderr, "%s", __VA_ARGS__); \
- fflush(stderr); \
- } while (0)
-
-#define LOGF(...) \
- do { \
- fprintf(stderr, __VA_ARGS__); \
- fflush(stderr); \
- } while (0)
-
/* Die with fatal error. */
#define FATAL(msg) \
do { \
@@ -158,13 +145,15 @@ enum test_status {
#define RETURN_TODO(explanation) \
do { \
- LOGF("%s\n", explanation); \
+ fprintf(stderr, "%s\n", explanation); \
+ fflush(stderr); \
return TEST_TODO; \
} while (0)
#define RETURN_SKIP(explanation) \
do { \
- LOGF("%s\n", explanation); \
+ fprintf(stderr, "%s\n", explanation); \
+ fflush(stderr); \
return TEST_SKIP; \
} while (0)
@@ -190,10 +179,15 @@ enum test_status {
#include
+/* Define inline for MSVC */
+# ifdef _MSC_VER
+# define inline __inline
+# endif
+
/* Emulate snprintf() on Windows, _snprintf() doesn't zero-terminate the buffer
* on overflow...
*/
-static int snprintf(char* buf, size_t len, const char* fmt, ...) {
+inline int snprintf(char* buf, size_t len, const char* fmt, ...) {
va_list ap;
int n;
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index cc5dc744501ec4..a0600b30797dd9 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -1094,7 +1094,8 @@ TEST_IMPL(fs_fstat) {
#elif defined(__sun) || \
defined(_BSD_SOURCE) || \
defined(_SVID_SOURCE) || \
- defined(_XOPEN_SOURCE)
+ defined(_XOPEN_SOURCE) || \
+ defined(_DEFAULT_SOURCE)
ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec);
ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec);
ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec);
@@ -1155,6 +1156,7 @@ TEST_IMPL(fs_access) {
/* Setup. */
unlink("test_file");
+ rmdir("test_dir");
loop = uv_default_loop();
@@ -1198,6 +1200,16 @@ TEST_IMPL(fs_access) {
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
+ /* Directory access */
+ r = uv_fs_mkdir(loop, &req, "test_dir", 0777, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_access(loop, &req, "test_dir", W_OK, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
/*
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
@@ -1206,6 +1218,7 @@ TEST_IMPL(fs_access) {
/* Cleanup. */
unlink("test_file");
+ rmdir("test_dir");
MAKE_VALGRIND_HAPPY();
return 0;
@@ -1310,6 +1323,65 @@ TEST_IMPL(fs_chmod) {
}
+TEST_IMPL(fs_unlink_readonly) {
+ int r;
+ uv_fs_t req;
+ uv_file file;
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop,
+ &req,
+ "test_file",
+ O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR,
+ NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result;
+ uv_fs_req_cleanup(&req);
+
+ iov = uv_buf_init(test_buf, sizeof(test_buf));
+ r = uv_fs_write(loop, &req, file, &iov, 1, -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+ close(file);
+
+ /* Make the file read-only */
+ r = uv_fs_chmod(loop, &req, "test_file", 0400, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ check_permission("test_file", 0400);
+
+ /* Try to unlink the file */
+ r = uv_fs_unlink(loop, &req, "test_file", NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ /*
+ * Run the loop just to check we don't have make any extraneous uv_ref()
+ * calls. This should drop out immediately.
+ */
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ /* Cleanup. */
+ uv_fs_chmod(loop, &req, "test_file", 0600, NULL);
+ uv_fs_req_cleanup(&req);
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(fs_chown) {
int r;
uv_fs_t req;
diff --git a/deps/uv/test/test-handle-fileno.c b/deps/uv/test/test-handle-fileno.c
index df5e984ab74338..3fe933adebdd87 100644
--- a/deps/uv/test/test-handle-fileno.c
+++ b/deps/uv/test/test-handle-fileno.c
@@ -102,7 +102,8 @@ TEST_IMPL(handle_fileno) {
tty_fd = get_tty_fd();
if (tty_fd < 0) {
- LOGF("Cannot open a TTY fd");
+ fprintf(stderr, "Cannot open a TTY fd");
+ fflush(stderr);
} else {
r = uv_tty_init(loop, &tty, tty_fd, 0);
ASSERT(r == 0);
diff --git a/deps/uv/test/test-idle.c b/deps/uv/test/test-idle.c
index 0e991c368cfd81..f49d1964827278 100644
--- a/deps/uv/test/test-idle.c
+++ b/deps/uv/test/test-idle.c
@@ -46,7 +46,8 @@ static void timer_cb(uv_timer_t* handle) {
uv_close((uv_handle_t*) &timer_handle, close_cb);
timer_cb_called++;
- LOGF("timer_cb %d\n", timer_cb_called);
+ fprintf(stderr, "timer_cb %d\n", timer_cb_called);
+ fflush(stderr);
}
@@ -54,7 +55,8 @@ static void idle_cb(uv_idle_t* handle) {
ASSERT(handle == &idle_handle);
idle_cb_called++;
- LOGF("idle_cb %d\n", idle_cb_called);
+ fprintf(stderr, "idle_cb %d\n", idle_cb_called);
+ fflush(stderr);
}
@@ -62,7 +64,8 @@ static void check_cb(uv_check_t* handle) {
ASSERT(handle == &check_handle);
check_cb_called++;
- LOGF("check_cb %d\n", check_cb_called);
+ fprintf(stderr, "check_cb %d\n", check_cb_called);
+ fflush(stderr);
}
diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c
index cf8491fb1b4d15..869b099e0fccaf 100644
--- a/deps/uv/test/test-ip6-addr.c
+++ b/deps/uv/test/test-ip6-addr.c
@@ -77,14 +77,16 @@ TEST_IMPL(ip6_addr_link_local) {
device_name);
#endif
- LOGF("Testing link-local address %s "
- "(iface_index: 0x%02x, device_name: %s)\n",
- scoped_addr,
- iface_index,
- device_name);
+ fprintf(stderr, "Testing link-local address %s "
+ "(iface_index: 0x%02x, device_name: %s)\n",
+ scoped_addr,
+ iface_index,
+ device_name);
+ fflush(stderr);
ASSERT(0 == uv_ip6_addr(scoped_addr, TEST_PORT, &addr));
- LOGF("Got scope_id 0x%02x\n", addr.sin6_scope_id);
+ fprintf(stderr, "Got scope_id 0x%02x\n", addr.sin6_scope_id);
+ fflush(stderr);
ASSERT(iface_index == addr.sin6_scope_id);
}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index aac15e0d9df0b7..1e3c13d5e9267d 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -43,6 +43,7 @@ TEST_DECLARE (semaphore_1)
TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
+TEST_DECLARE (tty_file)
TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ip6_pton)
TEST_DECLARE (ipc_listen_before_write)
@@ -61,6 +62,7 @@ TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_write_after_connect)
#endif
TEST_DECLARE (tcp_writealot)
+TEST_DECLARE (tcp_write_fail)
TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open)
@@ -195,6 +197,9 @@ TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always)
TEST_DECLARE (socket_buffer_size)
TEST_DECLARE (spawn_fails)
+#ifndef _WIN32
+TEST_DECLARE (spawn_fails_check_for_waitpid_cleanup)
+#endif
TEST_DECLARE (spawn_exit_code)
TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
@@ -209,6 +214,8 @@ TEST_DECLARE (spawn_setuid_fails)
TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (spawn_stdout_to_file)
TEST_DECLARE (spawn_stdout_and_stderr_to_file)
+TEST_DECLARE (spawn_stdout_and_stderr_to_file2)
+TEST_DECLARE (spawn_stdout_and_stderr_to_file_swap)
TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (spawn_closed_process_io)
TEST_DECLARE (spawn_reads_child_path)
@@ -227,6 +234,7 @@ TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
+TEST_DECLARE (fs_unlink_readonly)
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink)
@@ -343,6 +351,7 @@ TASK_LIST_START
#endif
TEST_ENTRY (pipe_set_non_blocking)
TEST_ENTRY (tty)
+ TEST_ENTRY (tty_file)
TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ip6_pton)
TEST_ENTRY (ipc_listen_before_write)
@@ -372,6 +381,9 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server)
+ TEST_ENTRY (tcp_write_fail)
+ TEST_HELPER (tcp_write_fail, tcp4_echo_server)
+
TEST_ENTRY (tcp_try_write)
TEST_ENTRY (tcp_write_queue_order)
@@ -551,6 +563,9 @@ TASK_LIST_START
TEST_ENTRY (socket_buffer_size)
TEST_ENTRY (spawn_fails)
+#ifndef _WIN32
+ TEST_ENTRY (spawn_fails_check_for_waitpid_cleanup)
+#endif
TEST_ENTRY (spawn_exit_code)
TEST_ENTRY (spawn_stdout)
TEST_ENTRY (spawn_stdin)
@@ -565,6 +580,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_setgid_fails)
TEST_ENTRY (spawn_stdout_to_file)
TEST_ENTRY (spawn_stdout_and_stderr_to_file)
+ TEST_ENTRY (spawn_stdout_and_stderr_to_file2)
+ TEST_ENTRY (spawn_stdout_and_stderr_to_file_swap)
TEST_ENTRY (spawn_auto_unref)
TEST_ENTRY (spawn_closed_process_io)
TEST_ENTRY (spawn_reads_child_path)
@@ -611,6 +628,7 @@ TASK_LIST_START
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
+ TEST_ENTRY (fs_unlink_readonly)
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_futime)
diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c
index 0986de52981e1b..c3e8498ae90a6b 100644
--- a/deps/uv/test/test-loop-handles.c
+++ b/deps/uv/test/test-loop-handles.c
@@ -113,7 +113,8 @@ static void timer_cb(uv_timer_t* handle) {
static void idle_2_close_cb(uv_handle_t* handle) {
- LOG("IDLE_2_CLOSE_CB\n");
+ fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n");
+ fflush(stderr);
ASSERT(handle == (uv_handle_t*)&idle_2_handle);
@@ -125,7 +126,8 @@ static void idle_2_close_cb(uv_handle_t* handle) {
static void idle_2_cb(uv_idle_t* handle) {
- LOG("IDLE_2_CB\n");
+ fprintf(stderr, "%s", "IDLE_2_CB\n");
+ fflush(stderr);
ASSERT(handle == &idle_2_handle);
@@ -138,7 +140,8 @@ static void idle_2_cb(uv_idle_t* handle) {
static void idle_1_cb(uv_idle_t* handle) {
int r;
- LOG("IDLE_1_CB\n");
+ fprintf(stderr, "%s", "IDLE_1_CB\n");
+ fflush(stderr);
ASSERT(handle != NULL);
ASSERT(idles_1_active > 0);
@@ -164,7 +167,8 @@ static void idle_1_cb(uv_idle_t* handle) {
static void idle_1_close_cb(uv_handle_t* handle) {
- LOG("IDLE_1_CLOSE_CB\n");
+ fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n");
+ fflush(stderr);
ASSERT(handle != NULL);
@@ -173,7 +177,8 @@ static void idle_1_close_cb(uv_handle_t* handle) {
static void prepare_1_close_cb(uv_handle_t* handle) {
- LOG("PREPARE_1_CLOSE_CB");
+ fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB");
+ fflush(stderr);
ASSERT(handle == (uv_handle_t*)&prepare_1_handle);
prepare_1_close_cb_called++;
@@ -181,7 +186,8 @@ static void prepare_1_close_cb(uv_handle_t* handle) {
static void check_close_cb(uv_handle_t* handle) {
- LOG("CHECK_CLOSE_CB\n");
+ fprintf(stderr, "%s", "CHECK_CLOSE_CB\n");
+ fflush(stderr);
ASSERT(handle == (uv_handle_t*)&check_handle);
check_close_cb_called++;
@@ -189,7 +195,8 @@ static void check_close_cb(uv_handle_t* handle) {
static void prepare_2_close_cb(uv_handle_t* handle) {
- LOG("PREPARE_2_CLOSE_CB\n");
+ fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n");
+ fflush(stderr);
ASSERT(handle == (uv_handle_t*)&prepare_2_handle);
prepare_2_close_cb_called++;
@@ -199,8 +206,8 @@ static void prepare_2_close_cb(uv_handle_t* handle) {
static void check_cb(uv_check_t* handle) {
int i, r;
- LOG("CHECK_CB\n");
-
+ fprintf(stderr, "%s", "CHECK_CB\n");
+ fflush(stderr);
ASSERT(handle == &check_handle);
if (loop_iteration < ITERATIONS) {
@@ -235,8 +242,8 @@ static void check_cb(uv_check_t* handle) {
static void prepare_2_cb(uv_prepare_t* handle) {
int r;
- LOG("PREPARE_2_CB\n");
-
+ fprintf(stderr, "%s", "PREPARE_2_CB\n");
+ fflush(stderr);
ASSERT(handle == &prepare_2_handle);
/* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */
@@ -255,8 +262,8 @@ static void prepare_2_cb(uv_prepare_t* handle) {
static void prepare_1_cb(uv_prepare_t* handle) {
int r;
- LOG("PREPARE_1_CB\n");
-
+ fprintf(stderr, "%s", "PREPARE_1_CB\n");
+ fflush(stderr);
ASSERT(handle == &prepare_1_handle);
if (loop_iteration % 2 == 0) {
diff --git a/deps/uv/test/test-osx-select.c b/deps/uv/test/test-osx-select.c
index 6ccf603483488a..a0afda9181ebd9 100644
--- a/deps/uv/test/test-osx-select.c
+++ b/deps/uv/test/test-osx-select.c
@@ -39,6 +39,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
fprintf(stdout, "got data %d\n", ++read_count);
+ fflush(stdout);
if (read_count == 3)
uv_close((uv_handle_t*) stream, NULL);
@@ -55,7 +56,8 @@ TEST_IMPL(osx_select) {
fd = open("/dev/tty", O_RDONLY);
if (fd < 0) {
- LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ fflush(stderr);
return TEST_SKIP;
}
@@ -107,7 +109,8 @@ TEST_IMPL(osx_select_many_fds) {
fd = open("/dev/tty", O_RDONLY);
if (fd < 0) {
- LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ fflush(stderr);
return TEST_SKIP;
}
diff --git a/deps/uv/test/test-pipe-set-non-blocking.c b/deps/uv/test/test-pipe-set-non-blocking.c
index 5cf2c19e7fbd29..fcc9fc0da85e99 100644
--- a/deps/uv/test/test-pipe-set-non-blocking.c
+++ b/deps/uv/test/test-pipe-set-non-blocking.c
@@ -88,8 +88,8 @@ TEST_IMPL(pipe_set_non_blocking) {
uv_close((uv_handle_t*) &pipe_handle, NULL);
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
- ASSERT(0 == close(fd[1])); /* fd[0] is closed by uv_close(). */
ASSERT(0 == uv_thread_join(&thread));
+ ASSERT(0 == close(fd[1])); /* fd[0] is closed by uv_close(). */
uv_barrier_destroy(&ctx.barrier);
MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 9b0030029c187c..d01862abe1d97a 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -21,6 +21,7 @@
#include "uv.h"
#include "task.h"
+#include
#include
#include
#include
@@ -34,6 +35,7 @@
# include
#else
# include
+# include
#endif
@@ -180,6 +182,37 @@ TEST_IMPL(spawn_fails) {
}
+#ifndef _WIN32
+TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) {
+ int r;
+ int status;
+ int err;
+
+ init_process_options("", fail_cb);
+ options.file = options.args[0] = "program-that-had-better-not-exist";
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_ENOENT || r == UV_EACCES);
+ ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ /* verify the child is successfully cleaned up within libuv */
+ do
+ err = waitpid(process.pid, &status, 0);
+ while (err == -1 && errno == EINTR);
+
+ ASSERT(err == -1);
+ ASSERT(errno == ECHILD);
+
+ uv_close((uv_handle_t*) &process, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
TEST_IMPL(spawn_exit_code) {
int r;
@@ -342,6 +375,163 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
}
+TEST_IMPL(spawn_stdout_and_stderr_to_file2) {
+#ifndef _WIN32
+ int r;
+ uv_file file;
+ uv_fs_t fs_req;
+ uv_stdio_container_t stdio[3];
+ uv_buf_t buf;
+
+ /* Setup. */
+ unlink("stdout_file");
+
+ init_process_options("spawn_helper6", exit_cb);
+
+ /* Replace stderr with our file */
+ r = uv_fs_open(uv_default_loop(),
+ &fs_req,
+ "stdout_file",
+ O_CREAT | O_RDWR,
+ S_IRUSR | S_IWUSR,
+ NULL);
+ ASSERT(r != -1);
+ uv_fs_req_cleanup(&fs_req);
+ file = dup2(r, STDERR_FILENO);
+ ASSERT(file != -1);
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_INHERIT_FD;
+ options.stdio[1].data.fd = file;
+ options.stdio[2].flags = UV_INHERIT_FD;
+ options.stdio[2].data.fd = file;
+ options.stdio_count = 3;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ buf = uv_buf_init(output, sizeof(output));
+ r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
+ ASSERT(r == 27);
+ uv_fs_req_cleanup(&fs_req);
+
+ r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&fs_req);
+
+ printf("output is: %s", output);
+ ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
+
+ /* Cleanup. */
+ unlink("stdout_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+#else
+ RETURN_SKIP("Unix only test");
+#endif
+}
+
+
+TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
+#ifndef _WIN32
+ int r;
+ uv_file stdout_file;
+ uv_file stderr_file;
+ uv_fs_t fs_req;
+ uv_stdio_container_t stdio[3];
+ uv_buf_t buf;
+
+ /* Setup. */
+ unlink("stdout_file");
+ unlink("stderr_file");
+
+ init_process_options("spawn_helper6", exit_cb);
+
+ /* open 'stdout_file' and replace STDOUT_FILENO with it */
+ r = uv_fs_open(uv_default_loop(),
+ &fs_req,
+ "stdout_file",
+ O_CREAT | O_RDWR,
+ S_IRUSR | S_IWUSR,
+ NULL);
+ ASSERT(r != -1);
+ uv_fs_req_cleanup(&fs_req);
+ stdout_file = dup2(r, STDOUT_FILENO);
+ ASSERT(stdout_file != -1);
+
+ /* open 'stderr_file' and replace STDERR_FILENO with it */
+ r = uv_fs_open(uv_default_loop(), &fs_req, "stderr_file", O_CREAT | O_RDWR,
+ S_IRUSR | S_IWUSR, NULL);
+ ASSERT(r != -1);
+ uv_fs_req_cleanup(&fs_req);
+ stderr_file = dup2(r, STDERR_FILENO);
+ ASSERT(stderr_file != -1);
+
+ /* now we're going to swap them: the child process' stdout will be our
+ * stderr_file and vice versa */
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_INHERIT_FD;
+ options.stdio[1].data.fd = stderr_file;
+ options.stdio[2].flags = UV_INHERIT_FD;
+ options.stdio[2].data.fd = stdout_file;
+ options.stdio_count = 3;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ buf = uv_buf_init(output, sizeof(output));
+
+ /* check the content of stdout_file */
+ r = uv_fs_read(uv_default_loop(), &fs_req, stdout_file, &buf, 1, 0, NULL);
+ ASSERT(r >= 15);
+ uv_fs_req_cleanup(&fs_req);
+
+ r = uv_fs_close(uv_default_loop(), &fs_req, stdout_file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&fs_req);
+
+ printf("output is: %s", output);
+ ASSERT(strncmp("hello errworld\n", output, 15) == 0);
+
+ /* check the content of stderr_file */
+ r = uv_fs_read(uv_default_loop(), &fs_req, stderr_file, &buf, 1, 0, NULL);
+ ASSERT(r >= 12);
+ uv_fs_req_cleanup(&fs_req);
+
+ r = uv_fs_close(uv_default_loop(), &fs_req, stderr_file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&fs_req);
+
+ printf("output is: %s", output);
+ ASSERT(strncmp("hello world\n", output, 12) == 0);
+
+ /* Cleanup. */
+ unlink("stdout_file");
+ unlink("stderr_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+#else
+ RETURN_SKIP("Unix only test");
+#endif
+}
+
+
TEST_IMPL(spawn_stdin) {
int r;
uv_pipe_t out;
@@ -1007,7 +1197,7 @@ TEST_IMPL(environment_creation) {
return 0;
}
-// Regression test for issue #909
+/* Regression test for issue #909 */
TEST_IMPL(spawn_with_an_odd_path) {
int r;
diff --git a/deps/uv/test/test-tcp-write-fail.c b/deps/uv/test/test-tcp-write-fail.c
new file mode 100644
index 00000000000000..2840d8161032be
--- /dev/null
+++ b/deps/uv/test/test-tcp-write-fail.c
@@ -0,0 +1,115 @@
+/* Copyright Joyent, Inc. and other Node 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
+#include
+#ifndef _WIN32
+# include
+#endif
+
+
+static int connect_cb_called = 0;
+static int write_cb_called = 0;
+static int close_cb_called = 0;
+
+static uv_connect_t connect_req;
+static uv_write_t write_req;
+
+
+static void close_socket(uv_tcp_t* sock) {
+ uv_os_fd_t fd;
+ int r;
+
+ r = uv_fileno((uv_handle_t*)sock, &fd);
+ ASSERT(r == 0);
+#ifdef _WIN32
+ r = closesocket(fd);
+#else
+ r = close(fd);
+#endif
+ ASSERT(r == 0);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+
+ ASSERT(status != 0);
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
+ write_cb_called++;
+
+ uv_close((uv_handle_t*)(req->handle), close_cb);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ uv_buf_t buf;
+ uv_stream_t* stream;
+ int r;
+
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ stream = req->handle;
+ connect_cb_called++;
+
+ /* close the socket, the hard way */
+ close_socket((uv_tcp_t*)stream);
+
+ buf = uv_buf_init("hello\n", 6);
+ r = uv_write(&write_req, stream, &buf, 1, write_cb);
+ ASSERT(r == 0);
+}
+
+
+TEST_IMPL(tcp_write_fail) {
+ struct sockaddr_in addr;
+ uv_tcp_t client;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-timer-again.c b/deps/uv/test/test-timer-again.c
index 095cd9e707baa8..f93c509be5dc0a 100644
--- a/deps/uv/test/test-timer-again.c
+++ b/deps/uv/test/test-timer-again.c
@@ -47,8 +47,9 @@ static void repeat_1_cb(uv_timer_t* handle) {
ASSERT(handle == &repeat_1);
ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
- LOGF("repeat_1_cb called after %ld ms\n",
- (long int)(uv_now(uv_default_loop()) - start_time));
+ fprintf(stderr, "repeat_1_cb called after %ld ms\n",
+ (long int)(uv_now(uv_default_loop()) - start_time));
+ fflush(stderr);
repeat_1_cb_called++;
@@ -69,8 +70,9 @@ static void repeat_2_cb(uv_timer_t* handle) {
ASSERT(handle == &repeat_2);
ASSERT(repeat_2_cb_allowed);
- LOGF("repeat_2_cb called after %ld ms\n",
- (long int)(uv_now(uv_default_loop()) - start_time));
+ fprintf(stderr, "repeat_2_cb called after %ld ms\n",
+ (long int)(uv_now(uv_default_loop()) - start_time));
+ fflush(stderr);
repeat_2_cb_called++;
@@ -80,8 +82,9 @@ static void repeat_2_cb(uv_timer_t* handle) {
return;
}
- LOGF("uv_timer_get_repeat %ld ms\n",
- (long int)uv_timer_get_repeat(&repeat_2));
+ fprintf(stderr, "uv_timer_get_repeat %ld ms\n",
+ (long int)uv_timer_get_repeat(&repeat_2));
+ fflush(stderr);
ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
/* This shouldn't take effect immediately. */
@@ -129,8 +132,9 @@ TEST_IMPL(timer_again) {
ASSERT(repeat_2_cb_called == 2);
ASSERT(close_cb_called == 2);
- LOGF("Test took %ld ms (expected ~700 ms)\n",
- (long int)(uv_now(uv_default_loop()) - start_time));
+ fprintf(stderr, "Test took %ld ms (expected ~700 ms)\n",
+ (long int)(uv_now(uv_default_loop()) - start_time));
+ fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index 7e1ce2668899f8..81e612c1d6ae1c 100644
--- a/deps/uv/test/test-tty.c
+++ b/deps/uv/test/test-tty.c
@@ -66,13 +66,15 @@ TEST_IMPL(tty) {
#else /* unix */
ttyin_fd = open("/dev/tty", O_RDONLY, 0);
if (ttyin_fd < 0) {
- LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ fflush(stderr);
return TEST_SKIP;
}
ttyout_fd = open("/dev/tty", O_WRONLY, 0);
if (ttyout_fd < 0) {
- LOGF("Cannot open /dev/tty as write-only: %s\n", strerror(errno));
+ fprintf(stderr, "Cannot open /dev/tty as write-only: %s\n", strerror(errno));
+ fflush(stderr);
return TEST_SKIP;
}
#endif
@@ -111,13 +113,20 @@ TEST_IMPL(tty) {
ASSERT(height > 10);
/* Turn on raw mode. */
- r = uv_tty_set_mode(&tty_in, 1);
+ r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW);
ASSERT(r == 0);
/* Turn off raw mode. */
- r = uv_tty_set_mode(&tty_in, 0);
+ r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_NORMAL);
ASSERT(r == 0);
+ /* Calling uv_tty_reset_mode() repeatedly should not clobber errno. */
+ errno = 0;
+ ASSERT(0 == uv_tty_reset_mode());
+ ASSERT(0 == uv_tty_reset_mode());
+ ASSERT(0 == uv_tty_reset_mode());
+ ASSERT(0 == errno);
+
/* TODO check the actual mode! */
uv_close((uv_handle_t*) &tty_in, NULL);
@@ -128,3 +137,45 @@ TEST_IMPL(tty) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+
+TEST_IMPL(tty_file) {
+#ifndef _WIN32
+ uv_loop_t loop;
+ uv_tty_t tty;
+ int fd;
+
+ ASSERT(0 == uv_loop_init(&loop));
+
+ fd = open("test/fixtures/empty_file", O_RDONLY);
+ if (fd != -1) {
+ ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
+ ASSERT(0 == close(fd));
+ }
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd != -1) {
+ ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
+ ASSERT(0 == close(fd));
+ }
+
+ fd = open("/dev/zero", O_RDONLY);
+ if (fd != -1) {
+ ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
+ ASSERT(0 == close(fd));
+ }
+
+ fd = open("/dev/tty", O_RDONLY);
+ if (fd != -1) {
+ ASSERT(0 == uv_tty_init(&loop, &tty, fd, 1));
+ ASSERT(0 == close(fd));
+ uv_close((uv_handle_t*) &tty, NULL);
+ }
+
+ ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
+ ASSERT(0 == uv_loop_close(&loop));
+
+ MAKE_VALGRIND_HAPPY();
+#endif
+ return 0;
+}
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 1ef8c05adc6496..acaed862d7c66e 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -39,7 +39,7 @@
'_FILE_OFFSET_BITS=64',
],
}],
- ['OS == "mac"', {
+ ['OS in "mac ios"', {
'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
}],
['OS == "linux"', {
@@ -167,18 +167,17 @@
'cflags': [ '-fPIC' ],
}],
['uv_library=="shared_library" and OS!="mac"', {
- 'link_settings': {
- # Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR
- # in include/uv-version.h
- 'libraries': [ '-Wl,-soname,libuv.so.1.0' ],
- },
+ # This will cause gyp to set soname
+ # Must correspond with UV_VERSION_MAJOR
+ # in include/uv-version.h
+ 'product_extension': 'so.1',
}],
],
}],
- [ 'OS in "linux mac android"', {
+ [ 'OS in "linux mac ios android"', {
'sources': [ 'src/unix/proctitle.c' ],
}],
- [ 'OS=="mac"', {
+ [ 'OS in "mac ios"', {
'sources': [
'src/unix/darwin.c',
'src/unix/fsevents.c',
@@ -261,7 +260,7 @@
'libraries': [ '-lkvm' ],
},
}],
- [ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
+ [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', {
'sources': [ 'src/unix/kqueue.c' ],
}],
['uv_library=="shared_library"', {
@@ -364,6 +363,7 @@
'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-write-after-connect.c',
'test/test-tcp-writealot.c',
+ 'test/test-tcp-write-fail.c',
'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.c',
'test/test-tcp-oob.c',
diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat
index d3b7aa154eec6a..084ab9578fe10d 100644
--- a/deps/uv/vcbuild.bat
+++ b/deps/uv/vcbuild.bat
@@ -90,8 +90,8 @@ if defined noprojgen goto msbuild
@rem Generate the VS project.
if exist build\gyp goto have_gyp
-echo git clone https://git.chromium.org/external/gyp.git build/gyp
-git clone https://git.chromium.org/external/gyp.git build/gyp
+echo git clone https://chromium.googlesource.com/external/gyp build/gyp
+git clone https://chromium.googlesource.com/external/gyp build/gyp
if errorlevel 1 goto gyp_install_failed
goto have_gyp
diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown
index 38649b55085313..e2922558040ef5 100644
--- a/doc/api/tls.markdown
+++ b/doc/api/tls.markdown
@@ -141,14 +141,37 @@ automatically set as a listener for the [secureConnection][] event. The
- `ciphers`: A string describing the ciphers to use or exclude, seperated by
`:`. The default cipher suite is:
- ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:
- DHE-RSA-AES256-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:
- HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA
-
- The default cipher suite prefers ECDHE and DHE ciphers for Perfect Forward
- secrecy, while offering *some* backward compatibiltity. Old clients which
- rely on insecure and deprecated RC4 or DES-based ciphers (like Internet
- Explorer 6) aren't able to complete the handshake with the default
+ ECDHE-RSA-AES128-GCM-SHA256:
+ ECDHE-ECDSA-AES128-GCM-SHA256:
+ ECDHE-RSA-AES256-GCM-SHA384:
+ ECDHE-ECDSA-AES256-GCM-SHA384:
+ DHE-RSA-AES128-GCM-SHA256:
+ ECDHE-RSA-AES128-SHA256:
+ DHE-RSA-AES128-SHA256:
+ ECDHE-RSA-AES256-SHA384:
+ DHE-RSA-AES256-SHA384:
+ ECDHE-RSA-AES256-SHA256:
+ DHE-RSA-AES256-SHA256:
+ HIGH:
+ !aNULL:
+ !eNULL:
+ !EXPORT:
+ !DES:
+ !RC4:
+ !MD5:
+ !PSK:
+ !SRP:
+ !CAMELLIA
+
+ The default cipher suite prefers GCM ciphers for [Chrome's 'modern
+ cryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect
+ Forward secrecy, while offering *some* backward compatibiltity.
+
+ 128 bit AES is preferred over 192 and 256 bit AES in light of [specific
+ attacks affecting larger AES key sizes].
+
+ Old clients that rely on insecure and deprecated RC4 or DES-based ciphers
+ (like Internet Explorer 6) aren't able to complete the handshake with the default
configuration. If you absolutely must support these clients, the
[TLS recommendations] may offer a compatible cipher suite. For more details
on the format, see the [OpenSSL cipher list format documentation].
@@ -160,8 +183,10 @@ automatically set as a listener for the [secureConnection][] event. The
- `dhparam`: A string or `Buffer` containing Diffie Hellman parameters,
required for Perfect Forward Secrecy. Use `openssl dhparam` to create it.
- If omitted or invalid, it is silently discarded and DHE ciphers won't be
- available.
+ Its key length should be greater than or equal to 1024 bits, otherwise
+ it throws an error. It is strongly recommended to use 2048 bits or
+ more for stronger security. If omitted or invalid, it is silently
+ discarded and DHE ciphers won't be available.
- `handshakeTimeout`: Abort the connection if the SSL/TLS handshake does not
finish in this many milliseconds. The default is 120 seconds.
@@ -784,6 +809,8 @@ The string representation of the local IP address.
The numeric representation of the local port.
[OpenSSL cipher list format documentation]: http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
+[Chrome's 'modern cryptography' setting]: http://www.chromium.org/Home/chromium-security/education/tls#TOC-Deprecation-of-TLS-Features-Algorithms-in-Chrome
+[specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html
[BEAST attacks]: http://blog.ivanristic.com/2011/10/mitigating-the-beast-attack-on-tls.html
[tls.createServer]: #tls_tls_createserver_options_secureconnectionlistener
[tls.createSecurePair]: #tls_tls_createsecurepair_credentials_isserver_requestcert_rejectunauthorized
diff --git a/doc/api/v8.markdown b/doc/api/v8.markdown
index adced82685eea4..cedd5c86d9b008 100644
--- a/doc/api/v8.markdown
+++ b/doc/api/v8.markdown
@@ -20,7 +20,7 @@ Returns an object with the following properties
}
```
-## setFlagsFromString()
+## setFlagsFromString(string)
Set additional V8 command line flags. Use with care; changing settings
after the VM has started may result in unpredictable behavior, including
diff --git a/lib/_debugger.js b/lib/_debugger.js
index f1885b2e32f467..4c503d2f5480e9 100644
--- a/lib/_debugger.js
+++ b/lib/_debugger.js
@@ -101,7 +101,7 @@ Protocol.prototype.execute = function(d) {
if (len - this.bodyStartByteIndex < this.contentLength) {
break;
}
- // pass thru
+ // falls through
case 'body':
var resRawByteLength = Buffer.byteLength(res.raw, 'utf8');
@@ -125,7 +125,6 @@ Protocol.prototype.execute = function(d) {
default:
throw new Error('Unknown state');
- break;
}
};
@@ -262,7 +261,7 @@ Client.prototype.req = function(req, cb) {
Client.prototype.reqVersion = function(cb) {
cb = cb || function() {};
- this.req({ command: 'version' } , function(err, body, res) {
+ this.req({ command: 'version' }, function(err, body, res) {
if (err) return cb(err);
cb(null, res.body.body.V8Version, res.body.running);
});
@@ -398,7 +397,7 @@ Client.prototype.reqFrameEval = function(expression, frame, cb) {
// reqBacktrace(cb)
// TODO: from, to, bottom
Client.prototype.reqBacktrace = function(cb) {
- this.req({ command: 'backtrace', arguments: { inlineRefs: true } } , cb);
+ this.req({ command: 'backtrace', arguments: { inlineRefs: true } }, cb);
};
@@ -432,7 +431,7 @@ Client.prototype.reqScripts = function(cb) {
var self = this;
cb = cb || function() {};
- this.req({ command: 'scripts' } , function(err, res) {
+ this.req({ command: 'scripts' }, function(err, res) {
if (err) return cb(err);
for (var i = 0; i < res.length; i++) {
diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js
index 41ece371cdfbe6..aea665e80973c9 100644
--- a/lib/_http_incoming.js
+++ b/lib/_http_incoming.js
@@ -137,8 +137,10 @@ IncomingMessage.prototype._addHeaderLine = function(field, value, dest) {
}
break;
+ /* eslint-disable max-len */
// list is taken from:
// https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
+ /* eslint-enable max-len */
case 'content-type':
case 'content-length':
case 'user-agent':
@@ -158,9 +160,9 @@ IncomingMessage.prototype._addHeaderLine = function(field, value, dest) {
default:
// make comma-separated list
- if (dest[field] !== undefined)
+ if (dest[field] !== undefined) {
dest[field] += ', ' + value;
- else {
+ } else {
dest[field] = value;
}
}
diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js
index 88590551c9defb..bfebef21b69af6 100644
--- a/lib/_http_outgoing.js
+++ b/lib/_http_outgoing.js
@@ -85,8 +85,9 @@ OutgoingMessage.prototype.setTimeout = function(msecs, callback) {
this.once('socket', function(socket) {
socket.setTimeout(msecs);
});
- } else
+ } else {
this.socket.setTimeout(msecs);
+ }
};
diff --git a/lib/_http_server.js b/lib/_http_server.js
index 99903024c26d14..ae2bba035c8763 100644
--- a/lib/_http_server.js
+++ b/lib/_http_server.js
@@ -221,9 +221,11 @@ function Server(requestListener) {
this.addListener('request', requestListener);
}
+ /* eslint-disable max-len */
// Similar option to this. Too lazy to write my own docs.
// http://www.squid-cache.org/Doc/config/half_closed_clients/
// http://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
+ /* eslint-enable max-len */
this.httpAllowHalfOpen = false;
this.addListener('connection', connectionListener);
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js
index 1de55597123d1b..bebbc80e2bf8dc 100644
--- a/lib/_stream_readable.js
+++ b/lib/_stream_readable.js
@@ -234,8 +234,9 @@ function howMuchToRead(n, state) {
if (!state.ended) {
state.needReadable = true;
return 0;
- } else
+ } else {
return state.length;
+ }
}
return n;
@@ -774,7 +775,7 @@ Readable.prototype.wrap = function(stream) {
if (this[i] === undefined && typeof stream[i] === 'function') {
this[i] = function(method) { return function() {
return stream[method].apply(stream, arguments);
- }}(i);
+ }; }(i);
}
}
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
index da65ddb90ae5ca..54f751abdf24ee 100644
--- a/lib/_stream_writable.js
+++ b/lib/_stream_writable.js
@@ -9,7 +9,6 @@ Writable.WritableState = WritableState;
const util = require('util');
const Stream = require('stream');
-const debug = util.debuglog('stream');
util.inherits(Writable, Stream);
@@ -273,9 +272,9 @@ function writeOrBuffer(stream, state, chunk, encoding, cb) {
} else {
state.bufferedRequest = state.lastBufferedRequest;
}
- }
- else
+ } else {
doWrite(stream, state, false, len, chunk, encoding, cb);
+ }
return ret;
}
@@ -471,8 +470,9 @@ function finishMaybe(stream, state) {
prefinish(stream, state);
state.finished = true;
stream.emit('finish');
- } else
+ } else {
prefinish(stream, state);
+ }
}
return need;
}
diff --git a/lib/_tls_legacy.js b/lib/_tls_legacy.js
index 3348d7f92d951c..0a0c7bca7b9024 100644
--- a/lib/_tls_legacy.js
+++ b/lib/_tls_legacy.js
@@ -646,7 +646,7 @@ function onnewsession(key, session) {
if (self.ssl)
self.ssl.newSessionDone();
- };
+ }
}
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
index 122c7042a4cf2f..5a35c3bd967b55 100644
--- a/lib/_tls_wrap.js
+++ b/lib/_tls_wrap.js
@@ -141,29 +141,23 @@ function onclienthello(hello) {
if (err)
return self.destroy(err);
- // Servername came from SSL session
- // NOTE: TLS Session ticket doesn't include servername information
- //
- // Another note, From RFC3546:
- //
- // If, on the other hand, the older
- // session is resumed, then the server MUST ignore extensions appearing
- // in the client hello, and send a server hello containing no
- // extensions; in this case the extension functionality negotiated
- // during the original session initiation is applied to the resumed
- // session.
- //
- // Therefore we should account session loading when dealing with servername
- var servername = session && session.servername || hello.servername;
- loadSNI(self, servername, function(err, ctx) {
+ self._handle.endParser();
+ });
+}
+
+
+function oncertcb(info) {
+ var self = this;
+ var servername = info.servername;
+
+ loadSNI(self, servername, function(err, ctx) {
+ if (err)
+ return self.destroy(err);
+ requestOCSP(self, info, ctx, function(err) {
if (err)
return self.destroy(err);
- requestOCSP(self, hello, ctx, function(err) {
- if (err)
- return self.destroy(err);
- self._handle.endParser();
- });
+ self._handle.certCbDone();
});
});
}
@@ -295,15 +289,22 @@ TLSSocket.prototype._wrapHandle = function(handle) {
}
});
- this.on('close', this._destroySSL);
+ this.on('close', function() {
+ this._destroySSL();
+ res = null;
+ });
return res;
};
TLSSocket.prototype._destroySSL = function _destroySSL() {
+ if (!this.ssl) return;
this.ssl.destroySSL();
- if (this.ssl._secureContext.singleUse)
+ if (this.ssl._secureContext.singleUse) {
this.ssl._secureContext.context.close();
+ this.ssl._secureContext.context = null;
+ }
+ this.ssl = null;
};
TLSSocket.prototype._init = function(socket, wrap) {
@@ -333,15 +334,18 @@ TLSSocket.prototype._init = function(socket, wrap) {
ssl.onhandshakestart = onhandshakestart.bind(this);
ssl.onhandshakedone = onhandshakedone.bind(this);
ssl.onclienthello = onclienthello.bind(this);
+ ssl.oncertcb = oncertcb.bind(this);
ssl.onnewsession = onnewsession.bind(this);
ssl.lastHandshakeTime = 0;
ssl.handshakes = 0;
- if (this.server &&
- (listenerCount(this.server, 'resumeSession') > 0 ||
- listenerCount(this.server, 'newSession') > 0 ||
- listenerCount(this.server, 'OCSPRequest') > 0)) {
- ssl.enableSessionCallbacks();
+ if (this.server) {
+ if (listenerCount(this.server, 'resumeSession') > 0 ||
+ listenerCount(this.server, 'newSession') > 0) {
+ ssl.enableSessionCallbacks();
+ }
+ if (listenerCount(this.server, 'OCSPRequest') > 0)
+ ssl.enableCertCb();
}
} else {
ssl.onhandshakestart = function() {};
@@ -358,7 +362,7 @@ TLSSocket.prototype._init = function(socket, wrap) {
self._writableState.errorEmitted = true;
// Destroy socket if error happened before handshake's finish
- if (!this._secureEstablished) {
+ if (!self._secureEstablished) {
self._tlsError(err);
self.destroy();
} else if (options.isServer &&
@@ -382,7 +386,7 @@ TLSSocket.prototype._init = function(socket, wrap) {
options.server._contexts.length)) {
assert(typeof options.SNICallback === 'function');
this._SNICallback = options.SNICallback;
- ssl.enableHelloParser();
+ ssl.enableCertCb();
}
if (process.features.tls_npn && options.NPNProtocols)
diff --git a/lib/assert.js b/lib/assert.js
index 4a01e5c7f0b356..70e784a50c34b9 100644
--- a/lib/assert.js
+++ b/lib/assert.js
@@ -323,4 +323,4 @@ assert.doesNotThrow = function(block, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments)));
};
-assert.ifError = function(err) { if (err) {throw err;}};
+assert.ifError = function(err) { if (err) throw err; };
diff --git a/lib/buffer.js b/lib/buffer.js
index 8f4e34d289fc27..dc2b656d7a7a33 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -247,6 +247,11 @@ Buffer.concat = function(list, length) {
if (!Array.isArray(list))
throw new TypeError('list argument must be an Array of Buffers.');
+ if (list.length === 0)
+ return new Buffer(0);
+ else if (list.length === 1)
+ return list[0];
+
if (length === undefined) {
length = 0;
for (var i = 0; i < list.length; i++)
@@ -255,11 +260,6 @@ Buffer.concat = function(list, length) {
length = length >>> 0;
}
- if (list.length === 0)
- return new Buffer(0);
- else if (list.length === 1)
- return list[0];
-
var buffer = new Buffer(length);
var pos = 0;
for (var i = 0; i < list.length; i++) {
diff --git a/lib/child_process.js b/lib/child_process.js
index 99da7cfbde94dc..34ce359f5b0ec5 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -169,7 +169,7 @@ SocketListSend.prototype._request = function(msg, cmd, callback) {
function onclose() {
self.slave.removeListener('internalMessage', onreply);
callback(new Error('Slave closed before reply'));
- };
+ }
function onreply(msg) {
if (!(msg.cmd === cmd && msg.key === self.key)) return;
@@ -177,7 +177,7 @@ SocketListSend.prototype._request = function(msg, cmd, callback) {
self.slave.removeListener('internalMessage', onreply);
callback(null, msg);
- };
+ }
this.slave.once('disconnect', onclose);
this.slave.on('internalMessage', onreply);
diff --git a/lib/cluster.js b/lib/cluster.js
index 10a55996f15cc8..ca1005b738068f 100644
--- a/lib/cluster.js
+++ b/lib/cluster.js
@@ -11,7 +11,7 @@ const SCHED_RR = 2;
const uv = process.binding('uv');
-const cluster = new EventEmitter;
+const cluster = new EventEmitter();
module.exports = cluster;
cluster.Worker = Worker;
cluster.isWorker = ('NODE_UNIQUE_ID' in process.env);
@@ -127,11 +127,10 @@ RoundRobinHandle.prototype.add = function(worker, send) {
function done() {
if (self.handle.getsockname) {
var out = {};
- var err = self.handle.getsockname(out);
+ self.handle.getsockname(out);
// TODO(bnoordhuis) Check err.
send(null, { sockname: out }, null);
- }
- else {
+ } else {
send(null, null, null); // UNIX socket.
}
self.handoff(worker); // In case there are connections pending.
@@ -196,7 +195,7 @@ else
function masterInit() {
cluster.workers = {};
- var intercom = new EventEmitter;
+ var intercom = new EventEmitter();
cluster.settings = {};
// XXX(bnoordhuis) Fold cluster.schedulingPolicy into cluster.settings?
@@ -511,6 +510,7 @@ function workerInit() {
});
cluster.worker = worker;
process.once('disconnect', function() {
+ worker.emit('disconnect');
if (!worker.suicide) {
// Unexpected disconnect, master exited, or some such nastiness, so
// worker exits immediately.
diff --git a/lib/console.js b/lib/console.js
index 63e3c5e0bf1aa4..f9032e24a0fa44 100644
--- a/lib/console.js
+++ b/lib/console.js
@@ -73,7 +73,7 @@ Console.prototype.timeEnd = function(label) {
Console.prototype.trace = function trace() {
// TODO probably can to do this better with V8's debug object once that is
// exposed.
- var err = new Error;
+ var err = new Error();
err.name = 'Trace';
err.message = util.format.apply(this, arguments);
Error.captureStackTrace(err, trace);
diff --git a/lib/crypto.js b/lib/crypto.js
index 10ff71e8547606..7ce89482d54b14 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -320,7 +320,7 @@ function Verify(algorithm, options) {
if (!(this instanceof Verify))
return new Verify(algorithm, options);
- this._handle = new binding.Verify;
+ this._handle = new binding.Verify();
this._handle.init(algorithm);
stream.Writable.call(this, options);
diff --git a/lib/dgram.js b/lib/dgram.js
index 7d2592819a8e87..1cce233eab808b 100644
--- a/lib/dgram.js
+++ b/lib/dgram.js
@@ -39,13 +39,13 @@ function lookup6(address, callback) {
function newHandle(type) {
if (type == 'udp4') {
- var handle = new UDP;
+ var handle = new UDP();
handle.lookup = lookup4;
return handle;
}
if (type == 'udp6') {
- var handle = new UDP;
+ var handle = new UDP();
handle.lookup = lookup6;
handle.bind = handle.bind6;
handle.send = handle.send6;
@@ -301,8 +301,7 @@ Socket.prototype.send = function(buffer,
if (ex) {
if (callback) callback(ex);
self.emit('error', ex);
- }
- else if (self._handle) {
+ } else if (self._handle) {
var req = new SendWrap();
req.buffer = buffer; // Keep reference alive.
req.length = length;
@@ -338,7 +337,10 @@ function afterSend(err) {
if (err) {
err = exceptionWithHostPort(err, 'send', this.address, this.port);
}
- this.callback(err, this.length);
+ var self = this;
+ setImmediate(function() {
+ self.callback(err, self.length);
+ });
}
diff --git a/lib/dns.js b/lib/dns.js
index 9334800e4da5c4..28f1607b44ece2 100644
--- a/lib/dns.js
+++ b/lib/dns.js
@@ -239,7 +239,7 @@ function resolver(bindingName) {
if (err) throw errnoException(err, bindingName);
callback.immediately = true;
return req;
- }
+ };
}
diff --git a/lib/events.js b/lib/events.js
index 064f3838b38ac9..3ea798b3bdb01a 100644
--- a/lib/events.js
+++ b/lib/events.js
@@ -140,7 +140,10 @@ EventEmitter.prototype.emit = function emit(type) {
} else if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
- throw new Error('Uncaught, unspecified "error" event.');
+ // At least give some kind of context to the user
+ var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
+ err.context = er;
+ throw err;
}
return false;
}
@@ -307,8 +310,9 @@ EventEmitter.prototype.removeListener =
if (--this._eventsCount === 0) {
this._events = {};
return this;
- } else
+ } else {
delete events[type];
+ }
} else {
spliceOne(list, position);
}
diff --git a/lib/fs.js b/lib/fs.js
index b6b62265403ee8..4cdd0ef5e31456 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -40,7 +40,7 @@ function rethrow() {
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
// is fairly slow to generate.
if (DEBUG) {
- var backtrace = new Error;
+ var backtrace = new Error();
return function(err) {
if (err) {
backtrace.stack = err.name + ': ' + err.message +
diff --git a/lib/net.js b/lib/net.js
index 847e417e67f4ca..b261196119a9ed 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -201,6 +201,7 @@ function onSocketFinish() {
var req = new ShutdownWrap();
req.oncomplete = afterShutdown;
+ req.handle = this._handle;
var err = this._handle.shutdown(req);
if (err)
@@ -430,7 +431,7 @@ Socket.prototype._destroy = function(exception, cb) {
});
self._writableState.errorEmitted = true;
}
- };
+ }
if (this.destroyed) {
debug('already destroyed, fire error callbacks');
@@ -627,6 +628,7 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
}
var req = new WriteWrap();
+ req.handle = this._handle;
req.oncomplete = afterWrite;
req.async = false;
var err;
@@ -1319,7 +1321,7 @@ Server.prototype.listen = function() {
Server.prototype.address = function() {
if (this._handle && this._handle.getsockname) {
var out = {};
- var err = this._handle.getsockname(out);
+ this._handle.getsockname(out);
// TODO(bnoordhuis) Check err and throw?
return out;
} else if (this._pipeName) {
diff --git a/lib/querystring.js b/lib/querystring.js
index 09220a919e3edc..6aa188725ae25a 100644
--- a/lib/querystring.js
+++ b/lib/querystring.js
@@ -28,7 +28,7 @@ QueryString.unescapeBuffer = function(s, decodeSpaces) {
break;
case charCode('+'):
if (decodeSpaces) c = charCode(' ');
- // pass thru
+ // falls through
default:
out[outIndex++] = c;
break;
diff --git a/lib/readline.js b/lib/readline.js
index a6845010dae661..5b9637b6f5455a 100644
--- a/lib/readline.js
+++ b/lib/readline.js
@@ -883,15 +883,25 @@ exports.Interface = Interface;
* accepts a readable Stream instance and makes it emit "keypress" events
*/
+const KEYPRESS_DECODER = Symbol('keypress-decoder');
+const ESCAPE_DECODER = Symbol('escape-decoder');
+
function emitKeypressEvents(stream) {
- if (stream._keypressDecoder) return;
+ if (stream[KEYPRESS_DECODER]) return;
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
- stream._keypressDecoder = new StringDecoder('utf8');
+ stream[KEYPRESS_DECODER] = new StringDecoder('utf8');
+
+ stream[ESCAPE_DECODER] = emitKeys(stream);
+ stream[ESCAPE_DECODER].next();
function onData(b) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
- var r = stream._keypressDecoder.write(b);
- if (r) emitKeys(stream, r);
+ var r = stream[KEYPRESS_DECODER].write(b);
+ if (r) {
+ for (var i = 0; i < r.length; i++) {
+ stream[ESCAPE_DECODER].next(r[i]);
+ }
+ }
} else {
// Nobody's watching anyway
stream.removeListener('data', onData);
@@ -944,102 +954,130 @@ exports.emitKeypressEvents = emitKeypressEvents;
// Regexes used for ansi escape code splitting
const metaKeyCodeReAnywhere = /(?:\x1b)([a-zA-Z0-9])/;
-const metaKeyCodeRe = new RegExp('^' + metaKeyCodeReAnywhere.source + '$');
const functionKeyCodeReAnywhere = new RegExp('(?:\x1b+)(O|N|\\[|\\[\\[)(?:' + [
'(\\d+)(?:;(\\d+))?([~^$])',
'(?:M([@ #!a`])(.)(.))', // mouse
'(?:1;)?(\\d+)?([a-zA-Z])'
].join('|') + ')');
-const functionKeyCodeRe = new RegExp('^' + functionKeyCodeReAnywhere.source);
-const escapeCodeReAnywhere = new RegExp([
- functionKeyCodeReAnywhere.source, metaKeyCodeReAnywhere.source, /\x1b./.source
-].join('|'));
-
-function emitKeys(stream, s) {
- if (s instanceof Buffer) {
- if (s[0] > 127 && s[1] === undefined) {
- s[0] -= 128;
- s = '\x1b' + s.toString(stream.encoding || 'utf-8');
- } else {
- s = s.toString(stream.encoding || 'utf-8');
- }
- }
- var buffer = [];
- var match;
- while (match = escapeCodeReAnywhere.exec(s)) {
- buffer = buffer.concat(s.slice(0, match.index).split(''));
- buffer.push(match[0]);
- s = s.slice(match.index + match[0].length);
- }
- buffer = buffer.concat(s.split(''));
-
- buffer.forEach(function(s) {
- var ch,
- key = {
- sequence: s,
- name: undefined,
- ctrl: false,
- meta: false,
- shift: false
- },
- parts;
-
- if (s === '\r') {
- // carriage return
- key.name = 'return';
- } else if (s === '\n') {
- // enter, should have been called linefeed
- key.name = 'enter';
+function* emitKeys(stream) {
+ while (true) {
+ var ch = yield;
+ var s = ch;
+ var escaped = false;
+ var key = {
+ sequence: null,
+ name: undefined,
+ ctrl: false,
+ meta: false,
+ shift: false
+ };
+
+ if (ch === '\x1b') {
+ escaped = true;
+ s += (ch = yield);
+
+ if (ch === '\x1b') {
+ s += (ch = yield);
+ }
+ }
- } else if (s === '\t') {
- // tab
- key.name = 'tab';
+ if (escaped && (ch === 'O' || ch === '[')) {
+ // ansi escape sequence
+ var code = ch;
+ var modifier = 0;
- } else if (s === '\b' || s === '\x7f' ||
- s === '\x1b\x7f' || s === '\x1b\b') {
- // backspace or ctrl+h
- key.name = 'backspace';
- key.meta = (s.charAt(0) === '\x1b');
+ if (ch === 'O') {
+ // ESC O letter
+ // ESC O modifier letter
+ s += (ch = yield);
- } else if (s === '\x1b' || s === '\x1b\x1b') {
- // escape key
- key.name = 'escape';
- key.meta = (s.length === 2);
+ if (ch >= '0' && ch <= '9') {
+ modifier = (ch >> 0) - 1;
+ s += (ch = yield);
+ }
- } else if (s === ' ' || s === '\x1b ') {
- key.name = 'space';
- key.meta = (s.length === 2);
+ code += ch;
- } else if (s.length === 1 && s <= '\x1a') {
- // ctrl+letter
- key.name = String.fromCharCode(s.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
- key.ctrl = true;
+ } else if (ch === '[') {
+ // ESC [ letter
+ // ESC [ modifier letter
+ // ESC [ [ modifier letter
+ // ESC [ [ num char
+ s += (ch = yield);
- } else if (s.length === 1 && s >= 'a' && s <= 'z') {
- // lowercase letter
- key.name = s;
+ if (ch === '[') {
+ // \x1b[[A
+ // ^--- escape codes might have a second bracket
+ code += ch;
+ s += (ch = yield);
+ }
- } else if (s.length === 1 && s >= 'A' && s <= 'Z') {
- // shift+letter
- key.name = s.toLowerCase();
- key.shift = true;
+ /*
+ * Here and later we try to buffer just enough data to get
+ * a complete ascii sequence.
+ *
+ * We have basically two classes of ascii characters to process:
+ *
+ *
+ * 1. `\x1b[24;5~` should be parsed as { code: '[24~', modifier: 5 }
+ *
+ * This particular example is featuring Ctrl+F12 in xterm.
+ *
+ * - `;5` part is optional, e.g. it could be `\x1b[24~`
+ * - first part can contain one or two digits
+ *
+ * So the generic regexp is like /^\d\d?(;\d)?[~^$]$/
+ *
+ *
+ * 2. `\x1b[1;5H` should be parsed as { code: '[H', modifier: 5 }
+ *
+ * This particular example is featuring Ctrl+Home in xterm.
+ *
+ * - `1;5` part is optional, e.g. it could be `\x1b[H`
+ * - `1;` part is optional, e.g. it could be `\x1b[5H`
+ *
+ * So the generic regexp is like /^((\d;)?\d)?[A-Za-z]$/
+ *
+ */
+ const cmdStart = s.length - 1;
+
+ // skip one or two leading digits
+ if (ch >= '0' && ch <= '9') {
+ s += (ch = yield);
+
+ if (ch >= '0' && ch <= '9') {
+ s += (ch = yield);
+ }
+ }
- } else if (parts = metaKeyCodeRe.exec(s)) {
- // meta+character key
- key.name = parts[1].toLowerCase();
- key.meta = true;
- key.shift = /^[A-Z]$/.test(parts[1]);
+ // skip modifier
+ if (ch === ';') {
+ s += (ch = yield);
- } else if (parts = functionKeyCodeRe.exec(s)) {
- // ansi escape sequence
+ if (ch >= '0' && ch <= '9') {
+ s += (ch = yield);
+ }
+ }
- // reassemble the key code leaving out leading \x1b's,
- // the modifier key bitflag and any meaningless "1;" sequence
- var code = (parts[1] || '') + (parts[2] || '') +
- (parts[4] || '') + (parts[9] || ''),
- modifier = (parts[3] || parts[8] || 1) - 1;
+ /*
+ * We buffered enough data, now trying to extract code
+ * and modifier from it
+ */
+ const cmd = s.slice(cmdStart);
+ var match;
+
+ if ((match = cmd.match(/^(\d\d?)(;(\d))?([~^$])$/))) {
+ code += match[1] + match[4];
+ modifier = (match[3] || 1) - 1;
+ } else if ((match = cmd.match(/^((\d;)?(\d))?([A-Za-z])$/))) {
+ code += match[4];
+ modifier = (match[3] || 1) - 1;
+ } else {
+ code += cmd;
+ }
+ }
// Parse the key modifier
key.ctrl = !!(modifier & 4);
@@ -1142,23 +1180,58 @@ function emitKeys(stream, s) {
/* misc. */
case '[Z': key.name = 'tab'; key.shift = true; break;
default: key.name = 'undefined'; break;
-
}
- }
- // Don't emit a key if no name was found
- if (key.name === undefined) {
- key = undefined;
- }
+ } else if (ch === '\r') {
+ // carriage return
+ key.name = 'return';
+
+ } else if (ch === '\n') {
+ // enter, should have been called linefeed
+ key.name = 'enter';
+
+ } else if (ch === '\t') {
+ // tab
+ key.name = 'tab';
- if (s.length === 1) {
- ch = s;
+ } else if (ch === '\b' || ch === '\x7f') {
+ // backspace or ctrl+h
+ key.name = 'backspace';
+ key.meta = escaped;
+
+ } else if (ch === '\x1b') {
+ // escape key
+ key.name = 'escape';
+ key.meta = escaped;
+
+ } else if (ch === ' ') {
+ key.name = 'space';
+ key.meta = escaped;
+
+ } else if (!escaped && ch <= '\x1a') {
+ // ctrl+letter
+ key.name = String.fromCharCode(ch.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
+ key.ctrl = true;
+
+ } else if (/^[0-9A-Za-z]$/.test(ch)) {
+ // letter, number, shift+letter
+ key.name = ch.toLowerCase();
+ key.shift = /^[A-Z]$/.test(ch);
+ key.meta = escaped;
}
- if (key || ch) {
- stream.emit('keypress', ch, key);
+ key.sequence = s;
+
+ if (key.name !== undefined) {
+ /* Named character or sequence */
+ stream.emit('keypress', escaped ? undefined : s, key);
+ } else if (s.length === 1) {
+ /* Single unnamed character, e.g. "." */
+ stream.emit('keypress', s);
+ } else {
+ /* Unrecognized or broken escape sequence, don't emit anything */
}
- });
+ }
}
diff --git a/lib/repl.js b/lib/repl.js
index 036b561f9c2a94..ddf3fecdfd56ea 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -318,7 +318,7 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
// Display prompt again
self.displayPrompt();
- };
+ }
});
self.on('SIGCONT', function() {
diff --git a/lib/tls.js b/lib/tls.js
index 3ae7a8f58b11a1..10c82860ba826e 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -15,12 +15,17 @@ exports.CLIENT_RENEG_WINDOW = 600;
exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024;
exports.DEFAULT_CIPHERS = [
+ 'ECDHE-RSA-AES128-GCM-SHA256',
+ 'ECDHE-ECDSA-AES128-GCM-SHA256',
+ 'ECDHE-RSA-AES256-GCM-SHA384',
+ 'ECDHE-ECDSA-AES256-GCM-SHA384',
+ 'DHE-RSA-AES128-GCM-SHA256',
+ 'ECDHE-RSA-AES128-SHA256',
+ 'DHE-RSA-AES128-SHA256',
'ECDHE-RSA-AES256-SHA384',
'DHE-RSA-AES256-SHA384',
'ECDHE-RSA-AES256-SHA256',
'DHE-RSA-AES256-SHA256',
- 'ECDHE-RSA-AES128-SHA256',
- 'DHE-RSA-AES128-SHA256',
'HIGH',
'!aNULL',
'!eNULL',
diff --git a/lib/url.js b/lib/url.js
index 1683f905037c52..8da2f025dc8ca2 100644
--- a/lib/url.js
+++ b/lib/url.js
@@ -80,7 +80,7 @@ const querystring = require('querystring');
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url instanceof Url) return url;
- var u = new Url;
+ var u = new Url();
u.parse(url, parseQueryString, slashesDenoteHost);
return u;
}
diff --git a/lib/util.js b/lib/util.js
index a04c19c7353fdf..4dbc59376dcefe 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -12,6 +12,8 @@ exports.format = function(f) {
return objects.join(' ');
}
+ if (arguments.length === 1) return f;
+
var i = 1;
var args = arguments;
var len = args.length;
@@ -27,6 +29,7 @@ exports.format = function(f) {
} catch (_) {
return '[Circular]';
}
+ // falls through
default:
return x;
}
diff --git a/src/async-wrap-inl.h b/src/async-wrap-inl.h
index b08f791c2e7635..0518cd3b7ce002 100644
--- a/src/async-wrap-inl.h
+++ b/src/async-wrap-inl.h
@@ -17,43 +17,30 @@ inline AsyncWrap::AsyncWrap(Environment* env,
v8::Handle object,
ProviderType provider,
AsyncWrap* parent)
- : BaseObject(env, object), bits_(static_cast(provider) << 1) {
+ : BaseObject(env, object, provider),
+ bits_(static_cast(provider) << 1) {
// Check user controlled flag to see if the init callback should run.
if (!env->using_asyncwrap())
return;
- if (!env->call_async_init_hook() && parent == nullptr)
- return;
- // TODO(trevnorris): Until it's verified all passed object's are not weak,
- // add a HandleScope to make sure there's no leak.
- v8::HandleScope scope(env->isolate());
+ // If callback hooks have not been enabled, and there is no parent, return.
+ if (!env->async_wrap_callbacks_enabled() && parent == nullptr)
+ return;
- v8::Local parent_obj;
+ // If callback hooks have not been enabled and parent has no queue, return.
+ if (!env->async_wrap_callbacks_enabled() && !parent->has_async_queue())
+ return;
+ v8::HandleScope scope(env->isolate());
v8::TryCatch try_catch;
- // If a parent value was sent then call its pre/post functions to let it know
- // a conceptual "child" is being instantiated (e.g. that a server has
- // received a connection).
- if (parent != nullptr) {
- parent_obj = parent->object();
- env->async_hooks_pre_function()->Call(parent_obj, 0, nullptr);
- if (try_catch.HasCaught())
- FatalError("node::AsyncWrap::AsyncWrap", "parent pre hook threw");
- }
-
- env->async_hooks_init_function()->Call(object, 0, nullptr);
+ v8::Local n = v8::Int32::New(env->isolate(), provider);
+ env->async_hooks_init_function()->Call(object, 1, &n);
if (try_catch.HasCaught())
FatalError("node::AsyncWrap::AsyncWrap", "init hook threw");
bits_ |= 1; // has_async_queue() is true now.
-
- if (parent != nullptr) {
- env->async_hooks_post_function()->Call(parent_obj, 0, nullptr);
- if (try_catch.HasCaught())
- FatalError("node::AsyncWrap::AsyncWrap", "parent post hook threw");
- }
}
diff --git a/src/async-wrap.cc b/src/async-wrap.cc
index 5710c43146060b..2da6b102934fa7 100644
--- a/src/async-wrap.cc
+++ b/src/async-wrap.cc
@@ -23,32 +23,28 @@ using v8::kExternalUint32Array;
namespace node {
+static void EnableHooksJS(const FunctionCallbackInfo& args) {
+ Environment* env = Environment::GetCurrent(args);
+ env->async_hooks()->set_enable_callbacks(1);
+}
+
+
+static void DisableHooksJS(const FunctionCallbackInfo& args) {
+ Environment* env = Environment::GetCurrent(args);
+ env->async_hooks()->set_enable_callbacks(0);
+}
+
+
static void SetupHooks(const FunctionCallbackInfo& args) {
- Environment* env = Environment::GetCurrent(args.GetIsolate());
+ Environment* env = Environment::GetCurrent(args);
- CHECK(args[0]->IsObject());
+ CHECK(args[0]->IsFunction());
CHECK(args[1]->IsFunction());
CHECK(args[2]->IsFunction());
- CHECK(args[3]->IsFunction());
-
- // Attach Fields enum from Environment::AsyncHooks.
- // Flags attached to this object are:
- // - kCallInitHook (0): Tells the AsyncWrap constructor whether it should
- // make a call to the init JS callback. This is disabled by default, so
- // even after setting the callbacks the flag will have to be set to
- // non-zero to have those callbacks called. This only affects the init
- // callback. If the init callback was called, then the pre/post callbacks
- // will automatically be called.
- Local