deps: update uv to v1.0.0-rc1
6
deps/uv/.gitignore
vendored
@ -61,3 +61,9 @@ UpgradeLog*.XML
|
||||
Debug
|
||||
Release
|
||||
ipch
|
||||
|
||||
# sphinx generated files
|
||||
/docs/build/
|
||||
|
||||
*.xcodeproj
|
||||
*.xcworkspace
|
||||
|
2
deps/uv/.mailmap
vendored
@ -14,11 +14,13 @@ Isaac Z. Schlueter <i@izs.me>
|
||||
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
|
||||
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
|
||||
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> <ruysch@outlook.com>
|
||||
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
|
||||
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
|
||||
|
2
deps/uv/AUTHORS
vendored
@ -155,3 +155,5 @@ Pavel Platto <hinidu@gmail.com>
|
||||
Tony Kelman <tony@kelman.net>
|
||||
John Firebaugh <john.firebaugh@gmail.com>
|
||||
lilohuang <lilohuang@hotmail.com>
|
||||
Paul Goldsmith <paul.goldsmith@aplink.net>
|
||||
Julien Gilli <julien.gilli@joyent.com>
|
||||
|
99
deps/uv/ChangeLog
vendored
@ -1,4 +1,101 @@
|
||||
2014.08.08, Version 0.11.28 (Unstable)
|
||||
2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49
|
||||
|
||||
* windows: improve timer precision (Alexis Campailla)
|
||||
|
||||
* build, gyp: set xcode flags (Recep ASLANTAS)
|
||||
|
||||
* ignore: include m4 files which are created manually (Recep ASLANTAS)
|
||||
|
||||
* build: add m4 for feature/flag-testing (Recep ASLANTAS)
|
||||
|
||||
* ignore: ignore Xcode project and workspace files (Recep ASLANTAS)
|
||||
|
||||
* unix: fix warnings about dollar symbol usage in identifiers (Recep ASLANTAS)
|
||||
|
||||
* unix: fix warnings when loading functions with dlsym (Recep ASLANTAS)
|
||||
|
||||
* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle)
|
||||
|
||||
* test: add test for closing and recreating default loop (Saúl Ibarra Corretgé)
|
||||
|
||||
* windows: properly close the default loop (Saúl Ibarra Corretgé)
|
||||
|
||||
* version: add ability to specify a version suffix (Saúl Ibarra Corretgé)
|
||||
|
||||
* doc: add API documentation (Saúl Ibarra Corretgé)
|
||||
|
||||
* test: don't close connection on write error (Trevor Norris)
|
||||
|
||||
* windows: further simplify the code for timers (Saúl Ibarra Corretgé)
|
||||
|
||||
* gyp: remove UNLIMITED_SELECT from dependent define (Fedor Indutny)
|
||||
|
||||
* darwin: allocate enough space for select() hack (Fedor Indutny)
|
||||
|
||||
* unix, windows: don't allow a NULL callback on timers (Saúl Ibarra Corretgé)
|
||||
|
||||
* windows: simplify code in uv_timer_again (Saúl Ibarra Corretgé)
|
||||
|
||||
* test: use less requests on tcp-write-queue-order (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: stop child process watcher after last one exits (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: simplify how process handle queue is managed (Saúl Ibarra Corretgé)
|
||||
|
||||
* windows: remove duplicated field (mattn)
|
||||
|
||||
* core: add a reserved field to uv_handle_t and uv_req_t (Saúl Ibarra Corretgé)
|
||||
|
||||
* windows: fix buffer leak after failed udp send (Bert Belder)
|
||||
|
||||
* windows: make sure sockets and handles are reset on close (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add uv_fileno (Saúl Ibarra Corretgé)
|
||||
|
||||
* build: use same CFLAGS in autotools build as in gyp (Saúl Ibarra Corretgé)
|
||||
|
||||
* build: remove unneeded define in uv.gyp (Saúl Ibarra Corretgé)
|
||||
|
||||
* test: fix watcher_cross_stop on Windows (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: move includes for EAI constants (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: fix exposing EAI_* glibc-isms (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: fix tcp write after bad connect freezing (Andrius Bentkus)
|
||||
|
||||
|
||||
2014.08.20, Version 0.11.29 (Unstable), 35451fed830807095bbae8ef981af004a4b9259e
|
||||
|
||||
Changes since version 0.11.28:
|
||||
|
||||
* windows: make uv_read_stop immediately stop reading (Jameson Nash)
|
||||
|
||||
* windows: fix uv__getaddrinfo_translate_error (Alexis Campailla)
|
||||
|
||||
* netbsd: fix build (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add uv_recv_buffer_size and uv_send_buffer_size (Andrius
|
||||
Bentkus)
|
||||
|
||||
* windows: add support for UNC paths on uv_spawn (Paul Goldsmith)
|
||||
|
||||
* windows: replace use of inet_addr with uv_inet_pton (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: replace some asserts with returning errors (Andrius Bentkus)
|
||||
|
||||
* windows: use OpenBSD implementation for uv_fs_mkdtemp (Pavel Platto)
|
||||
|
||||
* windows: fix GetNameInfoW error handling (Alexis Campailla)
|
||||
|
||||
* fs: introduce uv_readdir_next() and report types (Fedor Indutny)
|
||||
|
||||
* fs: extend reported types in uv_fs_readdir_next (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: read on stream even when UV__POLLHUP set. (Julien Gilli)
|
||||
|
||||
|
||||
2014.08.08, Version 0.11.28 (Unstable), fc9e2a0bc487b299c0cd3b2c9a23aeb554b5d8d1
|
||||
|
||||
Changes since version 0.11.27:
|
||||
|
||||
|
10
deps/uv/Makefile.am
vendored
@ -23,7 +23,7 @@ CLEANFILES =
|
||||
|
||||
lib_LTLIBRARIES = libuv.la
|
||||
libuv_la_CFLAGS = @CFLAGS@
|
||||
libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0
|
||||
libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
|
||||
libuv_la_SOURCES = src/fs-poll.c \
|
||||
src/heap-inl.h \
|
||||
src/inet.c \
|
||||
@ -81,6 +81,7 @@ 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 \
|
||||
@ -126,6 +127,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-condvar.c \
|
||||
test/test-connection-fail.c \
|
||||
test/test-cwd-and-chdir.c \
|
||||
test/test-default-loop-close.c \
|
||||
test/test-delayed-accept.c \
|
||||
test/test-dlerror.c \
|
||||
test/test-embed.c \
|
||||
@ -141,6 +143,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-getaddrinfo.c \
|
||||
test/test-getnameinfo.c \
|
||||
test/test-getsockname.c \
|
||||
test/test-handle-fileno.c \
|
||||
test/test-hrtime.c \
|
||||
test/test-idle.c \
|
||||
test/test-ip4-addr.c \
|
||||
@ -163,6 +166,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-pipe-getsockname.c \
|
||||
test/test-pipe-sendmsg.c \
|
||||
test/test-pipe-server-close.c \
|
||||
test/test-pipe-close-stdout-read-stdin.c \
|
||||
test/test-platform-output.c \
|
||||
test/test-poll-close.c \
|
||||
test/test-poll-closesocket.c \
|
||||
@ -177,6 +181,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-shutdown-twice.c \
|
||||
test/test-signal-multiple-loops.c \
|
||||
test/test-signal.c \
|
||||
test/test-socket-buffer-size.c \
|
||||
test/test-spawn.c \
|
||||
test/test-stdio-over-pipes.c \
|
||||
test/test-tcp-bind-error.c \
|
||||
@ -194,6 +199,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-tcp-shutdown-after-write.c \
|
||||
test/test-tcp-unexpected-read.c \
|
||||
test/test-tcp-write-to-half-open-connection.c \
|
||||
test/test-tcp-write-after-connect.c \
|
||||
test/test-tcp-writealot.c \
|
||||
test/test-tcp-try-write.c \
|
||||
test/test-tcp-write-queue-order.c \
|
||||
@ -216,6 +222,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-udp-options.c \
|
||||
test/test-udp-send-and-recv.c \
|
||||
test/test-udp-send-immediate.c \
|
||||
test/test-udp-send-unreachable.c \
|
||||
test/test-udp-try-send.c \
|
||||
test/test-walk-handles.c \
|
||||
test/test-watcher-cross-stop.c
|
||||
@ -253,6 +260,7 @@ endif
|
||||
if DARWIN
|
||||
include_HEADERS += include/uv-darwin.h
|
||||
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
|
||||
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
|
||||
libuv_la_SOURCES += src/unix/darwin.c \
|
||||
src/unix/darwin-proctitle.c \
|
||||
src/unix/fsevents.c \
|
||||
|
35
deps/uv/README.md
vendored
@ -34,6 +34,11 @@ used by Mozilla's [Rust language](http://www.rust-lang.org/),
|
||||
|
||||
* Threading and synchronization primitives
|
||||
|
||||
## Versioning
|
||||
|
||||
Starting with version 1.0.0 libuv follows the [semantic versioning](http://semver.org/)
|
||||
scheme. The API change and backwards compatiblity rules are those indicated by
|
||||
SemVer. libuv will keep a stable ABI across major releases.
|
||||
|
||||
## Community
|
||||
|
||||
@ -41,8 +46,34 @@ used by Mozilla's [Rust language](http://www.rust-lang.org/),
|
||||
|
||||
## Documentation
|
||||
|
||||
* [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
|
||||
— API documentation in the form of detailed header comments.
|
||||
### Official API documentation
|
||||
|
||||
Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/)
|
||||
framework, which makes it possible to build the documentation in multiple
|
||||
formats.
|
||||
|
||||
Show different supported building options:
|
||||
|
||||
$ make help
|
||||
|
||||
Build documentation as HTML:
|
||||
|
||||
$ make html
|
||||
|
||||
Build documentation as man pages:
|
||||
|
||||
$ make man
|
||||
|
||||
Build documentation as ePub:
|
||||
|
||||
$ make epub
|
||||
|
||||
NOTE: Windows users need to use make.bat instead of plain 'make'.
|
||||
|
||||
Documentation can be browsed online [here](http://docs.libuv.org).
|
||||
|
||||
### Other resources
|
||||
|
||||
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
|
||||
— An overview of libuv with tutorials.
|
||||
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
|
||||
|
4
deps/uv/configure.ac
vendored
@ -13,16 +13,18 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [0.11.28], [https://github.com/joyent/libuv/issues])
|
||||
AC_INIT([libuv], [1.0.0], [https://github.com/joyent/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
m4_include([m4/as_case.m4])
|
||||
m4_include([m4/libuv-check-flags.m4])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
||||
AC_CANONICAL_HOST
|
||||
AC_ENABLE_SHARED
|
||||
AC_ENABLE_STATIC
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
CC_CHECK_CFLAGS_APPEND([-Wno-dollar-in-identifier-extension])
|
||||
# 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])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
243
deps/uv/docs/make.bat
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
@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
|
56
deps/uv/docs/src/async.rst
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
.. _async:
|
||||
|
||||
:c:type:`uv_async_t` --- Async handle
|
||||
=====================================
|
||||
|
||||
Async handles allow the user to "wakeup" the event loop and get a callback
|
||||
called from another thread.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_async_t
|
||||
|
||||
Async handle type.
|
||||
|
||||
.. c:type:: void (*uv_async_cb)(uv_async_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_async_init`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb)
|
||||
|
||||
Initialize the handle. A NULL callback is allowed.
|
||||
|
||||
.. note::
|
||||
Unlike other handle initialization functions, it immediately starts the handle.
|
||||
|
||||
.. c:function:: int uv_async_send(uv_async_t* async)
|
||||
|
||||
Wakeup the event loop and call the async handle's callback.
|
||||
|
||||
.. note::
|
||||
It's safe to call this function from any thread. The callback will be called on the
|
||||
loop thread.
|
||||
|
||||
.. warning::
|
||||
libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will
|
||||
yield an execution of the callback, the only guarantee is that it will be called at least
|
||||
once. Thus, calling this function may not wakeup the event loop if it was already called
|
||||
previously within a short period of time.
|
||||
|
||||
.. seealso::
|
||||
The :c:type:`uv_handle_t` API functions also apply.
|
46
deps/uv/docs/src/check.rst
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
.. _check:
|
||||
|
||||
:c:type:`uv_check_t` --- Check handle
|
||||
=====================================
|
||||
|
||||
Check handles will run the given callback once per loop iteration, right
|
||||
after polling for i/o.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_check_t
|
||||
|
||||
Check handle type.
|
||||
|
||||
.. c:type:: void (*uv_check_cb)(uv_check_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_check_start`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_check_init(uv_loop_t*, uv_check_t* check)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb)
|
||||
|
||||
Start the handle with the given callback.
|
||||
|
||||
.. c:function:: int uv_check_stop(uv_check_t* check)
|
||||
|
||||
Stop the handle, the callback will no longer be called.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
348
deps/uv/docs/src/conf.py
vendored
Normal file
@ -0,0 +1,348 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# libuv API documentation documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Jul 27 11:47:51 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def get_libuv_version():
|
||||
with open('../../include/uv-version.h') as f:
|
||||
data = f.read()
|
||||
try:
|
||||
m = re.search(r"""^#define UV_VERSION_MAJOR (\d)$""", data, re.MULTILINE)
|
||||
major = int(m.group(1))
|
||||
m = re.search(r"""^#define UV_VERSION_MINOR (\d)$""", data, re.MULTILINE)
|
||||
minor = int(m.group(1))
|
||||
m = re.search(r"""^#define UV_VERSION_PATCH (\d)$""", data, re.MULTILINE)
|
||||
patch = int(m.group(1))
|
||||
m = re.search(r"""^#define UV_VERSION_IS_RELEASE (\d)$""", data, re.MULTILINE)
|
||||
is_release = int(m.group(1))
|
||||
m = re.search(r"""^#define UV_VERSION_SUFFIX \"(\w*)\"$""", data, re.MULTILINE)
|
||||
suffix = m.group(1)
|
||||
return '%d.%d.%d%s' % (major, minor, patch, '-%s' % suffix if not is_release else '')
|
||||
except Exception:
|
||||
return 'unknown'
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'libuv API documentation'
|
||||
copyright = u'libuv contributors'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = get_libuv_version()
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'nature'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
html_title = 'libuv API documentation'
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
html_short_title = 'libuv %s API documentation' % version
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = 'static/logo.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = 'static/favicon.ico'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'libuv'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'libuv.tex', u'libuv API documentation',
|
||||
u'libuv contributors', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'libuv', u'libuv API documentation',
|
||||
[u'libuv contributors'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'libuv', u'libuv API documentation',
|
||||
u'libuv contributors', 'libuv', 'Cross-platform asychronous I/O',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
# -- Options for Epub output ----------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = u'libuv API documentation'
|
||||
epub_author = u'libuv contributors'
|
||||
epub_publisher = u'libuv contributors'
|
||||
epub_copyright = u'2014, libuv contributors'
|
||||
|
||||
# The basename for the epub file. It defaults to the project name.
|
||||
epub_basename = u'libuv'
|
||||
|
||||
# The HTML theme for the epub output. Since the default themes are not optimized
|
||||
# for small screen space, using the same theme for HTML and epub output is
|
||||
# usually not wise. This defaults to 'epub', a theme designed to save visual
|
||||
# space.
|
||||
#epub_theme = 'epub'
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or en if the language is not set.
|
||||
#epub_language = ''
|
||||
|
||||
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
||||
#epub_scheme = ''
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#epub_uid = ''
|
||||
|
||||
# A tuple containing the cover image and cover page html template filenames.
|
||||
#epub_cover = ()
|
||||
|
||||
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
|
||||
#epub_guide = ()
|
||||
|
||||
# HTML files that should be inserted before the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_pre_files = []
|
||||
|
||||
# HTML files shat should be inserted after the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_post_files = []
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ['search.html']
|
||||
|
||||
# The depth of the table of contents in toc.ncx.
|
||||
#epub_tocdepth = 3
|
||||
|
||||
# Allow duplicate toc entries.
|
||||
#epub_tocdup = True
|
||||
|
||||
# Choose between 'default' and 'includehidden'.
|
||||
#epub_tocscope = 'default'
|
||||
|
||||
# Fix unsupported image types using the PIL.
|
||||
#epub_fix_images = False
|
||||
|
||||
# Scale large images.
|
||||
#epub_max_image_width = 0
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#epub_show_urls = 'inline'
|
||||
|
||||
# If false, no index is generated.
|
||||
#epub_use_index = True
|
137
deps/uv/docs/src/design.rst
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
.. _design:
|
||||
|
||||
Design overview
|
||||
===============
|
||||
|
||||
libuv is cross-platform support library which was originally written for NodeJS. It's designed
|
||||
around the event-driven asynchronous I/O model.
|
||||
|
||||
The library provides much more than simply abstraction over different I/O polling mechanisms:
|
||||
'handles' and 'streams' provde a high level abstraction for sockets and other entities;
|
||||
cross-platform file I/O and threading functionality is also provided, amongst other things.
|
||||
|
||||
Here is a diagram illustrating the different parts that compose libuv and what subsystem they
|
||||
relate to:
|
||||
|
||||
.. image:: static/architecture.png
|
||||
:scale: 75%
|
||||
:align: center
|
||||
|
||||
|
||||
Handles and requests
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
libuv provides users with 2 abstractions to work with, in combination with the event loop:
|
||||
handles and requests.
|
||||
|
||||
Handles represent long-lived objects capable of performing certain operations while active. Some
|
||||
examples: a prepare handle gets its callback called once every loop iteration when active, and
|
||||
a TCP server handle get its connection callback called every time there is a new connection.
|
||||
|
||||
Requests represent (typically) short-lived operations. These operations can be performed over a
|
||||
handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests
|
||||
don't need a handle they run directly on the loop.
|
||||
|
||||
|
||||
The I/O loop
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O
|
||||
operations, and it's meant to be tied to a single thread. One can run multiple event loops
|
||||
as long as each runs in a different thread. The libuv event loop (or any other API involving
|
||||
the loop or handles, for that matter) **is not thread-safe** except stated otherwise.
|
||||
|
||||
The event loop follows the rather usual single threaded asynchronous I/O approah: all (network)
|
||||
I/O is performed on non-blocking sockets which are polled using the best mechanism available
|
||||
on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP
|
||||
on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets
|
||||
which have been added to the poller and callbacks will be fired indicating socket conditions
|
||||
(readable, writable hangup) so handles can read, write or perform the desired I/O operation.
|
||||
|
||||
In order to better understand how the event loop operates, the following diagram illustrates all
|
||||
stages of a loop iteration:
|
||||
|
||||
.. image:: static/loop_iteration.png
|
||||
:scale: 75%
|
||||
:align: center
|
||||
|
||||
|
||||
#. The loop concept of 'now' is updated. The event loop caches the current time at the start of
|
||||
the event loop tick in order to reduce the number of time-related system calls.
|
||||
|
||||
#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So,
|
||||
when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
|
||||
requests or closing handles it's considered to be *alive*.
|
||||
|
||||
#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now*
|
||||
get their callbacks called.
|
||||
|
||||
#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
|
||||
most part. There are cases, however, in which calling such a callback is deferred for the next
|
||||
loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.
|
||||
|
||||
#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every
|
||||
loop iteration, if they are active.
|
||||
|
||||
#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before
|
||||
the loop will block for I/O.
|
||||
|
||||
#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should
|
||||
block. These are the rules when calculating the timeout:
|
||||
|
||||
* If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0.
|
||||
* If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0.
|
||||
* If there are no active handles or requests, the timeout is 0.
|
||||
* If there are any idle handles active, the timeout is 0.
|
||||
* If there are any handles pending to be closed, the timeout is 0.
|
||||
* If none of the above cases was matched, the timeout of the closest timer is taken, or
|
||||
if there are no active timers, infinity.
|
||||
|
||||
#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated
|
||||
on the previous step. All I/O related handles that were monitoring a given file descriptor
|
||||
for a read or write operation get their callbacks called at this point.
|
||||
|
||||
#. Check handle callbacks are called. Check handles get their callbacks called right after the
|
||||
loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles.
|
||||
|
||||
#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
|
||||
get the close callback called.
|
||||
|
||||
#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress.
|
||||
It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed
|
||||
so there might be timers which are due, those timers get their callbacks called.
|
||||
|
||||
#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
|
||||
iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
|
||||
it will contionue from the start if it's asill *alive*, otherwise it will also end.
|
||||
|
||||
|
||||
.. important::
|
||||
libuv uses a thread pool to make asynchronous file I/O operations possible, but
|
||||
network I/O is **always** performed in a single thread, each loop's thread.
|
||||
|
||||
.. note::
|
||||
While the polling mechanism is different, libuv makes the execution model consistent
|
||||
Unix systems and Windows.
|
||||
|
||||
|
||||
File I/O
|
||||
^^^^^^^^
|
||||
|
||||
Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on,
|
||||
so the current approach is to run blocking file I/O operations in a thread pool.
|
||||
|
||||
For a thorough explanation of the cross-platform file I/O landscape, checkout
|
||||
`this post <http://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_.
|
||||
|
||||
libuv currently uses a global thread pool on which all loops can queue work on. 3 types of
|
||||
operations are currently run on this pool:
|
||||
|
||||
* Filesystem operations
|
||||
* DNS functions (getaddrinfo and getnameinfo)
|
||||
* User specified code via :c:func:`uv_queue_work`
|
||||
|
||||
.. warning::
|
||||
See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size
|
||||
is quite limited.
|
44
deps/uv/docs/src/dll.rst
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
.. _dll:
|
||||
|
||||
Shared library handling
|
||||
=======================
|
||||
|
||||
libuv prodives cross platform utilities for loading shared libraries and
|
||||
retrieving symbols from them, using the following API.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_lib_t
|
||||
|
||||
Shared library data type.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_dlopen(const char* filename, uv_lib_t* lib)
|
||||
|
||||
Opens a shared library. The filename is in utf-8. Returns 0 on success and
|
||||
-1 on error. Call :c:func:`uv_dlerror` to get the error message.
|
||||
|
||||
.. c:function:: void uv_dlclose(uv_lib_t* lib)
|
||||
|
||||
Close the shared library.
|
||||
|
||||
.. c:function:: uv_dlsym(uv_lib_t* lib, const char* name, void** ptr)
|
||||
|
||||
Retrieves a data pointer from a dynamic library. It is legal for a symbol
|
||||
to map to NULL. Returns 0 on success and -1 if the symbol was not found.
|
||||
|
||||
.. c:function:: const char* uv_dlerror(const uv_lib_t* lib)
|
||||
|
||||
Returns the last uv_dlopen() or uv_dlsym() error message.
|
83
deps/uv/docs/src/dns.rst
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
.. _dns:
|
||||
|
||||
DNS utility functions
|
||||
=====================
|
||||
|
||||
libuv provides asynchronous variants of `getaddrinfo` and `getnameinfo`.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_getaddrinfo_t
|
||||
|
||||
`getaddrinfo` request type.
|
||||
|
||||
.. c:type:: void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
|
||||
|
||||
Callback which will be called with the getaddrinfo request result once
|
||||
complete. In case it was cancelled, `status` will have a value of
|
||||
``UV_ECANCELED``.
|
||||
|
||||
.. c:type:: uv_getnameinfo_t
|
||||
|
||||
`getnameinfo` request type.
|
||||
|
||||
.. c:type:: void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service)
|
||||
|
||||
Callback which will be called with the getnameinfo request result once
|
||||
complete. In case it was cancelled, `status` will have a value of
|
||||
``UV_ECANCELED``.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: uv_loop_t* uv_getaddrinfo_t.loop
|
||||
|
||||
Loop that started this getaddrinfo request and where completion will be
|
||||
reported. Readonly.
|
||||
|
||||
.. c:member:: uv_loop_t* uv_getnameinfo_t.loop
|
||||
|
||||
Loop that started this getnameinfo request and where completion will be
|
||||
reported. Readonly.
|
||||
|
||||
.. seealso:: The :c:type:`uv_req_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints)
|
||||
|
||||
Asynchronous ``getaddrinfo(3)``.
|
||||
|
||||
Either node or service may be NULL but not both.
|
||||
|
||||
`hints` is a pointer to a struct addrinfo with additional address type
|
||||
constraints, or NULL. Consult `man -s 3 getaddrinfo` for more details.
|
||||
|
||||
Returns 0 on success or an error code < 0 on failure. If successful, the
|
||||
callback will get called sometime in the future with the lookup result,
|
||||
which is either:
|
||||
|
||||
* status == 0, the res argument points to a valid `struct addrinfo`, or
|
||||
* status < 0, the res argument is NULL. See the UV_EAI_* constants.
|
||||
|
||||
Call :c:func:`uv_freeaddrinfo` to free the addrinfo structure.
|
||||
|
||||
.. c:function:: void uv_freeaddrinfo(struct addrinfo* ai)
|
||||
|
||||
Free the struct addrinfo. Passing NULL is allowed and is a no-op.
|
||||
|
||||
.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags)
|
||||
|
||||
Asynchronous ``getnameinfo(3)``.
|
||||
|
||||
Returns 0 on success or an error code < 0 on failure. If successful, the
|
||||
callback will get called sometime in the future with the lookup result.
|
||||
Consult `man -s 3 getnameinfo` for more details.
|
||||
|
||||
.. seealso:: The :c:type:`uv_req_t` API functions also apply.
|
329
deps/uv/docs/src/errors.rst
vendored
Normal file
@ -0,0 +1,329 @@
|
||||
|
||||
.. _errors:
|
||||
|
||||
Error handling
|
||||
==============
|
||||
|
||||
In libuv errors are negative numbered constants. As a rule of thumb, whenever
|
||||
there is a status parameter, or an API functions returns an integer, a negative
|
||||
number will imply an error.
|
||||
|
||||
.. note::
|
||||
Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on
|
||||
Windows they are defined by libuv to arbitrary negative numbers.
|
||||
|
||||
|
||||
Error constants
|
||||
---------------
|
||||
|
||||
.. c:macro:: UV_E2BIG
|
||||
|
||||
argument list too long
|
||||
|
||||
.. c:macro:: UV_EACCES
|
||||
|
||||
permission denied
|
||||
|
||||
.. c:macro:: UV_EADDRINUSE
|
||||
|
||||
address already in use
|
||||
|
||||
.. c:macro:: UV_EADDRNOTAVAIL
|
||||
|
||||
address not available
|
||||
|
||||
.. c:macro:: UV_EAFNOSUPPORT
|
||||
|
||||
address family not supported
|
||||
|
||||
.. c:macro:: UV_EAGAIN
|
||||
|
||||
resource temporarily unavailable
|
||||
|
||||
.. c:macro:: UV_EAI_ADDRFAMILY
|
||||
|
||||
address family not supported
|
||||
|
||||
.. c:macro:: UV_EAI_AGAIN
|
||||
|
||||
temporary failure
|
||||
|
||||
.. c:macro:: UV_EAI_BADFLAGS
|
||||
|
||||
bad ai_flags value
|
||||
|
||||
.. c:macro:: UV_EAI_BADHINTS
|
||||
|
||||
invalid value for hints
|
||||
|
||||
.. c:macro:: UV_EAI_CANCELED
|
||||
|
||||
request canceled
|
||||
|
||||
.. c:macro:: UV_EAI_FAIL
|
||||
|
||||
permanent failure
|
||||
|
||||
.. c:macro:: UV_EAI_FAMILY
|
||||
|
||||
ai_family not supported
|
||||
|
||||
.. c:macro:: UV_EAI_MEMORY
|
||||
|
||||
out of memory
|
||||
|
||||
.. c:macro:: UV_EAI_NODATA
|
||||
|
||||
no address
|
||||
|
||||
.. c:macro:: UV_EAI_NONAME
|
||||
|
||||
unknown node or service
|
||||
|
||||
.. c:macro:: UV_EAI_OVERFLOW
|
||||
|
||||
argument buffer overflow
|
||||
|
||||
.. c:macro:: UV_EAI_PROTOCOL
|
||||
|
||||
resolved protocol is unknown
|
||||
|
||||
.. c:macro:: UV_EAI_SERVICE
|
||||
|
||||
service not available for socket type
|
||||
|
||||
.. c:macro:: UV_EAI_SOCKTYPE
|
||||
|
||||
socket type not supported
|
||||
|
||||
.. c:macro:: UV_EALREADY
|
||||
|
||||
connection already in progress
|
||||
|
||||
.. c:macro:: UV_EBADF
|
||||
|
||||
bad file descriptor
|
||||
|
||||
.. c:macro:: UV_EBUSY
|
||||
|
||||
resource busy or locked
|
||||
|
||||
.. c:macro:: UV_ECANCELED
|
||||
|
||||
operation canceled
|
||||
|
||||
.. c:macro:: UV_ECHARSET
|
||||
|
||||
invalid Unicode character
|
||||
|
||||
.. c:macro:: UV_ECONNABORTED
|
||||
|
||||
software caused connection abort
|
||||
|
||||
.. c:macro:: UV_ECONNREFUSED
|
||||
|
||||
connection refused
|
||||
|
||||
.. c:macro:: UV_ECONNRESET
|
||||
|
||||
connection reset by peer
|
||||
|
||||
.. c:macro:: UV_EDESTADDRREQ
|
||||
|
||||
destination address required
|
||||
|
||||
.. c:macro:: UV_EEXIST
|
||||
|
||||
file already exists
|
||||
|
||||
.. c:macro:: UV_EFAULT
|
||||
|
||||
bad address in system call argument
|
||||
|
||||
.. c:macro:: UV_EFBIG
|
||||
|
||||
file too large
|
||||
|
||||
.. c:macro:: UV_EHOSTUNREACH
|
||||
|
||||
host is unreachable
|
||||
|
||||
.. c:macro:: UV_EINTR
|
||||
|
||||
interrupted system call
|
||||
|
||||
.. c:macro:: UV_EINVAL
|
||||
|
||||
invalid argument
|
||||
|
||||
.. c:macro:: UV_EIO
|
||||
|
||||
i/o error
|
||||
|
||||
.. c:macro:: UV_EISCONN
|
||||
|
||||
socket is already connected
|
||||
|
||||
.. c:macro:: UV_EISDIR
|
||||
|
||||
illegal operation on a directory
|
||||
|
||||
.. c:macro:: UV_ELOOP
|
||||
|
||||
too many symbolic links encountered
|
||||
|
||||
.. c:macro:: UV_EMFILE
|
||||
|
||||
too many open files
|
||||
|
||||
.. c:macro:: UV_EMSGSIZE
|
||||
|
||||
message too long
|
||||
|
||||
.. c:macro:: UV_ENAMETOOLONG
|
||||
|
||||
name too long
|
||||
|
||||
.. c:macro:: UV_ENETDOWN
|
||||
|
||||
network is down
|
||||
|
||||
.. c:macro:: UV_ENETUNREACH
|
||||
|
||||
network is unreachable
|
||||
|
||||
.. c:macro:: UV_ENFILE
|
||||
|
||||
file table overflow
|
||||
|
||||
.. c:macro:: UV_ENOBUFS
|
||||
|
||||
no buffer space available
|
||||
|
||||
.. c:macro:: UV_ENODEV
|
||||
|
||||
no such device
|
||||
|
||||
.. c:macro:: UV_ENOENT
|
||||
|
||||
no such file or directory
|
||||
|
||||
.. c:macro:: UV_ENOMEM
|
||||
|
||||
not enough memory
|
||||
|
||||
.. c:macro:: UV_ENONET
|
||||
|
||||
machine is not on the network
|
||||
|
||||
.. c:macro:: UV_ENOPROTOOPT
|
||||
|
||||
protocol not available
|
||||
|
||||
.. c:macro:: UV_ENOSPC
|
||||
|
||||
no space left on device
|
||||
|
||||
.. c:macro:: UV_ENOSYS
|
||||
|
||||
function not implemented
|
||||
|
||||
.. c:macro:: UV_ENOTCONN
|
||||
|
||||
socket is not connected
|
||||
|
||||
.. c:macro:: UV_ENOTDIR
|
||||
|
||||
not a directory
|
||||
|
||||
.. c:macro:: UV_ENOTEMPTY
|
||||
|
||||
directory not empty
|
||||
|
||||
.. c:macro:: UV_ENOTSOCK
|
||||
|
||||
socket operation on non-socket
|
||||
|
||||
.. c:macro:: UV_ENOTSUP
|
||||
|
||||
operation not supported on socket
|
||||
|
||||
.. c:macro:: UV_EPERM
|
||||
|
||||
operation not permitted
|
||||
|
||||
.. c:macro:: UV_EPIPE
|
||||
|
||||
broken pipe
|
||||
|
||||
.. c:macro:: UV_EPROTO
|
||||
|
||||
protocol error
|
||||
|
||||
.. c:macro:: UV_EPROTONOSUPPORT
|
||||
|
||||
protocol not supported
|
||||
|
||||
.. c:macro:: UV_EPROTOTYPE
|
||||
|
||||
protocol wrong type for socket
|
||||
|
||||
.. c:macro:: UV_ERANGE
|
||||
|
||||
result too large
|
||||
|
||||
.. c:macro:: UV_EROFS
|
||||
|
||||
read-only file system
|
||||
|
||||
.. c:macro:: UV_ESHUTDOWN
|
||||
|
||||
cannot send after transport endpoint shutdown
|
||||
|
||||
.. c:macro:: UV_ESPIPE
|
||||
|
||||
invalid seek
|
||||
|
||||
.. c:macro:: UV_ESRCH
|
||||
|
||||
no such process
|
||||
|
||||
.. c:macro:: UV_ETIMEDOUT
|
||||
|
||||
connection timed out
|
||||
|
||||
.. c:macro:: UV_ETXTBSY
|
||||
|
||||
text file is busy
|
||||
|
||||
.. c:macro:: UV_EXDEV
|
||||
|
||||
cross-device link not permitted
|
||||
|
||||
.. c:macro:: UV_UNKNOWN
|
||||
|
||||
unknown error
|
||||
|
||||
.. c:macro:: UV_EOF
|
||||
|
||||
end of file
|
||||
|
||||
.. c:macro:: UV_ENXIO
|
||||
|
||||
no such device or address
|
||||
|
||||
.. c:macro:: UV_EMLINK
|
||||
|
||||
too many links
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: const char* uv_strerror(int err)
|
||||
|
||||
Returns the error message for the given error code.
|
||||
|
||||
.. c:function:: const char* uv_err_name(int err)
|
||||
|
||||
Returns the error name for the given error code.
|
259
deps/uv/docs/src/fs.rst
vendored
Normal file
@ -0,0 +1,259 @@
|
||||
|
||||
.. _fs:
|
||||
|
||||
Filesystem operations
|
||||
=====================
|
||||
|
||||
libuv provides a wide variety of cross-platform sync and async filesystem
|
||||
operations. All functions defined in this document take a callback, which is
|
||||
allowed to be NULL. If the callback is NULL the request is completed synchronously,
|
||||
otherwise it will be performed asynchronously.
|
||||
|
||||
All file operations are run on the threadpool, see :ref:`threadpool` for information
|
||||
on the threadpool size.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_fs_t
|
||||
|
||||
Filesystem request type.
|
||||
|
||||
.. c:type:: uv_stat_t
|
||||
|
||||
Portable equivalent of `struct stat`.
|
||||
|
||||
::
|
||||
|
||||
typedef struct {
|
||||
uint64_t st_dev;
|
||||
uint64_t st_mode;
|
||||
uint64_t st_nlink;
|
||||
uint64_t st_uid;
|
||||
uint64_t st_gid;
|
||||
uint64_t st_rdev;
|
||||
uint64_t st_ino;
|
||||
uint64_t st_size;
|
||||
uint64_t st_blksize;
|
||||
uint64_t st_blocks;
|
||||
uint64_t st_flags;
|
||||
uint64_t st_gen;
|
||||
uv_timespec_t st_atim;
|
||||
uv_timespec_t st_mtim;
|
||||
uv_timespec_t st_ctim;
|
||||
uv_timespec_t st_birthtim;
|
||||
} uv_stat_t;
|
||||
|
||||
.. c:type:: uv_fs_type
|
||||
|
||||
Filesystem request type.
|
||||
|
||||
::
|
||||
|
||||
typedef enum {
|
||||
UV_FS_UNKNOWN = -1,
|
||||
UV_FS_CUSTOM,
|
||||
UV_FS_OPEN,
|
||||
UV_FS_CLOSE,
|
||||
UV_FS_READ,
|
||||
UV_FS_WRITE,
|
||||
UV_FS_SENDFILE,
|
||||
UV_FS_STAT,
|
||||
UV_FS_LSTAT,
|
||||
UV_FS_FSTAT,
|
||||
UV_FS_FTRUNCATE,
|
||||
UV_FS_UTIME,
|
||||
UV_FS_FUTIME,
|
||||
UV_FS_CHMOD,
|
||||
UV_FS_FCHMOD,
|
||||
UV_FS_FSYNC,
|
||||
UV_FS_FDATASYNC,
|
||||
UV_FS_UNLINK,
|
||||
UV_FS_RMDIR,
|
||||
UV_FS_MKDIR,
|
||||
UV_FS_MKDTEMP,
|
||||
UV_FS_RENAME,
|
||||
UV_FS_READDIR,
|
||||
UV_FS_LINK,
|
||||
UV_FS_SYMLINK,
|
||||
UV_FS_READLINK,
|
||||
UV_FS_CHOWN,
|
||||
UV_FS_FCHOWN
|
||||
} uv_fs_type;
|
||||
|
||||
.. c:type:: uv_dirent_t
|
||||
|
||||
Cross platform (reduced) equivalent of ``struct dirent``.
|
||||
Used in :c:func:`uv_fs_readdir_next`.
|
||||
|
||||
::
|
||||
|
||||
typedef enum {
|
||||
UV_DIRENT_UNKNOWN,
|
||||
UV_DIRENT_FILE,
|
||||
UV_DIRENT_DIR,
|
||||
UV_DIRENT_LINK,
|
||||
UV_DIRENT_FIFO,
|
||||
UV_DIRENT_SOCKET,
|
||||
UV_DIRENT_CHAR,
|
||||
UV_DIRENT_BLOCK
|
||||
} uv_dirent_type_t;
|
||||
|
||||
typedef struct uv_dirent_s {
|
||||
const char* name;
|
||||
uv_dirent_type_t type;
|
||||
} uv_dirent_t;
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: uv_loop_t* uv_fs_t.loop
|
||||
|
||||
Loop that started this request and where completion will be reported.
|
||||
Readonly.
|
||||
|
||||
.. c:member:: uv_fs_type uv_fs_t.fs_type
|
||||
|
||||
FS request type.
|
||||
|
||||
.. c:member:: const char* uv_fs_t.path
|
||||
|
||||
Path affecting the request.
|
||||
|
||||
.. c:member:: ssize_t uv_fs_t.result
|
||||
|
||||
Result of the request. < 0 means error, success otherwise. On requests such
|
||||
as :c:func:`uv_fs_read` or :c:func:`uv_fs_write` it indicates the amount of
|
||||
data that was read or written, respectively.
|
||||
|
||||
.. c:member:: uv_stat_t uv_fs_t.statbuf
|
||||
|
||||
Stores the result of :c:func:`uv_fs_stat` and other stat requests.
|
||||
|
||||
.. c:member:: void* uv_fs_t.ptr
|
||||
|
||||
Stores the result of :c:func:`uv_fs_readlink` and serves as an alias to
|
||||
`statbuf`.
|
||||
|
||||
.. seealso:: The :c:type:`uv_req_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: void uv_fs_req_cleanup(uv_fs_t* req)
|
||||
|
||||
Cleanup request. Must be called after a request is finished to deallocate
|
||||
any memory libuv might have allocated.
|
||||
|
||||
.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``close(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``open(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``preadv(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``unlink(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``pwritev(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``mkdir(2)``.
|
||||
|
||||
.. note::
|
||||
`mode` is currently not implemented on Windows.
|
||||
|
||||
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``mkdtemp(3)``.
|
||||
|
||||
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``rmdir(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent)
|
||||
|
||||
Equivalent to ``readdir(2)``, with a slightly different API. Once the callback
|
||||
for the request is called, the user can use :c:func:`uv_fs_readdir_next` to
|
||||
get `ent` populated with the next directory entry data. When there are no
|
||||
more entries ``UV_EOF`` will be returned.
|
||||
|
||||
.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``(f/l)stat(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``rename(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``fsync(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``fdatasync(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``ftruncate(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb)
|
||||
|
||||
Limited equivalent to ``sendfile(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``(f)chmod(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``(f)utime(s)(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``link(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``symlink(2)``.
|
||||
|
||||
.. note::
|
||||
On Windows the `flags` parameter can be specified to control how the symlink will
|
||||
be created:
|
||||
|
||||
* ``UV_FS_SYMLINK_DIR``: indicates that `path` points to a directory.
|
||||
|
||||
* ``UV_FS_SYMLINK_JUNCTION``: request that the symlink is created
|
||||
using junktion points.
|
||||
|
||||
.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``readlink(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``(f)chown(2)``.
|
||||
|
||||
.. note::
|
||||
These functions are not implemented on Windows.
|
||||
|
||||
.. seealso:: The :c:type:`uv_req_t` API functions also apply.
|
102
deps/uv/docs/src/fs_event.rst
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
.. _fs_event:
|
||||
|
||||
:c:type:`uv_fs_event_t` --- FS Event handle
|
||||
===========================================
|
||||
|
||||
FS Event handles allow the user to monitor a given path for changes, for example,
|
||||
if the file was renamed or there was a generic change in it. This handle uses
|
||||
the best backend for the job on each platform.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_fs_event_t
|
||||
|
||||
FS Event handle type.
|
||||
|
||||
.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status)
|
||||
|
||||
Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly
|
||||
after the handle is started. If the handle was started with a directory the
|
||||
`filename` parameter will be a relative path to a file contained in the directory.
|
||||
The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements.
|
||||
|
||||
.. c:type:: uv_fs_event
|
||||
|
||||
Event types that :c:type:`uv_fs_event_t` handles monitor.
|
||||
|
||||
::
|
||||
|
||||
enum uv_fs_event {
|
||||
UV_RENAME = 1,
|
||||
UV_CHANGE = 2
|
||||
};
|
||||
|
||||
.. c:type:: uv_fs_event_flags
|
||||
|
||||
Flags that can be passed to :c:func:`uv_fs_event_start` to control its
|
||||
behavior.
|
||||
|
||||
::
|
||||
|
||||
enum uv_fs_event_flags {
|
||||
/*
|
||||
* By default, if the fs event watcher is given a directory name, we will
|
||||
* watch for all events in that directory. This flags overrides this behavior
|
||||
* and makes fs_event report only changes to the directory entry itself. This
|
||||
* flag does not affect individual files watched.
|
||||
* This flag is currently not implemented yet on any backend.
|
||||
*/
|
||||
UV_FS_EVENT_WATCH_ENTRY = 1,
|
||||
/*
|
||||
* By default uv_fs_event will try to use a kernel interface such as inotify
|
||||
* or kqueue to detect events. This may not work on remote filesystems such
|
||||
* as NFS mounts. This flag makes fs_event fall back to calling stat() on a
|
||||
* regular interval.
|
||||
* This flag is currently not implemented yet on any backend.
|
||||
*/
|
||||
UV_FS_EVENT_STAT = 2,
|
||||
/*
|
||||
* By default, event watcher, when watching directory, is not registering
|
||||
* (is ignoring) changes in it's subdirectories.
|
||||
* This flag will override this behaviour on platforms that support it.
|
||||
*/
|
||||
UV_FS_EVENT_RECURSIVE = 4
|
||||
};
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags)
|
||||
|
||||
Start the handle with the given callback, which will watch the specified
|
||||
`path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`.
|
||||
|
||||
.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle)
|
||||
|
||||
Stop the handle, the callback will no longer be called.
|
||||
|
||||
.. c:function:: int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len)
|
||||
|
||||
Get the path being monitored by the handle. The buffer must be preallocated
|
||||
by the user. Returns 0 on success or an error code < 0 in case of failure.
|
||||
On sucess, `buf` will contain the path and `len` its length. If the buffer
|
||||
is not big enough UV_ENOBUFS will be returned and len will be set to the
|
||||
required size.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
65
deps/uv/docs/src/fs_poll.rst
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
.. _fs_poll:
|
||||
|
||||
:c:type:`uv_fs_poll_t` --- FS Poll handle
|
||||
=========================================
|
||||
|
||||
FS Poll handles allow the user to monitor a given path for changes. Unlike
|
||||
:c:type:`uv_fs_event_t`, fs poll handles use `stat` to detect when a file has
|
||||
changed so they can work on file systems where fs event handles can't.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_fs_poll_t
|
||||
|
||||
FS Poll handle type.
|
||||
|
||||
.. c:type:: void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr)
|
||||
|
||||
Callback passed to :c:func:`uv_fs_poll_start` which will be called repeatedly
|
||||
after the handle is started, when any change happens to the monitored path.
|
||||
|
||||
The callback is invoked with `status < 0` if `path` does not exist
|
||||
or is inaccessible. The watcher is *not* stopped but your callback is
|
||||
not called again until something changes (e.g. when the file is created
|
||||
or the error reason changes).
|
||||
|
||||
When `status == 0`, the callback receives pointers to the old and new
|
||||
:c:type:`uv_stat_t` structs. They are valid for the duration of the
|
||||
callback only.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval)
|
||||
|
||||
Check the file at `path` for changes every `interval` milliseconds.
|
||||
|
||||
.. note::
|
||||
For maximum portability, use multi-second intervals. Sub-second intervals will not detect
|
||||
all changes on many file systems.
|
||||
|
||||
.. c:function:: int uv_fs_poll_stop(uv_fs_poll_t* handle)
|
||||
|
||||
Stop the handle, the callback will no longer be called.
|
||||
|
||||
.. c:function:: int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len)
|
||||
|
||||
Get the path being monitored by the handle. The buffer must be preallocated
|
||||
by the user. Returns 0 on success or an error code < 0 in case of failure.
|
||||
On sucess, `buf` will contain the path and `len` its length. If the buffer
|
||||
is not big enough UV_ENOBUFS will be returned and len will be set to the
|
||||
required size.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
172
deps/uv/docs/src/handle.rst
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
|
||||
.. _handle:
|
||||
|
||||
:c:type:`uv_handle_t` --- Base handle
|
||||
=====================================
|
||||
|
||||
`uv_handle_t` is the base type for all libuv handle types.
|
||||
|
||||
Strcutures are aligned so that any libuv handle can be cast to `uv_handle_t`.
|
||||
All API functions defined here work with any handle type.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_handle_t
|
||||
|
||||
The base libuv handle type.
|
||||
|
||||
.. c:type:: uv_any_handle
|
||||
|
||||
Union of all handle types.
|
||||
|
||||
.. c:type:: void (*uv_close_cb)(uv_handle_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_close`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: uv_loop_t* uv_handle_t.loop
|
||||
|
||||
Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly.
|
||||
|
||||
.. c:member:: void* uv_handle_t.data
|
||||
|
||||
Space for user-defined arbitrary data. libuv does not use this field.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_is_active(const uv_handle_t* handle)
|
||||
|
||||
Returns non-zero if the handle is active, zero if it's inactive. What
|
||||
"active" means depends on the type of handle:
|
||||
|
||||
- A uv_async_t handle is always active and cannot be deactivated, except
|
||||
by closing it with uv_close().
|
||||
|
||||
- A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that
|
||||
deals with i/o - is active when it is doing something that involves i/o,
|
||||
like reading, writing, connecting, accepting new connections, etc.
|
||||
|
||||
- A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has
|
||||
been started with a call to uv_check_start(), uv_idle_start(), etc.
|
||||
|
||||
Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()`
|
||||
function, then it's active from the moment that function is called.
|
||||
Likewise, `uv_foo_stop()` deactivates the handle again.
|
||||
|
||||
.. c:function:: int uv_is_closing(const uv_handle_t* handle)
|
||||
|
||||
Returns non-zero if the handle is closing or closed, zero otherwise.
|
||||
|
||||
.. note::
|
||||
This function should only be used between the initialization of the handle and the
|
||||
arrival of the close callback.
|
||||
|
||||
.. c:function:: void uv_close(uv_handle_t* handle, uv_close_cb close_cb)
|
||||
|
||||
Request handle to be closed. `close_cb` will be called asynchronously after
|
||||
this call. This MUST be called on each handle before memory is released.
|
||||
|
||||
Handles that wrap file descriptors are closed immediately but
|
||||
`close_cb` will still be deferred to the next iteration of the event loop.
|
||||
It gives you a chance to free up any resources associated with the handle.
|
||||
|
||||
In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
|
||||
have their callbacks called asynchronously with status=UV_ECANCELED.
|
||||
|
||||
.. c:function:: void uv_ref(uv_handle_t* handle)
|
||||
|
||||
Reference the given handle. References are idempotent, that is, if a handle
|
||||
is already referenced calling this function again will have no effect.
|
||||
|
||||
See :ref:`refcount`.
|
||||
|
||||
.. c:function:: void uv_unref(uv_handle_t* handle)
|
||||
|
||||
Un-reference the given handle. References are idempotent, that is, if a handle
|
||||
is not referenced calling this function again will have no effect.
|
||||
|
||||
See :ref:`refcount`.
|
||||
|
||||
.. c:function:: int uv_has_ref(const uv_handle_t* handle)
|
||||
|
||||
Returns non-zero if the handle referenced, zero otherwise.
|
||||
|
||||
See :ref:`refcount`.
|
||||
|
||||
.. c:function:: size_t uv_handle_size(uv_handle_type type)
|
||||
|
||||
Returns the size of the given handle type. Useful for FFI binding writers
|
||||
who don't want to know the structure layout.
|
||||
|
||||
|
||||
Miscellaneous API functions
|
||||
---------------------------
|
||||
|
||||
The following API functions take a :c:type:`uv_handle_t` argument but they work
|
||||
just for some handle types.
|
||||
|
||||
.. c:function:: int uv_send_buffer_size(uv_handle_t* handle, int* value)
|
||||
|
||||
Gets or sets the size of the send buffer that the operating
|
||||
system uses for the socket.
|
||||
|
||||
If `*value` == 0, it will return the current send buffer size,
|
||||
otherwise it will use `*value` to set the new send buffer size.
|
||||
|
||||
This function works for TCP, pipe and UDP handles on Unix and for TCP and
|
||||
UDP handles on Windows.
|
||||
|
||||
.. note::
|
||||
Linux will set double the size and return double the size of the original set value.
|
||||
|
||||
.. c:function:: int uv_recv_buffer_size(uv_handle_t* handle, int* value)
|
||||
|
||||
Gets or sets the size of the receive buffer that the operating
|
||||
system uses for the socket.
|
||||
|
||||
If `*value` == 0, it will return the current receive buffer size,
|
||||
otherwise it will use `*value` to set the new receive buffer size.
|
||||
|
||||
This function works for TCP, pipe and UDP handles on Unix and for TCP and
|
||||
UDP handles on Windows.
|
||||
|
||||
.. note::
|
||||
Linux will set double the size and return double the size of the original set value.
|
||||
|
||||
.. c:function:: int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd)
|
||||
|
||||
Gets the platform dependent file descriptor equivalent.
|
||||
|
||||
The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing
|
||||
any other handle type will fail with `UV_EINVAL`.
|
||||
|
||||
If a handle doesn't have an attached file descriptor yet or the handle
|
||||
itself has been closed, this function will return `UV_EBADF`.
|
||||
|
||||
.. warning::
|
||||
Be very careful when using this function. libuv assumes it's in control of the file
|
||||
descriptor so any change to it may lead to malfunction.
|
||||
|
||||
|
||||
.. _refcount:
|
||||
|
||||
Reference counting
|
||||
------------------
|
||||
|
||||
The libuv event loop (if run in the default mode) will run until there are no
|
||||
active `and` referenced handles left. The user can force the loop to exit early
|
||||
by unreferencing handles which are active, for example by calling :c:func:`uv_unref`
|
||||
after calling :c:func:`uv_timer_start`.
|
||||
|
||||
A handle can be referenced or unreferenced, the refcounting scheme doesn't use
|
||||
a counter, so both operations are idempotent.
|
||||
|
||||
All handles are referenced when active by default, see :c:func:`uv_is_active`
|
||||
for a more detailed explanation on what being `active` involves.
|
54
deps/uv/docs/src/idle.rst
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
.. _idle:
|
||||
|
||||
:c:type:`uv_idle_t` --- Idle handle
|
||||
===================================
|
||||
|
||||
Idle handles will run the given callback once per loop iteration, right
|
||||
before the :c:type:`uv_prepare_t` handles.
|
||||
|
||||
.. note::
|
||||
The notable difference with prepare handles is that when there are active idle handles,
|
||||
the loop will perform a zero timeout poll instead of blocking for i/o.
|
||||
|
||||
.. warning::
|
||||
Despite the name, idle handles will get their callbacks called on every loop iteration,
|
||||
not when the loop is actually "idle".
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_idle_t
|
||||
|
||||
Idle handle type.
|
||||
|
||||
.. c:type:: void (*uv_idle_cb)(uv_idle_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_idle_start`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_idle_init(uv_loop_t*, uv_idle_t* idle)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)
|
||||
|
||||
Start the handle with the given callback.
|
||||
|
||||
.. c:function:: int uv_idle_stop(uv_idle_t* idle)
|
||||
|
||||
Stop the handle, the callback will no longer be called.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
84
deps/uv/docs/src/index.rst
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
Welcome to the libuv API documentation
|
||||
======================================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
libuv is a multi-platform support library with a focus on asynchronous I/O. It
|
||||
was primarily developed for use by `Node.js`_, but it's also used by Mozilla's
|
||||
`Rust language`_, `Luvit`_, `Julia`_, `pyuv`_, and `others`_.
|
||||
|
||||
.. note::
|
||||
In case you find errors in this documentation you can help by sending
|
||||
`pull requests <https://github.com/joyent/libuv>`_!
|
||||
|
||||
.. _Node.js: http://nodejs.org
|
||||
.. _Rust language: http://www.rust-lang.org
|
||||
.. _Luvit: http://luvit.io
|
||||
.. _Julia: http://julialang.org
|
||||
.. _pyuv: https://github.com/saghul/pyuv
|
||||
.. _others: https://github.com/joyent/libuv/wiki/Projects-that-use-libuv
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
|
||||
* Asynchronous TCP and UDP sockets
|
||||
* Asynchronous DNS resolution
|
||||
* Asynchronous file and file system operations
|
||||
* File system events
|
||||
* ANSI escape code controlled TTY
|
||||
* IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
|
||||
* Child processes
|
||||
* Thread pool
|
||||
* Signal handling
|
||||
* High resolution clock
|
||||
* Threading and synchronization primitives
|
||||
|
||||
|
||||
Downloads
|
||||
---------
|
||||
|
||||
libuv can be downloaded from `here <http://dist.libuv.org/dist/>`_.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Installation instructions can be found on `the README <https://github.com/joyent/libuv/blob/master/README.md>`_.
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
design
|
||||
errors
|
||||
loop
|
||||
handle
|
||||
request
|
||||
timer
|
||||
prepare
|
||||
check
|
||||
idle
|
||||
async
|
||||
poll
|
||||
signal
|
||||
process
|
||||
stream
|
||||
tcp
|
||||
pipe
|
||||
tty
|
||||
udp
|
||||
fs_event
|
||||
fs_poll
|
||||
fs
|
||||
threadpool
|
||||
dns
|
||||
dll
|
||||
threading
|
||||
misc
|
137
deps/uv/docs/src/loop.rst
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
.. _loop:
|
||||
|
||||
:c:type:`uv_loop_t` --- Event loop
|
||||
==================================
|
||||
|
||||
The event loop is the central part of libuv's functionality. It takes care
|
||||
of polling for i/o and scheduling callbacks to be run based on different sources
|
||||
of events.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_loop_t
|
||||
|
||||
Loop data type.
|
||||
|
||||
.. c:type:: uv_run_mode
|
||||
|
||||
Mode used to run the loop with :c:func:`uv_run`.
|
||||
|
||||
::
|
||||
|
||||
typedef enum {
|
||||
UV_RUN_DEFAULT = 0,
|
||||
UV_RUN_ONCE,
|
||||
UV_RUN_NOWAIT
|
||||
} uv_run_mode;
|
||||
|
||||
.. c:type:: void (*uv_walk_cb)(uv_handle_t* handle, void* arg)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_walk`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: void* uv_loop_t.data
|
||||
|
||||
Space for user-defined arbitrary data. libuv does not use this field.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_loop_init(uv_loop_t* loop)
|
||||
|
||||
Initializes the given `uv_loop_t` structure.
|
||||
|
||||
.. c:function:: int uv_loop_close(uv_loop_t* loop)
|
||||
|
||||
Closes all internal loop resources. This function must only be called once
|
||||
the loop has finished its execution or it will return UV_EBUSY. After this
|
||||
function returns the user shall free the memory allocated for the loop.
|
||||
|
||||
.. c:function:: uv_loop_t* uv_default_loop(void)
|
||||
|
||||
Returns the initialized default loop. It may return NULL in case of
|
||||
allocation failture.
|
||||
|
||||
.. c:function:: int uv_run(uv_loop_t* loop, uv_run_mode mode)
|
||||
|
||||
This function runs the event loop. It will act differently depending on the
|
||||
specified mode:
|
||||
|
||||
- UV_RUN_DEFAULT: Runs the event loop until there are no more active and
|
||||
referenced handles or requests. Always returns zero.
|
||||
- UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if
|
||||
there are no pending callbacks. Returns zero when done (no active handles
|
||||
or requests left), or non-zero if more callbacks are expected (meaning
|
||||
you should run the event loop again sometime in the future).
|
||||
- UV_RUN_NOWAIT: Poll for i/o once but don't block if there are no
|
||||
pending callbacks. Returns zero if done (no active handles
|
||||
or requests left), or non-zero if more callbacks are expected (meaning
|
||||
you should run the event loop again sometime in the future).
|
||||
|
||||
.. c:function:: int uv_loop_alive(const uv_loop_t* loop)
|
||||
|
||||
Returns non-zero if there are active handles or request in the loop.
|
||||
|
||||
.. c:function:: void uv_stop(uv_loop_t* loop)
|
||||
|
||||
Stop the event loop, causing :c:func:`uv_run` to end as soon as
|
||||
possible. This will happen not sooner than the next loop iteration.
|
||||
If this function was called before blocking for i/o, the loop won't block
|
||||
for i/o on this iteration.
|
||||
|
||||
.. c:function:: size_t uv_loop_size(void)
|
||||
|
||||
Returns the size of the `uv_loop_t` structure. Useful for FFI binding
|
||||
writers who don't want to know the structure layout.
|
||||
|
||||
.. c:function:: int uv_backend_fd(const uv_loop_t* loop)
|
||||
|
||||
Get backend file descriptor. Only kqueue, epoll and event ports are
|
||||
supported.
|
||||
|
||||
This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to
|
||||
poll in one thread and run the event loop's callbacks in another see
|
||||
test/test-embed.c for an example.
|
||||
|
||||
.. note::
|
||||
Embedding a kqueue fd in another kqueue pollset doesn't work on all platforms. It's not
|
||||
an error to add the fd but it never generates events.
|
||||
|
||||
.. c:function:: int uv_backend_timeout(const uv_loop_t* loop)
|
||||
|
||||
Get the poll timeout. The return value is in milliseconds, or -1 for no
|
||||
timeout.
|
||||
|
||||
.. c:function:: uint64_t uv_now(const uv_loop_t* loop)
|
||||
|
||||
Return the current timestamp in milliseconds. The timestamp is cached at
|
||||
the start of the event loop tick, see :c:func:`uv_update_time` for details
|
||||
and rationale.
|
||||
|
||||
The timestamp increases monotonically from some arbitrary point in time.
|
||||
Don't make assumptions about the starting point, you will only get
|
||||
disappointed.
|
||||
|
||||
.. note::
|
||||
Use :c:func:`uv_hrtime` if you need sub-millisecond granularity.
|
||||
|
||||
.. c:function:: void uv_update_time(uv_loop_t* loop)
|
||||
|
||||
Update the event loop's concept of "now". Libuv caches the current time
|
||||
at the start of the event loop tick in order to reduce the number of
|
||||
time-related system calls.
|
||||
|
||||
You won't normally need to call this function unless you have callbacks
|
||||
that block the event loop for longer periods of time, where "longer" is
|
||||
somewhat subjective but probably on the order of a millisecond or more.
|
||||
|
||||
.. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg)
|
||||
|
||||
Walk the list of handles: `walk_cb` will be executed with the given `arg`.
|
228
deps/uv/docs/src/misc.rst
vendored
Normal file
@ -0,0 +1,228 @@
|
||||
|
||||
.. _misc:
|
||||
|
||||
Miscelaneous utilities
|
||||
======================
|
||||
|
||||
This section contains miscelaneous functions that don't really belong in any
|
||||
other section.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_buf_t
|
||||
|
||||
Buffer data type.
|
||||
|
||||
.. c:type:: uv_file
|
||||
|
||||
Cross platform representation of a file handle.
|
||||
|
||||
.. c:type:: uv_os_sock_t
|
||||
|
||||
Cross platform representation of a socket handle.
|
||||
|
||||
.. c:type:: uv_os_fd_t
|
||||
|
||||
Abstract representation of a file descriptor. On Unix systems this is a
|
||||
`typedef` of `int` and on Windows fa `HANDLE`.
|
||||
|
||||
.. c:type:: uv_rusage_t
|
||||
|
||||
Data type for resource usage results.
|
||||
|
||||
::
|
||||
|
||||
typedef struct {
|
||||
uv_timeval_t ru_utime; /* user CPU time used */
|
||||
uv_timeval_t ru_stime; /* system CPU time used */
|
||||
uint64_t ru_maxrss; /* maximum resident set size */
|
||||
uint64_t ru_ixrss; /* integral shared memory size */
|
||||
uint64_t ru_idrss; /* integral unshared data size */
|
||||
uint64_t ru_isrss; /* integral unshared stack size */
|
||||
uint64_t ru_minflt; /* page reclaims (soft page faults) */
|
||||
uint64_t ru_majflt; /* page faults (hard page faults) */
|
||||
uint64_t ru_nswap; /* swaps */
|
||||
uint64_t ru_inblock; /* block input operations */
|
||||
uint64_t ru_oublock; /* block output operations */
|
||||
uint64_t ru_msgsnd; /* IPC messages sent */
|
||||
uint64_t ru_msgrcv; /* IPC messages received */
|
||||
uint64_t ru_nsignals; /* signals received */
|
||||
uint64_t ru_nvcsw; /* voluntary context switches */
|
||||
uint64_t ru_nivcsw; /* involuntary context switches */
|
||||
} uv_rusage_t;
|
||||
|
||||
.. c:type:: uv_cpu_info_t
|
||||
|
||||
Data type for CPU information.
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_cpu_info_s {
|
||||
char* model;
|
||||
int speed;
|
||||
struct uv_cpu_times_s {
|
||||
uint64_t user;
|
||||
uint64_t nice;
|
||||
uint64_t sys;
|
||||
uint64_t idle;
|
||||
uint64_t irq;
|
||||
} cpu_times;
|
||||
} uv_cpu_info_t;
|
||||
|
||||
.. c:type:: uv_interface_address_t
|
||||
|
||||
Data type for interface addresses.
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_interface_address_s {
|
||||
char* name;
|
||||
char phys_addr[6];
|
||||
int is_internal;
|
||||
union {
|
||||
struct sockaddr_in address4;
|
||||
struct sockaddr_in6 address6;
|
||||
} address;
|
||||
union {
|
||||
struct sockaddr_in netmask4;
|
||||
struct sockaddr_in6 netmask6;
|
||||
} netmask;
|
||||
} uv_interface_address_t;
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: uv_handle_type uv_guess_handle(uv_file file)
|
||||
|
||||
Used to detect what type of stream should be used with a given file
|
||||
descriptor. Usually this will be used during initialization to guess the
|
||||
type of the stdio streams.
|
||||
|
||||
For ``isatty()`` functionality use this function and test for ``UV_TTY``.
|
||||
|
||||
.. c:function:: unsigned int uv_version(void)
|
||||
|
||||
Returns the libuv version packed into a single integer. 8 bits are used for
|
||||
each component, with the patch number stored in the 8 least significant
|
||||
bits. E.g. for libuv 1.2.3 this would return 0x010203.
|
||||
|
||||
.. c:function:: const char* uv_version_string(void)
|
||||
|
||||
Returns the libuv version number as a string. For non-release versions
|
||||
"-pre" is appended, so the version number could be "1.2.3-pre".
|
||||
|
||||
.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
|
||||
|
||||
Constructor for :c:type:`uv_buf_t`.
|
||||
|
||||
Due to platform differences the user cannot rely on the ordering of the
|
||||
`base` and `len` members of the uv_buf_t struct. The user is responsible for
|
||||
freeing `base` after the uv_buf_t is done. Return struct passed by value.
|
||||
|
||||
.. c:function:: char** uv_setup_args(int argc, char** argv)
|
||||
|
||||
Store the program arguments. Required for getting / setting the process title.
|
||||
|
||||
.. c:function:: int uv_get_process_title(char* buffer, size_t size)
|
||||
|
||||
Gets the title of the current process.
|
||||
|
||||
.. c:function:: int uv_set_process_title(const char* title)
|
||||
|
||||
Sets the current process title.
|
||||
|
||||
.. c:function:: int uv_resident_set_memory(size_t* rss)
|
||||
|
||||
Gets the resident set size (RSS) for the current process.
|
||||
|
||||
.. c:function:: int uv_uptime(double* uptime)
|
||||
|
||||
Gets the current system uptime.
|
||||
|
||||
.. c:function:: int uv_getrusage(uv_rusage_t* rusage)
|
||||
|
||||
Gets the resource usage measures for the current process.
|
||||
|
||||
.. note::
|
||||
On Windows not all fields are set, the unsupported fields are filled with zeroes.
|
||||
|
||||
.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
|
||||
|
||||
Gets information about the CPUs on the system. The `cpu_infos` array will
|
||||
have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`.
|
||||
|
||||
.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count)
|
||||
|
||||
Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`.
|
||||
|
||||
.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count)
|
||||
|
||||
Gets address information about the network interfaces on the system. An
|
||||
array of `count` elements is allocated and returned in `addresses`. It must
|
||||
be freed by the user, calling :c:func:`uv_free_interface_addresses`.
|
||||
|
||||
.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count)
|
||||
|
||||
Free an array of :c:type:`uv_interface_address_t` which was returned by
|
||||
:c:func:`uv_interface_addresses`.
|
||||
|
||||
.. c:function:: void uv_loadavg(double avg[3])
|
||||
|
||||
Gets the load average. See: http://en.wikipedia.org/wiki/Load_(computing)
|
||||
|
||||
.. note::
|
||||
Returns [0,0,0] on Windows (i.e., it's not implemented).
|
||||
|
||||
.. c:function:: int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr)
|
||||
|
||||
Convert a string containing an IPv4 addresses to a binary structure.
|
||||
|
||||
.. c:function:: int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr)
|
||||
|
||||
Convert a string containing an IPv6 addresses to a binary structure.
|
||||
|
||||
.. c:function:: int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size)
|
||||
|
||||
Convert a binary structure containing an IPv4 addres to a string.
|
||||
|
||||
.. c:function:: int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size)
|
||||
|
||||
Convert a binary structure containing an IPv6 addres to a string.
|
||||
|
||||
.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size)
|
||||
.. c:function:: int uv_inet_pton(int af, const char* src, void* dst)
|
||||
|
||||
Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()``
|
||||
and ``inet_pton()`` functions. On success they return 0. In case of error
|
||||
the target `dst` pointer is unmodified.
|
||||
|
||||
.. c:function:: int uv_exepath(char* buffer, size_t* size)
|
||||
|
||||
Gets the executable path.
|
||||
|
||||
.. c:function:: int uv_cwd(char* buffer, size_t* size)
|
||||
|
||||
Gets the current working directory.
|
||||
|
||||
.. c:function:: int uv_chdir(const char* dir)
|
||||
|
||||
Changes the current working directory.
|
||||
|
||||
.. uint64_t uv_get_free_memory(void)
|
||||
.. c:function:: uint64_t uv_get_total_memory(void)
|
||||
|
||||
Gets memory information (in bytes).
|
||||
|
||||
.. c:function:: uint64_t uv_hrtime(void)
|
||||
|
||||
Returns the current high-resolution real time. This is expressed in
|
||||
nanoseconds. It is relative to an arbitrary time in the past. It is not
|
||||
related to the time of day and therefore not subject to clock drift. The
|
||||
primary use is for measuring performance between intervals.
|
||||
|
||||
.. note::
|
||||
Not every platform can support nanosecond resolution; however, this value will always
|
||||
be in nanoseconds.
|
86
deps/uv/docs/src/pipe.rst
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
.. _pipe:
|
||||
|
||||
:c:type:`uv_pipe_t` --- Pipe handle
|
||||
===================================
|
||||
|
||||
Pipe handles provide an abstraction over local domain sockets on Unix and named
|
||||
pipes on Windows.
|
||||
|
||||
:c:type:`uv_pipe_t` is a 'subclass' of :c:type:`uv_stream_t`.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_pipe_t
|
||||
|
||||
Pipe handle type.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_stream_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc)
|
||||
|
||||
Initialize a pipe handle. The `ipc` argument is a boolean to indicate if
|
||||
this pipe will be used for handle passing between processes.
|
||||
|
||||
.. c:function:: int uv_pipe_open(uv_pipe_t*, uv_file file)
|
||||
|
||||
Open an existing file descriptor or HANDLE as a pipe.
|
||||
|
||||
.. note::
|
||||
The user is responsible for setting the dile descriptor in non-blocking mode.
|
||||
|
||||
.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name)
|
||||
|
||||
Bind the pipe to a file path (Unix) or a name (Windows).
|
||||
|
||||
.. note::
|
||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
|
||||
92 and 108 bytes.
|
||||
|
||||
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
|
||||
|
||||
Connect to the Unix domain socket or the named pipe.
|
||||
|
||||
.. note::
|
||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
|
||||
92 and 108 bytes.
|
||||
|
||||
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len)
|
||||
|
||||
Get the name of the Unix domain socket or the named pipe.
|
||||
|
||||
A preallocated buffer must be provided. The len parameter holds the length
|
||||
of the buffer and it's set to the number of bytes written to the buffer on
|
||||
output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and
|
||||
len will contain the required size.
|
||||
|
||||
.. c:function:: void uv_pipe_pending_instances(uv_pipe_t* handle, int count)
|
||||
|
||||
Set the number of pending pipe instance handles when the pipe server is
|
||||
waiting for connections.
|
||||
|
||||
.. note::
|
||||
This setting applies to Windows only.
|
||||
|
||||
.. c:function:: int uv_pipe_pending_count(uv_pipe_t* handle)
|
||||
.. c:function:: uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle)
|
||||
|
||||
Used to receive handles over IPC pipes.
|
||||
|
||||
First - call :c:func:`uv_pipe_pending_count`, if it's > 0 then initialize
|
||||
a handle of the given `type`, returned by :c:func:`uv_pipe_pending_type`
|
||||
and call ``uv_accept(pipe, handle)``.
|
||||
|
||||
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
|
99
deps/uv/docs/src/poll.rst
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
|
||||
.. _poll:
|
||||
|
||||
:c:type:`uv_poll_t` --- Poll handle
|
||||
===================================
|
||||
|
||||
Poll handles are used to watch file descriptors for readability and
|
||||
writability, similar to the purpose of poll(2).
|
||||
|
||||
The purpose of poll handles is to enable integrating external libraries that
|
||||
rely on the event loop to signal it about the socket status changes, like
|
||||
c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended;
|
||||
:c:type:`uv_tcp_t`, :c:type:`uv_udp_t`, etc. provide an implementation that is faster and
|
||||
more scalable than what can be achieved with :c:type:`uv_poll_t`, especially on
|
||||
Windows.
|
||||
|
||||
It is possible that poll handles occasionally signal that a file descriptor is
|
||||
readable or writable even when it isn't. The user should therefore always
|
||||
be prepared to handle EAGAIN or equivalent when it attempts to read from or
|
||||
write to the fd.
|
||||
|
||||
It is not okay to have multiple active poll handles for the same socket, this
|
||||
can cause libuv to busyloop or otherwise malfunction.
|
||||
|
||||
The user should not close a file descriptor while it is being polled by an
|
||||
active poll handle. This can cause the handle to report an error,
|
||||
but it might also start polling another socket. However the fd can be safely
|
||||
closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`.
|
||||
|
||||
.. note::
|
||||
On windows only sockets can be polled with poll handles. On Unix any file
|
||||
descriptor that would be accepted by poll(2) can be used.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_poll_t
|
||||
|
||||
Poll handle type.
|
||||
|
||||
.. c:type:: void (*uv_poll_cb)(uv_poll_t* handle, int status, int events)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_poll_start`.
|
||||
|
||||
.. c:type:: uv_poll_event
|
||||
|
||||
Poll event types
|
||||
|
||||
::
|
||||
|
||||
enum uv_poll_event {
|
||||
UV_READABLE = 1,
|
||||
UV_WRITABLE = 2
|
||||
};
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd)
|
||||
|
||||
Initialize the handle using a file descriptor.
|
||||
|
||||
.. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket)
|
||||
|
||||
Initialize the handle using a socket descriptor. On Unix this is identical
|
||||
to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle.
|
||||
|
||||
.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb)
|
||||
|
||||
Starts polling the file descriptor. `events` is a bitmask consisting made up
|
||||
of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback
|
||||
will be called with `status` set to 0, and the detected events set on the
|
||||
`events` field.
|
||||
|
||||
If an error happens while polling, `status` will be < 0 and corresponds
|
||||
with one of the UV_E* error codes (see :ref:`errors`). The user should
|
||||
not close the socket while the handle is active. If the user does that
|
||||
anyway, the callback *may* be called reporting an error status, but this
|
||||
is **not** guaranteed.
|
||||
|
||||
.. note::
|
||||
Calling :c:func:`uv_poll_start` on a handle that is already active is fine. Doing so
|
||||
will update the events mask that is being watched for.
|
||||
|
||||
.. c:function:: int uv_poll_stop(uv_poll_t* poll)
|
||||
|
||||
Stop polling the file descriptor, the callback will no longer be called.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
46
deps/uv/docs/src/prepare.rst
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
.. _prepare:
|
||||
|
||||
:c:type:`uv_prepare_t` --- Prepare handle
|
||||
=========================================
|
||||
|
||||
Prepare handles will run the given callback once per loop iteration, right
|
||||
before polling for i/o.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_prepare_t
|
||||
|
||||
Prepare handle type.
|
||||
|
||||
.. c:type:: void (*uv_prepare_cb)(uv_prepare_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_prepare_start`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb)
|
||||
|
||||
Start the handle with the given callback.
|
||||
|
||||
.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare)
|
||||
|
||||
Stop the handle, the callback will no longer be called.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
215
deps/uv/docs/src/process.rst
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
|
||||
.. _process:
|
||||
|
||||
:c:type:`uv_process_t` --- Process handle
|
||||
=========================================
|
||||
|
||||
Process handles will spawn a new process and allow the user to control it and
|
||||
establish communication channels with it using streams.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_process_t
|
||||
|
||||
Process handle type.
|
||||
|
||||
.. c:type:: uv_process_options_t
|
||||
|
||||
Options for spawning the process (passed to :c:func:`uv_spawn`.
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_process_options_s {
|
||||
uv_exit_cb exit_cb;
|
||||
const char* file;
|
||||
char** args;
|
||||
char** env;
|
||||
const char* cwd;
|
||||
unsigned int flags;
|
||||
int stdio_count;
|
||||
uv_stdio_container_t* stdio;
|
||||
uv_uid_t uid;
|
||||
uv_gid_t gid;
|
||||
} uv_process_options_t;
|
||||
|
||||
.. c:type:: void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal)
|
||||
|
||||
Type definition for callback passed in :c:type:`uv_process_options_t` which
|
||||
will indicate the exit status and the signal that caused the process to
|
||||
terminate, if any.
|
||||
|
||||
.. c:type:: uv_process_flags
|
||||
|
||||
Flags to be set on the flags field of :c:type:`uv_process_options_t`.
|
||||
|
||||
::
|
||||
|
||||
enum uv_process_flags {
|
||||
/*
|
||||
* Set the child process' user id.
|
||||
*/
|
||||
UV_PROCESS_SETUID = (1 << 0),
|
||||
/*
|
||||
* Set the child process' group id.
|
||||
*/
|
||||
UV_PROCESS_SETGID = (1 << 1),
|
||||
/*
|
||||
* Do not wrap any arguments in quotes, or perform any other escaping, when
|
||||
* converting the argument list into a command line string. This option is
|
||||
* only meaningful on Windows systems. On Unix it is silently ignored.
|
||||
*/
|
||||
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2),
|
||||
/*
|
||||
* Spawn the child process in a detached state - this will make it a process
|
||||
* group leader, and will effectively enable the child to keep running after
|
||||
* the parent exits. Note that the child process will still keep the
|
||||
* parent's event loop alive unless the parent process calls uv_unref() on
|
||||
* the child's process handle.
|
||||
*/
|
||||
UV_PROCESS_DETACHED = (1 << 3),
|
||||
/*
|
||||
* Hide the subprocess console window that would normally be created. This
|
||||
* option is only meaningful on Windows systems. On Unix it is silently
|
||||
* ignored.
|
||||
*/
|
||||
UV_PROCESS_WINDOWS_HIDE = (1 << 4)
|
||||
};
|
||||
|
||||
.. c:type:: uv_stdio_container_t
|
||||
|
||||
Container for each stdio handle or fd passed to a child process.
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_stdio_container_s {
|
||||
uv_stdio_flags flags;
|
||||
union {
|
||||
uv_stream_t* stream;
|
||||
int fd;
|
||||
} data;
|
||||
} uv_stdio_container_t;
|
||||
|
||||
.. c:type:: uv_stdio_flags
|
||||
|
||||
Flags specifying how a stdio should be transmitted to the child process.
|
||||
|
||||
::
|
||||
|
||||
typedef enum {
|
||||
UV_IGNORE = 0x00,
|
||||
UV_CREATE_PIPE = 0x01,
|
||||
UV_INHERIT_FD = 0x02,
|
||||
UV_INHERIT_STREAM = 0x04,
|
||||
/*
|
||||
* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
|
||||
* determine the direction of flow, from the child process' perspective. Both
|
||||
* flags may be specified to create a duplex data stream.
|
||||
*/
|
||||
UV_READABLE_PIPE = 0x10,
|
||||
UV_WRITABLE_PIPE = 0x20
|
||||
} uv_stdio_flags;
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: uv_process_t.pid
|
||||
|
||||
The PID of the spawned process. It's set after calling :c:func:`uv_spawn`.
|
||||
|
||||
.. note::
|
||||
The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
.. c:member:: uv_process_options_t.exit_cb
|
||||
|
||||
Callback called after the process exits.
|
||||
|
||||
.. c:member:: uv_process_options_t.file
|
||||
|
||||
Path pointing to the program to be executed.
|
||||
|
||||
.. c:member:: uv_process_options_t.args
|
||||
|
||||
Command line arguments. args[0] should be the path to the program. On
|
||||
Windows this uses `CreateProcess` which concatenates the arguments into a
|
||||
string this can cause some strange errors. See the
|
||||
``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`.
|
||||
|
||||
.. c:member:: uv_process_options_t.env
|
||||
|
||||
Environment for the new process. If NULL the parents environment is used.
|
||||
|
||||
.. c:member:: uv_process_options_t.cwd
|
||||
|
||||
Current working directory for the subprocess.
|
||||
|
||||
.. c:member:: uv_process_options_t.flags
|
||||
|
||||
Various flags that control how :c:func:`uv_spawn` behaves. See
|
||||
:c:type:`uv_process_flags`.
|
||||
|
||||
.. c:member:: uv_process_options_t.stdio_count
|
||||
.. c:member:: uv_process_options_t.stdio
|
||||
|
||||
The `stdio` field points to an array of :c:type:`uv_stdio_container_t`
|
||||
structs that describe the file descriptors that will be made available to
|
||||
the child process. The convention is that stdio[0] points to stdin,
|
||||
fd 1 is used for stdout, and fd 2 is stderr.
|
||||
|
||||
.. note::
|
||||
On Windows file descriptors greater than 2 are available to the child process only if
|
||||
the child processes uses the MSVCRT runtime.
|
||||
|
||||
.. c:member:: uv_process_options_t.uid
|
||||
.. c:member:: uv_process_options_t.gid
|
||||
|
||||
Libuv can change the child process' user/group id. This happens only when
|
||||
the appropriate bits are set in the flags fields.
|
||||
|
||||
.. note::
|
||||
This is not supported on Windows, :c:func:`uv_spawn` will fail and set the error
|
||||
to ``UV_ENOTSUP``.
|
||||
|
||||
.. c:member:: uv_stdio_container_t.flags
|
||||
|
||||
Flags specifying how the stdio container should be passed to the child. See
|
||||
:c:type:`uv_stdio_flags`.
|
||||
|
||||
.. c:member:: uv_stdio_container_t.data
|
||||
|
||||
Union containing either the stream or fd to be passed on to the child
|
||||
process.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: void uv_disable_stdio_inheritance(void)
|
||||
|
||||
Disables inheritance for file descriptors / handles that this process
|
||||
inherited from its parent. The effect is that child processes spawned by
|
||||
this process don't accidentally inherit these handles.
|
||||
|
||||
It is recommended to call this function as early in your program as possible,
|
||||
before the inherited file descriptors can be closed or duplicated.
|
||||
|
||||
.. note::
|
||||
This function works on a best-effort basis: there is no guarantee that libuv can discover
|
||||
all file descriptors that were inherited. In general it does a better job on Windows than
|
||||
it does on Unix.
|
||||
|
||||
.. c:function:: int uv_spawn(uv_loop_t* loop, uv_process_t* handle, const uv_process_options_t* options)
|
||||
|
||||
Initializes the process handle and starts the process. If the process is
|
||||
successfully spawned, this function will return 0. Otherwise, the
|
||||
negative error code corresponding to the reason it couldn't spawn is
|
||||
returned.
|
||||
|
||||
Possible reasons for failing to spawn would include (but not be limited to)
|
||||
the file to execute not existing, not having permissions to use the setuid or
|
||||
setgid specified, or not having enough memory to allocate for the new
|
||||
process.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
82
deps/uv/docs/src/request.rst
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
.. _request:
|
||||
|
||||
:c:type:`uv_req_t` --- Base request
|
||||
===================================
|
||||
|
||||
`uv_req_t` is the base type for all libuv request types.
|
||||
|
||||
Strcutures are aligned so that any libuv request can be cast to `uv_req_t`.
|
||||
All API functions defined here work with any request type.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_req_t
|
||||
|
||||
The base libuv request structure.
|
||||
|
||||
.. c:type:: uv_any_req
|
||||
|
||||
Union of all request types.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: void* uv_request_t.data
|
||||
|
||||
Space for user-defined arbitrary data. libuv does not use this field.
|
||||
|
||||
.. c:member:: uv_req_type uv_req_t.type
|
||||
|
||||
Indicated the type of request. Readonly.
|
||||
|
||||
::
|
||||
|
||||
typedef enum {
|
||||
UV_UNKNOWN_REQ = 0,
|
||||
UV_REQ,
|
||||
UV_CONNECT,
|
||||
UV_WRITE,
|
||||
UV_SHUTDOWN,
|
||||
UV_UDP_SEND,
|
||||
UV_FS,
|
||||
UV_WORK,
|
||||
UV_GETADDRINFO,
|
||||
UV_GETNAMEINFO,
|
||||
UV_REQ_TYPE_PRIVATE,
|
||||
UV_REQ_TYPE_MAX,
|
||||
} uv_req_type;
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_cancel(uv_req_t* req)
|
||||
|
||||
Cancel a pending request. Fails if the request is executing or has finished
|
||||
executing.
|
||||
|
||||
Returns 0 on success, or an error code < 0 on failure.
|
||||
|
||||
Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`,
|
||||
:c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is
|
||||
currently supported.
|
||||
|
||||
Cancelled requests have their callbacks invoked some time in the future.
|
||||
It's **not** safe to free the memory associated with the request until the
|
||||
callback is called.
|
||||
|
||||
Here is how cancellation is reported to the callback:
|
||||
|
||||
* A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`.
|
||||
|
||||
* A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t`
|
||||
request has its callback invoked with status == `UV_ECANCELED`.
|
||||
|
||||
.. c:function:: size_t uv_req_size(uv_req_type type)
|
||||
|
||||
Returns the size of the given request type. Useful for FFI binding writers
|
||||
who don't want to know the structure layout.
|
77
deps/uv/docs/src/signal.rst
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
.. _signal:
|
||||
|
||||
:c:type:`uv_signal_t` --- Signal handle
|
||||
=======================================
|
||||
|
||||
Signal handles implement Unix style signal handling on a per-event loop bases.
|
||||
|
||||
Reception of some signals is emulated on Windows:
|
||||
|
||||
* SIGINT is normally delivered when the user presses CTRL+C. However, like
|
||||
on Unix, it is not generated when terminal raw mode is enabled.
|
||||
|
||||
* SIGBREAK is delivered when the user pressed CTRL + BREAK.
|
||||
|
||||
* SIGHUP is generated when the user closes the console window. On SIGHUP the
|
||||
program is given approximately 10 seconds to perform cleanup. After that
|
||||
Windows will unconditionally terminate it.
|
||||
|
||||
* SIGWINCH is raised whenever libuv detects that the console has been
|
||||
resized. SIGWINCH is emulated by libuv when the program uses a :c:type:`uv_tty_t`
|
||||
handle to write to the console. SIGWINCH may not always be delivered in a
|
||||
timely manner; libuv will only detect size changes when the cursor is
|
||||
being moved. When a readable :c:type:`uv_tty_t` handle is used in raw mode,
|
||||
resizing the console buffer will also trigger a SIGWINCH signal.
|
||||
|
||||
Watchers for other signals can be successfully created, but these signals
|
||||
are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`,
|
||||
`SIGTERM` and `SIGKILL.`
|
||||
|
||||
Calls to raise() or abort() to programmatically raise a signal are
|
||||
not detected by libuv; these will not trigger a signal watcher.
|
||||
|
||||
.. note::
|
||||
On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to
|
||||
manage threads. Installing watchers for those signals will lead to unpredictable behavior
|
||||
and is strongly discouraged. Future versions of libuv may simply reject them.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_signal_t
|
||||
|
||||
Signal handle type.
|
||||
|
||||
.. c:type:: void (*uv_signal_cb)(uv_signal_t* handle, int signum)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_signal_start`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: int uv_signal_t.signum
|
||||
|
||||
Signal being monitored by this handle. Readonly.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_signal_init(uv_loop_t*, uv_signal_t* signal)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_signal_start(uv_signal_t* signal, uv_signal_cb cb, int signum)
|
||||
|
||||
Start the handle with the given callback, watching for the given signal.
|
||||
|
||||
.. c:function:: int uv_signal_stop(uv_signal_t* signal)
|
||||
|
||||
Stop the handle, the callback will no longer be called.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
BIN
deps/uv/docs/src/static/architecture.png
vendored
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg
vendored
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/Index.zip
vendored
Normal file
8
deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<string>Template: White (2014-02-28 09:41)</string>
|
||||
<string>M6.2.2-1878-1</string>
|
||||
</array>
|
||||
</plist>
|
1
deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier
vendored
Normal file
@ -0,0 +1 @@
|
||||
F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA
|
BIN
deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist
vendored
Normal file
BIN
deps/uv/docs/src/static/diagrams.key/preview-micro.jpg
vendored
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/preview-web.jpg
vendored
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/preview.jpg
vendored
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
deps/uv/docs/src/static/favicon.ico
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
deps/uv/docs/src/static/logo.png
vendored
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
deps/uv/docs/src/static/loop_iteration.png
vendored
Normal file
After Width: | Height: | Size: 79 KiB |
189
deps/uv/docs/src/stream.rst
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
|
||||
.. _stream:
|
||||
|
||||
:c:type:`uv_stream_t` --- Stream handle
|
||||
=======================================
|
||||
|
||||
Stream handles provide an abstraction of a duplex communication channel.
|
||||
:c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations
|
||||
in the for of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_stream_t
|
||||
|
||||
Stream handle type.
|
||||
|
||||
.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||
|
||||
Callback called when data was read on a stream.
|
||||
|
||||
`nread` is > 0 if there is data available, 0 if libuv is done reading for
|
||||
now, or < 0 on error.
|
||||
|
||||
The callee is responsible for stopping closing the stream when an error happens
|
||||
by calling :c:func:`uv_read_stop` or :c:func:`uv_close`. Trying to read
|
||||
from the stream again is undefined.
|
||||
|
||||
The callee is responsible for freeing the buffer, libuv does not reuse it.
|
||||
The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on
|
||||
error.
|
||||
|
||||
.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status)
|
||||
|
||||
Callback called after data was written on a stream. `status` will be 0 in
|
||||
case of success, < 0 otherwise.
|
||||
|
||||
.. c:type:: void (*uv_connect_cb)(uv_connect_t* req, int status)
|
||||
|
||||
Callback called after a connection started by :c:func:`uv_connect` is done.
|
||||
`status` will be 0 in case of success, < 0 otherwise.
|
||||
|
||||
.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status)
|
||||
|
||||
Callback called after s shutdown request has been completed. `status` will
|
||||
be 0 in case of success, < 0 otherwise.
|
||||
|
||||
.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status)
|
||||
|
||||
Callback called when a stream server has received an incoming connection.
|
||||
The user can accept the connection by calling :c:func:`uv_accept`.
|
||||
`status` will de 0 in case of success, < 0 otherwise.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: size_t uv_stream_t.write_queue_size
|
||||
|
||||
Contains the amount of queued bytes waiting to be sent. Readonly.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb)
|
||||
|
||||
Shutdown the outgoing (write) side of a duplex stream. It waits for pending
|
||||
write requests to complete. The `handle` should refer to a initialized stream.
|
||||
`req` should be an uninitialized shutdown request struct. The `cb` is called
|
||||
after shutdown is complete.
|
||||
|
||||
.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb)
|
||||
|
||||
Start listening for incoming connections. `backlog` indicates the number of
|
||||
connections the kernel might queue, same as ``listen(2)``. When a new
|
||||
incoming connection is received the :c:type:`uv_connection_cb` callback is
|
||||
called.
|
||||
|
||||
.. c:function:: int uv_accept(uv_stream_t* server, uv_stream_t* client)
|
||||
|
||||
This call is used in conjunction with :c:func:`uv_listen` to accept incoming
|
||||
connections. Call this function after receiving a :c:type:`uv_connection_cb`
|
||||
to accept the connection. Before calling this function the client handle must
|
||||
be initialized. < 0 return value indicates an error.
|
||||
|
||||
When the :c:type:`uv_connection_cb` callback is called it is guaranteed that
|
||||
this function will complete successfully the first time. If you attempt to use
|
||||
it more than once, it may fail. It is suggested to only call this function once
|
||||
per :c:type:`uv_connection_cb` call.
|
||||
|
||||
.. note::
|
||||
`server` and `client` must be handles running on the same loop.
|
||||
|
||||
.. c:function:: int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
|
||||
|
||||
Read data from an incoming stream. The callback will be made several
|
||||
times until there is no more data to read or :c:func:`uv_read_stop` is called.
|
||||
When we've reached EOF `nread` will be set to ``UV_EOF``.
|
||||
|
||||
When `nread` < 0, the `buf` parameter might not point to a valid buffer;
|
||||
in that case `buf.len` and `buf.base` are both set to 0.
|
||||
|
||||
.. note::
|
||||
`nread` might also be 0, which does *not* indicate an error or EOF, it happens when
|
||||
libuv requested a buffer through the alloc callback but then decided that it didn't
|
||||
need that buffer.
|
||||
|
||||
.. c:function:: int uv_read_stop(uv_stream_t*)
|
||||
|
||||
Stop reading data from the stream. The :c:type:`uv_read_cb` callback will
|
||||
no longer be called.
|
||||
|
||||
.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
|
||||
|
||||
Write data to stream. Buffers are written in order. Example:
|
||||
|
||||
::
|
||||
|
||||
uv_buf_t a[] = {
|
||||
{ .base = "1", .len = 1 },
|
||||
{ .base = "2", .len = 1 }
|
||||
};
|
||||
|
||||
uv_buf_t b[] = {
|
||||
{ .base = "3", .len = 1 },
|
||||
{ .base = "4", .len = 1 }
|
||||
};
|
||||
|
||||
uv_write_t req1;
|
||||
uv_write_t req2;
|
||||
|
||||
/* writes "1234" */
|
||||
uv_write(&req1, stream, a, 2);
|
||||
uv_write(&req2, stream, b, 2);
|
||||
|
||||
.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb)
|
||||
|
||||
Extended write function for sending handles over a pipe. The pipe must be
|
||||
initialized with `ipc` == 1.
|
||||
|
||||
.. note::
|
||||
`send_handle` must be a TCP socket or pipe, which is a server or a connection (listening
|
||||
or connected state). Bound sockets or pipes will be assumed to be servers.
|
||||
|
||||
.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)
|
||||
|
||||
Same as :c:func:`uv_write`, but won't queue a write request if it can't be
|
||||
completed immediately.
|
||||
|
||||
Will return either:
|
||||
|
||||
* > 0: number of bytes written (can be less than the supplied buffer size).
|
||||
* < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent
|
||||
immediately).
|
||||
|
||||
.. c:function:: int uv_is_readable(const uv_stream_t* handle)
|
||||
|
||||
Returns 1 if the stream is readable, 0 otherwise.
|
||||
|
||||
.. c:function:: int uv_is_writable(const uv_stream_t* handle)
|
||||
|
||||
Returns 1 if the stream is writable, 0 otherwise.
|
||||
|
||||
.. c:function:: int uv_stream_set_blocking(uv_stream_t* handle, int blocking)
|
||||
|
||||
Enable or disable blocking mode for a stream.
|
||||
|
||||
When blocking mode is enabled all writes complete synchronously. The
|
||||
interface remains unchanged otherwise, e.g. completion or failure of the
|
||||
operation will still be reported through a callback which is made
|
||||
asychronously.
|
||||
|
||||
.. warning::
|
||||
Relying too much on this API is not recommended. It is likely to change
|
||||
significantly in the future.
|
||||
|
||||
Currently this only works on Windows and only for
|
||||
:c:type:`uv_pipe_t` handles.
|
||||
|
||||
Also libuv currently makes no ordering guarantee when the blocking mode
|
||||
is changed after write requests have already been submitted. Therefore it is
|
||||
recommended to set the blocking mode immediately after opening or creating
|
||||
the stream.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
97
deps/uv/docs/src/tcp.rst
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
|
||||
.. _tcp:
|
||||
|
||||
:c:type:`uv_tcp_t` --- TCP handle
|
||||
=================================
|
||||
|
||||
TCP handles are used to represent both TCP streams and servers.
|
||||
|
||||
:c:type:`uv_tcp_t` is a 'subclass' of :c:type:`uv_stream_t`.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_tcp_t
|
||||
|
||||
TCP handle type.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_stream_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock)
|
||||
|
||||
Open an existing file descriptor or SOCKET as a TCP handle.
|
||||
|
||||
.. note::
|
||||
The user is responsible for setting the file descriptor in
|
||||
non-blocking mode.
|
||||
|
||||
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)
|
||||
|
||||
Enable / disable Nagle's algorithm.
|
||||
|
||||
.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay)
|
||||
|
||||
Enable / disable TCP keep-alive. `delay` is the initial delay in seconds,
|
||||
ignored when `enable` is zero.
|
||||
|
||||
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
|
||||
|
||||
Enable / disable simultaneous asynchronous accept requests that are
|
||||
queued by the operating system when listening for new TCP connections.
|
||||
|
||||
This setting is used to tune a TCP server for the desired performance.
|
||||
Having simultaneous accepts can significantly improve the rate of accepting
|
||||
connections (which is why it is enabled by default) but may lead to uneven
|
||||
load distribution in multi-process setups.
|
||||
|
||||
.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
||||
|
||||
Bind the handle to an address and port. `addr` should point to an
|
||||
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
|
||||
|
||||
When the port is already taken, you can expect to see an ``UV_EADDRINUSE``
|
||||
error from either :c:func:`uv_tcp_bind`, :c:func:`uv_listen` or
|
||||
:c:func:`uv_tcp_connect`. That is, a successful call to this function does
|
||||
not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect`
|
||||
will succeed as well.
|
||||
|
||||
`flags` con contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
|
||||
is disabled and only IPv6 is used.
|
||||
|
||||
.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
|
||||
|
||||
Get the current address to which the handle is bound. `addr` must point to
|
||||
a valid and big enough chunk of memory, ``struct sockaddr_storage`` is
|
||||
recommended for IPv4 and IPv6 support.
|
||||
|
||||
.. c:function:: int uv_tcp_getpeername(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
|
||||
|
||||
Get the address of the peer connected to the handle. `addr` must point to
|
||||
a valid and big enough chunk of memory, ``struct sockaddr_storage`` is
|
||||
recommended for IPv4 and IPv6 support.
|
||||
|
||||
.. c:function:: int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, uv_connect_cb cb)
|
||||
|
||||
Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle
|
||||
and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an
|
||||
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
|
||||
|
||||
The callback is made when the connection has been established or when a
|
||||
connection error happened.
|
||||
|
||||
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
|
156
deps/uv/docs/src/threading.rst
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
|
||||
.. _threading:
|
||||
|
||||
Threading and synchronization utilities
|
||||
=======================================
|
||||
|
||||
libuv provides cross-platform implementations for multiple threading and
|
||||
synchronization primitives. The API largely follows the pthreads API.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_thread_t
|
||||
|
||||
Thread data type.
|
||||
|
||||
.. c:type:: void (*uv_thread_cb)(void* arg)
|
||||
|
||||
Callback that is invoked to initialize thread execution. `arg` is the same
|
||||
value that was passed to :c:func:`uv_thread_create`.
|
||||
|
||||
.. c:type:: uv_key_t
|
||||
|
||||
Thread-local key data type.
|
||||
|
||||
.. c:type:: uv_once_t
|
||||
|
||||
Once-only initializer data type.
|
||||
|
||||
.. c:type:: uv_mutex_t
|
||||
|
||||
Mutex data type.
|
||||
|
||||
.. c:type:: uv_rwlock_t
|
||||
|
||||
Read-write lock data type.
|
||||
|
||||
.. c:type:: uv_sem_t
|
||||
|
||||
Semaphore data type.
|
||||
|
||||
.. c:type:: uv_cond_t
|
||||
|
||||
Condition data type.
|
||||
|
||||
.. c:type:: uv_barrier_t
|
||||
|
||||
Barrier data type.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
Threads
|
||||
^^^^^^^
|
||||
|
||||
.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
|
||||
.. c:function:: unsigned long uv_thread_self(void)
|
||||
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
||||
|
||||
Thread-local storage
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
The total thread-local storage size may be limited. That is, it may not be possible to
|
||||
create many TLS keys.
|
||||
|
||||
.. c:function:: int uv_key_create(uv_key_t* key)
|
||||
.. c:function:: void uv_key_delete(uv_key_t* key)
|
||||
.. c:function:: void* uv_key_get(uv_key_t* key)
|
||||
.. c:function:: void uv_key_set(uv_key_t* key, void* value)
|
||||
|
||||
Once-only initialization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the
|
||||
same guard will block all callers except one (it's unspecified which one).
|
||||
The guard should be initialized statically with the UV_ONCE_INIT macro.
|
||||
|
||||
.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void))
|
||||
|
||||
Mutex locks
|
||||
^^^^^^^^^^^
|
||||
|
||||
Functions return 0 on success or an error code < 0 (unless the
|
||||
return type is void, of course).
|
||||
|
||||
.. c:function:: int uv_mutex_init(uv_mutex_t* handle)
|
||||
.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle)
|
||||
.. c:function:: void uv_mutex_lock(uv_mutex_t* handle)
|
||||
.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle)
|
||||
.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle)
|
||||
|
||||
Read-write locks
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Functions return 0 on success or an error code < 0 (unless the
|
||||
return type is void, of course).
|
||||
|
||||
.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock)
|
||||
.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock)
|
||||
.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock)
|
||||
.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock)
|
||||
.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock)
|
||||
.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock)
|
||||
.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock)
|
||||
.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock)
|
||||
|
||||
Semaphores
|
||||
^^^^^^^^^^
|
||||
|
||||
Functions return 0 on success or an error code < 0 (unless the
|
||||
return type is void, of course).
|
||||
|
||||
.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value)
|
||||
.. c:function:: void uv_sem_destroy(uv_sem_t* sem)
|
||||
.. c:function:: void uv_sem_post(uv_sem_t* sem)
|
||||
.. c:function:: void uv_sem_wait(uv_sem_t* sem)
|
||||
.. c:function:: int uv_sem_trywait(uv_sem_t* sem)
|
||||
|
||||
Conditions
|
||||
^^^^^^^^^^
|
||||
|
||||
Functions return 0 on success or an error code < 0 (unless the
|
||||
return type is void, of course).
|
||||
|
||||
.. note::
|
||||
Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` and
|
||||
:c:func:`uv_cond_timedwait`.
|
||||
|
||||
.. c:function:: int uv_cond_init(uv_cond_t* cond)
|
||||
.. c:function:: void uv_cond_destroy(uv_cond_t* cond)
|
||||
.. c:function:: void uv_cond_signal(uv_cond_t* cond)
|
||||
.. c:function:: void uv_cond_broadcast(uv_cond_t* cond)
|
||||
.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex)
|
||||
.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout)
|
||||
|
||||
Barriers
|
||||
^^^^^^^^
|
||||
|
||||
Functions return 0 on success or an error code < 0 (unless the
|
||||
return type is void, of course).
|
||||
|
||||
.. note::
|
||||
:c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread
|
||||
to facilitate cleanup, i.e.
|
||||
|
||||
::
|
||||
|
||||
if (uv_barrier_wait(&barrier) > 0)
|
||||
uv_barrier_destroy(&barrier);
|
||||
|
||||
.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count)
|
||||
.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier)
|
||||
.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier)
|
59
deps/uv/docs/src/threadpool.rst
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
.. _threadpool:
|
||||
|
||||
Thread pool work scheduling
|
||||
===========================
|
||||
|
||||
libuv provides a threadpool which can be used to run user code and get notified
|
||||
in the loop thread. This thread pool is internally used to run al filesystem
|
||||
operations, as well as getaddrinfo and getnameinfo requests.
|
||||
|
||||
Its default size is 4, but it can be changed at startup time by setting the
|
||||
``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum
|
||||
is 128).
|
||||
|
||||
The threadpool is global and shared across all event loops.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_work_t
|
||||
|
||||
Work request type.
|
||||
|
||||
.. c:type:: void (*uv_work_cb)(uv_work_t* req)
|
||||
|
||||
Callback passed to :c:func:`uv_queue_work` which will be run on the thread
|
||||
pool.
|
||||
|
||||
.. c:type:: void (*uv_after_work_cb)(uv_work_t* req, int status)
|
||||
|
||||
Callback passed to :c:func:`uv_queue_work` which will be called on the loop
|
||||
thread after the work on the threadpool has been completed. If the work
|
||||
was cancelled using :c:func:`uv_cancel` `status` will be ``UV_ECANCELED``.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: uv_loop_t* uv_work_t.loop
|
||||
|
||||
Loop that started this request and where completion will be reported.
|
||||
Readonly.
|
||||
|
||||
.. seealso:: The :c:type:`uv_req_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb)
|
||||
|
||||
Initializes a work request which will run the given `work_cb` in a thread
|
||||
from the threadpool. Once `work_cb` is completed, `after_work_cb` will be
|
||||
called on the loop thread.
|
||||
|
||||
This request can be cancelled with :c:func:`uv_cancel`.
|
||||
|
||||
.. seealso:: The :c:type:`uv_req_t` API functions also apply.
|
68
deps/uv/docs/src/timer.rst
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
.. _timer:
|
||||
|
||||
:c:type:`uv_timer_t` --- Timer handle
|
||||
=====================================
|
||||
|
||||
Timer handles are used to schedule callbacks to be called in the future.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_timer_t
|
||||
|
||||
Timer handle type.
|
||||
|
||||
.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_timer_start`.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
|
||||
|
||||
Start the timer. `timeout` and `repeat` are in milliseconds.
|
||||
|
||||
If `timeout` is zero, the callback fires on the next event loop iteration.
|
||||
If `repeat` is non-zero, the callback fires first after `timeout`
|
||||
milliseconds and then repeatedly after `repeat` milliseconds.
|
||||
|
||||
.. c:function:: int uv_timer_stop(uv_timer_t* handle)
|
||||
|
||||
Stop the timer, the callback will not be called anymore.
|
||||
|
||||
.. c:function:: int uv_timer_again(uv_timer_t* handle)
|
||||
|
||||
Stop the timer, and if it is repeating restart it using the repeat value
|
||||
as the timeout. If the timer has never been started before it returns
|
||||
UV_EINVAL.
|
||||
|
||||
.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat)
|
||||
|
||||
Set the repeat value in milliseconds.
|
||||
|
||||
.. note::
|
||||
If the repeat value is set from a timer callback it does not immediately take effect.
|
||||
If the timer was non-repeating before, it will have been stopped. If it was repeating,
|
||||
then the old repeat value will have been used to schedule the next timeout.
|
||||
|
||||
.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle)
|
||||
|
||||
Get the timer repeat value.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
63
deps/uv/docs/src/tty.rst
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
.. _tty:
|
||||
|
||||
:c:type:`uv_tty_t` --- TTY handle
|
||||
=================================
|
||||
|
||||
TTY handles represent a stream for the console.
|
||||
|
||||
:c:type:`uv_tty_t` is a 'subclass' of :c:type:`uv_stream_t`.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_tty_t
|
||||
|
||||
TTY handle type.
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
N/A
|
||||
|
||||
.. seealso:: The :c:type:`uv_stream_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable)
|
||||
|
||||
Initialize a new TTY stream with the given file descriptor. Usually the
|
||||
file descriptor will be:
|
||||
|
||||
* 0 = stdin
|
||||
* 1 = stdout
|
||||
* 2 = stderr
|
||||
|
||||
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with
|
||||
this stream. stdin is readable, stdout is not.
|
||||
|
||||
.. note::
|
||||
TTY streams which are not readable have blocking writes.
|
||||
|
||||
.. c:function:: int uv_tty_set_mode(uv_tty_t*, int mode)
|
||||
|
||||
Set the TTY mode. 0 for normal, 1 for raw.
|
||||
|
||||
.. c:function:: int uv_tty_reset_mode(void)
|
||||
|
||||
To be called when the program exits. Resets TTY settings to default
|
||||
values for the next process to take over.
|
||||
|
||||
This function is async signal-safe on Unix platforms but can fail with error
|
||||
code ``UV_EBUSY`` if you call it when execution is inside
|
||||
:c:func:`uv_tty_set_mode`.
|
||||
|
||||
.. c:function:: int uv_tty_get_winsize(uv_tty_t*, int* width, int* height)
|
||||
|
||||
Gets the current Window size. On success it returns 0.
|
||||
|
||||
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
|
280
deps/uv/docs/src/udp.rst
vendored
Normal file
@ -0,0 +1,280 @@
|
||||
|
||||
.. _udp:
|
||||
|
||||
:c:type:`uv_udp_t` --- UDP handle
|
||||
=================================
|
||||
|
||||
UDP handles encapsulate UDP communication for both clients and servers.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
.. c:type:: uv_udp_t
|
||||
|
||||
UDP handle type.
|
||||
|
||||
.. c:type:: uv_udp_send_t
|
||||
|
||||
UDP send request type.
|
||||
|
||||
.. c:type:: uv_udp_flags
|
||||
|
||||
Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`..
|
||||
|
||||
::
|
||||
|
||||
enum uv_udp_flags {
|
||||
/* Disables dual stack mode. */
|
||||
UV_UDP_IPV6ONLY = 1,
|
||||
/*
|
||||
* Indicates message was truncated because read buffer was too small. The
|
||||
* remainder was discarded by the OS. Used in uv_udp_recv_cb.
|
||||
*/
|
||||
UV_UDP_PARTIAL = 2,
|
||||
/*
|
||||
* Indicates if SO_REUSEADDR will be set when binding the handle in
|
||||
* uv_udp_bind.
|
||||
* This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
|
||||
* Unix platforms, it sets the SO_REUSEADDR flag. What that means is that
|
||||
* multiple threads or processes can bind to the same address without error
|
||||
* (provided they all set the flag) but only the last one to bind will receive
|
||||
* any traffic, in effect "stealing" the port from the previous listener.
|
||||
*/
|
||||
UV_UDP_REUSEADDR = 4
|
||||
};
|
||||
|
||||
.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_udp_send`, which is
|
||||
called after the data was sent.
|
||||
|
||||
.. c:type:: void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_udp_recv_start`, which
|
||||
is called when the endpoint receives data.
|
||||
|
||||
* `handle`: UDP handle
|
||||
* `nread`: Number of bytes that have been received.
|
||||
0 if there is no more data to read. You may discard or repurpose
|
||||
the read buffer. Note that 0 may also mean that an empty datagram
|
||||
was received (in this case `addr` is not NULL). < 0 if a transmission
|
||||
error was detected.
|
||||
* `buf`: :c:type:`uv_buf_t` with the received data.
|
||||
* `addr`: ``struct sockaddr*`` containing the address of the sender.
|
||||
Can be NULL. Valid for the duration of the callback only.
|
||||
* `flags`: One or more or'ed UV_UDP_* constants. Right now only
|
||||
``UV_UDP_PARTIAL`` is used.
|
||||
|
||||
.. note::
|
||||
The receive callback will be called with `nread` == 0 and `addr` == NULL when there is
|
||||
nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is
|
||||
received.
|
||||
|
||||
.. c:type:: uv_membership
|
||||
|
||||
Membership type for a multicast address.
|
||||
|
||||
::
|
||||
|
||||
typedef enum {
|
||||
UV_LEAVE_GROUP = 0,
|
||||
UV_JOIN_GROUP
|
||||
} uv_membership;
|
||||
|
||||
|
||||
Public members
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
.. c:member:: size_t uv_udp_t.send_queue_size
|
||||
|
||||
Number of bytes queued for sending. This field strictly shows how much
|
||||
information is currently queued.
|
||||
|
||||
.. c:member:: size_t uv_udp_t.send_queue_count
|
||||
|
||||
Number of send requests currently in the queue awaiting to be processed.
|
||||
|
||||
.. c:member:: uv_udp_t* uv_udp_send_t.handle
|
||||
|
||||
UDP handle where this send request is taking place.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_udp_init(uv_loop_t*, uv_udp_t* handle)
|
||||
|
||||
Initialize a new UDP handle. The actual socket is created lazily.
|
||||
Returns 0 on success.
|
||||
|
||||
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
|
||||
|
||||
Opens an existing file descriptor or Windows SOCKET as a UDP handle.
|
||||
|
||||
Unix only:
|
||||
The only requirement of the `sock` argument is that it follows the datagram
|
||||
contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc).
|
||||
In other words, other datagram-type sockets like raw sockets or netlink
|
||||
sockets can also be passed to this function.
|
||||
|
||||
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
||||
|
||||
Bind the UDP handle to an IP address and port.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param addr: `struct sockaddr_in` or `struct sockaddr_in6`
|
||||
with the address and port to bind to.
|
||||
|
||||
:param flags: Indicate how the socket will be bound,
|
||||
``UV_UDP_IPV6ONLY`` and ``UV_UDP_REUSEADDR`` are supported.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen)
|
||||
|
||||
Get the local IP and port of the UDP handle.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init` and bound.
|
||||
|
||||
:param name: Pointer to the structure to be filled with the address data.
|
||||
In order to support IPv4 and IPv6 `struct sockaddr_storage` should be
|
||||
used.
|
||||
|
||||
:param namelen: On input it indicates the data of the `name` field. On
|
||||
output it indicates how much of it was filled.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership)
|
||||
|
||||
Set membership for a multicast address
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param multicast_addr: Multicast address to set membership for.
|
||||
|
||||
:param interface_addr: Interface address.
|
||||
|
||||
:param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on)
|
||||
|
||||
Set IP multicast loop flag. Makes multicast packets loop back to
|
||||
local sockets.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param on: 1 for on, 0 for off.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl)
|
||||
|
||||
Set the multicast ttl.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param ttl: 1 through 255.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
|
||||
Set the multicast interface to send or receive data on.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param interface_addr: interface address.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_set_broadcast(uv_udp_t* handle, int on)
|
||||
|
||||
Set broadcast on or off.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param on: 1 for on, 0 for off.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_set_ttl(uv_udp_t* handle, int ttl)
|
||||
|
||||
Set the time to live.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param ttl: 1 through 255.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, uv_udp_send_cb send_cb)
|
||||
|
||||
Send data over the UDP socket. If the socket has not previously been bound
|
||||
with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0
|
||||
(the "all interfaces" IPv4 address) and a random port number.
|
||||
|
||||
:param req: UDP request handle. Need not be initialized.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param bufs: List of buffers to send.
|
||||
|
||||
:param nbufs: Number of buffers in `bufs`.
|
||||
|
||||
:param addr: `struct sockaddr_in` or `struct sockaddr_in6` with the
|
||||
address and port of the remote peer.
|
||||
|
||||
:param send_cb: Callback to invoke when the data has been sent out.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr)
|
||||
|
||||
Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't
|
||||
be completed immediately.
|
||||
|
||||
:returns: >= 0: number of bytes sent (it matches the given buffer size).
|
||||
< 0: negative error code (``UV_EAGAIN`` is returned when the message
|
||||
can't be sent immediately).
|
||||
|
||||
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
|
||||
|
||||
Prepare for receiving data. If the socket has not previously been bound
|
||||
with :c:func:`uv_udp_bind` it is bound to 0.0.0.0 (the "all interfaces"
|
||||
IPv4 address) and a random port number.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param alloc_cb: Callback to invoke when temporary storage is needed.
|
||||
|
||||
:param recv_cb: Callback to invoke with received data.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle)
|
||||
|
||||
Stop listening for incoming datagrams.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
6
deps/uv/include/uv-errno.h
vendored
@ -57,12 +57,6 @@
|
||||
# define UV__EACCES (-4092)
|
||||
#endif
|
||||
|
||||
#if defined(EADDRINFO) && !defined(_WIN32)
|
||||
# define UV__EADDRINFO EADDRINFO
|
||||
#else
|
||||
# define UV__EADDRINFO (-4091)
|
||||
#endif
|
||||
|
||||
#if defined(EADDRINUSE) && !defined(_WIN32)
|
||||
# define UV__EADDRINUSE (-EADDRINUSE)
|
||||
#else
|
||||
|
47
deps/uv/include/uv-unix.h
vendored
@ -25,6 +25,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -117,13 +118,14 @@ struct uv__async {
|
||||
#endif
|
||||
|
||||
/* Note: May be cast to struct iovec. See writev(2). */
|
||||
typedef struct {
|
||||
typedef struct uv_buf_t {
|
||||
char* base;
|
||||
size_t len;
|
||||
} uv_buf_t;
|
||||
|
||||
typedef int uv_file;
|
||||
typedef int uv_os_sock_t;
|
||||
typedef int uv_os_fd_t;
|
||||
|
||||
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
|
||||
@ -155,6 +157,47 @@ typedef pthread_barrier_t uv_barrier_t;
|
||||
typedef gid_t uv_gid_t;
|
||||
typedef uid_t uv_uid_t;
|
||||
|
||||
typedef struct dirent uv__dirent_t;
|
||||
|
||||
#if defined(DT_UNKNOWN)
|
||||
# define HAVE_DIRENT_TYPES
|
||||
# if defined(DT_REG)
|
||||
# define UV__DT_FILE DT_REG
|
||||
# else
|
||||
# define UV__DT_FILE -1
|
||||
# endif
|
||||
# if defined(DT_DIR)
|
||||
# define UV__DT_DIR DT_DIR
|
||||
# else
|
||||
# define UV__DT_DIR -2
|
||||
# endif
|
||||
# if defined(DT_LNK)
|
||||
# define UV__DT_LINK DT_LNK
|
||||
# else
|
||||
# define UV__DT_LINK -3
|
||||
# endif
|
||||
# if defined(DT_FIFO)
|
||||
# define UV__DT_FIFO DT_FIFO
|
||||
# else
|
||||
# define UV__DT_FIFO -4
|
||||
# endif
|
||||
# if defined(DT_SOCK)
|
||||
# define UV__DT_SOCKET DT_SOCK
|
||||
# else
|
||||
# define UV__DT_SOCKET -5
|
||||
# endif
|
||||
# if defined(DT_CHR)
|
||||
# define UV__DT_CHAR DT_CHR
|
||||
# else
|
||||
# define UV__DT_CHAR -6
|
||||
# endif
|
||||
# if defined(DT_BLK)
|
||||
# define UV__DT_BLOCK DT_BLK
|
||||
# else
|
||||
# define UV__DT_BLOCK -7
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Platform-specific definitions for uv_dlopen support. */
|
||||
#define UV_DYNAMIC /* empty */
|
||||
|
||||
@ -176,7 +219,7 @@ typedef struct {
|
||||
uv_async_t wq_async; \
|
||||
uv_rwlock_t cloexec_lock; \
|
||||
uv_handle_t* closing_handles; \
|
||||
void* process_handles[1][2]; \
|
||||
void* process_handles[2]; \
|
||||
void* prepare_handles[2]; \
|
||||
void* check_handles[2]; \
|
||||
void* idle_handles[2]; \
|
||||
|
13
deps/uv/include/uv-version.h
vendored
@ -23,16 +23,17 @@
|
||||
#define UV_VERSION_H
|
||||
|
||||
/*
|
||||
* Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
|
||||
* stable. When the minor version is odd, the API can change between patch
|
||||
* releases. Make sure you update the -soname directives in configure.ac
|
||||
* Versions with the same major number are ABI stable. API is allowed to
|
||||
* evolve between minor releases, but only in a backwards compatible way.
|
||||
* Make sure you update the -soname directives in configure.ac
|
||||
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
|
||||
* not UV_VERSION_PATCH.)
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 0
|
||||
#define UV_VERSION_MINOR 11
|
||||
#define UV_VERSION_PATCH 28
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 0
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX "rc1"
|
||||
|
||||
#endif /* UV_VERSION_H */
|
||||
|
34
deps/uv/include/uv-win.h
vendored
@ -39,6 +39,20 @@ typedef struct pollfd {
|
||||
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
|
||||
#endif
|
||||
|
||||
#ifndef LOCALE_INVARIANT
|
||||
# define LOCALE_INVARIANT 0x007f
|
||||
#endif
|
||||
|
||||
#ifndef _malloca
|
||||
# if defined(_DEBUG)
|
||||
# define _malloca(size) malloc(size)
|
||||
# define _freea(ptr) free(ptr)
|
||||
# else
|
||||
# define _malloca(size) alloca(size)
|
||||
# define _freea(ptr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
@ -215,8 +229,8 @@ typedef struct uv_buf_t {
|
||||
} uv_buf_t;
|
||||
|
||||
typedef int uv_file;
|
||||
|
||||
typedef SOCKET uv_os_sock_t;
|
||||
typedef HANDLE uv_os_fd_t;
|
||||
|
||||
typedef HANDLE uv_thread_t;
|
||||
|
||||
@ -275,6 +289,19 @@ typedef struct uv_once_s {
|
||||
typedef unsigned char uv_uid_t;
|
||||
typedef unsigned char uv_gid_t;
|
||||
|
||||
typedef struct uv__dirent_s {
|
||||
int d_type;
|
||||
char d_name[1];
|
||||
} uv__dirent_t;
|
||||
|
||||
#define UV__DT_DIR UV_DIRENT_DIR
|
||||
#define UV__DT_FILE UV_DIRENT_FILE
|
||||
#define UV__DT_LINK UV_DIRENT_LINK
|
||||
#define UV__DT_FIFO UV_DIRENT_FIFO
|
||||
#define UV__DT_SOCKET UV_DIRENT_SOCKET
|
||||
#define UV__DT_CHAR UV_DIRENT_CHAR
|
||||
#define UV__DT_BLOCK UV_DIRENT_BLOCK
|
||||
|
||||
/* Platform-specific definitions for uv_dlopen support. */
|
||||
#define UV_DYNAMIC FAR WINAPI
|
||||
typedef struct {
|
||||
@ -289,8 +316,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
HANDLE iocp; \
|
||||
/* The current time according to the event loop. in msecs. */ \
|
||||
uint64_t time; \
|
||||
/* GetTickCount() result when the event loop time was last updated. */ \
|
||||
DWORD last_tick_count; \
|
||||
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
|
||||
/* is empty, tail_ is NULL. If there is only one item, */ \
|
||||
/* tail_->next_req == tail_ */ \
|
||||
@ -443,7 +468,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
int queue_len; \
|
||||
} pending_ipc_info; \
|
||||
uv_write_t* non_overlapped_writes_tail; \
|
||||
void* reserved;
|
||||
uv_mutex_t readfile_mutex; \
|
||||
volatile HANDLE readfile_thread;
|
||||
|
||||
#define UV_PIPE_PRIVATE_FIELDS \
|
||||
HANDLE handle; \
|
||||
|
1281
deps/uv/include/uv.h
vendored
3
deps/uv/m4/.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
# Ignore libtoolize-generated files.
|
||||
*.m4
|
||||
!as_case.m4
|
||||
!dtrace.m4
|
||||
!libuv-check-flags.m4
|
21
deps/uv/m4/as_case.m4
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# AS_CASE(WORD, [PATTERN1], [IF-MATCHED1]...[DEFAULT])
|
||||
# ----------------------------------------------------
|
||||
# Expand into
|
||||
# | case WORD in
|
||||
# | PATTERN1) IF-MATCHED1 ;;
|
||||
# | ...
|
||||
# | *) DEFAULT ;;
|
||||
# | esac
|
||||
m4_define([_AS_CASE],
|
||||
[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
|
||||
[$#], 1, [ *) $1 ;;],
|
||||
[$#], 2, [ $1) m4_default([$2], [:]) ;;],
|
||||
[ $1) m4_default([$2], [:]) ;;
|
||||
$0(m4_shiftn(2, $@))])dnl
|
||||
])
|
||||
m4_defun([AS_CASE],
|
||||
[m4_ifval([$2$3],
|
||||
[case $1 in
|
||||
_AS_CASE(m4_shift($@))
|
||||
esac])])
|
||||
|
66
deps/uv/m4/dtrace.m4
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
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 ---------------------------------------------------------------------------
|
319
deps/uv/m4/libuv-check-flags.m4
vendored
Normal file
@ -0,0 +1,319 @@
|
||||
dnl Macros to check the presence of generic (non-typed) symbols.
|
||||
dnl Copyright (c) 2006-2008 Diego Pettenà <flameeyes gmail com>
|
||||
dnl Copyright (c) 2006-2008 xine project
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 3, or (at your option)
|
||||
dnl any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
dnl 02110-1301, USA.
|
||||
dnl
|
||||
dnl As a special exception, the copyright owners of the
|
||||
dnl macro gives unlimited permission to copy, distribute and modify the
|
||||
dnl configure scripts that are the output of Autoconf when processing the
|
||||
dnl Macro. You need not follow the terms of the GNU General Public
|
||||
dnl License when using or distributing such scripts, even though portions
|
||||
dnl of the text of the Macro appear in them. The GNU General Public
|
||||
dnl License (GPL) does govern all other use of the material that
|
||||
dnl constitutes the Autoconf Macro.
|
||||
dnl
|
||||
dnl This special exception to the GPL applies to versions of the
|
||||
dnl Autoconf Macro released by this project. When you make and
|
||||
dnl distribute a modified version of the Autoconf Macro, you may extend
|
||||
dnl this special exception to the GPL to apply to your modified version as
|
||||
dnl well.
|
||||
|
||||
dnl Check if the flag is supported by compiler
|
||||
dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
|
||||
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
|
||||
[ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $1"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],
|
||||
[eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
|
||||
[eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
])
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||
[$2], [$3])
|
||||
])
|
||||
|
||||
dnl Check if the flag is supported by compiler (cacheable)
|
||||
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([CC_CHECK_CFLAGS], [
|
||||
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||
AS_TR_SH([cc_cv_cflags_$1]),
|
||||
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
|
||||
)
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||
[$2], [$3])
|
||||
])
|
||||
|
||||
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
|
||||
dnl Check for CFLAG and appends them to CFLAGS if supported
|
||||
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
|
||||
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||
AS_TR_SH([cc_cv_cflags_$1]),
|
||||
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
|
||||
)
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||
[CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
|
||||
])
|
||||
|
||||
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
|
||||
AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
|
||||
for flag in $1; do
|
||||
CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])
|
||||
done
|
||||
])
|
||||
|
||||
dnl Check if the flag is supported by linker (cacheable)
|
||||
dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([CC_CHECK_LDFLAGS], [
|
||||
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||
AS_TR_SH([cc_cv_ldflags_$1]),
|
||||
[ac_save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $1"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])],
|
||||
[eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
|
||||
[eval "AS_TR_SH([cc_cv_ldflags_$1])="])
|
||||
AC_LANG_POP([C])
|
||||
LDFLAGS="$ac_save_LDFLAGS"
|
||||
])
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
|
||||
[$2], [$3])
|
||||
])
|
||||
|
||||
dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
|
||||
dnl the current linker to avoid undefined references in a shared object.
|
||||
AC_DEFUN([CC_NOUNDEFINED], [
|
||||
dnl We check $host for which systems to enable this for.
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
|
||||
case $host in
|
||||
dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads
|
||||
dnl are requested, as different implementations are present; to avoid problems
|
||||
dnl use -Wl,-z,defs only for those platform not behaving this way.
|
||||
*-freebsd* | *-openbsd*) ;;
|
||||
*)
|
||||
dnl First of all check for the --no-undefined variant of GNU ld. This allows
|
||||
dnl for a much more readable commandline, so that people can understand what
|
||||
dnl it does without going to look for what the heck -z defs does.
|
||||
for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do
|
||||
CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"])
|
||||
break
|
||||
done
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST([LDFLAGS_NOUNDEFINED])
|
||||
])
|
||||
|
||||
dnl Check for a -Werror flag or equivalent. -Werror is the GCC
|
||||
dnl and ICC flag that tells the compiler to treat all the warnings
|
||||
dnl as fatal. We usually need this option to make sure that some
|
||||
dnl constructs (like attributes) are not simply ignored.
|
||||
dnl
|
||||
dnl Other compilers don't support -Werror per se, but they support
|
||||
dnl an equivalent flag:
|
||||
dnl - Sun Studio compiler supports -errwarn=%all
|
||||
AC_DEFUN([CC_CHECK_WERROR], [
|
||||
AC_CACHE_CHECK(
|
||||
[for $CC way to treat warnings as errors],
|
||||
[cc_cv_werror],
|
||||
[CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
|
||||
[CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_CHECK_ATTRIBUTE], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
|
||||
AS_TR_SH([cc_cv_attribute_$1]),
|
||||
[ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])],
|
||||
[eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
|
||||
[eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
|
||||
AC_LANG_POP([C])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
])
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
|
||||
[AC_DEFINE(
|
||||
AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
|
||||
[Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
|
||||
)
|
||||
$4],
|
||||
[$5])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[constructor],,
|
||||
[void __attribute__((constructor)) ctor() { int a; }],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[format], [format(printf, n, n)],
|
||||
[void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[format_arg], [format_arg(printf)],
|
||||
[char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[visibility_$1], [visibility("$1")],
|
||||
[void __attribute__((visibility("$1"))) $1_function() { }],
|
||||
[$2], [$3])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[nonnull], [nonnull()],
|
||||
[void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[unused], ,
|
||||
[void some_function(void *foo, __attribute__((unused)) void *bar);],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[sentinel], ,
|
||||
[void some_function(void *foo, ...) __attribute__((sentinel));],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[deprecated], ,
|
||||
[void some_function(void *foo, ...) __attribute__((deprecated));],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[alias], [weak, alias],
|
||||
[void other_function(void *foo) { }
|
||||
void some_function(void *foo) __attribute__((weak, alias("other_function")));],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[malloc], ,
|
||||
[void * __attribute__((malloc)) my_alloc(int n);],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_PACKED], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[packed], ,
|
||||
[struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_CONST], [
|
||||
CC_CHECK_ATTRIBUTE(
|
||||
[const], ,
|
||||
[int __attribute__((const)) twopow(int n) { return 1 << n; } ],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_FLAG_VISIBILITY], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
|
||||
[cc_cv_flag_visibility],
|
||||
[cc_flag_visibility_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
|
||||
cc_cv_flag_visibility='yes',
|
||||
cc_cv_flag_visibility='no')
|
||||
CFLAGS="$cc_flag_visibility_save_CFLAGS"])
|
||||
|
||||
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
|
||||
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
|
||||
[Define this if the compiler supports the -fvisibility flag])
|
||||
$1],
|
||||
[$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_FUNC_EXPECT], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_CHECK([if compiler has __builtin_expect function],
|
||||
[cc_cv_func_expect],
|
||||
[ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
|
||||
[int some_function() {
|
||||
int a = 3;
|
||||
return (int)__builtin_expect(a, 3);
|
||||
}])],
|
||||
[cc_cv_func_expect=yes],
|
||||
[cc_cv_func_expect=no])
|
||||
AC_LANG_POP([C])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
])
|
||||
|
||||
AS_IF([test "x$cc_cv_func_expect" = "xyes"],
|
||||
[AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
|
||||
[Define this if the compiler supports __builtin_expect() function])
|
||||
$1],
|
||||
[$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
|
||||
[cc_cv_attribute_aligned],
|
||||
[ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||
AC_LANG_PUSH([C])
|
||||
for cc_attribute_align_try in 64 32 16 8 4 2; do
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
int main() {
|
||||
static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
|
||||
return c;
|
||||
}])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
|
||||
done
|
||||
AC_LANG_POP([C])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
])
|
||||
|
||||
if test "x$cc_cv_attribute_aligned" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
|
||||
[Define the highest alignment supported])
|
||||
fi
|
||||
])
|
15
deps/uv/src/fs-poll.c
vendored
@ -60,6 +60,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
struct poll_ctx* ctx;
|
||||
uv_loop_t* loop;
|
||||
size_t len;
|
||||
int err;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
return 0;
|
||||
@ -78,19 +79,25 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
ctx->parent_handle = handle;
|
||||
memcpy(ctx->path, path, len + 1);
|
||||
|
||||
if (uv_timer_init(loop, &ctx->timer_handle))
|
||||
abort();
|
||||
err = uv_timer_init(loop, &ctx->timer_handle);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
|
||||
uv__handle_unref(&ctx->timer_handle);
|
||||
|
||||
if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb))
|
||||
abort();
|
||||
err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
handle->poll_ctx = ctx;
|
||||
uv__handle_start(handle);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
57
deps/uv/src/unix/core.c
vendored
@ -163,6 +163,33 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
||||
uv__make_close_pending(handle);
|
||||
}
|
||||
|
||||
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
||||
int r;
|
||||
int fd;
|
||||
socklen_t len;
|
||||
|
||||
if (handle == NULL || value == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
|
||||
fd = uv__stream_fd((uv_stream_t*) handle);
|
||||
else if (handle->type == UV_UDP)
|
||||
fd = ((uv_udp_t *) handle)->io_watcher.fd;
|
||||
else
|
||||
return -ENOTSUP;
|
||||
|
||||
len = sizeof(*value);
|
||||
|
||||
if (*value == 0)
|
||||
r = getsockopt(fd, SOL_SOCKET, optname, value, &len);
|
||||
else
|
||||
r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
|
||||
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uv__make_close_pending(uv_handle_t* handle) {
|
||||
assert(handle->flags & UV_CLOSING);
|
||||
@ -635,6 +662,36 @@ void uv_disable_stdio_inheritance(void) {
|
||||
}
|
||||
|
||||
|
||||
int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
||||
int fd_out;
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_TCP:
|
||||
case UV_NAMED_PIPE:
|
||||
case UV_TTY:
|
||||
fd_out = uv__stream_fd((uv_stream_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_UDP:
|
||||
fd_out = ((uv_udp_t *) handle)->io_watcher.fd;
|
||||
break;
|
||||
|
||||
case UV_POLL:
|
||||
fd_out = ((uv_poll_t *) handle)->io_watcher.fd;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (uv__is_closing(handle) || fd_out == -1)
|
||||
return -EBADF;
|
||||
|
||||
*fd = fd_out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void uv__run_pending(uv_loop_t* loop) {
|
||||
QUEUE* q;
|
||||
uv__io_t* w;
|
||||
|
24
deps/uv/src/unix/darwin-proctitle.c
vendored
@ -36,7 +36,7 @@ static int uv__pthread_setname_np(const char* name) {
|
||||
int err;
|
||||
|
||||
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
||||
dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
*(void **)(&dynamic_pthread_setname_np) = dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
if (dynamic_pthread_setname_np == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
@ -94,13 +94,13 @@ int uv__set_process_title(const char* title) {
|
||||
if (application_services_handle == NULL || core_foundation_handle == NULL)
|
||||
goto out;
|
||||
|
||||
pCFStringCreateWithCString =
|
||||
*(void **)(&pCFStringCreateWithCString) =
|
||||
dlsym(core_foundation_handle, "CFStringCreateWithCString");
|
||||
pCFBundleGetBundleWithIdentifier =
|
||||
*(void **)(&pCFBundleGetBundleWithIdentifier) =
|
||||
dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier");
|
||||
pCFBundleGetDataPointerForName =
|
||||
*(void **)(&pCFBundleGetDataPointerForName) =
|
||||
dlsym(core_foundation_handle, "CFBundleGetDataPointerForName");
|
||||
pCFBundleGetFunctionPointerForName =
|
||||
*(void **)(&pCFBundleGetFunctionPointerForName) =
|
||||
dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName");
|
||||
|
||||
if (pCFStringCreateWithCString == NULL ||
|
||||
@ -118,14 +118,14 @@ int uv__set_process_title(const char* title) {
|
||||
if (launch_services_bundle == NULL)
|
||||
goto out;
|
||||
|
||||
pLSGetCurrentApplicationASN =
|
||||
*(void **)(&pLSGetCurrentApplicationASN) =
|
||||
pCFBundleGetFunctionPointerForName(launch_services_bundle,
|
||||
S("_LSGetCurrentApplicationASN"));
|
||||
|
||||
if (pLSGetCurrentApplicationASN == NULL)
|
||||
goto out;
|
||||
|
||||
pLSSetApplicationInformationItem =
|
||||
*(void **)(&pLSSetApplicationInformationItem) =
|
||||
pCFBundleGetFunctionPointerForName(launch_services_bundle,
|
||||
S("_LSSetApplicationInformationItem"));
|
||||
|
||||
@ -138,9 +138,9 @@ int uv__set_process_title(const char* title) {
|
||||
if (display_name_key == NULL || *display_name_key == NULL)
|
||||
goto out;
|
||||
|
||||
pCFBundleGetInfoDictionary = dlsym(core_foundation_handle,
|
||||
*(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle,
|
||||
"CFBundleGetInfoDictionary");
|
||||
pCFBundleGetMainBundle = dlsym(core_foundation_handle,
|
||||
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
|
||||
"CFBundleGetMainBundle");
|
||||
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
|
||||
goto out;
|
||||
@ -152,13 +152,13 @@ int uv__set_process_title(const char* title) {
|
||||
if (hi_services_bundle == NULL)
|
||||
goto out;
|
||||
|
||||
pSetApplicationIsDaemon = pCFBundleGetFunctionPointerForName(
|
||||
*(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName(
|
||||
hi_services_bundle,
|
||||
S("SetApplicationIsDaemon"));
|
||||
pLSApplicationCheckIn = pCFBundleGetFunctionPointerForName(
|
||||
*(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
|
||||
launch_services_bundle,
|
||||
S("_LSApplicationCheckIn"));
|
||||
pLSSetApplicationLaunchServicesServerConnectionStatus =
|
||||
*(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
|
||||
pCFBundleGetFunctionPointerForName(
|
||||
launch_services_bundle,
|
||||
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
|
||||
|
41
deps/uv/src/unix/fs.c
vendored
@ -38,7 +38,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <utime.h>
|
||||
@ -296,9 +295,9 @@ done:
|
||||
|
||||
|
||||
#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
|
||||
static int uv__fs_readdir_filter(struct dirent* dent) {
|
||||
static int uv__fs_readdir_filter(uv__dirent_t* dent) {
|
||||
#else
|
||||
static int uv__fs_readdir_filter(const struct dirent* dent) {
|
||||
static int uv__fs_readdir_filter(const uv__dirent_t* dent) {
|
||||
#endif
|
||||
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
|
||||
}
|
||||
@ -306,12 +305,8 @@ static int uv__fs_readdir_filter(const struct dirent* dent) {
|
||||
|
||||
/* This should have been called uv__fs_scandir(). */
|
||||
static ssize_t uv__fs_readdir(uv_fs_t* req) {
|
||||
struct dirent **dents;
|
||||
uv__dirent_t **dents;
|
||||
int saved_errno;
|
||||
size_t off;
|
||||
size_t len;
|
||||
char *buf;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
dents = NULL;
|
||||
@ -322,32 +317,17 @@ static ssize_t uv__fs_readdir(uv_fs_t* req) {
|
||||
else if (n == -1)
|
||||
return n;
|
||||
|
||||
len = 0;
|
||||
/* NOTE: We will use nbufs as an index field */
|
||||
req->ptr = dents;
|
||||
req->nbufs = 0;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
len += strlen(dents[i]->d_name) + 1;
|
||||
|
||||
buf = malloc(len);
|
||||
|
||||
if (buf == NULL) {
|
||||
errno = ENOMEM;
|
||||
n = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
off = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
len = strlen(dents[i]->d_name) + 1;
|
||||
memcpy(buf + off, dents[i]->d_name, len);
|
||||
off += len;
|
||||
}
|
||||
|
||||
req->ptr = buf;
|
||||
return n;
|
||||
|
||||
out:
|
||||
saved_errno = errno;
|
||||
if (dents != NULL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
free(dents[i]);
|
||||
free(dents);
|
||||
@ -1184,6 +1164,9 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
||||
req->path = NULL;
|
||||
req->new_path = NULL;
|
||||
|
||||
if (req->fs_type == UV_FS_READDIR && req->ptr != NULL)
|
||||
uv__fs_readdir_cleanup(req);
|
||||
|
||||
if (req->ptr != &req->statbuf)
|
||||
free(req->ptr);
|
||||
req->ptr = NULL;
|
||||
|
2
deps/uv/src/unix/fsevents.c
vendored
@ -525,7 +525,7 @@ static int uv__fsevents_global_init(void) {
|
||||
err = -ENOENT;
|
||||
#define V(handle, symbol) \
|
||||
do { \
|
||||
p ## symbol = dlsym((handle), #symbol); \
|
||||
*(void **)(&p ## symbol) = dlsym((handle), #symbol); \
|
||||
if (p ## symbol == NULL) \
|
||||
goto out; \
|
||||
} \
|
||||
|
67
deps/uv/src/unix/getaddrinfo.c
vendored
@ -18,6 +18,13 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
|
||||
* include any headers.
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
@ -26,6 +33,66 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* EAI_* constants. */
|
||||
#include <netdb.h>
|
||||
|
||||
|
||||
int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
switch (sys_err) {
|
||||
case 0: return 0;
|
||||
#if defined(EAI_ADDRFAMILY)
|
||||
case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
|
||||
#endif
|
||||
#if defined(EAI_AGAIN)
|
||||
case EAI_AGAIN: return UV_EAI_AGAIN;
|
||||
#endif
|
||||
#if defined(EAI_BADFLAGS)
|
||||
case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
|
||||
#endif
|
||||
#if defined(EAI_BADHINTS)
|
||||
case EAI_BADHINTS: return UV_EAI_BADHINTS;
|
||||
#endif
|
||||
#if defined(EAI_CANCELED)
|
||||
case EAI_CANCELED: return UV_EAI_CANCELED;
|
||||
#endif
|
||||
#if defined(EAI_FAIL)
|
||||
case EAI_FAIL: return UV_EAI_FAIL;
|
||||
#endif
|
||||
#if defined(EAI_FAMILY)
|
||||
case EAI_FAMILY: return UV_EAI_FAMILY;
|
||||
#endif
|
||||
#if defined(EAI_MEMORY)
|
||||
case EAI_MEMORY: return UV_EAI_MEMORY;
|
||||
#endif
|
||||
#if defined(EAI_NODATA)
|
||||
case EAI_NODATA: return UV_EAI_NODATA;
|
||||
#endif
|
||||
#if defined(EAI_NONAME)
|
||||
# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
|
||||
case EAI_NONAME: return UV_EAI_NONAME;
|
||||
# endif
|
||||
#endif
|
||||
#if defined(EAI_OVERFLOW)
|
||||
case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
|
||||
#endif
|
||||
#if defined(EAI_PROTOCOL)
|
||||
case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
|
||||
#endif
|
||||
#if defined(EAI_SERVICE)
|
||||
case EAI_SERVICE: return UV_EAI_SERVICE;
|
||||
#endif
|
||||
#if defined(EAI_SOCKTYPE)
|
||||
case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
|
||||
#endif
|
||||
#if defined(EAI_SYSTEM)
|
||||
case EAI_SYSTEM: return -errno;
|
||||
#endif
|
||||
}
|
||||
assert(!"unknown EAI_* error code");
|
||||
abort();
|
||||
return 0; /* Pacify compiler. */
|
||||
}
|
||||
|
||||
|
||||
static void uv__getaddrinfo_work(struct uv__work* w) {
|
||||
uv_getaddrinfo_t* req;
|
||||
|
2
deps/uv/src/unix/internal.h
vendored
@ -143,7 +143,7 @@ enum {
|
||||
UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
|
||||
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
|
||||
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
|
||||
UV_HANDLE_IPV6 = 0x2000 /* Handle is bound to a IPv6 socket. */
|
||||
UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
21
deps/uv/src/unix/linux-core.c
vendored
@ -149,6 +149,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
int fd;
|
||||
int op;
|
||||
int i;
|
||||
static int no_epoll_wait;
|
||||
|
||||
if (loop->nfds == 0) {
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
@ -195,10 +196,22 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||
|
||||
for (;;) {
|
||||
nfds = uv__epoll_wait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
if (!no_epoll_wait) {
|
||||
nfds = uv__epoll_wait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
no_epoll_wait = 1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
nfds = uv__epoll_pwait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
|
5
deps/uv/src/unix/loop.c
vendored
@ -99,7 +99,6 @@ void uv_loop_delete(uv_loop_t* loop) {
|
||||
|
||||
|
||||
static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
uv__signal_global_once_init();
|
||||
@ -138,9 +137,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
uv_signal_init(loop, &loop->child_watcher);
|
||||
uv__handle_unref(&loop->child_watcher);
|
||||
loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
|
||||
QUEUE_INIT(loop->process_handles + i);
|
||||
QUEUE_INIT(&loop->process_handles);
|
||||
|
||||
if (uv_rwlock_init(&loop->cloexec_lock))
|
||||
abort();
|
||||
|
1
deps/uv/src/unix/netbsd.c
vendored
@ -38,6 +38,7 @@
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
95
deps/uv/src/unix/process.c
vendored
@ -45,77 +45,65 @@ extern char **environ;
|
||||
#endif
|
||||
|
||||
|
||||
static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
|
||||
assert(pid > 0);
|
||||
return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
|
||||
}
|
||||
|
||||
|
||||
static void uv__chld(uv_signal_t* handle, int signum) {
|
||||
uv_process_t* process;
|
||||
uv_loop_t* loop;
|
||||
int exit_status;
|
||||
int term_signal;
|
||||
unsigned int i;
|
||||
int status;
|
||||
pid_t pid;
|
||||
QUEUE pending;
|
||||
QUEUE* h;
|
||||
QUEUE* q;
|
||||
QUEUE* h;
|
||||
|
||||
assert(signum == SIGCHLD);
|
||||
|
||||
QUEUE_INIT(&pending);
|
||||
loop = handle->loop;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) {
|
||||
h = loop->process_handles + i;
|
||||
q = QUEUE_HEAD(h);
|
||||
h = &loop->process_handles;
|
||||
q = QUEUE_HEAD(h);
|
||||
while (q != h) {
|
||||
process = QUEUE_DATA(q, uv_process_t, queue);
|
||||
q = QUEUE_NEXT(q);
|
||||
|
||||
while (q != h) {
|
||||
process = QUEUE_DATA(q, uv_process_t, queue);
|
||||
q = QUEUE_NEXT(q);
|
||||
do
|
||||
pid = waitpid(process->pid, &status, WNOHANG);
|
||||
while (pid == -1 && errno == EINTR);
|
||||
|
||||
do
|
||||
pid = waitpid(process->pid, &status, WNOHANG);
|
||||
while (pid == -1 && errno == EINTR);
|
||||
if (pid == 0)
|
||||
continue;
|
||||
|
||||
if (pid == 0)
|
||||
continue;
|
||||
|
||||
if (pid == -1) {
|
||||
if (errno != ECHILD)
|
||||
abort();
|
||||
continue;
|
||||
}
|
||||
|
||||
process->status = status;
|
||||
QUEUE_REMOVE(&process->queue);
|
||||
QUEUE_INSERT_TAIL(&pending, &process->queue);
|
||||
if (pid == -1) {
|
||||
if (errno != ECHILD)
|
||||
abort();
|
||||
continue;
|
||||
}
|
||||
|
||||
while (!QUEUE_EMPTY(&pending)) {
|
||||
q = QUEUE_HEAD(&pending);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INIT(q);
|
||||
|
||||
process = QUEUE_DATA(q, uv_process_t, queue);
|
||||
uv__handle_stop(process);
|
||||
|
||||
if (process->exit_cb == NULL)
|
||||
continue;
|
||||
|
||||
exit_status = 0;
|
||||
if (WIFEXITED(process->status))
|
||||
exit_status = WEXITSTATUS(process->status);
|
||||
|
||||
term_signal = 0;
|
||||
if (WIFSIGNALED(process->status))
|
||||
term_signal = WTERMSIG(process->status);
|
||||
|
||||
process->exit_cb(process, exit_status, term_signal);
|
||||
}
|
||||
process->status = status;
|
||||
QUEUE_REMOVE(&process->queue);
|
||||
QUEUE_INSERT_TAIL(&pending, &process->queue);
|
||||
}
|
||||
|
||||
QUEUE_FOREACH(q, &pending) {
|
||||
process = QUEUE_DATA(q, uv_process_t, queue);
|
||||
QUEUE_REMOVE(q);
|
||||
uv__handle_stop(process);
|
||||
|
||||
if (process->exit_cb == NULL)
|
||||
continue;
|
||||
|
||||
exit_status = 0;
|
||||
if (WIFEXITED(process->status))
|
||||
exit_status = WEXITSTATUS(process->status);
|
||||
|
||||
term_signal = 0;
|
||||
if (WIFSIGNALED(process->status))
|
||||
term_signal = WTERMSIG(process->status);
|
||||
|
||||
process->exit_cb(process, exit_status, term_signal);
|
||||
}
|
||||
assert(QUEUE_EMPTY(&pending));
|
||||
}
|
||||
|
||||
|
||||
@ -369,7 +357,6 @@ int uv_spawn(uv_loop_t* loop,
|
||||
int signal_pipe[2] = { -1, -1 };
|
||||
int (*pipes)[2];
|
||||
int stdio_count;
|
||||
QUEUE* q;
|
||||
ssize_t r;
|
||||
pid_t pid;
|
||||
int err;
|
||||
@ -483,8 +470,7 @@ int uv_spawn(uv_loop_t* loop,
|
||||
|
||||
/* Only activate this handle if exec() happened successfully */
|
||||
if (exec_errorno == 0) {
|
||||
q = uv__process_queue(loop, pid);
|
||||
QUEUE_INSERT_TAIL(q, &process->queue);
|
||||
QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue);
|
||||
uv__handle_start(process);
|
||||
}
|
||||
|
||||
@ -526,7 +512,8 @@ int uv_kill(int pid, int signum) {
|
||||
|
||||
|
||||
void uv__process_close(uv_process_t* handle) {
|
||||
/* TODO stop signal watcher when this is the last handle */
|
||||
QUEUE_REMOVE(&handle->queue);
|
||||
uv__handle_stop(handle);
|
||||
if (QUEUE_EMPTY(&handle->loop->process_handles))
|
||||
uv_signal_stop(&handle->loop->child_watcher);
|
||||
}
|
||||
|
153
deps/uv/src/unix/stream.c
vendored
@ -53,6 +53,10 @@ struct uv__stream_select_s {
|
||||
int fake_fd;
|
||||
int int_fd;
|
||||
int fd;
|
||||
fd_set* sread;
|
||||
size_t sread_sz;
|
||||
fd_set* swrite;
|
||||
size_t swrite_sz;
|
||||
};
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
@ -127,8 +131,6 @@ static void uv__stream_osx_select(void* arg) {
|
||||
uv_stream_t* stream;
|
||||
uv__stream_select_t* s;
|
||||
char buf[1024];
|
||||
fd_set sread;
|
||||
fd_set swrite;
|
||||
int events;
|
||||
int fd;
|
||||
int r;
|
||||
@ -149,17 +151,17 @@ static void uv__stream_osx_select(void* arg) {
|
||||
break;
|
||||
|
||||
/* Watch fd using select(2) */
|
||||
FD_ZERO(&sread);
|
||||
FD_ZERO(&swrite);
|
||||
memset(s->sread, 0, s->sread_sz);
|
||||
memset(s->swrite, 0, s->swrite_sz);
|
||||
|
||||
if (uv__io_active(&stream->io_watcher, UV__POLLIN))
|
||||
FD_SET(fd, &sread);
|
||||
FD_SET(fd, s->sread);
|
||||
if (uv__io_active(&stream->io_watcher, UV__POLLOUT))
|
||||
FD_SET(fd, &swrite);
|
||||
FD_SET(s->int_fd, &sread);
|
||||
FD_SET(fd, s->swrite);
|
||||
FD_SET(s->int_fd, s->sread);
|
||||
|
||||
/* Wait indefinitely for fd events */
|
||||
r = select(max_fd + 1, &sread, &swrite, NULL, NULL);
|
||||
r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL);
|
||||
if (r == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
@ -173,7 +175,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
continue;
|
||||
|
||||
/* Empty socketpair's buffer in case of interruption */
|
||||
if (FD_ISSET(s->int_fd, &sread))
|
||||
if (FD_ISSET(s->int_fd, s->sread))
|
||||
while (1) {
|
||||
r = read(s->int_fd, buf, sizeof(buf));
|
||||
|
||||
@ -194,12 +196,12 @@ static void uv__stream_osx_select(void* arg) {
|
||||
|
||||
/* Handle events */
|
||||
events = 0;
|
||||
if (FD_ISSET(fd, &sread))
|
||||
if (FD_ISSET(fd, s->sread))
|
||||
events |= UV__POLLIN;
|
||||
if (FD_ISSET(fd, &swrite))
|
||||
if (FD_ISSET(fd, s->swrite))
|
||||
events |= UV__POLLOUT;
|
||||
|
||||
assert(events != 0 || FD_ISSET(s->int_fd, &sread));
|
||||
assert(events != 0 || FD_ISSET(s->int_fd, s->sread));
|
||||
if (events != 0) {
|
||||
ACCESS_ONCE(int, s->events) = events;
|
||||
|
||||
@ -261,6 +263,9 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
int ret;
|
||||
int kq;
|
||||
int old_fd;
|
||||
int max_fd;
|
||||
size_t sread_sz;
|
||||
size_t swrite_sz;
|
||||
|
||||
kq = kqueue();
|
||||
if (kq == -1) {
|
||||
@ -284,31 +289,48 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
return 0;
|
||||
|
||||
/* At this point we definitely know that this fd won't work with kqueue */
|
||||
s = malloc(sizeof(*s));
|
||||
if (s == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Create fds for io watcher and to interrupt the select() loop.
|
||||
* NOTE: do it ahead of malloc below to allocate enough space for fd_sets
|
||||
*/
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
||||
return -errno;
|
||||
|
||||
max_fd = *fd;
|
||||
if (fds[1] > max_fd)
|
||||
max_fd = fds[1];
|
||||
|
||||
sread_sz = (max_fd + NBBY) / NBBY;
|
||||
swrite_sz = sread_sz;
|
||||
|
||||
s = malloc(sizeof(*s) + sread_sz + swrite_sz);
|
||||
if (s == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failed_malloc;
|
||||
}
|
||||
|
||||
s->events = 0;
|
||||
s->fd = *fd;
|
||||
s->sread = (fd_set*) ((char*) s + sizeof(*s));
|
||||
s->sread_sz = sread_sz;
|
||||
s->swrite = (fd_set*) ((char*) s->sread + sread_sz);
|
||||
s->swrite_sz = swrite_sz;
|
||||
|
||||
err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb);
|
||||
if (err) {
|
||||
free(s);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto failed_async_init;
|
||||
|
||||
s->async.flags |= UV__HANDLE_INTERNAL;
|
||||
uv__handle_unref(&s->async);
|
||||
|
||||
if (uv_sem_init(&s->close_sem, 0))
|
||||
goto fatal1;
|
||||
err = uv_sem_init(&s->close_sem, 0);
|
||||
if (err != 0)
|
||||
goto failed_close_sem_init;
|
||||
|
||||
if (uv_sem_init(&s->async_sem, 0))
|
||||
goto fatal2;
|
||||
|
||||
/* Create fds for io watcher and to interrupt the select() loop. */
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
||||
goto fatal3;
|
||||
err = uv_sem_init(&s->async_sem, 0);
|
||||
if (err != 0)
|
||||
goto failed_async_sem_init;
|
||||
|
||||
s->fake_fd = fds[0];
|
||||
s->int_fd = fds[1];
|
||||
@ -318,26 +340,36 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
stream->select = s;
|
||||
*fd = s->fake_fd;
|
||||
|
||||
if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
|
||||
goto fatal4;
|
||||
err = uv_thread_create(&s->thread, uv__stream_osx_select, stream);
|
||||
if (err != 0)
|
||||
goto failed_thread_create;
|
||||
|
||||
return 0;
|
||||
|
||||
fatal4:
|
||||
failed_thread_create:
|
||||
s->stream = NULL;
|
||||
stream->select = NULL;
|
||||
*fd = old_fd;
|
||||
uv__close(s->fake_fd);
|
||||
uv__close(s->int_fd);
|
||||
s->fake_fd = -1;
|
||||
s->int_fd = -1;
|
||||
fatal3:
|
||||
|
||||
uv_sem_destroy(&s->async_sem);
|
||||
fatal2:
|
||||
|
||||
failed_async_sem_init:
|
||||
uv_sem_destroy(&s->close_sem);
|
||||
fatal1:
|
||||
|
||||
failed_close_sem_init:
|
||||
uv__close(fds[0]);
|
||||
uv__close(fds[1]);
|
||||
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
|
||||
return -errno;
|
||||
return err;
|
||||
|
||||
failed_async_init:
|
||||
free(s);
|
||||
|
||||
failed_malloc:
|
||||
uv__close(fds[0]);
|
||||
uv__close(fds[1]);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
@ -361,10 +393,22 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
||||
}
|
||||
|
||||
|
||||
void uv__stream_destroy(uv_stream_t* stream) {
|
||||
void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
|
||||
uv_write_t* req;
|
||||
QUEUE* q;
|
||||
while (!QUEUE_EMPTY(&stream->write_queue)) {
|
||||
q = QUEUE_HEAD(&stream->write_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
|
||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||
req->error = error;
|
||||
|
||||
QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__stream_destroy(uv_stream_t* stream) {
|
||||
assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
|
||||
assert(stream->flags & UV_CLOSED);
|
||||
|
||||
@ -374,16 +418,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
||||
stream->connect_req = NULL;
|
||||
}
|
||||
|
||||
while (!QUEUE_EMPTY(&stream->write_queue)) {
|
||||
q = QUEUE_HEAD(&stream->write_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
|
||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||
req->error = -ECANCELED;
|
||||
|
||||
QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
|
||||
}
|
||||
|
||||
uv__stream_flush_write_queue(stream, -ECANCELED);
|
||||
uv__write_callbacks(stream);
|
||||
|
||||
if (stream->shutdown_req) {
|
||||
@ -537,7 +572,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
done:
|
||||
@ -573,7 +608,6 @@ done:
|
||||
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
||||
int err;
|
||||
|
||||
err = -EINVAL;
|
||||
switch (stream->type) {
|
||||
case UV_TCP:
|
||||
err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
||||
@ -584,7 +618,7 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
@ -1163,7 +1197,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
|
||||
/* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
|
||||
if (events & (UV__POLLIN | UV__POLLERR))
|
||||
if (events & (UV__POLLIN | UV__POLLERR | UV__POLLHUP))
|
||||
uv__read(stream);
|
||||
|
||||
if (uv__stream_fd(stream) == -1)
|
||||
@ -1233,10 +1267,21 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
||||
|
||||
stream->connect_req = NULL;
|
||||
uv__req_unregister(stream->loop, req);
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
|
||||
|
||||
if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) {
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
|
||||
}
|
||||
|
||||
if (req->cb)
|
||||
req->cb(req, error);
|
||||
|
||||
if (uv__stream_fd(stream) == -1)
|
||||
return;
|
||||
|
||||
if (error < 0) {
|
||||
uv__stream_flush_write_queue(stream, -ECANCELED);
|
||||
uv__write_callbacks(stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
3
deps/uv/src/unix/timer.c
vendored
@ -65,6 +65,9 @@ int uv_timer_start(uv_timer_t* handle,
|
||||
uint64_t repeat) {
|
||||
uint64_t clamped_timeout;
|
||||
|
||||
if (cb == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
uv_timer_stop(handle);
|
||||
|
||||
|
2
deps/uv/src/unix/udp.c
vendored
@ -340,8 +340,6 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
unsigned char taddr[sizeof(struct sockaddr_in6)];
|
||||
socklen_t addrlen;
|
||||
|
||||
assert(domain == AF_INET || domain == AF_INET6);
|
||||
|
||||
if (handle->io_watcher.fd != -1)
|
||||
return 0;
|
||||
|
||||
|
142
deps/uv/src/uv-common.c
vendored
@ -19,13 +19,6 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
|
||||
* include any headers.
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "uv.h"
|
||||
#include "uv-common.h"
|
||||
|
||||
@ -39,13 +32,6 @@
|
||||
# include <net/if.h> /* if_nametoindex */
|
||||
#endif
|
||||
|
||||
/* EAI_* constants. */
|
||||
#if !defined(_WIN32)
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
|
||||
|
||||
size_t uv_handle_size(uv_handle_type type) {
|
||||
@ -410,62 +396,6 @@ uint64_t uv_now(const uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
switch (sys_err) {
|
||||
case 0: return 0;
|
||||
#if defined(EAI_ADDRFAMILY)
|
||||
case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
|
||||
#endif
|
||||
#if defined(EAI_AGAIN)
|
||||
case EAI_AGAIN: return UV_EAI_AGAIN;
|
||||
#endif
|
||||
#if defined(EAI_BADFLAGS)
|
||||
case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
|
||||
#endif
|
||||
#if defined(EAI_BADHINTS)
|
||||
case EAI_BADHINTS: return UV_EAI_BADHINTS;
|
||||
#endif
|
||||
#if defined(EAI_CANCELED)
|
||||
case EAI_CANCELED: return UV_EAI_CANCELED;
|
||||
#endif
|
||||
#if defined(EAI_FAIL)
|
||||
case EAI_FAIL: return UV_EAI_FAIL;
|
||||
#endif
|
||||
#if defined(EAI_FAMILY)
|
||||
case EAI_FAMILY: return UV_EAI_FAMILY;
|
||||
#endif
|
||||
#if defined(EAI_MEMORY)
|
||||
case EAI_MEMORY: return UV_EAI_MEMORY;
|
||||
#endif
|
||||
#if defined(EAI_NODATA)
|
||||
case EAI_NODATA: return UV_EAI_NODATA;
|
||||
#endif
|
||||
#if defined(EAI_NONAME)
|
||||
# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
|
||||
case EAI_NONAME: return UV_EAI_NONAME;
|
||||
# endif
|
||||
#endif
|
||||
#if defined(EAI_OVERFLOW)
|
||||
case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
|
||||
#endif
|
||||
#if defined(EAI_PROTOCOL)
|
||||
case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
|
||||
#endif
|
||||
#if defined(EAI_SERVICE)
|
||||
case EAI_SERVICE: return UV_EAI_SERVICE;
|
||||
#endif
|
||||
#if defined(EAI_SOCKTYPE)
|
||||
case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
|
||||
#endif
|
||||
#if defined(EAI_SYSTEM)
|
||||
case EAI_SYSTEM: return -errno;
|
||||
#endif
|
||||
}
|
||||
assert(!"unknown EAI_* error code");
|
||||
abort();
|
||||
return 0; /* Pacify compiler. */
|
||||
}
|
||||
|
||||
|
||||
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
|
||||
unsigned int i;
|
||||
@ -478,6 +408,13 @@ size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int uv_recv_buffer_size(uv_handle_t* handle, int* value) {
|
||||
return uv__socket_sockopt(handle, SO_RCVBUF, value);
|
||||
}
|
||||
|
||||
int uv_send_buffer_size(uv_handle_t* handle, int *value) {
|
||||
return uv__socket_sockopt(handle, SO_SNDBUF, value);
|
||||
}
|
||||
|
||||
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
||||
size_t required_len;
|
||||
@ -498,3 +435,68 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__fs_readdir_cleanup(uv_fs_t* req) {
|
||||
uv__dirent_t** dents;
|
||||
|
||||
dents = req->ptr;
|
||||
if (req->nbufs > 0 && req->nbufs != (unsigned int) req->result)
|
||||
req->nbufs--;
|
||||
for (; req->nbufs < (unsigned int) req->result; req->nbufs++)
|
||||
free(dents[req->nbufs]);
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent) {
|
||||
uv__dirent_t** dents;
|
||||
uv__dirent_t* dent;
|
||||
|
||||
dents = req->ptr;
|
||||
|
||||
/* Free previous entity */
|
||||
if (req->nbufs > 0)
|
||||
free(dents[req->nbufs - 1]);
|
||||
|
||||
/* End was already reached */
|
||||
if (req->nbufs == (unsigned int) req->result) {
|
||||
free(dents);
|
||||
req->ptr = NULL;
|
||||
return UV_EOF;
|
||||
}
|
||||
|
||||
dent = dents[req->nbufs++];
|
||||
|
||||
ent->name = dent->d_name;
|
||||
#ifdef HAVE_DIRENT_TYPES
|
||||
switch (dent->d_type) {
|
||||
case UV__DT_DIR:
|
||||
ent->type = UV_DIRENT_DIR;
|
||||
break;
|
||||
case UV__DT_FILE:
|
||||
ent->type = UV_DIRENT_FILE;
|
||||
break;
|
||||
case UV__DT_LINK:
|
||||
ent->type = UV_DIRENT_LINK;
|
||||
break;
|
||||
case UV__DT_FIFO:
|
||||
ent->type = UV_DIRENT_FIFO;
|
||||
break;
|
||||
case UV__DT_SOCKET:
|
||||
ent->type = UV_DIRENT_SOCKET;
|
||||
break;
|
||||
case UV__DT_CHAR:
|
||||
ent->type = UV_DIRENT_CHAR;
|
||||
break;
|
||||
case UV__DT_BLOCK:
|
||||
ent->type = UV_DIRENT_BLOCK;
|
||||
break;
|
||||
default:
|
||||
ent->type = UV_DIRENT_UNKNOWN;
|
||||
}
|
||||
#else
|
||||
ent->type = UV_DIRENT_UNKNOWN;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
4
deps/uv/src/uv-common.h
vendored
@ -107,6 +107,10 @@ void uv__work_done(uv_async_t* handle);
|
||||
|
||||
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
|
||||
|
||||
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
|
||||
|
||||
void uv__fs_readdir_cleanup(uv_fs_t* req);
|
||||
|
||||
#define uv__has_active_reqs(loop) \
|
||||
(QUEUE_EMPTY(&(loop)->active_reqs) == 0)
|
||||
|
||||
|
2
deps/uv/src/version.c
vendored
@ -35,7 +35,7 @@
|
||||
#if UV_VERSION_IS_RELEASE
|
||||
# define UV_VERSION_STRING UV_VERSION_STRING_BASE
|
||||
#else
|
||||
# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre"
|
||||
# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX
|
||||
#endif
|
||||
|
||||
|
||||
|
138
deps/uv/src/win/core.c
vendored
@ -36,12 +36,11 @@
|
||||
#include "req-inl.h"
|
||||
|
||||
|
||||
/* The only event loop we support right now */
|
||||
static uv_loop_t uv_default_loop_;
|
||||
static uv_loop_t default_loop_struct;
|
||||
static uv_loop_t* default_loop_ptr;
|
||||
|
||||
/* uv_once intialization guards */
|
||||
static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
|
||||
static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
|
||||
|
||||
|
||||
#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
|
||||
@ -138,7 +137,6 @@ int uv_loop_init(uv_loop_t* loop) {
|
||||
* to zero before calling uv_update_time for the first time.
|
||||
*/
|
||||
loop->time = 0;
|
||||
loop->last_tick_count = 0;
|
||||
uv_update_time(loop);
|
||||
|
||||
QUEUE_INIT(&loop->wq);
|
||||
@ -181,48 +179,45 @@ int uv_loop_init(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
static void uv_default_loop_init(void) {
|
||||
/* Initialize libuv itself first */
|
||||
uv__once_init();
|
||||
|
||||
/* Initialize the main loop */
|
||||
uv_loop_init(&uv_default_loop_);
|
||||
}
|
||||
|
||||
|
||||
void uv__once_init(void) {
|
||||
uv_once(&uv_init_guard_, uv_init);
|
||||
}
|
||||
|
||||
|
||||
uv_loop_t* uv_default_loop(void) {
|
||||
uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
|
||||
return &uv_default_loop_;
|
||||
if (default_loop_ptr != NULL)
|
||||
return default_loop_ptr;
|
||||
|
||||
if (uv_loop_init(&default_loop_struct))
|
||||
return NULL;
|
||||
|
||||
default_loop_ptr = &default_loop_struct;
|
||||
return default_loop_ptr;
|
||||
}
|
||||
|
||||
|
||||
static void uv__loop_close(uv_loop_t* loop) {
|
||||
size_t i;
|
||||
|
||||
/* close the async handle without needeing an extra loop iteration */
|
||||
assert(!loop->wq_async.async_sent);
|
||||
loop->wq_async.close_cb = NULL;
|
||||
uv__handle_closing(&loop->wq_async);
|
||||
uv__handle_close(&loop->wq_async);
|
||||
|
||||
if (loop != &uv_default_loop_) {
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
|
||||
SOCKET sock = loop->poll_peer_sockets[i];
|
||||
if (sock != 0 && sock != INVALID_SOCKET)
|
||||
closesocket(sock);
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
|
||||
SOCKET sock = loop->poll_peer_sockets[i];
|
||||
if (sock != 0 && sock != INVALID_SOCKET)
|
||||
closesocket(sock);
|
||||
}
|
||||
/* TODO: cleanup default loop*/
|
||||
|
||||
uv_mutex_lock(&loop->wq_mutex);
|
||||
assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
|
||||
assert(!uv__has_active_reqs(loop));
|
||||
uv_mutex_unlock(&loop->wq_mutex);
|
||||
uv_mutex_destroy(&loop->wq_mutex);
|
||||
|
||||
CloseHandle(loop->iocp);
|
||||
}
|
||||
|
||||
|
||||
@ -242,6 +237,8 @@ int uv_loop_close(uv_loop_t* loop) {
|
||||
#ifndef NDEBUG
|
||||
memset(loop, -1, sizeof(*loop));
|
||||
#endif
|
||||
if (loop == default_loop_ptr)
|
||||
default_loop_ptr = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -265,9 +262,12 @@ uv_loop_t* uv_loop_new(void) {
|
||||
|
||||
|
||||
void uv_loop_delete(uv_loop_t* loop) {
|
||||
int err = uv_loop_close(loop);
|
||||
uv_loop_t* default_loop;
|
||||
int err;
|
||||
default_loop = default_loop_ptr;
|
||||
err = uv_loop_close(loop);
|
||||
assert(err == 0);
|
||||
if (loop != &uv_default_loop_)
|
||||
if (loop != default_loop)
|
||||
free(loop);
|
||||
}
|
||||
|
||||
@ -313,13 +313,17 @@ static void uv_poll(uv_loop_t* loop, DWORD timeout) {
|
||||
/* Package was dequeued */
|
||||
req = uv_overlapped_to_req(overlapped);
|
||||
uv_insert_pending_req(loop, req);
|
||||
|
||||
/* Some time might have passed waiting for I/O,
|
||||
* so update the loop time here.
|
||||
*/
|
||||
uv_update_time(loop);
|
||||
} else if (GetLastError() != WAIT_TIMEOUT) {
|
||||
/* Serious error */
|
||||
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
|
||||
} else {
|
||||
/* We're sure that at least `timeout` milliseconds have expired, but
|
||||
* this may not be reflected yet in the GetTickCount() return value.
|
||||
* Therefore we ensure it's taken into account here.
|
||||
} else if (timeout > 0) {
|
||||
/* GetQueuedCompletionStatus can occasionally return a little early.
|
||||
* Make sure that the desired timeout is reflected in the loop time.
|
||||
*/
|
||||
uv__time_forward(loop, timeout);
|
||||
}
|
||||
@ -346,13 +350,17 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
|
||||
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
|
||||
uv_insert_pending_req(loop, req);
|
||||
}
|
||||
|
||||
/* Some time might have passed waiting for I/O,
|
||||
* so update the loop time here.
|
||||
*/
|
||||
uv_update_time(loop);
|
||||
} else if (GetLastError() != WAIT_TIMEOUT) {
|
||||
/* Serious error */
|
||||
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
|
||||
} else if (timeout > 0) {
|
||||
/* We're sure that at least `timeout` milliseconds have expired, but
|
||||
* this may not be reflected yet in the GetTickCount() return value.
|
||||
* Therefore we ensure it's taken into account here.
|
||||
/* GetQueuedCompletionStatus can occasionally return a little early.
|
||||
* Make sure that the desired timeout is reflected in the loop time.
|
||||
*/
|
||||
uv__time_forward(loop, timeout);
|
||||
}
|
||||
@ -411,7 +419,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
||||
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
|
||||
* the check.
|
||||
*/
|
||||
uv_update_time(loop);
|
||||
uv_process_timers(loop);
|
||||
}
|
||||
|
||||
@ -428,3 +435,68 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
||||
uv_os_fd_t fd_out;
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_TCP:
|
||||
fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
|
||||
break;
|
||||
|
||||
case UV_NAMED_PIPE:
|
||||
fd_out = ((uv_pipe_t*) handle)->handle;
|
||||
break;
|
||||
|
||||
case UV_TTY:
|
||||
fd_out = ((uv_tty_t*) handle)->handle;
|
||||
break;
|
||||
|
||||
case UV_UDP:
|
||||
fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
|
||||
break;
|
||||
|
||||
case UV_POLL:
|
||||
fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
|
||||
break;
|
||||
|
||||
default:
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
|
||||
return UV_EBADF;
|
||||
|
||||
*fd = fd_out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
||||
int r;
|
||||
int len;
|
||||
SOCKET socket;
|
||||
|
||||
if (handle == NULL || value == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (handle->type == UV_TCP)
|
||||
socket = ((uv_tcp_t*) handle)->socket;
|
||||
else if (handle->type == UV_UDP)
|
||||
socket = ((uv_udp_t*) handle)->socket;
|
||||
else
|
||||
return UV_ENOTSUP;
|
||||
|
||||
len = sizeof(*value);
|
||||
|
||||
if (*value == 0)
|
||||
r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
|
||||
else
|
||||
r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
|
||||
|
||||
if (r == SOCKET_ERROR)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
226
deps/uv/src/win/fs.c
vendored
@ -36,11 +36,15 @@
|
||||
#include "req-inl.h"
|
||||
#include "handle-inl.h"
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
|
||||
#define UV_FS_FREE_PATHS 0x0002
|
||||
#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 { \
|
||||
@ -721,88 +725,75 @@ void fs__mkdir(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
/* Some parts of the implementation were borrowed from glibc. */
|
||||
/* OpenBSD original: lib/libc/stdio/mktemp.c */
|
||||
void fs__mkdtemp(uv_fs_t* req) {
|
||||
static const WCHAR letters[] =
|
||||
static const WCHAR *tempchars =
|
||||
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
static const size_t num_chars = 62;
|
||||
static const size_t num_x = 6;
|
||||
WCHAR *cp, *ep;
|
||||
unsigned int tries, i;
|
||||
size_t len;
|
||||
WCHAR* template_part;
|
||||
static uint64_t value;
|
||||
unsigned int count;
|
||||
int fd;
|
||||
|
||||
/* A lower bound on the number of temporary files to attempt to
|
||||
generate. The maximum total number of temporary file names that
|
||||
can exist for a given template is 62**6. It should never be
|
||||
necessary to try all these combinations. Instead if a reasonable
|
||||
number of names is tried (we define reasonable as 62**3) fail to
|
||||
give the system administrator the chance to remove the problems. */
|
||||
#define ATTEMPTS_MIN (62 * 62 * 62)
|
||||
|
||||
/* The number of times to attempt to generate a temporary file. To
|
||||
conform to POSIX, this must be no smaller than TMP_MAX. */
|
||||
#if ATTEMPTS_MIN < TMP_MAX
|
||||
unsigned int attempts = TMP_MAX;
|
||||
#else
|
||||
unsigned int attempts = ATTEMPTS_MIN;
|
||||
#endif
|
||||
HCRYPTPROV h_crypt_prov;
|
||||
uint64_t v;
|
||||
BOOL released;
|
||||
|
||||
len = wcslen(req->pathw);
|
||||
if (len < 6 || wcsncmp(&req->pathw[len - 6], L"XXXXXX", 6)) {
|
||||
ep = req->pathw + len;
|
||||
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is where the Xs start. */
|
||||
template_part = &req->pathw[len - 6];
|
||||
|
||||
/* Get some random data. */
|
||||
value += uv_hrtime() ^ _getpid();
|
||||
|
||||
for (count = 0; count < attempts; value += 7777, ++count) {
|
||||
uint64_t v = value;
|
||||
|
||||
/* Fill in the random bits. */
|
||||
template_part[0] = letters[v % 62];
|
||||
v /= 62;
|
||||
template_part[1] = letters[v % 62];
|
||||
v /= 62;
|
||||
template_part[2] = letters[v % 62];
|
||||
v /= 62;
|
||||
template_part[3] = letters[v % 62];
|
||||
v /= 62;
|
||||
template_part[4] = letters[v % 62];
|
||||
v /= 62;
|
||||
template_part[5] = letters[v % 62];
|
||||
|
||||
fd = _wmkdir(req->pathw);
|
||||
|
||||
if (fd >= 0) {
|
||||
len = strlen(req->path);
|
||||
wcstombs((char*) req->path + len - 6, template_part, 6);
|
||||
SET_REQ_RESULT(req, 0);
|
||||
return;
|
||||
} else if (errno != EEXIST) {
|
||||
SET_REQ_RESULT(req, -1);
|
||||
return;
|
||||
}
|
||||
if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
/* We got out of the loop because we ran out of combinations to try. */
|
||||
SET_REQ_RESULT(req, -1);
|
||||
tries = TMP_MAX;
|
||||
do {
|
||||
if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
cp = ep - num_x;
|
||||
for (i = 0; i < num_x; i++) {
|
||||
*cp++ = tempchars[v % num_chars];
|
||||
v /= num_chars;
|
||||
}
|
||||
|
||||
if (_wmkdir(req->pathw) == 0) {
|
||||
len = strlen(req->path);
|
||||
wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
|
||||
SET_REQ_RESULT(req, 0);
|
||||
break;
|
||||
} else if (errno != EEXIST) {
|
||||
SET_REQ_RESULT(req, -1);
|
||||
break;
|
||||
}
|
||||
} while (--tries);
|
||||
|
||||
released = CryptReleaseContext(h_crypt_prov, 0);
|
||||
assert(released);
|
||||
if (tries == 0) {
|
||||
SET_REQ_RESULT(req, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fs__readdir(uv_fs_t* req) {
|
||||
WCHAR* pathw = req->pathw;
|
||||
size_t len = wcslen(pathw);
|
||||
int result, size;
|
||||
WCHAR* buf = NULL, *ptr, *name;
|
||||
int result;
|
||||
WCHAR* name;
|
||||
HANDLE dir;
|
||||
WIN32_FIND_DATAW ent = { 0 };
|
||||
size_t buf_char_len = 4096;
|
||||
WCHAR* path2;
|
||||
const WCHAR* fmt;
|
||||
uv__dirent_t** dents;
|
||||
int dent_size;
|
||||
|
||||
if (len == 0) {
|
||||
fmt = L"./*";
|
||||
@ -821,7 +812,8 @@ void fs__readdir(uv_fs_t* req) {
|
||||
|
||||
path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4));
|
||||
if (!path2) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
_snwprintf(path2, len + 3, fmt, pathw);
|
||||
@ -834,71 +826,81 @@ void fs__readdir(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
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]))) {
|
||||
len = wcslen(name);
|
||||
if (!(name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))))
|
||||
continue;
|
||||
|
||||
if (!buf) {
|
||||
buf = (WCHAR*)malloc(buf_char_len * sizeof(WCHAR));
|
||||
if (!buf) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
/* Grow dents buffer, if needed */
|
||||
if (result >= dent_size) {
|
||||
uv__dirent_t** tmp;
|
||||
|
||||
ptr = buf;
|
||||
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;
|
||||
}
|
||||
|
||||
while ((ptr - buf) + len + 1 > buf_char_len) {
|
||||
buf_char_len *= 2;
|
||||
path2 = buf;
|
||||
buf = (WCHAR*)realloc(buf, buf_char_len * sizeof(WCHAR));
|
||||
if (!buf) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
|
||||
}
|
||||
|
||||
ptr = buf + (ptr - path2);
|
||||
}
|
||||
|
||||
wcscpy(ptr, name);
|
||||
ptr += len + 1;
|
||||
result++;
|
||||
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;
|
||||
|
||||
dents[result++] = dent;
|
||||
} while(FindNextFileW(dir, &ent));
|
||||
|
||||
FindClose(dir);
|
||||
|
||||
if (buf) {
|
||||
/* Convert result to UTF8. */
|
||||
size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0);
|
||||
if (!size) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
req->ptr = (char*)malloc(size + 1);
|
||||
if (!req->ptr) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size);
|
||||
if (!size) {
|
||||
free(buf);
|
||||
free(req->ptr);
|
||||
req->ptr = NULL;
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
((char*)req->ptr)[size] = '\0';
|
||||
if (dents != NULL)
|
||||
req->flags |= UV_FS_FREE_PTR;
|
||||
} else {
|
||||
req->ptr = NULL;
|
||||
}
|
||||
|
||||
/* NOTE: nbufs will be used as index */
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
19
deps/uv/src/win/getaddrinfo.c
vendored
@ -26,6 +26,25 @@
|
||||
#include "internal.h"
|
||||
#include "req-inl.h"
|
||||
|
||||
/* EAI_* constants. */
|
||||
#include <winsock2.h>
|
||||
|
||||
|
||||
int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
switch (sys_err) {
|
||||
case 0: return 0;
|
||||
case WSATRY_AGAIN: return UV_EAI_AGAIN;
|
||||
case WSAEINVAL: return UV_EAI_BADFLAGS;
|
||||
case WSANO_RECOVERY: return UV_EAI_FAIL;
|
||||
case WSAEAFNOSUPPORT: return UV_EAI_FAMILY;
|
||||
case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY;
|
||||
case WSAHOST_NOT_FOUND: return UV_EAI_NONAME;
|
||||
case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE;
|
||||
case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE;
|
||||
default: return uv_translate_sys_error(sys_err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MinGW is missing this
|
||||
|
16
deps/uv/src/win/getnameinfo.c
vendored
@ -46,13 +46,15 @@ static void uv__getnameinfo_work(struct uv__work* w) {
|
||||
int ret = 0;
|
||||
|
||||
req = container_of(w, uv_getnameinfo_t, work_req);
|
||||
ret = GetNameInfoW((struct sockaddr*)&req->storage,
|
||||
sizeof(req->storage),
|
||||
host,
|
||||
ARRAY_SIZE(host),
|
||||
service,
|
||||
ARRAY_SIZE(service),
|
||||
req->flags);
|
||||
if (GetNameInfoW((struct sockaddr*)&req->storage,
|
||||
sizeof(req->storage),
|
||||
host,
|
||||
ARRAY_SIZE(host),
|
||||
service,
|
||||
ARRAY_SIZE(service),
|
||||
req->flags)) {
|
||||
ret = WSAGetLastError();
|
||||
}
|
||||
req->retcode = uv__getaddrinfo_translate_error(ret);
|
||||
|
||||
/* convert results to UTF-8 */
|
||||
|
6
deps/uv/src/win/internal.h
vendored
@ -65,7 +65,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
|
||||
/* Used by all handles. */
|
||||
#define UV_HANDLE_CLOSED 0x00000002
|
||||
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
|
||||
#define UV_HANDLE_ACTIVE 0x00000010
|
||||
|
||||
/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
|
||||
/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
|
||||
@ -100,6 +99,7 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
|
||||
/* Only used by uv_pipe_t handles. */
|
||||
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
|
||||
#define UV_HANDLE_PIPESERVER 0x02000000
|
||||
#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000
|
||||
|
||||
/* Only used by uv_tty_t handles. */
|
||||
#define UV_HANDLE_TTY_READABLE 0x01000000
|
||||
@ -181,6 +181,9 @@ int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
|
||||
int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
|
||||
const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
|
||||
uv_write_cb cb);
|
||||
void uv__pipe_pause_read(uv_pipe_t* handle);
|
||||
void uv__pipe_unpause_read(uv_pipe_t* handle);
|
||||
void uv__pipe_stop_read(uv_pipe_t* handle);
|
||||
|
||||
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
|
||||
uv_req_t* req);
|
||||
@ -319,6 +322,7 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
|
||||
*/
|
||||
void uv__util_init();
|
||||
|
||||
uint64_t uv__hrtime(double scale);
|
||||
int uv_parent_pid();
|
||||
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
|
||||
|
||||
|
6
deps/uv/src/win/loop-watcher.c
vendored
@ -49,7 +49,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
||||
\
|
||||
assert(handle->type == UV_##NAME); \
|
||||
\
|
||||
if (handle->flags & UV_HANDLE_ACTIVE) \
|
||||
if (uv__is_active(handle)) \
|
||||
return 0; \
|
||||
\
|
||||
if (cb == NULL) \
|
||||
@ -67,7 +67,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
||||
loop->name##_handles = handle; \
|
||||
\
|
||||
handle->name##_cb = cb; \
|
||||
handle->flags |= UV_HANDLE_ACTIVE; \
|
||||
uv__handle_start(handle); \
|
||||
\
|
||||
return 0; \
|
||||
@ -79,7 +78,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
||||
\
|
||||
assert(handle->type == UV_##NAME); \
|
||||
\
|
||||
if (!(handle->flags & UV_HANDLE_ACTIVE)) \
|
||||
if (!uv__is_active(handle)) \
|
||||
return 0; \
|
||||
\
|
||||
/* Update loop head if needed */ \
|
||||
@ -99,7 +98,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
||||
handle->name##_next->name##_prev = handle->name##_prev; \
|
||||
} \
|
||||
\
|
||||
handle->flags &= ~UV_HANDLE_ACTIVE; \
|
||||
uv__handle_stop(handle); \
|
||||
\
|
||||
return 0; \
|
||||
|
105
deps/uv/src/win/pipe.c
vendored
@ -101,6 +101,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
||||
handle->pending_ipc_info.queue_len = 0;
|
||||
handle->ipc = ipc;
|
||||
handle->non_overlapped_writes_tail = NULL;
|
||||
handle->readfile_thread = NULL;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
|
||||
|
||||
@ -112,6 +113,12 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
|
||||
uv_connection_init((uv_stream_t*) handle);
|
||||
handle->read_req.data = handle;
|
||||
handle->eof_timer = NULL;
|
||||
assert(!(handle->flags & UV_HANDLE_PIPESERVER));
|
||||
if (pCancelSynchronousIo &&
|
||||
handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
|
||||
uv_mutex_init(&handle->readfile_mutex);
|
||||
handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -321,6 +328,11 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||
FILE_PIPE_LOCAL_INFORMATION pipe_info;
|
||||
uv__ipc_queue_item_t* item;
|
||||
|
||||
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
|
||||
uv_mutex_destroy(&handle->readfile_mutex);
|
||||
}
|
||||
|
||||
if ((handle->flags & UV_HANDLE_CONNECTION) &&
|
||||
handle->shutdown_req != NULL &&
|
||||
handle->write_reqs_pending == 0) {
|
||||
@ -658,12 +670,49 @@ error:
|
||||
}
|
||||
|
||||
|
||||
void uv__pipe_pause_read(uv_pipe_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
/* Pause the ReadFile task briefly, to work
|
||||
around the Windows kernel bug that causes
|
||||
any access to a NamedPipe to deadlock if
|
||||
any process has called ReadFile */
|
||||
HANDLE h;
|
||||
uv_mutex_lock(&handle->readfile_mutex);
|
||||
h = handle->readfile_thread;
|
||||
while (h) {
|
||||
/* spinlock: we expect this to finish quickly,
|
||||
or we are probably about to deadlock anyways
|
||||
(in the kernel), so it doesn't matter */
|
||||
pCancelSynchronousIo(h);
|
||||
SwitchToThread(); /* yield thread control briefly */
|
||||
h = handle->readfile_thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__pipe_unpause_read(uv_pipe_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
uv_mutex_unlock(&handle->readfile_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__pipe_stop_read(uv_pipe_t* handle) {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
uv__pipe_pause_read((uv_pipe_t*)handle);
|
||||
uv__pipe_unpause_read((uv_pipe_t*)handle);
|
||||
}
|
||||
|
||||
|
||||
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
|
||||
/* with it. */
|
||||
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||
int i;
|
||||
HANDLE pipeHandle;
|
||||
|
||||
uv__pipe_stop_read(handle);
|
||||
|
||||
if (handle->name) {
|
||||
free(handle->name);
|
||||
handle->name = NULL;
|
||||
@ -689,6 +738,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||
CloseHandle(handle->handle);
|
||||
handle->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -867,19 +917,61 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
|
||||
uv_read_t* req = (uv_read_t*) parameter;
|
||||
uv_pipe_t* handle = (uv_pipe_t*) req->data;
|
||||
uv_loop_t* loop = handle->loop;
|
||||
HANDLE hThread = NULL;
|
||||
DWORD err;
|
||||
uv_mutex_t *m = &handle->readfile_mutex;
|
||||
|
||||
assert(req != NULL);
|
||||
assert(req->type == UV_READ);
|
||||
assert(handle->type == UV_NAMED_PIPE);
|
||||
|
||||
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
|
||||
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
|
||||
GetCurrentProcess(), &hThread,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS)) {
|
||||
handle->readfile_thread = hThread;
|
||||
} else {
|
||||
hThread = NULL;
|
||||
}
|
||||
uv_mutex_unlock(m);
|
||||
}
|
||||
restart_readfile:
|
||||
result = ReadFile(handle->handle,
|
||||
&uv_zero_,
|
||||
0,
|
||||
&bytes,
|
||||
NULL);
|
||||
if (!result) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_OPERATION_ABORTED &&
|
||||
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
if (handle->flags & UV_HANDLE_READING) {
|
||||
/* just a brief break to do something else */
|
||||
handle->readfile_thread = NULL;
|
||||
/* resume after it is finished */
|
||||
uv_mutex_lock(m);
|
||||
handle->readfile_thread = hThread;
|
||||
uv_mutex_unlock(m);
|
||||
goto restart_readfile;
|
||||
} else {
|
||||
result = 1; /* successfully stopped reading */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hThread) {
|
||||
assert(hThread == handle->readfile_thread);
|
||||
/* mutex does not control clearing readfile_thread */
|
||||
handle->readfile_thread = NULL;
|
||||
uv_mutex_lock(m);
|
||||
/* only when we hold the mutex lock is it safe to
|
||||
open or close the handle */
|
||||
CloseHandle(hThread);
|
||||
uv_mutex_unlock(m);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
SET_REQ_ERROR(req, GetLastError());
|
||||
SET_REQ_ERROR(req, err);
|
||||
}
|
||||
|
||||
POST_COMPLETION_FOR_REQ(loop, req);
|
||||
@ -1836,6 +1928,8 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */
|
||||
|
||||
nt_status = pNtQueryInformationFile(handle->handle,
|
||||
&io_status,
|
||||
&tmp_name_info,
|
||||
@ -1846,7 +1940,8 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
||||
name_info = malloc(name_size);
|
||||
if (!name_info) {
|
||||
*len = 0;
|
||||
return UV_ENOMEM;
|
||||
err = UV_ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
nt_status = pNtQueryInformationFile(handle->handle,
|
||||
@ -1918,10 +2013,14 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
||||
buf[addrlen++] = '\0';
|
||||
*len = addrlen;
|
||||
|
||||
return 0;
|
||||
err = 0;
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
free(name_info);
|
||||
|
||||
cleanup:
|
||||
uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */
|
||||
return err;
|
||||
}
|
||||
|
||||
|
16
deps/uv/src/win/process.c
vendored
@ -171,8 +171,10 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
|
||||
size_t cwd_len) {
|
||||
WCHAR *result, *result_pos;
|
||||
DWORD attrs;
|
||||
|
||||
if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
|
||||
if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') {
|
||||
/* It's a UNC path so ignore cwd */
|
||||
cwd_len = 0;
|
||||
} else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
|
||||
/* It's a full path without drive letter, use cwd's drive letter only */
|
||||
cwd_len = 2;
|
||||
} else if (dir_len >= 2 && dir[1] == L':' &&
|
||||
@ -331,7 +333,11 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir,
|
||||
* file that is not readable/executable; if the spawn fails it will not
|
||||
* continue searching.
|
||||
*
|
||||
* TODO: correctly interpret UNC paths
|
||||
* UNC path support: we are dealing with UNC paths in both the path and the
|
||||
* filename. This is a deviation from what cmd.exe does (it does not let you
|
||||
* start a program by specifying an UNC path on the command line) but this is
|
||||
* really a pointless restriction.
|
||||
*
|
||||
*/
|
||||
static WCHAR* search_path(const WCHAR *file,
|
||||
WCHAR *cwd,
|
||||
@ -794,10 +800,8 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
||||
i++;
|
||||
} else {
|
||||
/* copy var from env_block */
|
||||
DWORD r;
|
||||
len = wcslen(*ptr_copy) + 1;
|
||||
r = wmemcpy_s(ptr, (env_len - (ptr - dst)), *ptr_copy, len);
|
||||
assert(!r);
|
||||
wmemcpy(ptr, *ptr_copy, len);
|
||||
ptr_copy++;
|
||||
if (cmp == 0)
|
||||
i++;
|
||||
|
6
deps/uv/src/win/stream.c
vendored
@ -106,7 +106,11 @@ int uv_read_stop(uv_stream_t* handle) {
|
||||
if (handle->type == UV_TTY) {
|
||||
err = uv_tty_read_stop((uv_tty_t*) handle);
|
||||
} else {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
if (handle->type == UV_NAMED_PIPE) {
|
||||
uv__pipe_stop_read((uv_pipe_t*) handle);
|
||||
} else {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
}
|
||||
DECREASE_ACTIVE_COUNT(handle->loop, handle);
|
||||
}
|
||||
|
||||
|
2
deps/uv/src/win/tcp.c
vendored
@ -196,6 +196,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
||||
closesocket(handle->socket);
|
||||
handle->socket = INVALID_SOCKET;
|
||||
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||
}
|
||||
|
||||
@ -1368,6 +1369,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||
|
||||
if (close_socket) {
|
||||
closesocket(tcp->socket);
|
||||
tcp->socket = INVALID_SOCKET;
|
||||
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||
}
|
||||
|
||||
|
100
deps/uv/src/win/timer.c
vendored
@ -28,39 +28,17 @@
|
||||
#include "handle-inl.h"
|
||||
|
||||
|
||||
/* The number of milliseconds in one second. */
|
||||
#define UV__MILLISEC 1000
|
||||
|
||||
|
||||
void uv_update_time(uv_loop_t* loop) {
|
||||
DWORD ticks;
|
||||
ULARGE_INTEGER time;
|
||||
|
||||
ticks = GetTickCount();
|
||||
|
||||
time.QuadPart = loop->time;
|
||||
|
||||
/* GetTickCount() can conceivably wrap around, so when the current tick
|
||||
* count is lower than the last tick count, we'll assume it has wrapped.
|
||||
* uv_poll must make sure that the timer can never overflow more than
|
||||
* once between two subsequent uv_update_time calls.
|
||||
*/
|
||||
time.LowPart = ticks;
|
||||
if (ticks < loop->last_tick_count)
|
||||
time.HighPart++;
|
||||
|
||||
/* Remember the last tick count. */
|
||||
loop->last_tick_count = ticks;
|
||||
|
||||
/* The GetTickCount() resolution isn't too good. Sometimes it'll happen
|
||||
* that GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx() has
|
||||
* waited for a couple of ms but this is not reflected in the GetTickCount
|
||||
* result yet. Therefore whenever GetQueuedCompletionStatus times out
|
||||
* we'll add the number of ms that it has waited to the current loop time.
|
||||
* When that happened the loop time might be a little ms farther than what
|
||||
* we've just computed, and we shouldn't update the loop time.
|
||||
*/
|
||||
if (loop->time < time.QuadPart)
|
||||
loop->time = time.QuadPart;
|
||||
uint64_t new_time = uv__hrtime(UV__MILLISEC);
|
||||
if (new_time > loop->time) {
|
||||
loop->time = new_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__time_forward(uv_loop_t* loop, uint64_t msecs) {
|
||||
loop->time += msecs;
|
||||
}
|
||||
@ -119,14 +97,15 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
|
||||
uv_loop_t* loop = handle->loop;
|
||||
uv_timer_t* old;
|
||||
|
||||
if (handle->flags & UV_HANDLE_ACTIVE) {
|
||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
||||
}
|
||||
if (timer_cb == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
uv_timer_stop(handle);
|
||||
|
||||
handle->timer_cb = timer_cb;
|
||||
handle->due = get_clamped_due_time(loop->time, timeout);
|
||||
handle->repeat = repeat;
|
||||
handle->flags |= UV_HANDLE_ACTIVE;
|
||||
uv__handle_start(handle);
|
||||
|
||||
/* start_id is the second index to be compared in uv__timer_cmp() */
|
||||
@ -142,12 +121,10 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
|
||||
int uv_timer_stop(uv_timer_t* handle) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_ACTIVE))
|
||||
if (!uv__is_active(handle))
|
||||
return 0;
|
||||
|
||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
||||
|
||||
handle->flags &= ~UV_HANDLE_ACTIVE;
|
||||
uv__handle_stop(handle);
|
||||
|
||||
return 0;
|
||||
@ -155,28 +132,14 @@ int uv_timer_stop(uv_timer_t* handle) {
|
||||
|
||||
|
||||
int uv_timer_again(uv_timer_t* handle) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
|
||||
/* If timer_cb is NULL that means that the timer was never started. */
|
||||
if (!handle->timer_cb) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
if (handle->flags & UV_HANDLE_ACTIVE) {
|
||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
||||
handle->flags &= ~UV_HANDLE_ACTIVE;
|
||||
uv__handle_stop(handle);
|
||||
}
|
||||
|
||||
if (handle->repeat) {
|
||||
handle->due = get_clamped_due_time(loop->time, handle->repeat);
|
||||
|
||||
if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
|
||||
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
|
||||
}
|
||||
|
||||
handle->flags |= UV_HANDLE_ACTIVE;
|
||||
uv__handle_start(handle);
|
||||
uv_timer_stop(handle);
|
||||
uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -206,16 +169,9 @@ DWORD uv__next_timeout(const uv_loop_t* loop) {
|
||||
timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers);
|
||||
if (timer) {
|
||||
delta = timer->due - loop->time;
|
||||
if (delta >= UINT_MAX >> 1) {
|
||||
/* A timeout value of UINT_MAX means infinite, so that's no good. But
|
||||
* more importantly, there's always the risk that GetTickCount wraps.
|
||||
* uv_update_time can detect this, but we must make sure that the
|
||||
* tick counter never overflows twice between two subsequent
|
||||
* uv_update_time calls. We do this by never sleeping more than half
|
||||
* the time it takes to wrap the counter - which is huge overkill,
|
||||
* but hey, it's not so bad to wake up every 25 days.
|
||||
*/
|
||||
return UINT_MAX >> 1;
|
||||
if (delta >= UINT_MAX - 1) {
|
||||
/* A timeout value of UINT_MAX means infinite, so that's no good. */
|
||||
return UINT_MAX - 1;
|
||||
} else if (delta < 0) {
|
||||
/* Negative timeout values are not allowed */
|
||||
return 0;
|
||||
@ -236,23 +192,9 @@ void uv_process_timers(uv_loop_t* loop) {
|
||||
for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
|
||||
timer != NULL && timer->due <= loop->time;
|
||||
timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
|
||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, timer);
|
||||
|
||||
if (timer->repeat != 0) {
|
||||
/* If it is a repeating timer, reschedule with repeat timeout. */
|
||||
timer->due = get_clamped_due_time(timer->due, timer->repeat);
|
||||
if (timer->due < loop->time) {
|
||||
timer->due = loop->time;
|
||||
}
|
||||
if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) {
|
||||
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
|
||||
}
|
||||
} else {
|
||||
/* If non-repeating, mark the timer as inactive. */
|
||||
timer->flags &= ~UV_HANDLE_ACTIVE;
|
||||
uv__handle_stop(timer);
|
||||
}
|
||||
|
||||
uv_timer_stop(timer);
|
||||
uv_timer_again(timer);
|
||||
timer->timer_cb((uv_timer_t*) timer);
|
||||
}
|
||||
}
|
||||
|
1
deps/uv/src/win/tty.c
vendored
@ -1903,6 +1903,7 @@ void uv_tty_close(uv_tty_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_READING)
|
||||
uv_tty_read_stop(handle);
|
||||
|
||||
handle->handle = INVALID_HANDLE_VALUE;
|
||||
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
uv__handle_closing(handle);
|
||||
|
||||
|
15
deps/uv/src/win/udp.c
vendored
@ -144,6 +144,7 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
||||
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
|
||||
uv_udp_recv_stop(handle);
|
||||
closesocket(handle->socket);
|
||||
handle->socket = INVALID_SOCKET;
|
||||
|
||||
uv__handle_closing(handle);
|
||||
|
||||
@ -505,9 +506,13 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
|
||||
} else if (err == WSAEWOULDBLOCK) {
|
||||
/* Kernel buffer empty */
|
||||
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
||||
} else if (err != WSAECONNRESET && err != WSAENETRESET) {
|
||||
/* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */
|
||||
/* just indicates that a previous sendto operation failed. */
|
||||
} else if (err == WSAECONNRESET || err == WSAENETRESET) {
|
||||
/* WSAECONNRESET/WSANETRESET is ignored because this just indicates
|
||||
* that a previous sendto operation failed.
|
||||
*/
|
||||
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
||||
} else {
|
||||
/* Any other error that we want to report back to the user. */
|
||||
uv_udp_recv_stop(handle);
|
||||
handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
|
||||
}
|
||||
@ -572,7 +577,9 @@ static int uv__udp_set_membership4(uv_udp_t* handle,
|
||||
memset(&mreq, 0, sizeof mreq);
|
||||
|
||||
if (interface_addr) {
|
||||
mreq.imr_interface.s_addr = inet_addr(interface_addr);
|
||||
err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
|
37
deps/uv/src/win/util.c
vendored
@ -52,16 +52,15 @@
|
||||
#define MAX_TITLE_LENGTH 8192
|
||||
|
||||
/* The number of nanoseconds in one second. */
|
||||
#undef NANOSEC
|
||||
#define NANOSEC 1000000000
|
||||
#define UV__NANOSEC 1000000000
|
||||
|
||||
|
||||
/* Cached copy of the process title, plus a mutex guarding it. */
|
||||
static char *process_title;
|
||||
static CRITICAL_SECTION process_title_lock;
|
||||
|
||||
/* Frequency (ticks per nanosecond) of the high-resolution clock. */
|
||||
static double hrtime_frequency_ = 0;
|
||||
/* Interval (in seconds) of the high-resolution clock. */
|
||||
static double hrtime_interval_ = 0;
|
||||
|
||||
|
||||
/*
|
||||
@ -73,11 +72,14 @@ void uv__util_init() {
|
||||
/* Initialize process title access mutex. */
|
||||
InitializeCriticalSection(&process_title_lock);
|
||||
|
||||
/* Retrieve high-resolution timer frequency. */
|
||||
if (QueryPerformanceFrequency(&perf_frequency))
|
||||
hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
|
||||
else
|
||||
hrtime_frequency_= 0;
|
||||
/* Retrieve high-resolution timer frequency
|
||||
* and precompute its reciprocal.
|
||||
*/
|
||||
if (QueryPerformanceFrequency(&perf_frequency)) {
|
||||
hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
|
||||
} else {
|
||||
hrtime_interval_= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -463,26 +465,27 @@ int uv_get_process_title(char* buffer, size_t size) {
|
||||
|
||||
|
||||
uint64_t uv_hrtime(void) {
|
||||
uv__once_init();
|
||||
return uv__hrtime(UV__NANOSEC);
|
||||
}
|
||||
|
||||
uint64_t uv__hrtime(double scale) {
|
||||
LARGE_INTEGER counter;
|
||||
|
||||
uv__once_init();
|
||||
|
||||
/* If the performance frequency is zero, there's no support. */
|
||||
if (hrtime_frequency_ == 0) {
|
||||
/* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
|
||||
/* If the performance interval is zero, there's no support. */
|
||||
if (hrtime_interval_ == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!QueryPerformanceCounter(&counter)) {
|
||||
/* uv__set_sys_error(loop, GetLastError()); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Because we have no guarantee about the order of magnitude of the
|
||||
* performance counter frequency, integer math could cause this computation
|
||||
* performance counter interval, integer math could cause this computation
|
||||
* to overflow. Therefore we resort to floating point math.
|
||||
*/
|
||||
return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
|
||||
return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
|
||||
}
|
||||
|
||||
|
||||
|
4
deps/uv/src/win/winapi.c
vendored
@ -51,6 +51,7 @@ sSleepConditionVariableCS pSleepConditionVariableCS;
|
||||
sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||
sWakeAllConditionVariable pWakeAllConditionVariable;
|
||||
sWakeConditionVariable pWakeConditionVariable;
|
||||
sCancelSynchronousIo pCancelSynchronousIo;
|
||||
|
||||
|
||||
void uv_winapi_init() {
|
||||
@ -156,4 +157,7 @@ void uv_winapi_init() {
|
||||
|
||||
pWakeConditionVariable = (sWakeConditionVariable)
|
||||
GetProcAddress(kernel32_module, "WakeConditionVariable");
|
||||
|
||||
pCancelSynchronousIo = (sCancelSynchronousIo)
|
||||
GetProcAddress(kernel32_module, "CancelSynchronousIo");
|
||||
}
|
||||
|
3
deps/uv/src/win/winapi.h
vendored
@ -4617,6 +4617,8 @@ typedef VOID (WINAPI* sWakeAllConditionVariable)
|
||||
typedef VOID (WINAPI* sWakeConditionVariable)
|
||||
(PCONDITION_VARIABLE ConditionVariable);
|
||||
|
||||
typedef BOOL (WINAPI* sCancelSynchronousIo)
|
||||
(HANDLE hThread);
|
||||
|
||||
/* Ntdll function pointers */
|
||||
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
|
||||
@ -4644,5 +4646,6 @@ extern sSleepConditionVariableCS pSleepConditionVariableCS;
|
||||
extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||
extern sWakeAllConditionVariable pWakeAllConditionVariable;
|
||||
extern sWakeConditionVariable pWakeConditionVariable;
|
||||
extern sCancelSynchronousIo pCancelSynchronousIo;
|
||||
|
||||
#endif /* UV_WIN_WINAPI_H_ */
|
||||
|
22
deps/uv/test/echo-server.c
vendored
@ -51,20 +51,21 @@ static void after_write(uv_write_t* req, int status) {
|
||||
/* Free the read/write buffer and the request */
|
||||
wr = (write_req_t*) req;
|
||||
free(wr->buf.base);
|
||||
free(wr);
|
||||
|
||||
if (status == 0) {
|
||||
free(wr);
|
||||
if (status == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"uv_write error: %s - %s\n",
|
||||
uv_err_name(status),
|
||||
uv_strerror(status));
|
||||
}
|
||||
|
||||
if (!uv_is_closing((uv_handle_t*) req->handle))
|
||||
uv_close((uv_handle_t*) req->handle, on_close);
|
||||
free(wr);
|
||||
|
||||
static void after_shutdown(uv_shutdown_t* req, int status) {
|
||||
uv_close((uv_handle_t*) req->handle, on_close);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
@ -73,16 +74,15 @@ static void after_read(uv_stream_t* handle,
|
||||
const uv_buf_t* buf) {
|
||||
int i;
|
||||
write_req_t *wr;
|
||||
uv_shutdown_t* sreq;
|
||||
|
||||
if (nread < 0) {
|
||||
/* Error or EOF */
|
||||
ASSERT(nread == UV_EOF);
|
||||
|
||||
if (buf->base) {
|
||||
free(buf->base);
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*) handle, on_close);
|
||||
free(buf->base);
|
||||
sreq = malloc(sizeof* sreq);
|
||||
ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown));
|
||||
return;
|
||||
}
|
||||
|
||||
|
59
deps/uv/test/test-default-loop-close.c
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
static int timer_cb_called;
|
||||
|
||||
|
||||
static void timer_cb(uv_timer_t* timer) {
|
||||
timer_cb_called++;
|
||||
uv_close((uv_handle_t*) timer, NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(default_loop_close) {
|
||||
uv_loop_t* loop;
|
||||
uv_timer_t timer_handle;
|
||||
|
||||
loop = uv_default_loop();
|
||||
ASSERT(loop != NULL);
|
||||
|
||||
ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
||||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
ASSERT(1 == timer_cb_called);
|
||||
ASSERT(0 == uv_loop_close(loop));
|
||||
|
||||
loop = uv_default_loop();
|
||||
ASSERT(loop != NULL);
|
||||
|
||||
ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
||||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
ASSERT(2 == timer_cb_called);
|
||||
ASSERT(0 == uv_loop_close(loop));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
28
deps/uv/test/test-fs.c
vendored
@ -417,12 +417,16 @@ static void rmdir_cb(uv_fs_t* req) {
|
||||
|
||||
|
||||
static void readdir_cb(uv_fs_t* req) {
|
||||
uv_dirent_t dent;
|
||||
ASSERT(req == &readdir_req);
|
||||
ASSERT(req->fs_type == UV_FS_READDIR);
|
||||
ASSERT(req->result == 2);
|
||||
ASSERT(req->ptr);
|
||||
ASSERT(memcmp(req->ptr, "file1\0file2\0", 12) == 0
|
||||
|| memcmp(req->ptr, "file2\0file1\0", 12) == 0);
|
||||
|
||||
while (UV_EOF != uv_fs_readdir_next(req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
readdir_cb_count++;
|
||||
ASSERT(req->path);
|
||||
ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
|
||||
@ -802,6 +806,7 @@ TEST_IMPL(fs_file_write_null_buffer) {
|
||||
|
||||
TEST_IMPL(fs_async_dir) {
|
||||
int r;
|
||||
uv_dirent_t dent;
|
||||
|
||||
/* Setup */
|
||||
unlink("test_dir/file1");
|
||||
@ -844,8 +849,10 @@ TEST_IMPL(fs_async_dir) {
|
||||
ASSERT(r == 2);
|
||||
ASSERT(readdir_req.result == 2);
|
||||
ASSERT(readdir_req.ptr);
|
||||
ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
|
||||
|| memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
|
||||
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
ASSERT(!readdir_req.ptr);
|
||||
|
||||
@ -1521,6 +1528,7 @@ TEST_IMPL(fs_symlink_dir) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
char* test_dir;
|
||||
uv_dirent_t dent;
|
||||
|
||||
/* set-up */
|
||||
unlink("test_dir/file1");
|
||||
@ -1597,8 +1605,10 @@ TEST_IMPL(fs_symlink_dir) {
|
||||
ASSERT(r == 2);
|
||||
ASSERT(readdir_req.result == 2);
|
||||
ASSERT(readdir_req.ptr);
|
||||
ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
|
||||
|| memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
|
||||
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
ASSERT(!readdir_req.ptr);
|
||||
|
||||
@ -1615,8 +1625,10 @@ TEST_IMPL(fs_symlink_dir) {
|
||||
ASSERT(r == 2);
|
||||
ASSERT(readdir_req.result == 2);
|
||||
ASSERT(readdir_req.ptr);
|
||||
ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
|
||||
|| memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
|
||||
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
ASSERT(!readdir_req.ptr);
|
||||
|
||||
|
120
deps/uv/test/test-handle-fileno.c
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
static int get_tty_fd(void) {
|
||||
/* Make sure we have an FD that refers to a tty */
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
handle = CreateFileA("conout$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
return _open_osfhandle((intptr_t) handle, 0);
|
||||
#else /* unix */
|
||||
return open("/dev/tty", O_RDONLY, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(handle_fileno) {
|
||||
int r;
|
||||
int tty_fd;
|
||||
struct sockaddr_in addr;
|
||||
uv_os_fd_t fd;
|
||||
uv_tcp_t tcp;
|
||||
uv_udp_t udp;
|
||||
uv_pipe_t pipe;
|
||||
uv_tty_t tty;
|
||||
uv_idle_t idle;
|
||||
uv_loop_t* loop;
|
||||
|
||||
loop = uv_default_loop();
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
|
||||
r = uv_idle_init(loop, &idle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &idle, &fd);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
uv_close((uv_handle_t*) &idle, NULL);
|
||||
|
||||
r = uv_tcp_init(loop, &tcp);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &tcp, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &tcp, &fd);
|
||||
ASSERT(r == 0);
|
||||
uv_close((uv_handle_t*) &tcp, NULL);
|
||||
r = uv_fileno((uv_handle_t*) &tcp, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
|
||||
r = uv_udp_init(loop, &udp);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &udp, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &udp, &fd);
|
||||
ASSERT(r == 0);
|
||||
uv_close((uv_handle_t*) &udp, NULL);
|
||||
r = uv_fileno((uv_handle_t*) &udp, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
|
||||
r = uv_pipe_init(loop, &pipe, 0);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &pipe, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
r = uv_pipe_bind(&pipe, TEST_PIPENAME);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &pipe, &fd);
|
||||
ASSERT(r == 0);
|
||||
uv_close((uv_handle_t*) &pipe, NULL);
|
||||
r = uv_fileno((uv_handle_t*) &pipe, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
|
||||
tty_fd = get_tty_fd();
|
||||
if (tty_fd < 0) {
|
||||
LOGF("Cannot open a TTY fd");
|
||||
} else {
|
||||
r = uv_tty_init(loop, &tty, tty_fd, 0);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fileno((uv_handle_t*) &tty, &fd);
|
||||
ASSERT(r == 0);
|
||||
uv_close((uv_handle_t*) &tty, NULL);
|
||||
r = uv_fileno((uv_handle_t*) &tty, &fd);
|
||||
ASSERT(r == UV_EBADF);
|
||||
}
|
||||
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
29
deps/uv/test/test-list.h
vendored
@ -29,6 +29,7 @@ TEST_DECLARE (loop_close)
|
||||
TEST_DECLARE (loop_stop)
|
||||
TEST_DECLARE (loop_update_time)
|
||||
TEST_DECLARE (loop_backend_timeout)
|
||||
TEST_DECLARE (default_loop_close)
|
||||
TEST_DECLARE (barrier_1)
|
||||
TEST_DECLARE (barrier_2)
|
||||
TEST_DECLARE (barrier_3)
|
||||
@ -55,6 +56,9 @@ TEST_DECLARE (tcp_ping_pong_v6)
|
||||
TEST_DECLARE (pipe_ping_pong)
|
||||
TEST_DECLARE (delayed_accept)
|
||||
TEST_DECLARE (multiple_listen)
|
||||
#ifndef _WIN32
|
||||
TEST_DECLARE (tcp_write_after_connect)
|
||||
#endif
|
||||
TEST_DECLARE (tcp_writealot)
|
||||
TEST_DECLARE (tcp_try_write)
|
||||
TEST_DECLARE (tcp_write_queue_order)
|
||||
@ -89,6 +93,7 @@ TEST_DECLARE (udp_bind)
|
||||
TEST_DECLARE (udp_bind_reuseaddr)
|
||||
TEST_DECLARE (udp_send_and_recv)
|
||||
TEST_DECLARE (udp_send_immediate)
|
||||
TEST_DECLARE (udp_send_unreachable)
|
||||
TEST_DECLARE (udp_multicast_join)
|
||||
TEST_DECLARE (udp_multicast_join6)
|
||||
TEST_DECLARE (udp_multicast_ttl)
|
||||
@ -109,6 +114,7 @@ TEST_DECLARE (pipe_connect_bad_name)
|
||||
TEST_DECLARE (pipe_connect_to_file)
|
||||
TEST_DECLARE (pipe_getsockname)
|
||||
TEST_DECLARE (pipe_getsockname_abstract)
|
||||
TEST_DECLARE (pipe_getsockname_blocking)
|
||||
TEST_DECLARE (pipe_sendmsg)
|
||||
TEST_DECLARE (pipe_server_close)
|
||||
TEST_DECLARE (connection_fail)
|
||||
@ -128,6 +134,7 @@ TEST_DECLARE (timer_huge_timeout)
|
||||
TEST_DECLARE (timer_huge_repeat)
|
||||
TEST_DECLARE (timer_run_once)
|
||||
TEST_DECLARE (timer_from_check)
|
||||
TEST_DECLARE (timer_null_callback)
|
||||
TEST_DECLARE (idle_starvation)
|
||||
TEST_DECLARE (loop_handles)
|
||||
TEST_DECLARE (get_loadavg)
|
||||
@ -155,6 +162,9 @@ TEST_DECLARE (pipe_ref)
|
||||
TEST_DECLARE (pipe_ref2)
|
||||
TEST_DECLARE (pipe_ref3)
|
||||
TEST_DECLARE (pipe_ref4)
|
||||
#ifndef _WIN32
|
||||
TEST_DECLARE (pipe_close_stdout_read_stdin)
|
||||
#endif
|
||||
TEST_DECLARE (process_ref)
|
||||
TEST_DECLARE (has_ref)
|
||||
TEST_DECLARE (active)
|
||||
@ -165,6 +175,7 @@ TEST_DECLARE (get_currentexe)
|
||||
TEST_DECLARE (process_title)
|
||||
TEST_DECLARE (cwd_and_chdir)
|
||||
TEST_DECLARE (get_memory)
|
||||
TEST_DECLARE (handle_fileno)
|
||||
TEST_DECLARE (hrtime)
|
||||
TEST_DECLARE (getaddrinfo_fail)
|
||||
TEST_DECLARE (getaddrinfo_basic)
|
||||
@ -175,6 +186,7 @@ TEST_DECLARE (getsockname_tcp)
|
||||
TEST_DECLARE (getsockname_udp)
|
||||
TEST_DECLARE (fail_always)
|
||||
TEST_DECLARE (pass_always)
|
||||
TEST_DECLARE (socket_buffer_size)
|
||||
TEST_DECLARE (spawn_fails)
|
||||
TEST_DECLARE (spawn_exit_code)
|
||||
TEST_DECLARE (spawn_stdout)
|
||||
@ -275,6 +287,7 @@ TEST_DECLARE (closed_fd_events)
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
TEST_DECLARE (osx_select)
|
||||
TEST_DECLARE (osx_select_many_fds)
|
||||
#endif
|
||||
HELPER_DECLARE (tcp4_echo_server)
|
||||
HELPER_DECLARE (tcp6_echo_server)
|
||||
@ -296,6 +309,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (loop_stop)
|
||||
TEST_ENTRY (loop_update_time)
|
||||
TEST_ENTRY (loop_backend_timeout)
|
||||
TEST_ENTRY (default_loop_close)
|
||||
TEST_ENTRY (barrier_1)
|
||||
TEST_ENTRY (barrier_2)
|
||||
TEST_ENTRY (barrier_3)
|
||||
@ -312,6 +326,9 @@ TASK_LIST_START
|
||||
TEST_ENTRY (pipe_connect_to_file)
|
||||
|
||||
TEST_ENTRY (pipe_server_close)
|
||||
#ifndef _WIN32
|
||||
TEST_ENTRY (pipe_close_stdout_read_stdin)
|
||||
#endif
|
||||
TEST_ENTRY (tty)
|
||||
TEST_ENTRY (stdio_over_pipes)
|
||||
TEST_ENTRY (ip6_pton)
|
||||
@ -335,6 +352,10 @@ TASK_LIST_START
|
||||
TEST_ENTRY (delayed_accept)
|
||||
TEST_ENTRY (multiple_listen)
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST_ENTRY (tcp_write_after_connect)
|
||||
#endif
|
||||
|
||||
TEST_ENTRY (tcp_writealot)
|
||||
TEST_HELPER (tcp_writealot, tcp4_echo_server)
|
||||
|
||||
@ -381,6 +402,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (udp_bind_reuseaddr)
|
||||
TEST_ENTRY (udp_send_and_recv)
|
||||
TEST_ENTRY (udp_send_immediate)
|
||||
TEST_ENTRY (udp_send_unreachable)
|
||||
TEST_ENTRY (udp_dgram_too_big)
|
||||
TEST_ENTRY (udp_dual_stack)
|
||||
TEST_ENTRY (udp_ipv6_only)
|
||||
@ -402,6 +424,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (pipe_listen_without_bind)
|
||||
TEST_ENTRY (pipe_getsockname)
|
||||
TEST_ENTRY (pipe_getsockname_abstract)
|
||||
TEST_ENTRY (pipe_getsockname_blocking)
|
||||
TEST_ENTRY (pipe_sendmsg)
|
||||
|
||||
TEST_ENTRY (connection_fail)
|
||||
@ -432,6 +455,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (timer_huge_repeat)
|
||||
TEST_ENTRY (timer_run_once)
|
||||
TEST_ENTRY (timer_from_check)
|
||||
TEST_ENTRY (timer_null_callback)
|
||||
|
||||
TEST_ENTRY (idle_starvation)
|
||||
|
||||
@ -487,6 +511,8 @@ TASK_LIST_START
|
||||
|
||||
TEST_ENTRY (get_loadavg)
|
||||
|
||||
TEST_ENTRY (handle_fileno)
|
||||
|
||||
TEST_ENTRY (hrtime)
|
||||
|
||||
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
|
||||
@ -504,6 +530,8 @@ TASK_LIST_START
|
||||
TEST_ENTRY (poll_unidirectional)
|
||||
TEST_ENTRY (poll_close)
|
||||
|
||||
TEST_ENTRY (socket_buffer_size)
|
||||
|
||||
TEST_ENTRY (spawn_fails)
|
||||
TEST_ENTRY (spawn_exit_code)
|
||||
TEST_ENTRY (spawn_stdout)
|
||||
@ -549,6 +577,7 @@ TASK_LIST_START
|
||||
|
||||
#ifdef __APPLE__
|
||||
TEST_ENTRY (osx_select)
|
||||
TEST_ENTRY (osx_select_many_fds)
|
||||
#endif
|
||||
|
||||
TEST_ENTRY (fs_file_noent)
|
||||
|
48
deps/uv/test/test-osx-select.c
vendored
@ -79,4 +79,52 @@ TEST_IMPL(osx_select) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(osx_select_many_fds) {
|
||||
int r;
|
||||
int fd;
|
||||
size_t i;
|
||||
size_t len;
|
||||
const char* str;
|
||||
struct sockaddr_in addr;
|
||||
uv_tty_t tty;
|
||||
uv_tcp_t tcps[1500];
|
||||
|
||||
r = uv_ip4_addr("127.0.0.1", 0, &addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tcps); i++) {
|
||||
r = uv_tcp_init(uv_default_loop(), &tcps[i]);
|
||||
ASSERT(r == 0);
|
||||
r = uv_tcp_bind(&tcps[i], (const struct sockaddr *) &addr, 0);
|
||||
ASSERT(r == 0);
|
||||
uv_unref((uv_handle_t*) &tcps[i]);
|
||||
}
|
||||
|
||||
fd = open("/dev/tty", O_RDONLY);
|
||||
ASSERT(fd >= 0);
|
||||
|
||||
r = uv_tty_init(uv_default_loop(), &tty, fd, 1);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Emulate user-input */
|
||||
str = "got some input\n"
|
||||
"with a couple of lines\n"
|
||||
"feel pretty happy\n";
|
||||
for (i = 0, len = strlen(str); i < len; i++) {
|
||||
r = ioctl(fd, TIOCSTI, str + i);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(read_count == 3);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
103
deps/uv/test/test-pipe-close-stdout-read-stdin.c
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf)
|
||||
{
|
||||
static char buffer[1024];
|
||||
|
||||
buf->base = buffer;
|
||||
buf->len = sizeof(buffer);
|
||||
}
|
||||
|
||||
void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf)
|
||||
{
|
||||
if (nread < 0) {
|
||||
uv_close((uv_handle_t*)stream, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This test is a reproduction of joyent/libuv#1419 .
|
||||
*/
|
||||
TEST_IMPL(pipe_close_stdout_read_stdin) {
|
||||
int r = -1;
|
||||
int pid;
|
||||
int fd[2];
|
||||
int status;
|
||||
|
||||
pipe(fd);
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
/*
|
||||
* Make the read side of the pipe our stdin.
|
||||
* The write side will be closed by the parent process.
|
||||
*/
|
||||
close(fd[1]);
|
||||
close(0);
|
||||
dup(fd[0]);
|
||||
|
||||
/* 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);
|
||||
|
||||
r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/*
|
||||
* Because the other end of the pipe was closed, there should
|
||||
* be no event left to process after one run of the event loop.
|
||||
* Otherwise, it means that events were not processed correctly.
|
||||
*/
|
||||
ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0);
|
||||
} else {
|
||||
/*
|
||||
* Close both ends of the pipe so that the child
|
||||
* get a POLLHUP event when it tries to read from
|
||||
* the other end.
|
||||
*/
|
||||
close(fd[1]);
|
||||
close(fd[0]);
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0);
|
||||
}
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ifndef _WIN32 */
|
58
deps/uv/test/test-pipe-getsockname.c
vendored
@ -32,6 +32,8 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h> /* close */
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
@ -120,3 +122,59 @@ TEST_IMPL(pipe_getsockname_abstract) {
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_IMPL(pipe_getsockname_blocking) {
|
||||
#ifdef _WIN32
|
||||
uv_pipe_t reader;
|
||||
HANDLE readh, writeh;
|
||||
int readfd;
|
||||
char buf1[1024], buf2[1024];
|
||||
size_t len1, len2;
|
||||
int r;
|
||||
|
||||
r = CreatePipe(&readh, &writeh, NULL, 65536);
|
||||
ASSERT(r != 0);
|
||||
|
||||
r = uv_pipe_init(uv_default_loop(), &reader, 0);
|
||||
ASSERT(r == 0);
|
||||
readfd = _open_osfhandle((intptr_t)readh, _O_RDONLY);
|
||||
ASSERT(r != -1);
|
||||
r = uv_pipe_open(&reader, readfd);
|
||||
ASSERT(r == 0);
|
||||
r = uv_read_start((uv_stream_t*)&reader, NULL, NULL);
|
||||
ASSERT(r == 0);
|
||||
Sleep(100);
|
||||
r = uv_read_stop((uv_stream_t*)&reader);
|
||||
ASSERT(r == 0);
|
||||
|
||||
len1 = sizeof buf1;
|
||||
r = uv_pipe_getsockname(&reader, buf1, &len1);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t*)&reader, NULL, NULL);
|
||||
ASSERT(r == 0);
|
||||
Sleep(100);
|
||||
|
||||
len2 = sizeof buf2;
|
||||
r = uv_pipe_getsockname(&reader, buf2, &len2);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_stop((uv_stream_t*)&reader);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(len1 == len2);
|
||||
ASSERT(memcmp(buf1, buf2, len1) == 0);
|
||||
|
||||
close_cb_called = 0;
|
||||
uv_close((uv_handle_t*)&reader, close_cb);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
_close(readfd);
|
||||
CloseHandle(writeh);
|
||||
#endif
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
77
deps/uv/test/test-socket-buffer-size.c
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static uv_udp_t udp;
|
||||
static uv_tcp_t tcp;
|
||||
static int close_cb_called;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void check_buffer_size(uv_handle_t* handle) {
|
||||
int value;
|
||||
|
||||
value = 0;
|
||||
ASSERT(0 == uv_recv_buffer_size(handle, &value));
|
||||
ASSERT(value > 0);
|
||||
|
||||
value = 10000;
|
||||
ASSERT(0 == uv_recv_buffer_size(handle, &value));
|
||||
|
||||
value = 0;
|
||||
ASSERT(0 == uv_recv_buffer_size(handle, &value));
|
||||
/* linux sets double the value */
|
||||
ASSERT(value == 10000 || value == 20000);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(socket_buffer_size) {
|
||||
struct sockaddr_in addr;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
|
||||
ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp));
|
||||
ASSERT(0 == uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0));
|
||||
check_buffer_size((uv_handle_t*) &tcp);
|
||||
uv_close((uv_handle_t*) &tcp, close_cb);
|
||||
|
||||
ASSERT(0 == uv_udp_init(uv_default_loop(), &udp));
|
||||
ASSERT(0 == uv_udp_bind(&udp, (struct sockaddr*) &addr, 0));
|
||||
check_buffer_size((uv_handle_t*) &udp);
|
||||
uv_close((uv_handle_t*) &udp, close_cb);
|
||||
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||
|
||||
ASSERT(close_cb_called == 2);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|