From 46b0654347eec229f7dac5ec350bb45aab25e05f Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 10 Aug 2011 14:23:26 -0700 Subject: [PATCH] Upgrade libuv to db190c7 --- deps/uv/.gitignore | 11 ++ deps/uv/all.gyp | 324 ++++++++++++++++++++++++++++++++ deps/uv/build/all.gyp | 254 ------------------------- deps/uv/{build => }/common.gypi | 0 deps/uv/create-msvs-files.bat | 19 +- deps/uv/{build => }/gyp_uv | 3 +- deps/uv/include/uv.h | 4 + deps/uv/src/eio/config_sunos.h | 3 + deps/uv/src/eio/ecb.h | 2 +- deps/uv/src/eio/eio.c | 4 +- deps/uv/src/uv-sunos.c | 2 +- deps/uv/src/uv-unix.c | 60 +++--- deps/uv/src/win/process.c | 81 +++++++- deps/uv/test/test-list.h | 2 + deps/uv/test/test-spawn.c | 49 ++++- 15 files changed, 512 insertions(+), 306 deletions(-) create mode 100644 deps/uv/all.gyp delete mode 100644 deps/uv/build/all.gyp rename deps/uv/{build => }/common.gypi (100%) rename deps/uv/{build => }/gyp_uv (91%) mode change 100755 => 100644 diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore index 32a57295de..465f8a67c8 100644 --- a/deps/uv/.gitignore +++ b/deps/uv/.gitignore @@ -14,3 +14,14 @@ /test/run-tests.dSYM /test/run-benchmarks /test/run-benchmarks.dSYM + +*.sln +*.vcproj +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +_UpgradeReport_Files/ +UpgradeLog*.XML +build/Debug +build/Release +build/ipch diff --git a/deps/uv/all.gyp b/deps/uv/all.gyp new file mode 100644 index 0000000000..115e5428ef --- /dev/null +++ b/deps/uv/all.gyp @@ -0,0 +1,324 @@ +{ + 'target_defaults': { + 'default_configuration': 'Debug', + 'configurations': { + # TODO: hoist these out and put them somewhere common, because + # RuntimeLibrary MUST MATCH across the entire project + 'Debug': { + 'defines': [ 'DEBUG', '_DEBUG' ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 1, # static debug + }, + }, + }, + 'Release': { + 'defines': [ 'NDEBUG' ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 0, # static release + }, + }, + } + }, + 'msvs_settings': { + 'VCCLCompilerTool': { + }, + 'VCLibrarianTool': { + }, + 'VCLinkerTool': { + 'GenerateDebugInformation': 'true', + }, + }, + 'conditions': [ + ['OS == "win"', { + 'defines': [ + 'WIN32' + ], + }] + ], + }, + + 'targets': [ + { + 'target_name': 'uv', + 'type': 'static_library', + 'include_dirs': [ 'include' ], + 'direct_dependent_settings': { + 'include_dirs': [ 'include' ], + }, + + 'defines': [ + 'HAVE_CONFIG_H' + ], + 'sources': [ + 'include/ares.h', + 'include/ares_version.h', + 'include/uv.h', + 'src/uv-common.c', + 'src/uv-common.h', + 'src/ares/ares__close_sockets.c', + 'src/ares/ares__get_hostent.c', + 'src/ares/ares__read_line.c', + 'src/ares/ares__timeval.c', + 'src/ares/ares_cancel.c', + 'src/ares/ares_data.c', + 'src/ares/ares_data.h', + 'src/ares/ares_destroy.c', + 'src/ares/ares_dns.h', + 'src/ares/ares_expand_name.c', + 'src/ares/ares_expand_string.c', + 'src/ares/ares_fds.c', + 'src/ares/ares_free_hostent.c', + 'src/ares/ares_free_string.c', + 'src/ares/ares_gethostbyaddr.c', + 'src/ares/ares_gethostbyname.c', + 'src/ares/ares_getnameinfo.c', + 'src/ares/ares_getopt.c', + 'src/ares/ares_getopt.h', + 'src/ares/ares_getsock.c', + 'src/ares/ares_init.c', + 'src/ares/ares_ipv6.h', + 'src/ares/ares_library_init.c', + 'src/ares/ares_library_init.h', + 'src/ares/ares_llist.c', + 'src/ares/ares_llist.h', + 'src/ares/ares_mkquery.c', + 'src/ares/ares_nowarn.c', + 'src/ares/ares_nowarn.h', + 'src/ares/ares_options.c', + 'src/ares/ares_parse_a_reply.c', + 'src/ares/ares_parse_aaaa_reply.c', + 'src/ares/ares_parse_mx_reply.c', + 'src/ares/ares_parse_ns_reply.c', + 'src/ares/ares_parse_ptr_reply.c', + 'src/ares/ares_parse_srv_reply.c', + 'src/ares/ares_parse_txt_reply.c', + 'src/ares/ares_private.h', + 'src/ares/ares_process.c', + 'src/ares/ares_query.c', + 'src/ares/ares_rules.h', + 'src/ares/ares_search.c', + 'src/ares/ares_send.c', + 'src/ares/ares_setup.h', + 'src/ares/ares_strcasecmp.c', + 'src/ares/ares_strcasecmp.h', + 'src/ares/ares_strdup.c', + 'src/ares/ares_strdup.h', + 'src/ares/ares_strerror.c', + 'src/ares/ares_timeout.c', + 'src/ares/ares_version.c', + 'src/ares/ares_writev.c', + 'src/ares/ares_writev.h', + 'src/ares/bitncmp.c', + 'src/ares/bitncmp.h', + 'src/ares/inet_net_pton.c', + 'src/ares/inet_net_pton.h', + 'src/ares/inet_ntop.c', + 'src/ares/inet_ntop.h', + 'src/ares/nameser.h', + 'src/ares/setup_once.h', + ], + 'conditions': [ + [ 'OS=="win"', { + 'include_dirs': [ + 'src/ares/config_win32' + ], + 'sources': [ 'src/ares/windows_port.c' ], + 'defines': [ + '_WIN32_WINNT=0x0502', + 'EIO_STACKSIZE=262144', + '_GNU_SOURCE', + ], + 'sources': [ + 'include/tree.h', + 'include/uv-win.h', + 'src/ares/config_win32/ares_config.h', + 'src/win/async.c', + 'src/win/cares.c', + 'src/win/core.c', + 'src/win/error.c', + 'src/win/getaddrinfo.c', + 'src/win/handle.c', + 'src/win/internal.h', + 'src/win/loop-watcher.c', + 'src/win/pipe.c', + 'src/win/process.c', + 'src/win/req.c', + 'src/win/stdio.c', + 'src/win/stream.c', + 'src/win/tcp.c', + 'src/win/timer.c', + 'src/win/util.c', + ] + }, { # Not Windows i.e. POSIX + 'cflags': [ + '-g', + '--std=gnu89', + '-pedantic', + '-Wall', + '-Wextra', + '-Wno-unused-parameter' + ], + 'sources': [ + 'include/eio.h', + 'include/ev.h', + 'include/ngx-queue.h', + 'include/uv-unix.h', + 'src/uv-eio.c', + 'src/uv-eio.h', + 'src/uv-unix.c', + 'src/ares/config_cygwin/ares_config.h', + 'src/ares/config_darwin/ares_config.h', + 'src/ares/config_freebsd/ares_config.h', + 'src/ares/config_linux/ares_config.h', + 'src/ares/config_openbsd/ares_config.h', + 'src/ares/config_sunos/ares_config.h', + 'src/eio/config_cygwin.h', + 'src/eio/config_darwin.h', + 'src/eio/config_freebsd.h', + 'src/eio/config_linux.h', + 'src/eio/config_sunos.h', + 'src/eio/ecb.h', + 'src/eio/eio.c', + 'src/eio/xthread.h', + 'src/ev/config_cygwin.h', + 'src/ev/config_darwin.h', + 'src/ev/config_freebsd.h', + 'src/ev/config_linux.h', + 'src/ev/config_sunos.h', + 'src/ev/ev.c', + 'src/ev/ev_vars.h', + 'src/ev/ev_wrap.h', + 'src/ev/event.h', + ], + 'include_dirs': [ + 'src/ev' + ], + 'defines': [ + '_LARGEFILE_SOURCE', + '_FILE_OFFSET_BITS=64', + '_GNU_SOURCE', + 'EIO_STACKSIZE=262144' + ], + 'libraries': [ '-lm' ] + }], + [ 'OS=="mac"', { + 'include_dirs': [ 'src/ares/config_darwin' ], + 'sources': [ 'src/uv-darwin.c' ], + 'direct_dependent_settings': { + 'libraries': [ '-framework CoreServices' ], + }, + 'defines': [ + 'EV_CONFIG_H="config_darwin.h"', + 'EIO_CONFIG_H="config_darwin.h"', + ] + }], + [ 'OS=="linux"', { + 'include_dirs': [ 'src/ares/config_linux' ], + 'sources': [ 'src/uv-linux.c' ], + 'defines': [ + 'EV_CONFIG_H="config_linux.h"', + 'EIO_CONFIG_H="config_linux.h"', + ], + 'direct_dependent_settings': { + 'libraries': [ '-lrt' ], + }, + }], + # TODO add OS=='sun' + ] + }, + + { + 'target_name': 'run-tests', + 'type': 'executable', + 'dependencies': [ 'uv' ], + 'sources': [ + 'test/echo-server.c', + 'test/run-tests.c', + 'test/runner.c', + 'test/runner.h', + 'test/task.h', + 'test/test-async.c', + 'test/test-callback-stack.c', + 'test/test-connection-fail.c', + 'test/test-delayed-accept.c', + 'test/test-fail-always.c', + 'test/test-get-currentexe.c', + 'test/test-getaddrinfo.c', + 'test/test-gethostbyname.c', + 'test/test-getsockname.c', + 'test/test-hrtime.c', + 'test/test-idle.c', + 'test/test-list.h', + 'test/test-loop-handles.c', + 'test/test-pass-always.c', + 'test/test-ping-pong.c', + 'test/test-pipe-bind-error.c', + 'test/test-ref.c', + 'test/test-shutdown-eof.c', + 'test/test-spawn.c', + 'test/test-tcp-bind-error.c', + 'test/test-tcp-bind6-error.c', + 'test/test-tcp-writealot.c', + 'test/test-timer-again.c', + 'test/test-timer.c', + ], + 'conditions': [ + [ 'OS=="win"', { + 'sources': [ + 'test/runner-win.c', + 'test/runner-win.h' + ], + 'libraries': [ 'ws2_32.lib' ] + }, { # POSIX + 'defines': [ '_GNU_SOURCE' ], + 'ldflags': [ '-pthread' ], + 'sources': [ + 'test/runner-unix.c', + 'test/runner-unix.h', + ] + }] + ] + }, + + { + 'target_name': 'run-benchmarks', + 'type': 'executable', + 'dependencies': [ 'uv' ], + 'sources': [ + 'test/benchmark-ares.c', + 'test/benchmark-getaddrinfo.c', + 'test/benchmark-list.h', + 'test/benchmark-ping-pongs.c', + 'test/benchmark-pound.c', + 'test/benchmark-pump.c', + 'test/benchmark-sizes.c', + 'test/benchmark-spawn.c', + 'test/dns-server.c', + 'test/echo-server.c', + 'test/run-benchmarks.c', + 'test/runner.c', + 'test/runner.h', + 'test/task.h', + ], + 'conditions': [ + [ 'OS=="win"', { + 'sources': [ + 'test/runner-win.c', + 'test/runner-win.h', + ], + 'libraries': [ 'ws2_32.lib' ] + }, { # POSIX + 'defines': [ '_GNU_SOURCE' ], + 'ldflags': [ '-pthread' ], + 'sources': [ + 'test/runner-unix.c', + 'test/runner-unix.h', + ] + }] + ] + } + ] +} + diff --git a/deps/uv/build/all.gyp b/deps/uv/build/all.gyp deleted file mode 100644 index 5e1580c9f4..0000000000 --- a/deps/uv/build/all.gyp +++ /dev/null @@ -1,254 +0,0 @@ -{ - 'target_defaults': { - 'default_configuration': 'Debug', - 'configurations': { - # TODO: hoist these out and put them somewhere common, because - # RuntimeLibrary MUST MATCH across the entire project - 'Debug': { - 'defines': [ 'DEBUG', '_DEBUG' ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'RuntimeLibrary': 1, # static debug - }, - }, - }, - 'Release': { - 'defines': [ 'NDEBUG' ], - 'msvs_settings': { - 'VCCLCompilerTool': { - 'RuntimeLibrary': 0, # static release - }, - }, - } - }, - 'msvs_settings': { - 'VCCLCompilerTool': { - }, - 'VCLibrarianTool': { - }, - 'VCLinkerTool': { - 'GenerateDebugInformation': 'true', - }, - }, - 'conditions': [ - ['OS == "win"', { - 'defines': [ - 'WIN32' - ], - }] - ], - }, - - 'targets': [ - { - 'target_name': 'uv', - 'type': 'static_library', - 'include_dirs': [ '../include' ], - 'direct_dependent_settings': { - 'include_dirs': [ '../include' ], - }, - - 'defines': [ - 'HAVE_CONFIG_H' - ], - 'sources': [ - '../src/uv-common.c', - '../src/ares/ares__close_sockets.c', - '../src/ares/ares__get_hostent.c', - '../src/ares/ares__read_line.c', - '../src/ares/ares__timeval.c', - '../src/ares/ares_cancel.c', - '../src/ares/ares_data.c', - '../src/ares/ares_destroy.c', - '../src/ares/ares_expand_name.c', - '../src/ares/ares_expand_string.c', - '../src/ares/ares_fds.c', - '../src/ares/ares_free_hostent.c', - '../src/ares/ares_free_string.c', - '../src/ares/ares_gethostbyaddr.c', - '../src/ares/ares_gethostbyname.c', - '../src/ares/ares_getnameinfo.c', - '../src/ares/ares_getopt.c', - '../src/ares/ares_getsock.c', - '../src/ares/ares_init.c', - '../src/ares/ares_library_init.c', - '../src/ares/ares_llist.c', - '../src/ares/ares_mkquery.c', - '../src/ares/ares_nowarn.c', - '../src/ares/ares_options.c', - '../src/ares/ares_parse_a_reply.c', - '../src/ares/ares_parse_aaaa_reply.c', - '../src/ares/ares_parse_mx_reply.c', - '../src/ares/ares_parse_ns_reply.c', - '../src/ares/ares_parse_ptr_reply.c', - '../src/ares/ares_parse_srv_reply.c', - '../src/ares/ares_parse_txt_reply.c', - '../src/ares/ares_process.c', - '../src/ares/ares_query.c', - '../src/ares/ares_search.c', - '../src/ares/ares_send.c', - '../src/ares/ares_strcasecmp.c', - '../src/ares/ares_strdup.c', - '../src/ares/ares_strerror.c', - '../src/ares/ares_timeout.c', - '../src/ares/ares_version.c', - '../src/ares/ares_writev.c', - '../src/ares/bitncmp.c', - '../src/ares/inet_net_pton.c', - '../src/ares/inet_ntop.c', - ], - 'conditions': [ - [ 'OS=="win"', { - 'include_dirs': [ - '../src/ares/config_win32' - ], - 'sources': [ '../src/ares/windows_port.c' ], - 'defines': [ - '_WIN32_WINNT=0x0502', - 'EIO_STACKSIZE=262144', - '_GNU_SOURCE', - ], - 'sources': [ - '../src/win/async.c', - '../src/win/cares.c', - '../src/win/core.c', - '../src/win/error.c', - '../src/win/getaddrinfo.c', - '../src/win/handle.c', - '../src/win/loop-watcher.c', - '../src/win/pipe.c', - '../src/win/process.c', - '../src/win/req.c', - '../src/win/stdio.c', - '../src/win/stream.c', - '../src/win/tcp.c', - '../src/win/timer.c', - '../src/win/util.c', - ] - }, { # Not Windows i.e. POSIX - 'cflags': [ - '-g', - '--std=gnu89', - '-pedantic', - '-Wall', - '-Wextra', - '-Wno-unused-parameter' - ], - 'sources': [ - '../src/uv-eio.c', - '../src/eio/eio.c', - '../src/uv-unix.c', - '../src/ev/ev.c', - ], - 'include_dirs': [ - '../src/ev' - ], - 'defines': [ - '_LARGEFILE_SOURCE', - '_FILE_OFFSET_BITS=64', - '_GNU_SOURCE', - 'EIO_STACKSIZE=262144' - ], - 'libraries': [ '-lm' ] - }], - [ 'OS=="mac"', { - 'include_dirs': [ '../src/ares/config_darwin' ], - 'sources': [ '../src/uv-darwin.c' ], - 'direct_dependent_settings': { - 'libraries': [ '-framework CoreServices' ], - }, - 'defines': [ - 'EV_CONFIG_H="config_darwin.h"', - 'EIO_CONFIG_H="config_darwin.h"', - ] - }], - [ 'OS=="linux"', { - 'include_dirs': [ '../src/ares/config_linux' ], - 'sources': [ '../src/uv-linux.c' ], - 'defines': [ - 'EV_CONFIG_H="config_linux.h"', - 'EIO_CONFIG_H="config_linux.h"', - ], - 'direct_dependent_settings': { - 'libraries': [ '-lrt' ], - }, - }], - # TODO add OS=='sun' - ] - }, - - { - 'target_name': 'run-tests', - 'type': 'executable', - 'dependencies': [ 'uv' ], - 'sources': [ - '../test/runner.c', - '../test/run-tests.c', - '../test/test-async.c', - '../test/echo-server.c', - '../test/test-callback-stack.c', - '../test/test-connection-fail.c', - '../test/test-delayed-accept.c', - '../test/test-fail-always.c', - '../test/test-get-currentexe.c', - '../test/test-getaddrinfo.c', - '../test/test-gethostbyname.c', - '../test/test-getsockname.c', - '../test/test-hrtime.c', - '../test/test-idle.c', - '../test/test-loop-handles.c', - '../test/test-pass-always.c', - '../test/test-ping-pong.c', - '../test/test-pipe-bind-error.c', - '../test/test-ref.c', - '../test/test-shutdown-eof.c', - '../test/test-spawn.c', - '../test/test-tcp-bind-error.c', - '../test/test-tcp-bind6-error.c', - '../test/test-tcp-writealot.c', - '../test/test-timer-again.c', - '../test/test-timer.c', - ], - 'conditions': [ - [ 'OS=="win"', { - 'sources': [ '../test/runner-win.c' ], - 'libraries': [ 'ws2_32.lib' ] - }, { # POSIX - 'defines': [ '_GNU_SOURCE' ], - 'ldflags': [ '-pthread' ], - 'sources': [ '../test/runner-unix.c' ] - }] - ] - }, - - { - 'target_name': 'run-benchmarks', - 'type': 'executable', - 'dependencies': [ 'uv' ], - 'sources': [ - '../test/runner.c', - '../test/run-benchmarks.c', - '../test/echo-server.c', - '../test/dns-server.c', - '../test/benchmark-ares.c', - '../test/benchmark-getaddrinfo.c', - '../test/benchmark-ping-pongs.c', - '../test/benchmark-pound.c', - '../test/benchmark-pump.c', - '../test/benchmark-sizes.c', - '../test/benchmark-spawn.c' - ], - 'conditions': [ - [ 'OS=="win"', { - 'sources': [ '../test/runner-win.c' ], - 'libraries': [ 'ws2_32.lib' ] - }, { # POSIX - 'defines': [ '_GNU_SOURCE' ], - 'ldflags': [ '-pthread' ], - 'sources': [ '../test/runner-unix.c' ] - }] - ] - } - ] -} - diff --git a/deps/uv/build/common.gypi b/deps/uv/common.gypi similarity index 100% rename from deps/uv/build/common.gypi rename to deps/uv/common.gypi diff --git a/deps/uv/create-msvs-files.bat b/deps/uv/create-msvs-files.bat index 954ca8e08e..a83358bc4c 100644 --- a/deps/uv/create-msvs-files.bat +++ b/deps/uv/create-msvs-files.bat @@ -1,14 +1,21 @@ -@REM Hello World +@echo off cd %~dp0 -IF EXIST %~dp0build\gyp GOTO WINDIR - +if exist build\gyp goto have_gyp +echo svn co http://gyp.googlecode.com/svn/trunk@983 build/gyp svn co http://gyp.googlecode.com/svn/trunk@983 build/gyp +if errorlevel 1 goto gyp_install_failed +goto have_gyp -:WINDIR - -@python build\gyp_uv +:gyp_install_failed +echo Failed to download gyp. Make sure you have subversion installed, or +echo manually install gyp into %~dp0build\gyp. +goto exit +:have_gyp +python gyp_uv +if not errorlevel 1 echo Done. +:exit diff --git a/deps/uv/build/gyp_uv b/deps/uv/gyp_uv old mode 100755 new mode 100644 similarity index 91% rename from deps/uv/build/gyp_uv rename to deps/uv/gyp_uv index bb59dc157e..978fb906fa --- a/deps/uv/build/gyp_uv +++ b/deps/uv/gyp_uv @@ -5,8 +5,7 @@ import shlex import sys script_dir = os.path.dirname(__file__) -uv_root = os.path.normpath(os.path.join(script_dir, os.pardir)) -print("uv_root " + uv_root) +uv_root = os.path.abspath(script_dir) sys.path.insert(0, os.path.join(uv_root, 'build', 'gyp', 'pylib')) import gyp diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 2ee7c315f2..2e39d08ac9 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -228,6 +228,10 @@ int uv_is_active(uv_handle_t* handle); /* * Request handle to be closed. close_cb will be called asynchronously after * this call. This MUST be called on each handle before memory is released. + * + * Note that handles that wrap file descriptors are closed immediately but + * close_cb will still be deferred to the next iteration of the event loop. + * It gives you a chance to free up any resources associated with the handle. */ void uv_close(uv_handle_t* handle, uv_close_cb close_cb); diff --git a/deps/uv/src/eio/config_sunos.h b/deps/uv/src/eio/config_sunos.h index 8f878efd95..01d049c3e6 100644 --- a/deps/uv/src/eio/config_sunos.h +++ b/deps/uv/src/eio/config_sunos.h @@ -7,6 +7,9 @@ /* fdatasync(2) is available */ #define HAVE_FDATASYNC 1 +/* utimes(2) is available */ +#define HAVE_UTIMES 1 + /* futimes(2) is available */ /* #undef HAVE_FUTIMES */ diff --git a/deps/uv/src/eio/ecb.h b/deps/uv/src/eio/ecb.h index 8383374ae4..a4aabc1091 100644 --- a/deps/uv/src/eio/ecb.h +++ b/deps/uv/src/eio/ecb.h @@ -67,7 +67,7 @@ #ifndef ECB_MEMORY_FENCE #if ECB_GCC_VERSION(2,5) - #if __x86 + #if defined(__x86) || defined(__i386) #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE /* non-lock xchg might be enough */ #define ECB_MEMORY_FENCE_RELEASE do { } while (0) /* unlikely to change in future cpus */ diff --git a/deps/uv/src/eio/eio.c b/deps/uv/src/eio/eio.c index dc69474329..280feec09e 100644 --- a/deps/uv/src/eio/eio.c +++ b/deps/uv/src/eio/eio.c @@ -192,7 +192,9 @@ static void eio_destroy (eio_req *req); } /* POSIX API only */ - #define CreateHardLink(neu,old,flags) 0 + #ifndef CreateHardLink + # define CreateHardLink(neu,old,flags) 0 + #endif #define CreateSymbolicLink(neu,old,flags) 0 struct statvfs diff --git a/deps/uv/src/uv-sunos.c b/deps/uv/src/uv-sunos.c index 4a75461413..9ee6a31034 100644 --- a/deps/uv/src/uv-sunos.c +++ b/deps/uv/src/uv-sunos.c @@ -37,7 +37,7 @@ uint64_t uv_hrtime() { * we don't want to potentially create a race condition in the use of snprintf. */ int uv_exepath(char* buffer, size_t* size) { - size_t res; + ssize_t res; pid_t pid; char buf[128]; diff --git a/deps/uv/src/uv-unix.c b/deps/uv/src/uv-unix.c index a57a30b978..48357016bf 100644 --- a/deps/uv/src/uv-unix.c +++ b/deps/uv/src/uv-unix.c @@ -199,19 +199,31 @@ static uv_err_t uv_err_new(uv_handle_t* handle, int sys_error) { void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { - uv_tcp_t* tcp; - uv_pipe_t* pipe; uv_async_t* async; uv_timer_t* timer; + uv_stream_t* stream; uv_process_t* process; handle->close_cb = close_cb; switch (handle->type) { + case UV_NAMED_PIPE: + uv_pipe_cleanup((uv_pipe_t*)handle); + /* Fall through. */ + case UV_TCP: - tcp = (uv_tcp_t*) handle; - uv_read_stop((uv_stream_t*)tcp); - ev_io_stop(EV_DEFAULT_ &tcp->write_watcher); + stream = (uv_stream_t*)handle; + + uv_read_stop(stream); + ev_io_stop(EV_DEFAULT_ &stream->write_watcher); + + uv__close(stream->fd); + stream->fd = -1; + + if (stream->accepted_fd >= 0) { + uv__close(stream->accepted_fd); + stream->accepted_fd = -1; + } break; case UV_PREPARE: @@ -240,13 +252,6 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { ev_timer_stop(EV_DEFAULT_ &timer->timer_watcher); break; - case UV_NAMED_PIPE: - pipe = (uv_pipe_t*)handle; - uv_pipe_cleanup(pipe); - uv_read_stop((uv_stream_t*)handle); - ev_io_stop(EV_DEFAULT_ &pipe->write_watcher); - break; - case UV_PROCESS: process = (uv_process_t*)handle; ev_child_stop(EV_DEFAULT_UC_ &process->child_watcher); @@ -574,23 +579,9 @@ void uv__finish_close(uv_handle_t* handle) { case UV_NAMED_PIPE: case UV_TCP: - { - uv_stream_t* stream; - - stream = (uv_stream_t*)handle; - - assert(!ev_is_active(&stream->read_watcher)); - assert(!ev_is_active(&stream->write_watcher)); - - uv__close(stream->fd); - stream->fd = -1; - - if (stream->accepted_fd >= 0) { - uv__close(stream->accepted_fd); - stream->accepted_fd = -1; - } + assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher)); + assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher)); break; - } case UV_PROCESS: assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher)); @@ -874,10 +865,10 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { "uv_shutdown (unix) only supports uv_handle_t right now"); assert(stream->fd >= 0); - if (!(((uv_handle_t*)stream)->flags & UV_WRITABLE) || - ((uv_handle_t*)stream)->flags & UV_SHUT || - ((uv_handle_t*)stream)->flags & UV_CLOSED || - ((uv_handle_t*)stream)->flags & UV_CLOSING) { + if (!(stream->flags & UV_WRITABLE) || + stream->flags & UV_SHUT || + stream->flags & UV_CLOSED || + stream->flags & UV_CLOSING) { uv_err_new((uv_handle_t*)stream, EINVAL); return -1; } @@ -1990,9 +1981,8 @@ int uv_pipe_connect(uv_connect_t* req, goto out; } - handle->fd = sockfd; - ev_io_init(&handle->read_watcher, uv__stream_io, sockfd, EV_READ); - ev_io_init(&handle->write_watcher, uv__stream_io, sockfd, EV_WRITE); + uv__stream_open((uv_stream_t*)handle, sockfd, UV_READABLE | UV_WRITABLE); + ev_io_start(EV_DEFAULT_ &handle->read_watcher); ev_io_start(EV_DEFAULT_ &handle->write_watcher); diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 7b4b562e85..eac889aedc 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -28,6 +28,16 @@ #include #include +typedef struct env_var { + const char* narrow; + const wchar_t* wide; + int len; /* including null or '=' */ + int supplied; + int value_len; +} env_var_t; + +#define E_V(str) { ##str"=", L##str, sizeof(##str), 0, 0 } + #define UTF8_TO_UTF16(s, t) \ size = uv_utf8_to_utf16(s, NULL, 0) * sizeof(wchar_t); \ t = (wchar_t*)malloc(size); \ @@ -361,6 +371,7 @@ static wchar_t* search_path(const wchar_t *file, return result; } + /* * Quotes command line arguments * Returns a pointer to the end (next char to be written) of the buffer @@ -437,6 +448,7 @@ wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) { return target; } + wchar_t* make_program_args(char** args, int verbatim_arguments) { wchar_t* dst; wchar_t* ptr; @@ -494,23 +506,69 @@ error: return NULL; } + +/* + * If we learn that people are passing in huge environment blocks + * then we should probably qsort() the array and then bsearch() + * to see if it contains this variable. But there are ownership + * issues associated with that solution; this is the caller's + * char**, and modifying it is rude. + */ +static void check_required_vars_contains_var(env_var_t* required, int size, const char* var) { + int i; + for (i = 0; i < size; ++i) { + if (_strnicmp(required[i].narrow, var, required[i].len) == 0) { + required[i].supplied = 1; + return; + } + } +} + + /* - * The way windows takes environment variables is different than what C does; - * Windows wants a contiguous block of null-terminated strings, terminated - * with an additional null. - */ + * The way windows takes environment variables is different than what C does; + * Windows wants a contiguous block of null-terminated strings, terminated + * with an additional null. + * + * Windows has a few "essential" environment variables. winsock will fail + * to initialize if SYSTEMROOT is not defined; some APIs make reference to + * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that + * these get defined if the input environment block does not contain any + * values for them. + */ wchar_t* make_program_env(char** env_block) { wchar_t* dst; wchar_t* ptr; char** env; int env_len = 1 * sizeof(wchar_t); /* room for closing null */ int len; + int i; + DWORD var_size; + + env_var_t required_vars[] = { + E_V("SYSTEMROOT"), + E_V("SYSTEMDRIVE"), + E_V("TEMP"), + }; for (env = env_block; *env; env++) { + check_required_vars_contains_var(required_vars, COUNTOF(required_vars), *env); env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(wchar_t)); } - dst = (wchar_t*)malloc(env_len); + for (i = 0; i < COUNTOF(required_vars); ++i) { + if (!required_vars[i].supplied) { + env_len += required_vars[i].len * sizeof(wchar_t); + var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); + if (var_size == 0) { + uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); + } + required_vars[i].value_len = (int)var_size; + env_len += (int)var_size * sizeof(wchar_t); + } + } + + dst = malloc(env_len); if (!dst) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } @@ -525,6 +583,19 @@ wchar_t* make_program_env(char** env_block) { } } + for (i = 0; i < COUNTOF(required_vars); ++i) { + if (!required_vars[i].supplied) { + wcscpy(ptr, required_vars[i].wide); + ptr += required_vars[i].len - 1; + *ptr++ = L'='; + var_size = GetEnvironmentVariableW(required_vars[i].wide, ptr, required_vars[i].value_len); + if (var_size == 0) { + uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); + } + ptr += required_vars[i].value_len; + } + } + *ptr = L'\0'; return dst; } diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 08ed92a2bd..9d1f2e9be0 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -70,6 +70,7 @@ TEST_DECLARE (spawn_and_kill) #ifdef _WIN32 TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows) TEST_DECLARE (argument_escaping) +TEST_DECLARE (environment_creation) #endif HELPER_DECLARE (tcp4_echo_server) HELPER_DECLARE (tcp6_echo_server) @@ -155,6 +156,7 @@ TASK_LIST_START #ifdef _WIN32 TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows) TEST_ENTRY (argument_escaping) + TEST_ENTRY (environment_creation) #endif #if 0 diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 18a9bb7d97..c0396e18cd 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -340,6 +340,53 @@ TEST_IMPL(argument_escaping) { ASSERT(wcscmp(verbatim_output, L"cmd.exe /c c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"") == 0); ASSERT(wcscmp(non_verbatim_output, L"cmd.exe /c \"c:\\path\\to\\node.exe --eval \\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\"") == 0); + free(verbatim_output); + free(non_verbatim_output); + return 0; } -#endif \ No newline at end of file + +wchar_t* make_program_env(char** env_block); + +TEST_IMPL(environment_creation) { + int i; + char* environment[] = { + "FOO=BAR", + "SYSTEM=ROOT", /* substring of a supplied var name */ + "SYSTEMROOTED=OMG", /* supplied var name is a substring */ + "TEMP=C:\\Temp", + "BAZ=QUX", + NULL + }; + + wchar_t expected[512]; + wchar_t* ptr = expected; + wchar_t* result; + wchar_t* str; + + for (i = 0; i < sizeof(environment) / sizeof(environment[0]) - 1; i++) { + ptr += uv_utf8_to_utf16(environment[i], ptr, expected + sizeof(expected) - ptr); + } + + memcpy(ptr, L"SYSTEMROOT=", sizeof(L"SYSTEMROOT=")); + ptr += sizeof(L"SYSTEMROOT=")/sizeof(wchar_t) - 1; + ptr += GetEnvironmentVariableW(L"SYSTEMROOT", ptr, expected + sizeof(expected) - ptr); + ++ptr; + + memcpy(ptr, L"SYSTEMDRIVE=", sizeof(L"SYSTEMDRIVE=")); + ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(wchar_t) - 1; + ptr += GetEnvironmentVariableW(L"SYSTEMDRIVE", ptr, expected + sizeof(expected) - ptr); + ++ptr; + *ptr = '\0'; + + result = make_program_env(environment); + + for (str = result; *str; str += wcslen(str) + 1) { + wprintf(L"%s\n", str); + } + + ASSERT(wcscmp(expected, result) == 0); + + return 0; +} +#endif