deps: update libuv to 1.2.0
authorBen Noordhuis <info@bnoordhuis.nl>
Mon, 5 Jan 2015 19:44:25 +0000 (20:44 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Mon, 5 Jan 2015 21:25:20 +0000 (22:25 +0100)
PR-URL: https://github.com/iojs/io.js/pull/237
Reviewed-By: Bert Belder <bertbelder@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
64 files changed:
deps/uv/.gitignore
deps/uv/.mailmap
deps/uv/AUTHORS
deps/uv/ChangeLog
deps/uv/Makefile.am
deps/uv/autogen.sh
deps/uv/common.gypi
deps/uv/configure.ac
deps/uv/docs/make.bat
deps/uv/docs/src/loop.rst
deps/uv/docs/src/misc.rst
deps/uv/docs/src/tty.rst
deps/uv/gyp_uv.py
deps/uv/include/uv-version.h
deps/uv/include/uv-win.h
deps/uv/include/uv.h
deps/uv/m4/dtrace.m4 [deleted file]
deps/uv/src/unix/aix.c
deps/uv/src/unix/core.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/freebsd.c
deps/uv/src/unix/fs.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/linux-core.c
deps/uv/src/unix/linux-syscalls.c
deps/uv/src/unix/linux-syscalls.h
deps/uv/src/unix/netbsd.c
deps/uv/src/unix/openbsd.c
deps/uv/src/unix/pipe.c
deps/uv/src/unix/sunos.c
deps/uv/src/unix/tty.c
deps/uv/src/unix/udp.c
deps/uv/src/uv-common.h
deps/uv/src/win/core.c
deps/uv/src/win/dl.c
deps/uv/src/win/fs.c
deps/uv/src/win/internal.h
deps/uv/src/win/poll.c
deps/uv/src/win/req-inl.h
deps/uv/src/win/thread.c
deps/uv/src/win/tty.c
deps/uv/src/win/winapi.c
deps/uv/src/win/winapi.h
deps/uv/src/win/winsock.c
deps/uv/test/runner-unix.c
deps/uv/test/task.h
deps/uv/test/test-cwd-and-chdir.c
deps/uv/test/test-dlerror.c
deps/uv/test/test-fs.c
deps/uv/test/test-get-currentexe.c
deps/uv/test/test-list.h
deps/uv/test/test-loop-configure.c [new file with mode: 0644]
deps/uv/test/test-osx-select.c
deps/uv/test/test-ping-pong.c
deps/uv/test/test-pipe-close-stdout-read-stdin.c
deps/uv/test/test-platform-output.c
deps/uv/test/test-poll-close-doesnt-corrupt-stack.c [new file with mode: 0644]
deps/uv/test/test-spawn.c
deps/uv/test/test-tcp-bind6-error.c
deps/uv/test/test-udp-ipv6.c
deps/uv/test/test-udp-multicast-interface6.c
deps/uv/test/test-udp-multicast-join6.c
deps/uv/test/test-udp-options.c
deps/uv/uv.gyp

index 14a174adf63de7930a839af4369c2f8338609957..e7f8f3f59fa7ee52e269b1e7e64fb398fe3748b8 100644 (file)
@@ -34,9 +34,6 @@ vgcore.*
 Makefile
 Makefile.in
 
-# Generated by dtrace(1) when doing an in-tree build.
-/include/uv-dtrace.h
-
 # Generated by gyp for android
 *.target.mk
 
@@ -52,7 +49,10 @@ Makefile.in
 /test/run-benchmarks.dSYM
 
 *.sln
+*.sln.cache
+*.ncb
 *.vcproj
+*.vcproj*.user
 *.vcxproj
 *.vcxproj.filters
 *.vcxproj.user
index 34f5e4daf3500732fdb6ca567e9cdff4c7c68521..3a350a4b9ac0b4dc6bec26024334f888bf5d5379 100644 (file)
@@ -17,12 +17,8 @@ Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
 Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
 Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
 Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
-Rasmus Christian Pedersen <ruysch@outlook.com>
-Rasmus Christian Pedersen <ruysch@outlook.com>
-Rasmus Christian Pedersen <ruysch@outlook.com>
-Rasmus Christian Pedersen <ruysch@outlook.com>
+Rasmus Christian Pedersen <zerhacken@yahoo.com>
 Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
-Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
 Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
 Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
 Ryan Emery <seebees@gmail.com>
index d4c18cf532f8ecca47dbde80c778806d744847e4..7e455f6736ab98d8a234c9fcaec12a78e61652a2 100644 (file)
@@ -173,3 +173,7 @@ Michael Ira Krufky <m.krufky@samsung.com>
 Helge Deller <deller@gmx.de>
 Joey Geralnik <jgeralnik@gmail.com>
 Tim Caswell <tim@creationix.com>
+Logan Rosen <loganrosen@gmail.com>
+Kenneth Perry <thothonegan@gmail.com>
+John Marino <marino@FreeBSD.org>
+Alexey Melnichuk <mimir@newmail.ru>
index e2169998429ec51b4bede57dfb860a6d51ed52e4..0f3fce81ebe18428beba1f196661da4365bd9eac 100644 (file)
@@ -1,3 +1,152 @@
+2015.01.06, Version 1.2.0 (Stable)
+
+Changes since version 1.1.0:
+
+* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis)
+
+* tty: implement binary I/O terminal mode (Yuri D'Elia)
+
+* test: fix spawn test with autotools build (Ben Noordhuis)
+
+* test: skip ipv6 tests when ipv6 is not supported (Ben Noordhuis)
+
+* common: move STATIC_ASSERT to uv-common.h (Alexey Melnichuk)
+
+* win/thread: store thread handle in a TLS slot (Alexey Melnichuk)
+
+* unix: fix ttl, multicast ttl and loop options on IPv6 (Saúl Ibarra Corretgé)
+
+* linux: fix support for preadv/pwritev-less kernels (Ben Noordhuis)
+
+* unix: make uv_exepath(size=0) return UV_EINVAL (Ben Noordhuis)
+
+* darwin: fix uv_exepath(smallbuf) UV_EPERM error (Ben Noordhuis)
+
+* openbsd: fix uv_exepath(smallbuf) UV_EINVAL error (Ben Noordhuis)
+
+* linux: fix uv_exepath(size=1) UV_EINVAL error (Ben Noordhuis)
+
+* sunos: preemptively fix uv_exepath(size=1) (Ben Noordhuis)
+
+* win: fix and clarify comments in winapi.h (Bert Belder)
+
+* win: make available NtQueryDirectoryFile (Bert Belder)
+
+* win: add definitions for directory information types (Bert Belder)
+
+* win: use NtQueryDirectoryFile to implement uv_fs_scandir (Bert Belder)
+
+* unix: don't unlink unix socket on bind error (Ben Noordhuis)
+
+* build: fix bad comment in autogen.sh (Ben Noordhuis)
+
+* build: add AC_PROG_LIBTOOL to configure.ac (Ben Noordhuis)
+
+* test: skip udp_options6 if there no IPv6 support (Saúl Ibarra Corretgé)
+
+* win: add definitions for MUI errors mingw lacks (Bert Belder)
+
+* build: enable warnings in autotools build (Ben Noordhuis)
+
+* build: remove -Wno-dollar-in-identifier-extension (Ben Noordhuis)
+
+* build: move flags from Makefile.am to configure.ac (Ben Noordhuis)
+
+
+2015.01.06, Version 0.10.32 (Stable), 378de30c59aef5fdb6d130fa5cfcb0a68fce571c
+
+Changes since version 0.10.31:
+
+* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis)
+
+
+2014.12.25, Version 1.1.0 (Stable), 9572f3e74a167f59a8017e57ca3ebe91ffd88e18
+
+Changes since version 1.0.2:
+
+* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder)
+
+* win: fix compilation of tests (Marc Schlaich)
+
+* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder)
+
+* win: avoid stack corruption when closing a poll handle (Bert Belder)
+
+* test: fix test-fs-file-loop on Windows (Bert Belder)
+
+* test: fix test-cwd-and-chdir (Bert Belder)
+
+* doc: indicate what version uv_loop_configure was added on (Saúl Ibarra
+  Corretgé)
+
+* doc: fix sphinx warning (Saúl Ibarra Corretgé)
+
+* test: skip spawn_setuid_setgid if we get EACCES (Saúl Ibarra Corretgé)
+
+* test: silence some Clang warnings (Saúl Ibarra Corretgé)
+
+* test: relax osx_select_many_fds (Saúl Ibarra Corretgé)
+
+* test: fix compilation warnings when building with Clang (Saúl Ibarra
+  Corretgé)
+
+* win: fix autotools build of tests (Luis Lavena)
+
+* gitignore: ignore Visual Studio files (Marc Schlaich)
+
+* win: set fallback message if FormatMessage fails (Marc Schlaich)
+
+* win: fall back to default language in uv_dlerror (Marc Schlaich)
+
+* test: improve compatibility for dlerror test (Marc Schlaich)
+
+* test: check dlerror is "no error" in no error case (Marc Schlaich)
+
+* unix: change uv_cwd not to return a trailing slash (Saúl Ibarra Corretgé)
+
+* test: fix cwd_and_chdir test on Unix (Saúl Ibarra Corretgé)
+
+* test: add uv_cwd output to platform_output test (Saúl Ibarra Corretgé)
+
+* build: fix dragonflybsd autotools build (John Marino)
+
+* win: scandir use 'ls' for formatting long strings (Kenneth Perry)
+
+* build: remove clang and gcc_version gyp defines (Ben Noordhuis)
+
+* unix, windows: don't treat uv_run_mode as a bitmask (Saúl Ibarra Corretgé)
+
+* unix, windows: fix UV_RUN_ONCE mode if progress was made (Saúl Ibarra
+  Corretgé)
+
+
+2014.12.25, Version 0.10.31 (Stable), 4dbd27e2219069a6daa769fb37f98673b77b4261
+
+Changes since version 0.10.30:
+
+* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder)
+
+* win: fix compilation of tests (Marc Schlaich)
+
+* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder)
+
+* win: avoid stack corruption when closing a poll handle (Bert Belder)
+
+* gitignore: ignore Visual Studio files (Marc Schlaich)
+
+* win: set fallback message if FormatMessage fails (Marc Schlaich)
+
+* win: fall back to default language in uv_dlerror (Marc Schlaich)
+
+* test: improve compatibility for dlerror test (Marc Schlaich)
+
+* test: check dlerror is "no error" in no error case (Marc Schlaich)
+
+* build: link against -pthread (Logan Rosen)
+
+* win: scandir use 'ls' for formatting long strings (Kenneth Perry)
+
+
 2014.12.10, Version 1.0.2 (Stable), eec671f0059953505f9a3c9aeb7f9f31466dd7cd
 
 Changes since version 1.0.1:
index 371df711d65633c8cfc7265fda1417abac4b21f1..c5b8a1fa8700924ab7184894ec9f3fe2ca8c8d16 100644 (file)
@@ -34,6 +34,8 @@ libuv_la_SOURCES = src/fs-poll.c \
                    src/version.c
 
 if SUNOS
+# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
+# on other platforms complain that the argument is unused during compilation.
 libuv_la_CFLAGS += -pthread
 endif
 
@@ -81,7 +83,6 @@ else  # WINNT
 
 include_HEADERS += include/uv-unix.h
 AM_CPPFLAGS += -I$(top_srcdir)/src/unix
-libuv_la_CFLAGS += -g --std=gnu89 -pedantic -Wall -Wextra -Wno-unused-parameter
 libuv_la_SOURCES += src/unix/async.c \
                    src/unix/atomic-ops.h \
                    src/unix/core.c \
@@ -159,6 +160,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-loop-close.c \
                          test/test-loop-stop.c \
                          test/test-loop-time.c \
+                         test/test-loop-configure.c \
                          test/test-multiple-listen.c \
                          test/test-mutexes.c \
                          test/test-osx-select.c \
@@ -172,6 +174,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-pipe-close-stdout-read-stdin.c \
                          test/test-platform-output.c \
                          test/test-poll-close.c \
+                         test/test-poll-close-doesnt-corrupt-stack.c \
                          test/test-poll-closesocket.c \
                          test/test-poll.c \
                          test/test-process-title.c \
@@ -274,7 +277,6 @@ endif
 
 if DRAGONFLY
 include_HEADERS += include/uv-bsd.h
-libuv_la_SOURCES += src/unix/kqueue.c src/unix/freebsd.c
 endif
 
 if FREEBSD
index 751b4f5562493a5cf8b26c1d76db973122016a44..0574778a4e1040cce97d6f888b8cb0b85d24feca 100755 (executable)
@@ -33,7 +33,7 @@ UV_EXTRA_AUTOMAKE_FLAGS=
 if test "$automake_version_major" -gt 1 || \
    test "$automake_version_major" -eq 1 && \
    test "$automake_version_minor" -gt 11; then
-  # serial-tests is available in v0.12 and newer.
+  # serial-tests is available in v1.12 and newer.
   UV_EXTRA_AUTOMAKE_FLAGS="$UV_EXTRA_AUTOMAKE_FLAGS serial-tests"
 fi
 echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
index a8e2ef44c6131d15b4790ffe4a40d7d416bd6b19..ecf9475234f3daa57637d6bbb8e798b4925d6a21 100644 (file)
@@ -6,8 +6,6 @@
     'uv_library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
     'component%': 'static_library',  # NB. these names match with what V8 expects
     'msvs_multi_core_compile': '0',  # we do enable multicore compiles, but not using the V8 way
-    'gcc_version%': 'unknown',
-    'clang%': 0,
   },
 
   'target_defaults': {
             'cflags': [ '-pthread' ],
             'ldflags': [ '-pthread' ],
           }],
-          [ 'visibility=="hidden" and (clang==1 or gcc_version >= 40)', {
+          [ 'visibility=="hidden"', {
             'cflags': [ '-fvisibility=hidden' ],
           }],
         ],
index 6ae53cc9164f197509ca10c6e6de8fadaa3e6034..56e97abf37880b815bea13637ffada856a5d1a4f 100644 (file)
@@ -13,7 +13,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_PREREQ(2.57)
-AC_INIT([libuv], [1.0.2], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.2.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])
@@ -24,9 +24,16 @@ AC_ENABLE_SHARED
 AC_ENABLE_STATIC
 AC_PROG_CC
 AM_PROG_CC_C_O
-CC_CHECK_CFLAGS_APPEND([-Wno-dollar-in-identifier-extension])
+CC_CHECK_CFLAGS_APPEND([-g])
+CC_CHECK_CFLAGS_APPEND([-std=gnu89])
+CC_CHECK_CFLAGS_APPEND([-pedantic])
+CC_CHECK_CFLAGS_APPEND([-Wall])
+CC_CHECK_CFLAGS_APPEND([-Wextra])
+CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter])
 # AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+# autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR.
+AC_PROG_LIBTOOL
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 LT_INIT
 # TODO(bnoordhuis) Check for -pthread vs. -pthreads
index 10eb94b013b791d94f9d4e33c6bc4b6078aedae6..aa7089ab5cf26a6271eb35aad55d58f110ebe76b 100644 (file)
-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
-       set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=build
-set SRCDIR=src
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR%
-set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR%
-if NOT "%PAPER%" == "" (
-       set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
-       set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
-       :help
-       echo.Please use `make ^<target^>` where ^<target^> is one of
-       echo.  html       to make standalone HTML files
-       echo.  dirhtml    to make HTML files named index.html in directories
-       echo.  singlehtml to make a single large HTML file
-       echo.  pickle     to make pickle files
-       echo.  json       to make JSON files
-       echo.  htmlhelp   to make HTML files and a HTML help project
-       echo.  qthelp     to make HTML files and a qthelp project
-       echo.  devhelp    to make HTML files and a Devhelp project
-       echo.  epub       to make an epub
-       echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
-       echo.  text       to make text files
-       echo.  man        to make manual pages
-       echo.  texinfo    to make Texinfo files
-       echo.  gettext    to make PO message catalogs
-       echo.  changes    to make an overview over all changed/added/deprecated items
-       echo.  xml        to make Docutils-native XML files
-       echo.  pseudoxml  to make pseudoxml-XML files for display purposes
-       echo.  linkcheck  to check all external links for integrity
-       echo.  doctest    to run all doctests embedded in the documentation if enabled
-       goto end
-)
-
-if "%1" == "clean" (
-       for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
-       del /q /s %BUILDDIR%\*
-       goto end
-)
-
-
-%SPHINXBUILD% 2> nul
-if errorlevel 9009 (
-       echo.
-       echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
-       echo.installed, then set the SPHINXBUILD environment variable to point
-       echo.to the full path of the 'sphinx-build' executable. Alternatively you
-       echo.may add the Sphinx directory to PATH.
-       echo.
-       echo.If you don't have Sphinx installed, grab it from
-       echo.http://sphinx-doc.org/
-       exit /b 1
-)
-
-if "%1" == "html" (
-       %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The HTML pages are in %BUILDDIR%/html.
-       goto end
-)
-
-if "%1" == "dirhtml" (
-       %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
-       goto end
-)
-
-if "%1" == "singlehtml" (
-       %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
-       goto end
-)
-
-if "%1" == "pickle" (
-       %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can process the pickle files.
-       goto end
-)
-
-if "%1" == "json" (
-       %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can process the JSON files.
-       goto end
-)
-
-if "%1" == "htmlhelp" (
-       %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
-       goto end
-)
-
-if "%1" == "qthelp" (
-       %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
-       echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp
-       echo.To view the help file:
-       echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc
-       goto end
-)
-
-if "%1" == "devhelp" (
-       %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished.
-       goto end
-)
-
-if "%1" == "epub" (
-       %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The epub file is in %BUILDDIR%/epub.
-       goto end
-)
-
-if "%1" == "latex" (
-       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
-       goto end
-)
-
-if "%1" == "latexpdf" (
-       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
-       cd %BUILDDIR%/latex
-       make all-pdf
-       cd %BUILDDIR%/..
-       echo.
-       echo.Build finished; the PDF files are in %BUILDDIR%/latex.
-       goto end
-)
-
-if "%1" == "latexpdfja" (
-       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
-       cd %BUILDDIR%/latex
-       make all-pdf-ja
-       cd %BUILDDIR%/..
-       echo.
-       echo.Build finished; the PDF files are in %BUILDDIR%/latex.
-       goto end
-)
-
-if "%1" == "text" (
-       %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The text files are in %BUILDDIR%/text.
-       goto end
-)
-
-if "%1" == "man" (
-       %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The manual pages are in %BUILDDIR%/man.
-       goto end
-)
-
-if "%1" == "texinfo" (
-       %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
-       goto end
-)
-
-if "%1" == "gettext" (
-       %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
-       goto end
-)
-
-if "%1" == "changes" (
-       %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.The overview file is in %BUILDDIR%/changes.
-       goto end
-)
-
-if "%1" == "linkcheck" (
-       %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
-       goto end
-)
-
-if "%1" == "doctest" (
-       %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
-       goto end
-)
-
-if "%1" == "xml" (
-       %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The XML files are in %BUILDDIR%/xml.
-       goto end
-)
-
-if "%1" == "pseudoxml" (
-       %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
-       goto end
-)
-
-:end
+@ECHO OFF\r
+\r
+REM Command file for Sphinx documentation\r
+\r
+if "%SPHINXBUILD%" == "" (\r
+       set SPHINXBUILD=sphinx-build\r
+)\r
+set BUILDDIR=build\r
+set SRCDIR=src\r
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR%\r
+set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR%\r
+if NOT "%PAPER%" == "" (\r
+       set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\r
+       set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\r
+)\r
+\r
+if "%1" == "" goto help\r
+\r
+if "%1" == "help" (\r
+       :help\r
+       echo.Please use `make ^<target^>` where ^<target^> is one of\r
+       echo.  html       to make standalone HTML files\r
+       echo.  dirhtml    to make HTML files named index.html in directories\r
+       echo.  singlehtml to make a single large HTML file\r
+       echo.  pickle     to make pickle files\r
+       echo.  json       to make JSON files\r
+       echo.  htmlhelp   to make HTML files and a HTML help project\r
+       echo.  qthelp     to make HTML files and a qthelp project\r
+       echo.  devhelp    to make HTML files and a Devhelp project\r
+       echo.  epub       to make an epub\r
+       echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\r
+       echo.  text       to make text files\r
+       echo.  man        to make manual pages\r
+       echo.  texinfo    to make Texinfo files\r
+       echo.  gettext    to make PO message catalogs\r
+       echo.  changes    to make an overview over all changed/added/deprecated items\r
+       echo.  xml        to make Docutils-native XML files\r
+       echo.  pseudoxml  to make pseudoxml-XML files for display purposes\r
+       echo.  linkcheck  to check all external links for integrity\r
+       echo.  doctest    to run all doctests embedded in the documentation if enabled\r
+       goto end\r
+)\r
+\r
+if "%1" == "clean" (\r
+       for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i\r
+       del /q /s %BUILDDIR%\*\r
+       goto end\r
+)\r
+\r
+\r
+%SPHINXBUILD% 2> nul\r
+if errorlevel 9009 (\r
+       echo.\r
+       echo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r
+       echo.installed, then set the SPHINXBUILD environment variable to point\r
+       echo.to the full path of the 'sphinx-build' executable. Alternatively you\r
+       echo.may add the Sphinx directory to PATH.\r
+       echo.\r
+       echo.If you don't have Sphinx installed, grab it from\r
+       echo.http://sphinx-doc.org/\r
+       exit /b 1\r
+)\r
+\r
+if "%1" == "html" (\r
+       %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The HTML pages are in %BUILDDIR%/html.\r
+       goto end\r
+)\r
+\r
+if "%1" == "dirhtml" (\r
+       %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\r
+       goto end\r
+)\r
+\r
+if "%1" == "singlehtml" (\r
+       %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\r
+       goto end\r
+)\r
+\r
+if "%1" == "pickle" (\r
+       %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can process the pickle files.\r
+       goto end\r
+)\r
+\r
+if "%1" == "json" (\r
+       %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can process the JSON files.\r
+       goto end\r
+)\r
+\r
+if "%1" == "htmlhelp" (\r
+       %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can run HTML Help Workshop with the ^\r
+.hhp project file in %BUILDDIR%/htmlhelp.\r
+       goto end\r
+)\r
+\r
+if "%1" == "qthelp" (\r
+       %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; now you can run "qcollectiongenerator" with the ^\r
+.qhcp project file in %BUILDDIR%/qthelp, like this:\r
+       echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp\r
+       echo.To view the help file:\r
+       echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc\r
+       goto end\r
+)\r
+\r
+if "%1" == "devhelp" (\r
+       %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished.\r
+       goto end\r
+)\r
+\r
+if "%1" == "epub" (\r
+       %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The epub file is in %BUILDDIR%/epub.\r
+       goto end\r
+)\r
+\r
+if "%1" == "latex" (\r
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\r
+       goto end\r
+)\r
+\r
+if "%1" == "latexpdf" (\r
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r
+       cd %BUILDDIR%/latex\r
+       make all-pdf\r
+       cd %BUILDDIR%/..\r
+       echo.\r
+       echo.Build finished; the PDF files are in %BUILDDIR%/latex.\r
+       goto end\r
+)\r
+\r
+if "%1" == "latexpdfja" (\r
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r
+       cd %BUILDDIR%/latex\r
+       make all-pdf-ja\r
+       cd %BUILDDIR%/..\r
+       echo.\r
+       echo.Build finished; the PDF files are in %BUILDDIR%/latex.\r
+       goto end\r
+)\r
+\r
+if "%1" == "text" (\r
+       %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The text files are in %BUILDDIR%/text.\r
+       goto end\r
+)\r
+\r
+if "%1" == "man" (\r
+       %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The manual pages are in %BUILDDIR%/man.\r
+       goto end\r
+)\r
+\r
+if "%1" == "texinfo" (\r
+       %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\r
+       goto end\r
+)\r
+\r
+if "%1" == "gettext" (\r
+       %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The message catalogs are in %BUILDDIR%/locale.\r
+       goto end\r
+)\r
+\r
+if "%1" == "changes" (\r
+       %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.The overview file is in %BUILDDIR%/changes.\r
+       goto end\r
+)\r
+\r
+if "%1" == "linkcheck" (\r
+       %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Link check complete; look for any errors in the above output ^\r
+or in %BUILDDIR%/linkcheck/output.txt.\r
+       goto end\r
+)\r
+\r
+if "%1" == "doctest" (\r
+       %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Testing of doctests in the sources finished, look at the ^\r
+results in %BUILDDIR%/doctest/output.txt.\r
+       goto end\r
+)\r
+\r
+if "%1" == "xml" (\r
+       %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The XML files are in %BUILDDIR%/xml.\r
+       goto end\r
+)\r
+\r
+if "%1" == "pseudoxml" (\r
+       %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\r
+       if errorlevel 1 exit /b 1\r
+       echo.\r
+       echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\r
+       goto end\r
+)\r
+\r
+:end\r
index 0a9e8a608699568729d2dc2e7f049c9588378c0c..d347534bfc77cc666d167772281c42cb5befefb2 100644 (file)
@@ -52,6 +52,8 @@ API
 
 .. c:function:: int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...)
 
+    .. versionadded:: 1.0.2
+
     Set additional loop options.  You should normally call this before the
     first call to :c:func:`uv_run` unless mentioned otherwise.
 
index 4b810fe08475e87e21ce5d31ac2821ad51f13bbd..10c349e9b736f3d8916414d387032c267b91e886 100644 (file)
@@ -2,7 +2,7 @@
 .. _misc:
 
 Miscellaneous utilities
-======================
+=======================
 
 This section contains miscellaneous functions that don't really belong in any
 other section.
@@ -207,6 +207,10 @@ API
 
     Gets the current working directory.
 
+    .. versionchanged:: 1.1.0
+
+        On Unix the path no longer ends in a slash.
+
 .. c:function:: int uv_chdir(const char* dir)
 
     Changes the current working directory.
index 8cb006632038ba3236bcaac32b701d0701a53ec7..74b485941c07abacd59795d7eb4e90f7304c672d 100644 (file)
@@ -16,6 +16,24 @@ Data types
 
     TTY handle type.
 
+.. c:type:: uv_tty_mode_t
+
+    .. versionadded:: 1.2.0
+
+    TTY mode type:
+
+    ::
+
+        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;
+
+
 
 Public members
 ^^^^^^^^^^^^^^
@@ -43,9 +61,12 @@ API
     .. note::
         TTY streams which are not readable have blocking writes.
 
-.. c:function:: int uv_tty_set_mode(uv_tty_t*, int mode)
+.. 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.
 
-    Set the TTY mode. 0 for normal, 1 for raw.
+    Set the TTY using the specified terminal mode.
 
 .. c:function:: int uv_tty_reset_mode(void)
 
index f5afc6da2d6b0b740cfccdedc209c9f93321c016..0491ff873f1af1492e52e849427c6a5b26f42b00 100755 (executable)
@@ -1,9 +1,7 @@
 #!/usr/bin/env python
 
-import glob
-import platform
 import os
-import subprocess
+import platform
 import sys
 
 try:
@@ -35,16 +33,6 @@ def host_arch():
   return machine  # Return as-is and hope for the best.
 
 
-def compiler_version():
-  proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
-  is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
-  proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
-  version = proc.communicate()[0].split('.')
-  version = map(int, version[:2])
-  version = tuple(version)
-  return (version, is_clang)
-
-
 def run_gyp(args):
   rc = gyp.main(args)
   if rc != 0:
@@ -85,9 +73,6 @@ if __name__ == '__main__':
     if 'eclipse' not in args and 'ninja' not in args:
       args.extend(['-Goutput_dir=' + output_dir])
       args.extend(['--generator-output', output_dir])
-    (major, minor), is_clang = compiler_version()
-    args.append('-Dgcc_version=%d' % (10 * major + minor))
-    args.append('-Dclang=%d' % int(is_clang))
 
   if not any(a.startswith('-Dhost_arch=') for a in args):
     args.append('-Dhost_arch=%s' % host_arch())
index 25c31ab5e1093dc0c30d6b627cab460a93b70884..85d74723af1727834908a16d174bc47379d122bf 100644 (file)
@@ -31,8 +31,8 @@
  */
 
 #define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 0
-#define UV_VERSION_PATCH 2
+#define UV_VERSION_MINOR 2
+#define UV_VERSION_PATCH 0
 #define UV_VERSION_IS_RELEASE 1
 #define UV_VERSION_SUFFIX ""
 
index 0c188e7e22af85cba58533140f81d1e94f83bf21..4abb294c0517db323be4cfaffe3b983a12cc5757 100644 (file)
@@ -517,10 +517,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
   /* Used in fast mode */                                                     \
   SOCKET peer_socket;                                                         \
   AFD_POLL_INFO afd_poll_info_1;                                              \
-  union {                                                                     \
-    AFD_POLL_INFO* afd_poll_info_ptr;                                         \
-    AFD_POLL_INFO afd_poll_info;                                              \
-  } afd_poll_info_2;                                                          \
+  AFD_POLL_INFO afd_poll_info_2;                                              \
   /* Used in fast and slow mode. */                                           \
   uv_req_t poll_req_1;                                                        \
   uv_req_t poll_req_2;                                                        \
index 7b3c25223b29ede9a776a2e56c50bec4f24101a5..a2332504ca95511ae3d69b157aff05c344060535 100644 (file)
@@ -628,11 +628,30 @@ struct uv_tty_s {
   UV_TTY_PRIVATE_FIELDS
 };
 
+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;
+
 UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
-UV_EXTERN int uv_tty_set_mode(uv_tty_t*, int mode);
+UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode);
 UV_EXTERN int uv_tty_reset_mode(void);
 UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
 
+#ifdef __cplusplus
+}  /* extern "C" */
+
+inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
+  return uv_tty_set_mode(handle, static_cast<uv_tty_mode_t>(mode));
+}
+
+extern "C" {
+#endif
+
 UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
 
 /*
diff --git a/deps/uv/m4/dtrace.m4 b/deps/uv/m4/dtrace.m4
deleted file mode 100644 (file)
index 09f7dc8..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-dnl  Copyright (C) 2009 Sun Microsystems
-dnl This file is free software; Sun Microsystems
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl ---------------------------------------------------------------------------
-dnl Macro: PANDORA_ENABLE_DTRACE
-dnl ---------------------------------------------------------------------------
-AC_DEFUN([PANDORA_ENABLE_DTRACE],[
-  AC_ARG_ENABLE([dtrace],
-    [AS_HELP_STRING([--disable-dtrace],
-            [enable DTrace USDT probes. @<:@default=yes@:>@])],
-    [ac_cv_enable_dtrace="$enableval"],
-    [ac_cv_enable_dtrace="yes"])
-
-  AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[
-    AC_CHECK_PROGS([DTRACE], [dtrace])
-    AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[
-
-      AC_CACHE_CHECK([if dtrace works],[ac_cv_dtrace_works],[
-        cat >conftest.d <<_ACEOF
-provider Example {
-  probe increment(int);
-};
-_ACEOF
-        $DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
-        AS_IF([test $? -eq 0],[ac_cv_dtrace_works=yes],
-          [ac_cv_dtrace_works=no])
-        rm -f conftest.h conftest.d
-      ])
-      AS_IF([test "x$ac_cv_dtrace_works" = "xyes"],[
-        AC_DEFINE([HAVE_DTRACE], [1], [Enables DTRACE Support])
-        AC_CACHE_CHECK([if dtrace should instrument object files],
-          [ac_cv_dtrace_needs_objects],[
-            dnl DTrace on MacOSX does not use -G option
-            cat >conftest.d <<_ACEOF
-provider Example {
-  probe increment(int);
-};
-_ACEOF
-          cat > conftest.c <<_ACEOF
-#include "conftest.h"
-void foo() {
-  EXAMPLE_INCREMENT(1);
-}
-_ACEOF
-            $DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
-            $CC -c -o conftest.o conftest.c
-            $DTRACE -G -o conftest.d.o -s conftest.d conftest.o 2>/dev/zero
-            AS_IF([test $? -eq 0],[ac_cv_dtrace_needs_objects=yes],
-              [ac_cv_dtrace_needs_objects=no])
-            rm -f conftest.d.o conftest.d conftest.h conftest.o conftest.c
-        ])
-      ])
-      AC_SUBST(DTRACEFLAGS) dnl TODO: test for -G on OSX
-      ac_cv_have_dtrace=yes
-    ])])
-
-AM_CONDITIONAL([HAVE_DTRACE], [test "x$ac_cv_dtrace_works" = "xyes"])
-AM_CONDITIONAL([DTRACE_NEEDS_OBJECTS],
-               [test "x$ac_cv_dtrace_needs_objects" = "xyes"])
-
-])
-dnl ---------------------------------------------------------------------------
-dnl End Macro: PANDORA_ENABLE_DTRACE
-dnl ---------------------------------------------------------------------------
index 349c2b558e4facc15bd81a05279cfd2d95e20b74..0c5d1f4b508453d1c9da6d7dc8c19af0511db4de 100644 (file)
@@ -294,7 +294,7 @@ int uv_exepath(char* buffer, size_t* size) {
   int fd;
   char **argv;
 
-  if ((buffer == NULL) || (size == NULL))
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
   snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
index c08040e5378f5f0f129b82bbf2ed25ccaced41e8..6f284ffa7aea31cbfb033ef767ccc09f8f25ef86 100644 (file)
@@ -74,7 +74,7 @@
 #include <sys/ioctl.h>
 #endif
 
-static void uv__run_pending(uv_loop_t* loop);
+static int uv__run_pending(uv_loop_t* loop);
 
 /* Verify that uv_buf_t is ABI-compatible with struct iovec. */
 STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));
@@ -304,6 +304,7 @@ int uv_loop_alive(const uv_loop_t* loop) {
 int uv_run(uv_loop_t* loop, uv_run_mode mode) {
   int timeout;
   int r;
+  int ran_pending;
 
   r = uv__loop_alive(loop);
   if (!r)
@@ -312,12 +313,12 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
   while (r != 0 && loop->stop_flag == 0) {
     uv__update_time(loop);
     uv__run_timers(loop);
-    uv__run_pending(loop);
+    ran_pending = uv__run_pending(loop);
     uv__run_idle(loop);
     uv__run_prepare(loop);
 
     timeout = 0;
-    if ((mode & UV_RUN_NOWAIT) == 0)
+    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
       timeout = uv_backend_timeout(loop);
 
     uv__io_poll(loop, timeout);
@@ -338,8 +339,7 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
     }
 
     r = uv__loop_alive(loop);
-
-    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
       break;
   }
 
@@ -635,6 +635,11 @@ int uv_cwd(char* buffer, size_t* size) {
     return -errno;
 
   *size = strlen(buffer);
+  if (*size > 1 && buffer[*size - 1] == '/') {
+    buffer[*size-1] = '\0';
+    (*size)--;
+  }
+
   return 0;
 }
 
@@ -689,10 +694,13 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
 }
 
 
-static void uv__run_pending(uv_loop_t* loop) {
+static int uv__run_pending(uv_loop_t* loop) {
   QUEUE* q;
   uv__io_t* w;
 
+  if (QUEUE_EMPTY(&loop->pending_queue))
+    return 0;
+
   while (!QUEUE_EMPTY(&loop->pending_queue)) {
     q = QUEUE_HEAD(&loop->pending_queue);
     QUEUE_REMOVE(q);
@@ -701,6 +709,8 @@ static void uv__run_pending(uv_loop_t* loop) {
     w = QUEUE_DATA(q, uv__io_t, pending_queue);
     w->cb(loop, w, UV__POLLOUT);
   }
+
+  return 1;
 }
 
 
index c9a45edee4252040ca09cf6d6a06137c572f665c..651545f85ee3d106cd1f7ff33296e1ca4f6a63b4 100644 (file)
@@ -65,28 +65,33 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
 
 
 int uv_exepath(char* buffer, size_t* size) {
-  uint32_t usize;
-  int result;
-  char* path;
-  char* fullpath;
+  /* realpath(exepath) may be > PATH_MAX so double it to be on the safe side. */
+  char abspath[PATH_MAX * 2 + 1];
+  char exepath[PATH_MAX + 1];
+  uint32_t exepath_size;
+  size_t abspath_size;
 
-  if (buffer == NULL || size == NULL)
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
-  usize = *size;
-  result = _NSGetExecutablePath(buffer, &usize);
-  if (result) return result;
+  exepath_size = sizeof(exepath);
+  if (_NSGetExecutablePath(exepath, &exepath_size))
+    return -EIO;
 
-  path = malloc(2 * PATH_MAX);
-  fullpath = realpath(buffer, path);
-  if (fullpath == NULL) {
-    SAVE_ERRNO(free(path));
+  if (realpath(exepath, abspath) != abspath)
     return -errno;
-  }
 
-  strncpy(buffer, fullpath, *size);
-  free(fullpath);
-  *size = strlen(buffer);
+  abspath_size = strlen(abspath);
+  if (abspath_size == 0)
+    return -EIO;
+
+  *size -= 1;
+  if (*size > abspath_size)
+    *size = abspath_size;
+
+  memcpy(buffer, abspath, *size);
+  buffer[*size] = '\0';
+
   return 0;
 }
 
index d59e3773a557ca105b950db33218ef4fe4b4b3d6..55492adc4801e6c356b530f67e10ad094b308b99 100644 (file)
@@ -78,7 +78,7 @@ int uv_exepath(char* buffer, size_t* size) {
   int mib[4];
   size_t cb;
 
-  if (buffer == NULL || size == NULL)
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
 #ifdef __DragonFly__
index 65fd01230b3e09c2d3d17ae893a19338325f61a5..e7eee2f9abc4ed610ee3c329be58796bd16d2b8e 100644 (file)
 #include <string.h>
 
 #include <sys/types.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/uio.h>
 #include <pthread.h>
 #include <unistd.h>
 #include <fcntl.h>
     defined(__OpenBSD__)    ||                                            \
     defined(__NetBSD__)
 # define HAVE_PREADV 1
-#elif defined(__linux__)
-# include <linux/version.h>
-# if defined(__GLIBC_PREREQ)
-#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) &&                    \
-       __GLIBC_PREREQ(2,10)
-#    define HAVE_PREADV 1
-#   else
-#    define HAVE_PREADV 0
-#   endif
-# else
-#  define HAVE_PREADV 0
-# endif
 #else
 # define HAVE_PREADV 0
 #endif
 
 #if defined(__linux__) || defined(__sun)
 # include <sys/sendfile.h>
-#elif defined(__APPLE__) || defined(__FreeBSD__)
-# include <sys/socket.h>
-#endif
-
-#if HAVE_PREADV || defined(__APPLE__)
-# include <sys/uio.h>
 #endif
 
 #define INIT(type)                                                            \
@@ -219,6 +203,9 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
 
 
 static ssize_t uv__fs_read(uv_fs_t* req) {
+#if defined(__linux__)
+  static int no_preadv;
+#endif
   ssize_t result;
 
 #if defined(_AIX)
@@ -245,16 +232,12 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
     result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
 #else
 # if defined(__linux__)
-    static int no_preadv;
-    if (no_preadv)
+    if (no_preadv) retry:
 # endif
     {
       off_t nread;
       size_t index;
 
-# if defined(__linux__)
-    retry:
-# endif
       nread = 0;
       index = 0;
       result = 1;
@@ -578,6 +561,9 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
 
 
 static ssize_t uv__fs_write(uv_fs_t* req) {
+#if defined(__linux__)
+  static int no_pwritev;
+#endif
   ssize_t r;
 
   /* Serialize writes on OS X, concurrent write() and pwrite() calls result in
@@ -603,16 +589,12 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
     r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
 #else
 # if defined(__linux__)
-    static int no_pwritev;
-    if (no_pwritev)
+    if (no_pwritev) retry:
 # endif
     {
       off_t written;
       size_t index;
 
-# if defined(__linux__)
-    retry:
-# endif
       written = 0;
       index = 0;
       r = 0;
index daad61b782f17fc0de47ac39483fd3b2cb17714c..03a9226101dd7b1df06e81c10a389a38793b74a7 100644 (file)
@@ -52,9 +52,6 @@
 # include <CoreServices/CoreServices.h>
 #endif
 
-#define STATIC_ASSERT(expr)                                                   \
-  void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)])
-
 #define ACCESS_ONCE(type, var)                                                \
   (*(volatile type*) &(var))
 
index a2145b0f369eee2f17b1b365511b23461ce91017..d77b13fd6fddb5add140adcba5e0c36a7273c8e5 100644 (file)
@@ -33,7 +33,6 @@
 #include <sys/prctl.h>
 #include <sys/sysinfo.h>
 #include <unistd.h>
-#include <signal.h>
 #include <fcntl.h>
 #include <time.h>
 
@@ -142,8 +141,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
   struct uv__epoll_event e;
   QUEUE* q;
   uv__io_t* w;
-  sigset_t* pset;
-  sigset_t set;
+  uint64_t sigmask;
   uint64_t base;
   uint64_t diff;
   int nevents;
@@ -194,24 +192,21 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
     w->events = w->pevents;
   }
 
-  pset = NULL;
-  if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
-    pset = &set;
-    sigemptyset(pset);
-    sigaddset(pset, SIGPROF);
-  }
+  sigmask = 0;
+  if (loop->flags & UV_LOOP_BLOCK_SIGPROF)
+    sigmask |= 1 << (SIGPROF - 1);
 
   assert(timeout >= -1);
   base = loop->time;
   count = 48; /* Benchmarks suggest this gives the best throughput. */
 
   for (;;) {
-    if (no_epoll_wait || pset != NULL) {
+    if (no_epoll_wait || sigmask) {
       nfds = uv__epoll_pwait(loop->backend_fd,
                              events,
                              ARRAY_SIZE(events),
                              timeout,
-                             pset);
+                             sigmask);
     } else {
       nfds = uv__epoll_wait(loop->backend_fd,
                             events,
@@ -383,10 +378,13 @@ void uv_loadavg(double avg[3]) {
 int uv_exepath(char* buffer, size_t* size) {
   ssize_t n;
 
-  if (buffer == NULL || size == NULL)
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
-  n = readlink("/proc/self/exe", buffer, *size - 1);
+  n = *size - 1;
+  if (n > 0)
+    n = readlink("/proc/self/exe", buffer, n);
+
   if (n == -1)
     return -errno;
 
index e036fad5ef6427047f289560ed7e828eba9d5000..7bf2c0f87dbea4671872a9a701e44bfd0257d29e 100644 (file)
@@ -321,15 +321,15 @@ int uv__epoll_pwait(int epfd,
                     struct uv__epoll_event* events,
                     int nevents,
                     int timeout,
-                    const sigset_t* sigmask) {
+                    uint64_t sigmask) {
 #if defined(__NR_epoll_pwait)
   return syscall(__NR_epoll_pwait,
                  epfd,
                  events,
                  nevents,
                  timeout,
-                 sigmask,
-                 _NSIG / 8);
+                 &sigmask,
+                 sizeof(sigmask));
 #else
   return errno = ENOSYS, -1;
 #endif
index fd6bb48665fb9cebf185bd165aa06cc87d0ad590..6f249b724536753f1524aa2ebf0dadc0d40e736f 100644 (file)
@@ -131,7 +131,7 @@ int uv__epoll_pwait(int epfd,
                     struct uv__epoll_event* events,
                     int nevents,
                     int timeout,
-                    const sigset_t* sigmask);
+                    uint64_t sigmask);
 int uv__eventfd2(unsigned int count, int flags);
 int uv__inotify_init(void);
 int uv__inotify_init1(int flags);
index 5f1182f8b43edcbd33b32d753cc38a9f0a0e0ca7..de99d135f7aa6039db72f07686cbd0a65004fd9f 100644 (file)
@@ -83,7 +83,7 @@ int uv_exepath(char* buffer, size_t* size) {
   size_t cb;
   pid_t mypid;
 
-  if (buffer == NULL || size == NULL)
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
   mypid = getpid();
index cde8d4d0c962adddab2badb469e0707e3340c406..3e7ae848eec7d2a90a5207cfc7570401da79bdfb 100644 (file)
@@ -85,7 +85,7 @@ int uv_exepath(char* buffer, size_t* size) {
   pid_t mypid;
   int err;
 
-  if (buffer == NULL || size == NULL)
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
   mypid = getpid();
@@ -108,17 +108,19 @@ int uv_exepath(char* buffer, size_t* size) {
     }
     argsbuf_size *= 2U;
   }
+
   if (argsbuf[0] == NULL) {
     err = -EINVAL;  /* FIXME(bnoordhuis) More appropriate error. */
     goto out;
   }
+
+  *size -= 1;
   exepath_size = strlen(argsbuf[0]);
-  if (exepath_size >= *size) {
-    err = -EINVAL;
-    goto out;
-  }
-  memcpy(buffer, argsbuf[0], exepath_size + 1U);
-  *size = exepath_size;
+  if (*size > exepath_size)
+    *size = exepath_size;
+
+  memcpy(buffer, argsbuf[0], *size);
+  buffer[*size] = '\0';
   err = 0;
 
 out:
index b20fb9210c074b0e39c0aa99af19f61a4005d997..ef47700b7a1635d61e1ae8fa84201fd77444c31e 100644 (file)
@@ -55,17 +55,15 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
 
   /* Make a copy of the file name, it outlives this function's scope. */
   pipe_fname = strdup(name);
-  if (pipe_fname == NULL) {
-    err = -ENOMEM;
-    goto out;
-  }
+  if (pipe_fname == NULL)
+    return -ENOMEM;
 
   /* We've got a copy, don't touch the original any more. */
   name = NULL;
 
   err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
   if (err < 0)
-    goto out;
+    goto err_socket;
   sockfd = err;
 
   memset(&saddr, 0, sizeof saddr);
@@ -78,7 +76,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
     /* Convert ENOENT to EACCES for compatibility with Windows. */
     if (err == -ENOENT)
       err = -EACCES;
-    goto out;
+    goto err_bind;
   }
 
   /* Success. */
@@ -86,11 +84,10 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
   handle->io_watcher.fd = sockfd;
   return 0;
 
-out:
-  /* unlink() before uv__close() to avoid races. */
-  assert(pipe_fname != NULL);
-  unlink(pipe_fname);
+err_bind:
   uv__close(sockfd);
+
+err_socket:
   free((void*)pipe_fname);
   return err;
 }
index d6fb7f49509185714aec2f5488ba14ce1e6e1ec3..ca183a62279a5ee5e9f278fb3e0e5b58414cd919 100644 (file)
@@ -300,11 +300,15 @@ int uv_exepath(char* buffer, size_t* size) {
   ssize_t res;
   char buf[128];
 
-  if (buffer == NULL || size == NULL)
+  if (buffer == NULL || size == NULL || *size == 0)
     return -EINVAL;
 
   snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
-  res = readlink(buf, buffer, *size - 1);
+
+  res = *size - 1;
+  if (res > 0)
+    res = readlink(buf, buffer, res);
+
   if (res == -1)
     return -errno;
 
index 7ae19905fbffcb979c4334ef2fc660bd52ebd4e4..068025eaf59ceaa73f910cb4b8e459787bec83e3 100644 (file)
@@ -98,19 +98,19 @@ skip:
     uv__nonblock(fd, 1);
 
   uv__stream_open((uv_stream_t*) tty, fd, flags);
-  tty->mode = 0;
+  tty->mode = UV_TTY_MODE_NORMAL;
 
   return 0;
 }
 
 
-int uv_tty_set_mode(uv_tty_t* tty, int mode) {
-  struct termios raw;
+int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
+  struct termios tmp;
   int fd;
 
   fd = uv__stream_fd(tty);
 
-  if (mode && tty->mode == 0) {  /* on */
+  if (tty->mode == UV_TTY_MODE_NORMAL && mode != UV_TTY_MODE_NORMAL) {
     if (tcgetattr(fd, &tty->orig_termios))
       return -errno;
 
@@ -121,27 +121,30 @@ int uv_tty_set_mode(uv_tty_t* tty, int mode) {
       orig_termios_fd = fd;
     }
     uv_spinlock_unlock(&termios_spinlock);
+  }
 
-    raw = tty->orig_termios;
-    raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
-    raw.c_oflag |= (ONLCR);
-    raw.c_cflag |= (CS8);
-    raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
-    raw.c_cc[VMIN] = 1;
-    raw.c_cc[VTIME] = 0;
-
-    /* Put terminal in raw mode after draining */
-    if (tcsetattr(fd, TCSADRAIN, &raw))
-      return -errno;
-
-    tty->mode = 1;
-  } else if (mode == 0 && tty->mode) {  /* off */
-    /* Put terminal in original mode after flushing */
-    if (tcsetattr(fd, TCSAFLUSH, &tty->orig_termios))
-      return -errno;
-    tty->mode = 0;
+  tmp = tty->orig_termios;
+  switch (mode) {
+    case UV_TTY_MODE_NORMAL:
+      break;
+    case UV_TTY_MODE_RAW:
+      tmp.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+      tmp.c_oflag |= (ONLCR);
+      tmp.c_cflag |= (CS8);
+      tmp.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+      tmp.c_cc[VMIN] = 1;
+      tmp.c_cc[VTIME] = 0;
+      break;
+    case UV_TTY_MODE_IO:
+      cfmakeraw(&tmp);
+      break;
   }
 
+  /* Apply changes after draining */
+  if (tcsetattr(fd, TCSADRAIN, &tmp))
+    return -errno;
+
+  tty->mode = mode;
   return 0;
 }
 
index 71a0e41f1f743e94c66e98763ab1958121662270..2e1824c358ae91af5b3573a01677afe48f10aa37 100644 (file)
@@ -598,7 +598,11 @@ int uv_udp_set_membership(uv_udp_t* handle,
 }
 
 
-static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
+static int uv__setsockopt_maybe_char(uv_udp_t* handle,
+                                     int option4,
+                                     int option6,
+                                     int val) {
+  int r;
 #if defined(__sun) || defined(_AIX)
   char arg = val;
 #else
@@ -608,7 +612,20 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
   if (val < 0 || val > 255)
     return -EINVAL;
 
-  if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, option, &arg, sizeof(arg)))
+  if (handle->flags & UV_HANDLE_IPV6)
+    r = setsockopt(handle->io_watcher.fd,
+                   IPPROTO_IPV6,
+                   option6,
+                   &arg,
+                   sizeof(arg));
+  else
+    r = setsockopt(handle->io_watcher.fd,
+                   IPPROTO_IP,
+                   option4,
+                   &arg,
+                   sizeof(arg));
+
+  if (r)
     return -errno;
 
   return 0;
@@ -632,20 +649,26 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
   if (ttl < 1 || ttl > 255)
     return -EINVAL;
 
-  if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)))
-    return -errno;
-
-  return 0;
+  return uv__setsockopt_maybe_char(handle,
+                                   IP_TTL,
+                                   IPV6_UNICAST_HOPS,
+                                   ttl);
 }
 
 
 int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
-  return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, ttl);
+  return uv__setsockopt_maybe_char(handle,
+                                   IP_MULTICAST_TTL,
+                                   IPV6_MULTICAST_HOPS,
+                                   ttl);
 }
 
 
 int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
-  return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, on);
+  return uv__setsockopt_maybe_char(handle,
+                                   IP_MULTICAST_LOOP,
+                                   IPV6_MULTICAST_LOOP,
+                                   on);
 }
 
 int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
index 7d3c58f1218501b72ae1de21e5bde6ecb3219b0b..11e7fc395c43ebb94eb914e877989192cc568d2c 100644 (file)
@@ -46,6 +46,9 @@
 #define container_of(ptr, type, member) \
   ((type *) ((char *) (ptr) - offsetof(type, member)))
 
+#define STATIC_ASSERT(expr)                                                   \
+  void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)])
+
 #ifndef _WIN32
 enum {
   UV__HANDLE_INTERNAL = 0x8000,
index 48897cf29bc735f5c78014c00fc0c57f96b03ce2..2bef8b7f332062504944675de1a328cd3c12ff72 100644 (file)
@@ -387,6 +387,7 @@ int uv_loop_alive(const uv_loop_t* loop) {
 int uv_run(uv_loop_t *loop, uv_run_mode mode) {
   DWORD timeout;
   int r;
+  int ran_pending;
   void (*poll)(uv_loop_t* loop, DWORD timeout);
 
   if (pGetQueuedCompletionStatusEx)
@@ -402,12 +403,12 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
     uv_update_time(loop);
     uv_process_timers(loop);
 
-    uv_process_reqs(loop);
+    ran_pending = uv_process_reqs(loop);
     uv_idle_invoke(loop);
     uv_prepare_invoke(loop);
 
     timeout = 0;
-    if ((mode & UV_RUN_NOWAIT) == 0)
+    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
       timeout = uv_backend_timeout(loop);
 
     (*poll)(loop, timeout);
@@ -428,7 +429,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
     }
 
     r = uv__loop_alive(loop);
-    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
       break;
   }
 
index 2ef1f6c54f2fa773a10aef160b0c3f3d8cc082d5..e5f3407f8eb27e65b3ea003966e735e99c518477 100644 (file)
@@ -69,17 +69,44 @@ const char* uv_dlerror(const uv_lib_t* lib) {
 }
 
 
+static void uv__format_fallback_error(uv_lib_t* lib, int errorno){
+  DWORD_PTR args[1] = { (DWORD_PTR) errorno };
+  LPSTR fallback_error = "error: %1!d!";
+
+  FormatMessageA(FORMAT_MESSAGE_FROM_STRING |
+                 FORMAT_MESSAGE_ARGUMENT_ARRAY |
+                 FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                 fallback_error, 0, 0,
+                 (LPSTR) &lib->errmsg,
+                 0, (va_list*) args);
+}
+
+
+
 static int uv__dlerror(uv_lib_t* lib, int errorno) {
+  DWORD res;
+
   if (lib->errmsg) {
     LocalFree((void*)lib->errmsg);
     lib->errmsg = NULL;
   }
 
   if (errorno) {
-    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
-                   FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
-                   MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
-                   (LPSTR)&lib->errmsg, 0, NULL);
+    res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                         FORMAT_MESSAGE_FROM_SYSTEM |
+                         FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+                         MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+                         (LPSTR) &lib->errmsg, 0, NULL);
+    if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
+      res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                           FORMAT_MESSAGE_FROM_SYSTEM |
+                           FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+                           0, (LPSTR) &lib->errmsg, 0, NULL);
+    }
+
+    if (!res) {
+      uv__format_fallback_error(lib, errorno);
+    }
   }
 
   return errorno ? -1 : 0;
index 30a457a023b4907cf9fcabcece463964d3c05c32..33bc9da304054fce5b9cfa07a822ab84227be6cc 100644 (file)
@@ -43,8 +43,6 @@
 #define UV_FS_FREE_PTR           0x0008
 #define UV_FS_CLEANEDUP          0x0010
 
-static const int uv__fs_dirent_slide = 0x20;
-
 
 #define QUEUE_FS_TP_JOB(loop, req)                                          \
   do {                                                                      \
@@ -788,123 +786,203 @@ void fs__mkdtemp(uv_fs_t* req) {
 
 
 void fs__scandir(uv_fs_t* req) {
-  WCHAR* pathw = req->pathw;
-  size_t len = wcslen(pathw);
-  int result;
-  WCHAR* name;
-  HANDLE dir;
-  WIN32_FIND_DATAW ent = { 0 };
-  WCHAR* path2;
-  const WCHAR* fmt;
-  uv__dirent_t** dents;
-  int dent_size;
-
-  if (len == 0) {
-    fmt = L"./*";
-  } else if (pathw[len - 1] == L'/' || pathw[len - 1] == L'\\') {
-    fmt = L"%s*";
-  } else {
-    fmt = L"%s\\*";
-  }
+  static const size_t dirents_initial_size = 32;
 
-  /* Figure out whether path is a file or a directory. */
-  if (!(GetFileAttributesW(pathw) & FILE_ATTRIBUTE_DIRECTORY)) {
-    req->result = UV_ENOTDIR;
-    req->sys_errno_ = ERROR_SUCCESS;
-    return;
-  }
-
-  path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4));
-  if (!path2) {
-    SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
-    return;
-  }
+  HANDLE dir_handle = INVALID_HANDLE_VALUE;
 
-  _snwprintf(path2, len + 3, fmt, pathw);
-  dir = FindFirstFileW(path2, &ent);
-  free(path2);
-
-  if(dir == INVALID_HANDLE_VALUE) {
-    SET_REQ_WIN32_ERROR(req, GetLastError());
-    return;
-  }
-
-  result = 0;
-  dents = NULL;
-  dent_size = 0;
-
-  do {
-    uv__dirent_t* dent;
-    int utf8_len;
-
-    name = ent.cFileName;
-
-    if (!(name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))))
-      continue;
+  uv__dirent_t** dirents = NULL;
+  size_t dirents_size = 0;
+  size_t dirents_used = 0;
 
-    /* Grow dents buffer, if needed */
-    if (result >= dent_size) {
-      uv__dirent_t** tmp;
+  IO_STATUS_BLOCK iosb;
+  NTSTATUS status;
 
-      dent_size += uv__fs_dirent_slide;
-      tmp = realloc(dents, dent_size * sizeof(*dents));
-      if (tmp == NULL) {
-        SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
-        goto fatal;
+  /* Buffer to hold directory entries returned by NtQueryDirectoryFile.
+   * It's important that this buffer can hold at least one entry, regardless
+   * of the length of the file names present in the enumerated directory.
+   * A file name is at most 256 WCHARs long.
+   * According to MSDN, the buffer must be aligned at an 8-byte boundary.
+   */
+  __declspec(align(8)) char buffer[8192];
+
+  STATIC_ASSERT(sizeof buffer >=
+                sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR));
+
+  /* Open the directory. */
+  dir_handle =
+      CreateFileW(req->pathw,
+                  FILE_LIST_DIRECTORY | SYNCHRONIZE,
+                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                  NULL,
+                  OPEN_EXISTING,
+                  FILE_FLAG_BACKUP_SEMANTICS,
+                  NULL);
+  if (dir_handle == INVALID_HANDLE_VALUE)
+    goto win32_error;
+
+  /* Read the first chunk. */
+  status = pNtQueryDirectoryFile(dir_handle,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &iosb,
+                                 &buffer,
+                                 sizeof buffer,
+                                 FileDirectoryInformation,
+                                 FALSE,
+                                 NULL,
+                                 TRUE);
+
+  /* If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER.
+   * This should be reported back as UV_ENOTDIR.
+   */
+  if (status == STATUS_INVALID_PARAMETER)
+    goto not_a_directory_error;
+
+  while (NT_SUCCESS(status)) {
+    char* position = buffer;
+    size_t next_entry_offset = 0;
+
+    do {
+      FILE_DIRECTORY_INFORMATION* info;
+      uv__dirent_t* dirent;
+
+      size_t wchar_len;
+      size_t utf8_len;
+
+      /* Obtain a pointer to the current directory entry. */
+      position += next_entry_offset;
+      info = (FILE_DIRECTORY_INFORMATION*) position;
+
+      /* Fetch the offset to the next directory entry. */
+      next_entry_offset = info->NextEntryOffset;
+
+      /* Compute the length of the filename in WCHARs. */
+      wchar_len = info->FileNameLength / sizeof info->FileName[0];
+
+      /* Skip over '.' and '..' entries. */
+      if (wchar_len == 1 && info->FileName[0] == L'.')
+        continue;
+      if (wchar_len == 2 && info->FileName[0] == L'.' &&
+          info->FileName[1] == L'.')
+        continue;
+
+      /* Compute the space required to store the filename as UTF-8. */
+      utf8_len = WideCharToMultiByte(
+          CP_UTF8, 0, &info->FileName[0], wchar_len, NULL, 0, NULL, NULL);
+      if (utf8_len == 0)
+        goto win32_error;
+
+      /* Resize the dirent array if needed. */
+      if (dirents_used >= dirents_size) {
+        size_t new_dirents_size =
+            dirents_size == 0 ? dirents_initial_size : dirents_size << 1;
+        uv__dirent_t** new_dirents =
+            realloc(dirents, new_dirents_size * sizeof *dirents);
+
+        if (new_dirents == NULL)
+          goto out_of_memory_error;
+
+        dirents_size = new_dirents_size;
+        dirents = new_dirents;
       }
-      dents = tmp;
-    }
-
-    /* Allocate enough space to fit utf8 encoding of file name */
-    len = wcslen(name);
-    utf8_len = uv_utf16_to_utf8(name, len, NULL, 0);
-    if (!utf8_len) {
-      SET_REQ_WIN32_ERROR(req, GetLastError());
-      goto fatal;
-    }
-
-    dent = malloc(sizeof(*dent) + utf8_len + 1);
-    if (dent == NULL) {
-      SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
-      goto fatal;
-    }
 
-    /* Copy file name */
-    utf8_len = uv_utf16_to_utf8(name, len, dent->d_name, utf8_len);
-    if (!utf8_len) {
-      free(dent);
-      SET_REQ_WIN32_ERROR(req, GetLastError());
-      goto fatal;
-    }
-    dent->d_name[utf8_len] = '\0';
-
-    /* Copy file type */
-    if ((ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
-      dent->d_type = UV__DT_DIR;
-    else if ((ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
-      dent->d_type = UV__DT_LINK;
-    else
-      dent->d_type = UV__DT_FILE;
+      /* Allocate space for the uv dirent structure. The dirent structure
+       * includes room for the first character of the filename, but `utf8_len`
+       * doesn't count the NULL terminator at this point.
+       */
+      dirent = malloc(sizeof *dirent + utf8_len);
+      if (dirent == NULL)
+        goto out_of_memory_error;
+
+      dirents[dirents_used++] = dirent;
+
+      /* Convert file name to UTF-8. */
+      if (WideCharToMultiByte(CP_UTF8,
+                              0,
+                              &info->FileName[0],
+                              wchar_len,
+                              &dirent->d_name[0],
+                              utf8_len,
+                              NULL,
+                              NULL) == 0)
+        goto win32_error;
+
+      /* Add a null terminator to the filename. */
+      dirent->d_name[utf8_len] = '\0';
+
+      /* Fill out the type field. */
+      if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE)
+        dirent->d_type = UV__DT_CHAR;
+      else if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+        dirent->d_type = UV__DT_LINK;
+      else if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        dirent->d_type = UV__DT_DIR;
+      else
+        dirent->d_type = UV__DT_FILE;
+    } while (next_entry_offset != 0);
+
+    /* Read the next chunk. */
+    status = pNtQueryDirectoryFile(dir_handle,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   &iosb,
+                                   &buffer,
+                                   sizeof buffer,
+                                   FileDirectoryInformation,
+                                   FALSE,
+                                   NULL,
+                                   FALSE);
+
+    /* After the first pNtQueryDirectoryFile call, the function may return
+     * STATUS_SUCCESS even if the buffer was too small to hold at least one
+     * directory entry.
+     */
+    if (status == STATUS_SUCCESS && iosb.Information == 0)
+      status = STATUS_BUFFER_OVERFLOW;
+  }
 
-    dents[result++] = dent;
-  } while(FindNextFileW(dir, &ent));
+  if (status != STATUS_NO_MORE_FILES)
+    goto nt_error;
 
-  FindClose(dir);
+  CloseHandle(dir_handle);
 
-  if (dents != NULL)
+  /* Store the result in the request object. */
+  req->ptr = dirents;
+  if (dirents != NULL)
     req->flags |= UV_FS_FREE_PTR;
 
-  /* NOTE: nbufs will be used as index */
+  SET_REQ_RESULT(req, dirents_used);
+
+  /* `nbufs` will be used as index by uv_fs_scandir_next. */
   req->nbufs = 0;
-  req->ptr = dents;
-  SET_REQ_RESULT(req, result);
+
   return;
 
-fatal:
-  /* Deallocate dents */
-  for (result--; result >= 0; result--)
-    free(dents[result]);
-  free(dents);
+nt_error:
+  SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+  goto cleanup;
+
+win32_error:
+  SET_REQ_WIN32_ERROR(req, GetLastError());
+  goto cleanup;
+
+not_a_directory_error:
+  SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY);
+  goto cleanup;
+
+out_of_memory_error:
+  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+  goto cleanup;
+
+cleanup:
+  if (dir_handle != INVALID_HANDLE_VALUE)
+    CloseHandle(dir_handle);
+  while (dirents_used > 0)
+    free(dirents[--dirents_used]);
+  if (dirents != NULL)
+    free(dirents);
 }
 
 
index d87402b73a095250fa314248e78d5dd00e097071..89290aea3277e0e31b8e434d711e4dc52f28bd0e 100644 (file)
@@ -364,8 +364,8 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
     int* addr_len, WSAOVERLAPPED *overlapped,
     LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
 
-int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
-    OVERLAPPED* overlapped);
+int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
+    AFD_POLL_INFO* info_out, OVERLAPPED* overlapped);
 
 /* Whether there are any non-IFS LSPs stacked on TCP */
 extern int uv_tcp_non_ifs_lsp_ipv4;
index 622cbabe399eb2e7662cfbbc806525f06f5ffead..578d9fff17fd7a47e9052c5d64031b404e74a134 100644 (file)
@@ -46,6 +46,8 @@ typedef struct uv_single_fd_set_s {
 static OVERLAPPED overlapped_dummy_;
 static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT;
 
+static AFD_POLL_INFO afd_poll_info_dummy_;
+
 
 static void uv__init_overlapped_dummy(void) {
   HANDLE event;
@@ -65,6 +67,11 @@ static OVERLAPPED* uv__get_overlapped_dummy() {
 }
 
 
+static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() {
+  return &afd_poll_info_dummy_;
+}
+
+
 static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
   uv_req_t* req;
   AFD_POLL_INFO* afd_poll_info;
@@ -79,7 +86,7 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
     handle->mask_events_2 = handle->events;
   } else if (handle->submitted_events_2 == 0) {
     req = &handle->poll_req_2;
-    afd_poll_info = &handle->afd_poll_info_2.afd_poll_info_ptr[0];
+    afd_poll_info = &handle->afd_poll_info_2;
     handle->submitted_events_2 = handle->events;
     handle->mask_events_1 = handle->events;
     handle->mask_events_2 = 0;
@@ -108,6 +115,7 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
   memset(&req->overlapped, 0, sizeof req->overlapped);
 
   result = uv_msafd_poll((SOCKET) handle->peer_socket,
+                         afd_poll_info,
                          afd_poll_info,
                          &req->overlapped);
   if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
@@ -119,26 +127,25 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
 
 
 static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
-  AFD_POLL_INFO* afd_poll_info;
+  AFD_POLL_INFO afd_poll_info;
   DWORD result;
 
-  afd_poll_info = &handle->afd_poll_info_2.afd_poll_info_ptr[1];
-  afd_poll_info->Exclusive = TRUE;
-  afd_poll_info->NumberOfHandles = 1;
-  afd_poll_info->Timeout.QuadPart = INT64_MAX;
-  afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket;
-  afd_poll_info->Handles[0].Status = 0;
-  afd_poll_info->Handles[0].Events = AFD_POLL_ALL;
+  afd_poll_info.Exclusive = TRUE;
+  afd_poll_info.NumberOfHandles = 1;
+  afd_poll_info.Timeout.QuadPart = INT64_MAX;
+  afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
+  afd_poll_info.Handles[0].Status = 0;
+  afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
 
   result = uv_msafd_poll(handle->socket,
-                         afd_poll_info,
+                         &afd_poll_info,
+                         uv__get_afd_poll_info_dummy(),
                          uv__get_overlapped_dummy());
 
   if (result == SOCKET_ERROR) {
     DWORD error = WSAGetLastError();
-    if (error != WSA_IO_PENDING) {
-      return WSAGetLastError();
-    }
+    if (error != WSA_IO_PENDING)
+      return error;
   }
 
   return 0;
@@ -155,7 +162,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
     handle->submitted_events_1 = 0;
     mask_events = handle->mask_events_1;
   } else if (req == &handle->poll_req_2) {
-    afd_poll_info = &handle->afd_poll_info_2.afd_poll_info_ptr[0];
+    afd_poll_info = &handle->afd_poll_info_2;
     handle->submitted_events_2 = 0;
     mask_events = handle->mask_events_2;
   } else {
@@ -558,11 +565,6 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
   handle->poll_req_2.type = UV_POLL_REQ;
   handle->poll_req_2.data = handle;
 
-  handle->afd_poll_info_2.afd_poll_info_ptr = malloc(sizeof(*handle->afd_poll_info_2.afd_poll_info_ptr) * 2);
-  if (handle->afd_poll_info_2.afd_poll_info_ptr == NULL) {
-    return UV_ENOMEM;
-  }
-
   return 0;
 }
 
@@ -624,9 +626,5 @@ void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
   assert(handle->submitted_events_1 == 0);
   assert(handle->submitted_events_2 == 0);
 
-  if (handle->afd_poll_info_2.afd_poll_info_ptr) {
-    free(handle->afd_poll_info_2.afd_poll_info_ptr);
-    handle->afd_poll_info_2.afd_poll_info_ptr = NULL;
-  }
   uv__handle_close(handle);
 }
index 97342e5c7e001730fbd518cd267df6c0f478c789..46c7d9b106a869477f56f1946b0cf2fab8766886 100644 (file)
@@ -130,14 +130,13 @@ INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
   } while (0)
 
 
-INLINE static void uv_process_reqs(uv_loop_t* loop) {
+INLINE static int uv_process_reqs(uv_loop_t* loop) {
   uv_req_t* req;
   uv_req_t* first;
   uv_req_t* next;
 
-  if (loop->pending_reqs_tail == NULL) {
-    return;
-  }
+  if (loop->pending_reqs_tail == NULL)
+    return 0;
 
   first = loop->pending_reqs_tail->next_req;
   next = first;
@@ -207,6 +206,8 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) {
         assert(0);
     }
   }
+
+  return 1;
 }
 
 #endif /* UV_WIN_REQ_INL_H_ */
index a697d7ae74456bf740e478320677b6d385566d2b..993d66162c40fa9e8f9850197f76e577f3d9f72e 100644 (file)
@@ -117,7 +117,19 @@ void uv_once(uv_once_t* guard, void (*callback)(void)) {
   uv__once_inner(guard, callback);
 }
 
-static UV_THREAD_LOCAL uv_thread_t uv__current_thread = NULL;
+
+/* Verify that uv_thread_t can be stored in a TLS slot. */
+STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*));
+
+static uv_key_t uv__current_thread_key;
+static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT;
+
+
+static void uv__init_current_thread_key(void) {
+  if (uv_key_create(&uv__current_thread_key))
+    abort();
+}
+
 
 struct thread_ctx {
   void (*entry)(void* arg);
@@ -126,8 +138,7 @@ struct thread_ctx {
 };
 
 
-static UINT __stdcall uv__thread_start(void* arg)
-{
+static UINT __stdcall uv__thread_start(void* arg) {
   struct thread_ctx *ctx_p;
   struct thread_ctx ctx;
 
@@ -135,7 +146,9 @@ static UINT __stdcall uv__thread_start(void* arg)
   ctx = *ctx_p;
   free(ctx_p);
 
-  uv__current_thread = ctx.self;
+  uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
+  uv_key_set(&uv__current_thread_key, (void*) ctx.self);
+
   ctx.entry(ctx.arg);
 
   return 0;
@@ -177,9 +190,10 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
 
 
 uv_thread_t uv_thread_self(void) {
-  return uv__current_thread;
+  return (uv_thread_t) uv_key_get(&uv__current_thread_key);
 }
 
+
 int uv_thread_join(uv_thread_t *tid) {
   if (WaitForSingleObject(*tid, INFINITE))
     return uv_translate_sys_error(GetLastError());
index 6d6709f79e1170ad462128c67fcf865df07f7f2f..be4a8b81e40de2696a3319a1ea0378125dacbe51 100644 (file)
@@ -170,7 +170,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
 }
 
 
-int uv_tty_set_mode(uv_tty_t* tty, int mode) {
+int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
   DWORD flags;
   unsigned char was_reading;
   uv_alloc_cb alloc_cb;
@@ -185,12 +185,15 @@ int uv_tty_set_mode(uv_tty_t* tty, int mode) {
     return 0;
   }
 
-  if (mode) {
-    /* Raw input */
-    flags = ENABLE_WINDOW_INPUT;
-  } else {
-    /* Line-buffered mode. */
-    flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+  switch (mode) {
+    case UV_TTY_MODE_NORMAL:
+      flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+      break;
+    case UV_TTY_MODE_RAW:
+      flags = ENABLE_WINDOW_INPUT;
+      break;
+    case UV_TTY_MODE_IO:
+      return UV_ENOTSUP;
   }
 
   if (!SetConsoleMode(tty->handle, flags)) {
index 84ce73e3a023b670686e4fb0d4c686108cb57291..f3f27f77c15a4ee6919bc04528fe64df1628f8b6 100644 (file)
@@ -31,6 +31,7 @@ sNtDeviceIoControlFile pNtDeviceIoControlFile;
 sNtQueryInformationFile pNtQueryInformationFile;
 sNtSetInformationFile pNtSetInformationFile;
 sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+sNtQueryDirectoryFile pNtQueryDirectoryFile;
 sNtQuerySystemInformation pNtQuerySystemInformation;
 
 
@@ -97,6 +98,12 @@ void uv_winapi_init() {
     uv_fatal_error(GetLastError(), "GetProcAddress");
   }
 
+  pNtQueryDirectoryFile = (sNtQueryDirectoryFile)
+      GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
+  if (pNtQueryVolumeInformationFile == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
   pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
       ntdll_module,
       "NtQuerySystemInformation");
index 1bb0e9aae1eed9d4d17274e5294e1559bdac33d0..f4f9145b388f008061441ae9f4f115adad468cef 100644 (file)
 # define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE          0x00002000
 #endif
 
+/* from winternl.h */
+typedef struct _UNICODE_STRING {
+  USHORT Length;
+  USHORT MaximumLength;
+  PWSTR  Buffer;
+} UNICODE_STRING, *PUNICODE_STRING;
+
+typedef const UNICODE_STRING *PCUNICODE_STRING;
+
+/* from ntifs.h */
 #ifndef DEVICE_TYPE
 # define DEVICE_TYPE DWORD
 #endif
 
-/* from ntifs.h */
-/* MinGW already has it, mingw-w64 does not. */
+/* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does
+ * not.
+ */
 #if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
   typedef struct _REPARSE_DATA_BUFFER {
     ULONG  ReparseTag;
@@ -4205,6 +4216,37 @@ typedef enum _FILE_INFORMATION_CLASS {
   FileMaximumInformation
 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
 
+typedef struct _FILE_DIRECTORY_INFORMATION {
+  ULONG NextEntryOffset;
+  ULONG FileIndex;
+  LARGE_INTEGER CreationTime;
+  LARGE_INTEGER LastAccessTime;
+  LARGE_INTEGER LastWriteTime;
+  LARGE_INTEGER ChangeTime;
+  LARGE_INTEGER EndOfFile;
+  LARGE_INTEGER AllocationSize;
+  ULONG FileAttributes;
+  ULONG FileNameLength;
+  WCHAR FileName[1];
+} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
+
+typedef struct _FILE_BOTH_DIR_INFORMATION {
+  ULONG NextEntryOffset;
+  ULONG FileIndex;
+  LARGE_INTEGER CreationTime;
+  LARGE_INTEGER LastAccessTime;
+  LARGE_INTEGER LastWriteTime;
+  LARGE_INTEGER ChangeTime;
+  LARGE_INTEGER EndOfFile;
+  LARGE_INTEGER AllocationSize;
+  ULONG FileAttributes;
+  ULONG FileNameLength;
+  ULONG EaSize;
+  CCHAR ShortNameLength;
+  WCHAR ShortName[12];
+  WCHAR FileName[1];
+} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
+
 typedef struct _FILE_BASIC_INFORMATION {
   LARGE_INTEGER CreationTime;
   LARGE_INTEGER LastAccessTime;
@@ -4512,6 +4554,19 @@ typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
                   ULONG SystemInformationLength,
                   PULONG ReturnLength);
 
+typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile)
+                 (HANDLE FileHandle,
+                  HANDLE Event,
+                  PIO_APC_ROUTINE ApcRoutine,
+                  PVOID ApcContext,
+                  PIO_STATUS_BLOCK IoStatusBlock,
+                  PVOID FileInformation,
+                  ULONG Length,
+                  FILE_INFORMATION_CLASS FileInformationClass,
+                  BOOLEAN ReturnSingleEntry,
+                  PUNICODE_STRING FileName,
+                  BOOLEAN RestartScan
+                );
 
 /*
  * Kernel32 headers
@@ -4555,6 +4610,30 @@ typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
 # define ERROR_SYMLINK_NOT_SUPPORTED 1464
 #endif
 
+#ifndef ERROR_MUI_FILE_NOT_FOUND
+# define ERROR_MUI_FILE_NOT_FOUND 15100
+#endif
+
+#ifndef ERROR_MUI_INVALID_FILE
+# define ERROR_MUI_INVALID_FILE 15101
+#endif
+
+#ifndef ERROR_MUI_INVALID_RC_CONFIG
+# define ERROR_MUI_INVALID_RC_CONFIG 15102
+#endif
+
+#ifndef ERROR_MUI_INVALID_LOCALE_NAME
+# define ERROR_MUI_INVALID_LOCALE_NAME 15103
+#endif
+
+#ifndef ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME
+# define ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME 15104
+#endif
+
+#ifndef ERROR_MUI_FILE_NOT_LOADED
+# define ERROR_MUI_FILE_NOT_LOADED 15105
+#endif
+
 typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx)
              (HANDLE CompletionPort,
               LPOVERLAPPED_ENTRY lpCompletionPortEntries,
@@ -4626,6 +4705,7 @@ extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
 extern sNtQueryInformationFile pNtQueryInformationFile;
 extern sNtSetInformationFile pNtSetInformationFile;
 extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
 extern sNtQuerySystemInformation pNtQuerySystemInformation;
 
 
index 3711ee9cb6735a87932ebf05639b3feae6e0d9b2..d2e667e9f7546ae5d464e6e2c71127463d04efc7 100644 (file)
@@ -474,8 +474,8 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
 }
 
 
-int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
-    OVERLAPPED* overlapped) {
+int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
+    AFD_POLL_INFO* info_out, OVERLAPPED* overlapped) {
   IO_STATUS_BLOCK iosb;
   IO_STATUS_BLOCK* iosb_ptr;
   HANDLE event = NULL;
@@ -513,10 +513,10 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
                                   apc_context,
                                   iosb_ptr,
                                   IOCTL_AFD_POLL,
-                                  info,
-                                  sizeof *info,
-                                  info,
-                                  sizeof *info);
+                                  info_in,
+                                  sizeof *info_in,
+                                  info_out,
+                                  sizeof *info_out);
 
   if (overlapped == NULL) {
     /* If this is a blocking operation, wait for the event to become */
index 1f12c6f12d91b01cbb44d7989d788c62fe2857e8..5da720fad43a9db7d89fb8fca6ea3c47e1548297 100644 (file)
@@ -68,6 +68,7 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
   const char* arg;
   char* args[16];
   int n;
+  pid_t pid;
 
   stdout_file = tmpfile();
   if (!stdout_file) {
@@ -78,7 +79,7 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
   p->terminated = 0;
   p->status = 0;
 
-  pid_t pid = fork();
+  pid = fork();
 
   if (pid < 0) {
     perror("fork");
@@ -167,8 +168,14 @@ static void* dowait(void* data) {
 /* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */
 int process_wait(process_info_t* vec, int n, int timeout) {
   int i;
+  int r;
+  int retval;
   process_info_t* p;
   dowait_args args;
+  pthread_t tid;
+  struct timeval tv;
+  fd_set fds;
+
   args.vec = vec;
   args.n = n;
   args.pipe[0] = -1;
@@ -186,10 +193,7 @@ int process_wait(process_info_t* vec, int n, int timeout) {
    * we'd need to lock vec.
    */
 
-  pthread_t tid;
-  int retval;
-
-  int r = pipe((int*)&(args.pipe));
+  r = pipe((int*)&(args.pipe));
   if (r) {
     perror("pipe()");
     return -1;
@@ -202,11 +206,9 @@ int process_wait(process_info_t* vec, int n, int timeout) {
     goto terminate;
   }
 
-  struct timeval tv;
   tv.tv_sec = timeout / 1000;
   tv.tv_usec = 0;
 
-  fd_set fds;
   FD_ZERO(&fds);
   FD_SET(args.pipe[0], &fds);
 
@@ -259,15 +261,16 @@ long int process_output_size(process_info_t *p) {
 
 /* Copy the contents of the stdio output buffer to `fd`. */
 int process_copy_output(process_info_t *p, int fd) {
-  int r = fseek(p->stdout_file, 0, SEEK_SET);
+  ssize_t nwritten;
+  char buf[1024];
+  int r;
+
+  r = fseek(p->stdout_file, 0, SEEK_SET);
   if (r < 0) {
     perror("fseek");
     return -1;
   }
 
-  ssize_t nwritten;
-  char buf[1024];
-
   /* TODO: what if the line is longer than buf */
   while (fgets(buf, sizeof(buf), p->stdout_file) != NULL) {
    /* TODO: what if write doesn't write the whole buffer... */
index e890c77fe177d5da303b9ab70c38cfddbb5a7b9e..07584c52996f8c95d51e7da31b08cf7e6349ace2 100644 (file)
 # include <sys/resource.h>  /* setrlimit() */
 #endif
 
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+#endif
+
 #define TEST_PORT 9123
 #define TEST_PORT_2 9124
 
@@ -229,4 +234,21 @@ UNUSED static void close_loop(uv_loop_t* loop) {
   uv_run(loop, UV_RUN_DEFAULT);
 }
 
+UNUSED static int can_ipv6(void) {
+  uv_interface_address_t* addr;
+  int supported;
+  int count;
+  int i;
+
+  if (uv_interface_addresses(&addr, &count))
+    return 1;  /* Assume IPv6 support on failure. */
+
+  supported = 0;
+  for (i = 0; supported == 0 && i < count; i += 1)
+    supported = (AF_INET6 == addr[i].address.address6.sin6_family);
+
+  uv_free_interface_addresses(addr, count);
+  return supported;
+}
+
 #endif /* TASK_H_ */
index 6f6173192dbb3c79a7dd6d8a3440ed52dd9a561d..1e95043c1775a90035d6591e5832994a8ed565e9 100644 (file)
@@ -29,35 +29,22 @@ extern char executable_path[];
 TEST_IMPL(cwd_and_chdir) {
   char buffer_orig[PATHMAX];
   char buffer_new[PATHMAX];
-  size_t size;
-  char* last_slash;
+  size_t size1;
+  size_t size2;
   int err;
 
-  size = sizeof(buffer_orig);
-  err = uv_cwd(buffer_orig, &size);
+  size1 = sizeof buffer_orig;
+  err = uv_cwd(buffer_orig, &size1);
   ASSERT(err == 0);
 
-  /* Remove trailing slash unless at a root directory. */
-#ifdef _WIN32
-  last_slash = strrchr(buffer_orig, '\\');
-  ASSERT(last_slash);
-  if (last_slash > buffer_orig && *(last_slash - 1) != ':') {
-    *last_slash = '\0';
-  }
-#else /* Unix */
-  last_slash = strrchr(buffer_orig, '/');
-  ASSERT(last_slash);
-  if (last_slash != buffer_orig) {
-    *last_slash = '\0';
-  }
-#endif
-
   err = uv_chdir(buffer_orig);
   ASSERT(err == 0);
 
-  err = uv_cwd(buffer_new, &size);
+  size2 = sizeof buffer_new;
+  err = uv_cwd(buffer_new, &size2);
   ASSERT(err == 0);
 
+  ASSERT(size1 == size2);
   ASSERT(strcmp(buffer_orig, buffer_new) == 0);
 
   return 0;
index 877ebf3712a213454c3b9fe88ba1c9cf1e7fd689..091200edbed5914293fe2d59335c6ca9ea58df7d 100644 (file)
 
 TEST_IMPL(dlerror) {
   const char* path = "test/fixtures/load_error.node";
+  const char* dlerror_no_error = "no error";
   const char* msg;
   uv_lib_t lib;
   int r;
 
-#ifdef __linux__
-  const char* dlerror_desc = "file too short";
-#elif defined (__sun__)
-  const char* dlerror_desc = "unknown file type";
-#elif defined (_WIN32)
-  const char* dlerror_desc = "%1 is not a valid Win32 application";
-#else
-  const char* dlerror_desc = "";
-#endif
+  lib.errmsg = NULL;
+  lib.handle = NULL;
+  msg = uv_dlerror(&lib);
+  ASSERT(msg != NULL);
+  ASSERT(strstr(msg, dlerror_no_error) != NULL);
 
   r = uv_dlopen(path, &lib);
   ASSERT(r == -1);
 
   msg = uv_dlerror(&lib);
   ASSERT(msg != NULL);
-  ASSERT(strstr(msg, dlerror_desc) != NULL);
+  ASSERT(strstr(msg, dlerror_no_error) == NULL);
 
   /* Should return the same error twice in a row. */
   msg = uv_dlerror(&lib);
   ASSERT(msg != NULL);
-  ASSERT(strstr(msg, dlerror_desc) != NULL);
+  ASSERT(strstr(msg, dlerror_no_error) == NULL);
 
   uv_dlclose(&lib);
 
index 471860a76c4c0e73a2297b73784687e058642bbc..2c392251f03ce5a805b9ad49036f3bacf075fe69 100644 (file)
@@ -568,7 +568,17 @@ TEST_IMPL(fs_file_loop) {
   loop = uv_default_loop();
 
   unlink("test_symlink");
-  uv_fs_symlink(loop, &req, "test_symlink", "test_symlink", 0, NULL);
+  r = uv_fs_symlink(loop, &req, "test_symlink", "test_symlink", 0, NULL);
+#ifdef _WIN32
+  /*
+   * Windows XP and Server 2003 don't support symlinks; we'll get UV_ENOTSUP.
+   * Starting with vista they are supported, but only when elevated, otherwise
+   * we'll see UV_EPERM.
+   */
+  if (r == UV_ENOTSUP || r == UV_EPERM)
+    return 0;
+#endif
+  ASSERT(r == 0);
   uv_fs_req_cleanup(&req);
 
   r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, NULL);
index be578db75d48bf6cedb22fe18973bfedbe5cc059..0e9d6965402daf4dae0de54ab57041292b2b5354 100644 (file)
@@ -61,5 +61,26 @@ TEST_IMPL(get_currentexe) {
   r = uv_exepath(buffer, NULL);
   ASSERT(r == UV_EINVAL);
 
+  size = 0;
+  r = uv_exepath(buffer, &size);
+  ASSERT(r == UV_EINVAL);
+
+  memset(buffer, -1, sizeof(buffer));
+
+  size = 1;
+  r = uv_exepath(buffer, &size);
+  ASSERT(r == 0);
+  ASSERT(size == 0);
+  ASSERT(buffer[0] == '\0');
+
+  memset(buffer, -1, sizeof(buffer));
+
+  size = 2;
+  r = uv_exepath(buffer, &size);
+  ASSERT(r == 0);
+  ASSERT(size == 1);
+  ASSERT(buffer[0] != '\0');
+  ASSERT(buffer[1] == '\0');
+
   return 0;
 }
index 85ddac82ae123a01d023ce8603402fa8d3bdc01e..eb78a43cc79787c42be22f820739857c0e52d766 100644 (file)
@@ -29,6 +29,7 @@ TEST_DECLARE   (loop_close)
 TEST_DECLARE   (loop_stop)
 TEST_DECLARE   (loop_update_time)
 TEST_DECLARE   (loop_backend_timeout)
+TEST_DECLARE   (loop_configure)
 TEST_DECLARE   (default_loop_close)
 TEST_DECLARE   (barrier_1)
 TEST_DECLARE   (barrier_2)
@@ -103,6 +104,7 @@ TEST_DECLARE   (udp_dgram_too_big)
 TEST_DECLARE   (udp_dual_stack)
 TEST_DECLARE   (udp_ipv6_only)
 TEST_DECLARE   (udp_options)
+TEST_DECLARE   (udp_options6)
 TEST_DECLARE   (udp_no_autobind)
 TEST_DECLARE   (udp_open)
 TEST_DECLARE   (udp_try_send)
@@ -269,6 +271,7 @@ TEST_DECLARE   (ip4_addr)
 TEST_DECLARE   (ip6_addr_link_local)
 
 #ifdef _WIN32
+TEST_DECLARE   (poll_close_doesnt_corrupt_stack)
 TEST_DECLARE   (poll_closesocket)
 TEST_DECLARE   (spawn_detect_pipe_name_collisions_on_windows)
 TEST_DECLARE   (argument_escaping)
@@ -312,6 +315,7 @@ TASK_LIST_START
   TEST_ENTRY  (loop_stop)
   TEST_ENTRY  (loop_update_time)
   TEST_ENTRY  (loop_backend_timeout)
+  TEST_ENTRY  (loop_configure)
   TEST_ENTRY  (default_loop_close)
   TEST_ENTRY  (barrier_1)
   TEST_ENTRY  (barrier_2)
@@ -410,6 +414,7 @@ TASK_LIST_START
   TEST_ENTRY  (udp_dual_stack)
   TEST_ENTRY  (udp_ipv6_only)
   TEST_ENTRY  (udp_options)
+  TEST_ENTRY  (udp_options6)
   TEST_ENTRY  (udp_no_autobind)
   TEST_ENTRY  (udp_multicast_interface)
   TEST_ENTRY  (udp_multicast_interface6)
@@ -558,6 +563,7 @@ TASK_LIST_START
   TEST_ENTRY  (kill)
 
 #ifdef _WIN32
+  TEST_ENTRY  (poll_close_doesnt_corrupt_stack)
   TEST_ENTRY  (poll_closesocket)
   TEST_ENTRY  (spawn_detect_pipe_name_collisions_on_windows)
   TEST_ENTRY  (argument_escaping)
diff --git a/deps/uv/test/test-loop-configure.c b/deps/uv/test/test-loop-configure.c
new file mode 100644 (file)
index 0000000..d057c1e
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (c) 2014, Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static void timer_cb(uv_timer_t* handle) {
+  uv_close((uv_handle_t*) handle, NULL);
+}
+
+
+TEST_IMPL(loop_configure) {
+  uv_timer_t timer_handle;
+  uv_loop_t loop;
+  ASSERT(0 == uv_loop_init(&loop));
+#ifdef _WIN32
+  ASSERT(UV_ENOSYS == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, 0));
+#else
+  ASSERT(0 == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF));
+#endif
+  ASSERT(0 == uv_timer_init(&loop, &timer_handle));
+  ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 10, 0));
+  ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
+  ASSERT(0 == uv_loop_close(&loop));
+  return 0;
+}
index 49b1bb8229aeb8bcef1c03354a30815ae59de247..ef551eaf2fcc8dec995e984e1e3dd67f3ecae883 100644 (file)
@@ -90,7 +90,7 @@ TEST_IMPL(osx_select_many_fds) {
   uv_tty_t tty;
   uv_tcp_t tcps[1500];
 
-  TEST_FILE_LIMIT(ARRAY_SIZE(tcps) + 2);
+  TEST_FILE_LIMIT(ARRAY_SIZE(tcps) + 100);
 
   r = uv_ip4_addr("127.0.0.1", 0, &addr);
   ASSERT(r == 0);
index 81941ab83db3b6dbd42cb664f8e812f95bae457a..c074178541b0a36c4a1d474463bea4f264dc2a3d 100644 (file)
@@ -246,6 +246,9 @@ TEST_IMPL(tcp_ping_pong) {
 
 
 TEST_IMPL(tcp_ping_pong_v6) {
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   tcp_pinger_v6_new();
   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
 
index 3064babf98c05f3c7061e3d472dd7c2f7a5cbf9b..ee8bb2a9a8bc383c04df379f6422a2a0093be452 100644 (file)
@@ -53,6 +53,7 @@ TEST_IMPL(pipe_close_stdout_read_stdin) {
   int pid;
   int fd[2];
   int status;
+  uv_pipe_t stdin_pipe;
 
   r = pipe(fd);
   ASSERT(r == 0);
@@ -68,8 +69,6 @@ TEST_IMPL(pipe_close_stdout_read_stdin) {
     ASSERT(r != -1);
 
     /* Create a stream that reads from the pipe. */
-    uv_pipe_t stdin_pipe;
-
     r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0);
     ASSERT(r == 0);
 
index 931311985bbdf7e10ed331c967d42d831c02a33e..dc6fa32b0d115fd9ed5edb243561750cf8e16fcf 100644 (file)
@@ -27,6 +27,7 @@
 TEST_IMPL(platform_output) {
   char buffer[512];
   size_t rss;
+  size_t size;
   double uptime;
   uv_rusage_t rusage;
   uv_cpu_info_t* cpus;
@@ -39,6 +40,11 @@ TEST_IMPL(platform_output) {
   ASSERT(err == 0);
   printf("uv_get_process_title: %s\n", buffer);
 
+  size = sizeof(buffer);
+  err = uv_cwd(buffer, &size);
+  ASSERT(err == 0);
+  printf("uv_cwd: %s\n", buffer);
+
   err = uv_resident_set_memory(&rss);
   ASSERT(err == 0);
   printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss);
diff --git a/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c b/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c
new file mode 100644 (file)
index 0000000..fc2cc00
--- /dev/null
@@ -0,0 +1,114 @@
+/* Copyright Bert Belder, and other libuv contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifdef _WIN32
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "uv.h"
+#include "task.h"
+
+#ifdef _MSC_VER  /* msvc */
+# define NO_INLINE __declspec(noinline)
+#else  /* gcc */
+# define NO_INLINE __attribute__ ((noinline))
+#endif
+
+
+uv_os_sock_t sock;
+uv_poll_t handle;
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* h) {
+  close_cb_called++;
+}
+
+
+static void poll_cb(uv_poll_t* h, int status, int events) {
+  ASSERT(0 && "should never get here");
+}
+
+
+static void NO_INLINE close_socket_and_verify_stack() {
+  const uint32_t MARKER = 0xDEADBEEF;
+  const int VERIFY_AFTER = 10; /* ms */
+  int r;
+
+  volatile uint32_t data[65536];
+  size_t i;
+
+  for (i = 0; i < ARRAY_SIZE(data); i++)
+    data[i] = MARKER;
+
+  r = closesocket(sock);
+  ASSERT(r == 0);
+
+  uv_sleep(VERIFY_AFTER);
+
+  for (i = 0; i < ARRAY_SIZE(data); i++)
+    ASSERT(data[i] == MARKER);
+}
+
+
+TEST_IMPL(poll_close_doesnt_corrupt_stack) {
+  struct WSAData wsa_data;
+  int r;
+  unsigned long on;
+  struct sockaddr_in addr;
+
+  r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+  ASSERT(r == 0);
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  ASSERT(sock != INVALID_SOCKET);
+  on = 1;
+  r = ioctlsocket(sock, FIONBIO, &on);
+  ASSERT(r == 0);
+
+  r = uv_ip4_addr("127.0.0.1", TEST_PORT, &addr);
+  ASSERT(r == 0);
+
+  r = connect(sock, (const struct sockaddr*) &addr, sizeof addr);
+  ASSERT(r != 0);
+  ASSERT(WSAGetLastError() == WSAEWOULDBLOCK);
+
+  r = uv_poll_init_socket(uv_default_loop(), &handle, sock);
+  ASSERT(r == 0);
+  r = uv_poll_start(&handle, UV_READABLE | UV_WRITABLE, poll_cb);
+  ASSERT(r == 0);
+
+  uv_close((uv_handle_t*) &handle, close_cb);
+
+  close_socket_and_verify_stack();
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  ASSERT(r == 0);
+
+  ASSERT(close_cb_called == 1);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+#endif  /* _WIN32 */
index 11f43bdf1341a756a62dac7db8ab8404ee52ca3b..5c25f81926b6e652ed4a2e722dc1812c4b15211f 100644 (file)
@@ -1032,6 +1032,7 @@ TEST_IMPL(spawn_with_an_odd_path) {
 #ifndef _WIN32
 TEST_IMPL(spawn_setuid_setgid) {
   int r;
+  struct passwd* pw;
 
   /* if not root, then this will fail. */
   uv_uid_t uid = getuid();
@@ -1043,7 +1044,6 @@ TEST_IMPL(spawn_setuid_setgid) {
   init_process_options("spawn_helper1", exit_cb);
 
   /* become the "nobody" user. */
-  struct passwd* pw;
   pw = getpwnam("nobody");
   ASSERT(pw != NULL);
   options.uid = pw->pw_uid;
@@ -1051,6 +1051,9 @@ TEST_IMPL(spawn_setuid_setgid) {
   options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID;
 
   r = uv_spawn(uv_default_loop(), &process, &options);
+  if (r == UV_EACCES)
+    RETURN_SKIP("user 'nobody' cannot access the test runner");
+
   ASSERT(r == 0);
 
   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
@@ -1297,7 +1300,16 @@ TEST_IMPL(spawn_reads_child_path) {
   int len;
   char file[64];
   char path[1024];
-  char *env[2] = {path, NULL};
+  char* env[3];
+
+  /* Need to carry over the dynamic linker path when the test runner is
+   * linked against libuv.so, see https://github.com/libuv/libuv/issues/85.
+   */
+#if defined(__APPLE__)
+  static const char dyld_path_var[] = "DYLD_LIBRARY_PATH";
+#else
+  static const char dyld_path_var[] = "LD_LIBRARY_PATH";
+#endif
 
   /* Set up the process, but make sure that the file to run is relative and */
   /* requires a lookup into PATH */
@@ -1312,6 +1324,16 @@ TEST_IMPL(spawn_reads_child_path) {
   strcpy(path, "PATH=");
   strcpy(path + 5, exepath);
 
+  env[0] = path;
+  env[1] = getenv(dyld_path_var);
+  env[2] = NULL;
+
+  if (env[1] != NULL) {
+    static char buf[1024 + sizeof(dyld_path_var)];
+    snprintf(buf, sizeof(buf), "%s=%s", dyld_path_var, env[1]);
+    env[1] = buf;
+  }
+
   options.file = file;
   options.args[0] = file;
   options.env = env;
index 1d65f3de3e6eecfa9c00cf9d1116a596e81c6894..b762bcb3d1b8d087abb712cf0f138a1f39729123 100644 (file)
@@ -39,6 +39,9 @@ TEST_IMPL(tcp_bind6_error_addrinuse) {
   uv_tcp_t server1, server2;
   int r;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr));
 
   r = uv_tcp_init(uv_default_loop(), &server1);
@@ -73,6 +76,9 @@ TEST_IMPL(tcp_bind6_error_addrnotavail) {
   uv_tcp_t server;
   int r;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   ASSERT(0 == uv_ip6_addr("4:4:4:4:4:4:4:4", TEST_PORT, &addr));
 
   r = uv_tcp_init(uv_default_loop(), &server);
@@ -98,6 +104,9 @@ TEST_IMPL(tcp_bind6_error_fault) {
   uv_tcp_t server;
   int r;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   garbage_addr = (struct sockaddr_in6*) &garbage;
 
   r = uv_tcp_init(uv_default_loop(), &server);
@@ -123,6 +132,9 @@ TEST_IMPL(tcp_bind6_error_inval) {
   uv_tcp_t server;
   int r;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr1));
   ASSERT(0 == uv_ip6_addr("::", TEST_PORT_2, &addr2));
 
@@ -149,6 +161,9 @@ TEST_IMPL(tcp_bind6_localhost_ok) {
   uv_tcp_t server;
   int r;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
 
   r = uv_tcp_init(uv_default_loop(), &server);
index 0ca9f4dcff6a6eddcd9ef4868d5f1f353b07fc7f..1d5720ce73162aeaa84817a565eb2f42b1006961 100644 (file)
@@ -147,23 +147,22 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) {
 
 
 TEST_IMPL(udp_dual_stack) {
-#if defined(__DragonFly__)  || \
-    defined(__FreeBSD__)    || \
-    defined(__OpenBSD__)    || \
-    defined(__NetBSD__)
-  RETURN_SKIP("dual stack not enabled by default in this OS.");
-#else
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   do_test(ipv6_recv_ok, 0);
 
   ASSERT(recv_cb_called == 1);
   ASSERT(send_cb_called == 1);
 
   return 0;
-#endif
 }
 
 
 TEST_IMPL(udp_ipv6_only) {
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   do_test(ipv6_recv_fail, UV_UDP_IPV6ONLY);
 
   ASSERT(recv_cb_called == 0);
index e54e738b0be301b312ee185e8b02d70157de1e08..d3881e83bb1565cd3e5c619a17044259af9e08bb 100644 (file)
@@ -60,6 +60,9 @@ TEST_IMPL(udp_multicast_interface6) {
   struct sockaddr_in6 addr;
   struct sockaddr_in6 baddr;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
index babf61e2bf7dc3b6c4c17fd66cf6dab2bac0fddb..9ba201ab9eba985b778d386aa3f70eaf9c3442b4 100644 (file)
@@ -103,6 +103,9 @@ TEST_IMPL(udp_multicast_join6) {
   uv_buf_t buf;
   struct sockaddr_in6 addr;
 
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
   ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
index 19c45c2e31976d4b339b38a856438d5dc5cffbca..0da1786f506fc4bb29e5250d466cc0270053ff75 100644 (file)
 #include <string.h>
 
 
-TEST_IMPL(udp_options) {
+static int udp_options_test(const struct sockaddr* addr) {
   static int invalid_ttls[] = { -1, 0, 256 };
-  struct sockaddr_in addr;
   uv_loop_t* loop;
   uv_udp_t h;
   int i, r;
 
-  ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
-
   loop = uv_default_loop();
 
   r = uv_udp_init(loop, &h);
@@ -43,7 +40,7 @@ TEST_IMPL(udp_options) {
 
   uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */
 
-  r = uv_udp_bind(&h, (const struct sockaddr*) &addr, 0);
+  r = uv_udp_bind(&h, addr, 0);
   ASSERT(r == 0);
 
   r = uv_udp_set_broadcast(&h, 1);
@@ -88,6 +85,25 @@ TEST_IMPL(udp_options) {
 }
 
 
+TEST_IMPL(udp_options) {
+  struct sockaddr_in addr;
+
+  ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+  return udp_options_test((const struct sockaddr*) &addr);
+}
+
+
+TEST_IMPL(udp_options6) {
+  struct sockaddr_in6 addr;
+
+  if (!can_ipv6())
+    RETURN_SKIP("IPv6 not supported");
+
+  ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr));
+  return udp_options_test((const struct sockaddr*) &addr);
+}
+
+
 TEST_IMPL(udp_no_autobind) {
   uv_loop_t* loop;
   uv_udp_t h;
index a5ba14c315a14aea9249adeb92da833446983029..45af6a1f96aa6313e7939e5396740172356808de 100644 (file)
       }],
     ],
     'xcode_settings': {
-        'conditions': [
-          [ 'clang==1', {
-            'WARNING_CFLAGS': [
-              '-Wall',
-              '-Wextra',
-              '-Wno-unused-parameter',
-              '-Wno-dollar-in-identifier-extension'
-            ]}, {
-           'WARNING_CFLAGS': [
-             '-Wall',
-             '-Wextra',
-             '-Wno-unused-parameter'
-          ]}
-        ]
-      ],
-      'OTHER_LDFLAGS': [
-      ],
-      'OTHER_CFLAGS': [
-        '-g',
-        '--std=gnu89',
-        '-pedantic'
-      ],
+      'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' ],
+      'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ],
     }
   },
 
         'test/test-loop-close.c',
         'test/test-loop-stop.c',
         'test/test-loop-time.c',
+        'test/test-loop-configure.c',
         'test/test-walk-handles.c',
         'test/test-watcher-cross-stop.c',
         'test/test-multiple-listen.c',
         'test/test-platform-output.c',
         'test/test-poll.c',
         'test/test-poll-close.c',
+        'test/test-poll-close-doesnt-corrupt-stack.c',
         'test/test-poll-closesocket.c',
         'test/test-process-title.c',
         'test/test-ref.c',