libuv 1.42.0.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3650 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
5197eb91f7
commit
da51e87774
1
Makefile
1
Makefile
@ -58,6 +58,7 @@ UV_SOURCES = \
|
||||
deps/libuv/src/unix/async.c \
|
||||
deps/libuv/src/unix/core.c \
|
||||
deps/libuv/src/unix/dl.c \
|
||||
deps/libuv/src/unix/epoll.c \
|
||||
deps/libuv/src/unix/fs.c \
|
||||
deps/libuv/src/unix/getaddrinfo.c \
|
||||
deps/libuv/src/unix/getnameinfo.c \
|
||||
|
2
deps/libuv/.github/ISSUE_TEMPLATE.md
vendored
2
deps/libuv/.github/ISSUE_TEMPLATE.md
vendored
@ -2,7 +2,7 @@
|
||||
If you want to report a bug, you are in the right place!
|
||||
|
||||
If you need help or have a question, go here:
|
||||
https://github.com/libuv/help/issues/new
|
||||
https://github.com/libuv/libuv/discussions
|
||||
|
||||
If you are reporting a libuv test failure, please ensure that you are not
|
||||
running the test as root.
|
||||
|
17
deps/libuv/.github/workflows/sanitizer.yml
vendored
Normal file
17
deps/libuv/.github/workflows/sanitizer.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: Sanitizer checks
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
asan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Envinfo
|
||||
run: npx envinfo
|
||||
- name: ASAN
|
||||
run: |
|
||||
mkdir build
|
||||
cd build && cmake .. -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake --build . && ./uv_run_tests_a
|
||||
|
6
deps/libuv/.mailmap
vendored
6
deps/libuv/.mailmap
vendored
@ -2,6 +2,7 @@ A. Hauptmann <andreashauptmann@t-online.de>
|
||||
Aaron Bieber <qbit@deftly.net> <deftly@gmail.com>
|
||||
Alan Gutierrez <alan@prettyrobots.com> <alan@blogometer.com>
|
||||
Andrius Bentkus <andrius.bentkus@gmail.com> <toxedvirus@gmail.com>
|
||||
Andy Fiddaman <andy@omniosce.org> <omnios@citrus-it.co.uk>
|
||||
Bert Belder <bertbelder@gmail.com> <i@bertbelder.com>
|
||||
Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
|
||||
Bert Belder <bertbelder@gmail.com> <user@ChrUbuntu.(none)>
|
||||
@ -10,6 +11,8 @@ Brian White <mscdex@mscdex.net>
|
||||
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
|
||||
Caleb James DeLisle <cjd@hyperboria.ca> <cjd@cjdns.fr>
|
||||
Christoph Iserlohn <christoph.iserlohn@innoq.com>
|
||||
Darshan Sen <raisinten@gmail.com>
|
||||
David Carlier <devnexen@gmail.com>
|
||||
Devchandra Meetei Leishangthem <dlmeetei@gmail.com>
|
||||
Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
|
||||
Frank Denis <github@pureftpd.org>
|
||||
@ -32,6 +35,7 @@ Nicholas Vavilov <vvnicholas@gmail.com>
|
||||
Nick Logan <ugexe@cpan.org> <nlogan@gmail.com>
|
||||
Rasmus Christian Pedersen <zerhacken@yahoo.com>
|
||||
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
|
||||
Richard Lau <rlau@redhat.com> <riclau@uk.ibm.com>
|
||||
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
|
||||
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
|
||||
Ryan Emery <seebees@gmail.com>
|
||||
@ -47,8 +51,10 @@ Timothy J. Fontaine <tjfontaine@gmail.com>
|
||||
Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
||||
Yazhong Liu <yorkiefixer@gmail.com>
|
||||
Yuki Okumura <mjt@cltn.org>
|
||||
cjihrig <cjihrig@gmail.com>
|
||||
gengjiawen <technicalcute@gmail.com>
|
||||
jBarz <jBarz@users.noreply.github.com> <jbarboza@ca.ibm.com>
|
||||
jBarz <jBarz@users.noreply.github.com> <jbarz@users.noreply.github.com>
|
||||
ptlomholt <pt@lomholt.com>
|
||||
tjarlama <59913901+tjarlama@users.noreply.github.com> <tjarlama@gmail.com>
|
||||
zlargon <zlargon1988@gmail.com>
|
||||
|
11
deps/libuv/.readthedocs.yaml
vendored
Normal file
11
deps/libuv/.readthedocs.yaml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
builder: html
|
||||
configuration: null
|
||||
fail_on_warning: false
|
||||
|
||||
python:
|
||||
version: 3.8
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
37
deps/libuv/AUTHORS
vendored
37
deps/libuv/AUTHORS
vendored
@ -114,7 +114,6 @@ Dylan Cali <calid1984@gmail.com>
|
||||
Austin Foxley <austinf@cetoncorp.com>
|
||||
Benjamin Saunders <ben.e.saunders@gmail.com>
|
||||
Geoffry Song <goffrie@gmail.com>
|
||||
Rasmus Christian Pedersen <ruysch@outlook.com>
|
||||
William Light <wrl@illest.net>
|
||||
Oleg Efimov <o.efimov@corp.badoo.com>
|
||||
Lars Gierth <larsg@systemli.org>
|
||||
@ -123,7 +122,6 @@ Justin Venus <justin.venus@gmail.com>
|
||||
Kristian Evensen <kristian.evensen@gmail.com>
|
||||
Linus Mårtensson <linus.martensson@sonymobile.com>
|
||||
Navaneeth Kedaram Nambiathan <navaneethkn@gmail.com>
|
||||
Yorkie <yorkiefixer@gmail.com>
|
||||
StarWing <weasley.wx@gmail.com>
|
||||
thierry-FreeBSD <thierry@FreeBSD.org>
|
||||
Isaiah Norton <isaiah.norton@gmail.com>
|
||||
@ -212,7 +210,7 @@ guworks <ground.up.works@gmail.com>
|
||||
RossBencina <rossb@audiomulch.com>
|
||||
Roger A. Light <roger@atchoo.org>
|
||||
chenttuuvv <chenttuuvv@yahoo.com>
|
||||
Richard Lau <riclau@uk.ibm.com>
|
||||
Richard Lau <rlau@redhat.com>
|
||||
ronkorving <rkorving@wizcorp.jp>
|
||||
Corbin Simpson <MostAwesomeDude@gmail.com>
|
||||
Zachary Hamm <zsh@imipolexg.org>
|
||||
@ -448,3 +446,36 @@ Aleksej Lebedev <root@zta.lk>
|
||||
Nikolay Mitev <github@hmel.org>
|
||||
Ulrik Strid <ulrik.strid@outlook.com>
|
||||
Elad Lahav <elahav@qnx.com>
|
||||
Elad Nachmias <eladn@pazam.net>
|
||||
Darshan Sen <raisinten@gmail.com>
|
||||
Simon Kadisch <simon.kadisch@k13-engineering.at>
|
||||
Momtchil Momtchev <momtchil@momtchev.com>
|
||||
Ethel Weston <66453757+ethelweston@users.noreply.github.com>
|
||||
Drew DeVault <sir@cmpwn.com>
|
||||
Mark Klein <klein@cscs.ch>
|
||||
schamberg97 <50446906+schamberg97@users.noreply.github.com>
|
||||
Bob Weinand <bobwei9@hotmail.com>
|
||||
Issam E. Maghni <issam.e.maghni@mailbox.org>
|
||||
Juan Pablo Canepa <jpcanepa@gmail.com>
|
||||
Shuowang (Wayne) Zhang <shuowang.zhang@ibm.com>
|
||||
Ondřej Surý <ondrej@sury.org>
|
||||
Juan José Arboleda <soyjuanarbol@gmail.com>
|
||||
Zhao Zhili <zhilizhao@tencent.com>
|
||||
Brandon Cheng <brandon.cheng@protonmail.com>
|
||||
Matvii Hodovaniuk <matvii@hodovani.uk>
|
||||
Hayden <me@diatr.us>
|
||||
yiyuaner <yguoaz@gmail.com>
|
||||
bbara <bbara93@gmail.com>
|
||||
SeverinLeonhardt <Severin.Leonhardt@teamviewer.com>
|
||||
Andy Fiddaman <andy@omniosce.org>
|
||||
Romain Roffé <rofferom@gmail.com>
|
||||
Eagle Liang <eagleliang@gmail.com>
|
||||
Ricky Zhou <ives199511@gmail.com>
|
||||
Simon Kissane <skissane@gmail.com>
|
||||
James M Snell <jasnell@gmail.com>
|
||||
Ali Mohammad Pur <Ali.mpfard@gmail.com>
|
||||
Erkhes N <71805796+rexes-ND@users.noreply.github.com>
|
||||
Joshua M. Clulow <josh@sysmgr.org>
|
||||
Guilherme Íscaro <cabelitostos@gmail.com>
|
||||
Martin Storsjö <martin@martin.st>
|
||||
Claes Nästén <pekdon@gmail.com>
|
||||
|
75
deps/libuv/CMakeLists.txt
vendored
75
deps/libuv/CMakeLists.txt
vendored
@ -30,6 +30,14 @@ if(QEMU)
|
||||
add_definitions(-D__QEMU__=1)
|
||||
endif()
|
||||
|
||||
option(ASAN "Enable AddressSanitizer (ASan)" OFF)
|
||||
if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang")
|
||||
add_definitions(-D__ASAN__=1)
|
||||
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||
endif()
|
||||
|
||||
# Compiler check
|
||||
string(CONCAT is-msvc $<OR:
|
||||
$<C_COMPILER_ID:MSVC>,
|
||||
@ -95,6 +103,9 @@ list(APPEND uv_cflags ${lint-no-conditional-assignment-msvc})
|
||||
list(APPEND uv_cflags ${lint-no-unsafe-msvc})
|
||||
list(APPEND uv_cflags ${lint-utf8-msvc} )
|
||||
|
||||
check_c_compiler_flag(-fno-strict-aliasing UV_F_STRICT_ALIASING)
|
||||
list(APPEND uv_cflags $<$<BOOL:${UV_F_STRICT_ALIASING}>:-fno-strict-aliasing>)
|
||||
|
||||
set(uv_sources
|
||||
src/fs-poll.c
|
||||
src/idna.c
|
||||
@ -108,7 +119,7 @@ set(uv_sources
|
||||
src/version.c)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0600)
|
||||
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602)
|
||||
list(APPEND uv_libraries
|
||||
psapi
|
||||
user32
|
||||
@ -199,10 +210,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
src/unix/pthread-fixes.c
|
||||
src/unix/random-getentropy.c
|
||||
src/unix/random-getrandom.c
|
||||
src/unix/random-sysctl-linux.c)
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/epoll.c)
|
||||
endif()
|
||||
|
||||
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS390")
|
||||
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux")
|
||||
list(APPEND uv_sources src/unix/proctitle.c)
|
||||
endif()
|
||||
|
||||
@ -243,7 +255,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
src/unix/linux-syscalls.c
|
||||
src/unix/procfs-exepath.c
|
||||
src/unix/random-getrandom.c
|
||||
src/unix/random-sysctl-linux.c)
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/epoll.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
||||
@ -256,9 +269,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
list(APPEND uv_defines PATH_MAX=255)
|
||||
enable_language(CXX)
|
||||
list(APPEND uv_defines PATH_MAX=1024)
|
||||
list(APPEND uv_defines _AE_BIMODAL)
|
||||
list(APPEND uv_defines _ALL_SOURCE)
|
||||
list(APPEND uv_defines _ENHANCED_ASCII_EXT=0xFFFFFFFF)
|
||||
list(APPEND uv_defines _ISOC99_SOURCE)
|
||||
list(APPEND uv_defines _LARGE_TIME_API)
|
||||
list(APPEND uv_defines _OPEN_MSGQ_EXT)
|
||||
@ -269,14 +284,31 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
list(APPEND uv_defines _UNIX03_SOURCE)
|
||||
list(APPEND uv_defines _UNIX03_THREADS)
|
||||
list(APPEND uv_defines _UNIX03_WITHDRAWN)
|
||||
list(APPEND uv_defines _XOPEN_SOURCE=600)
|
||||
list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED)
|
||||
list(APPEND uv_sources
|
||||
src/unix/pthread-fixes.c
|
||||
src/unix/os390.c
|
||||
src/unix/os390-syscalls.c)
|
||||
list(APPEND uv_cflags -Wc,DLL -Wc,exportall -Wc,xplink)
|
||||
list(APPEND uv_libraries -Wl,xplink)
|
||||
list(APPEND uv_test_libraries -Wl,xplink)
|
||||
src/unix/os390-syscalls.c
|
||||
src/unix/os390-proctitle.c)
|
||||
list(APPEND uv_cflags
|
||||
-q64
|
||||
-qascii
|
||||
-qexportall
|
||||
-qgonumber
|
||||
-qlongname
|
||||
-qlibansi
|
||||
-qfloat=IEEE
|
||||
-qtune=10
|
||||
-qarch=10
|
||||
-qasm
|
||||
-qasmlib=sys1.maclib:sys1.modgen)
|
||||
find_library(ZOSLIB
|
||||
NAMES zoslib
|
||||
PATHS ${ZOSLIB_DIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
list(APPEND uv_libraries ${ZOSLIB})
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS400")
|
||||
@ -293,9 +325,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS400")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500)
|
||||
list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500 _REENTRANT)
|
||||
list(APPEND uv_libraries kstat nsl sendfile socket)
|
||||
list(APPEND uv_sources src/unix/no-proctitle.c src/unix/sunos.c)
|
||||
list(APPEND uv_sources
|
||||
src/unix/no-proctitle.c
|
||||
src/unix/sunos.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
|
||||
@ -318,7 +352,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
||||
src/unix/bsd-ifaddrs.c
|
||||
src/unix/no-proctitle.c
|
||||
src/unix/no-fsevents.c)
|
||||
list(APPEND uv_cflags -fno-strict-aliasing)
|
||||
list(APPEND uv_libraries socket)
|
||||
endif()
|
||||
|
||||
@ -340,6 +373,10 @@ target_include_directories(uv
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
target_include_directories(uv PUBLIC $<BUILD_INTERFACE:${ZOSLIB_DIR}/include>)
|
||||
set_target_properties(uv PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif()
|
||||
target_link_libraries(uv ${uv_libraries})
|
||||
|
||||
add_library(uv_a STATIC ${uv_sources})
|
||||
@ -351,6 +388,10 @@ target_include_directories(uv_a
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
target_include_directories(uv_a PUBLIC $<BUILD_INTERFACE:${ZOSLIB_DIR}/include>)
|
||||
set_target_properties(uv_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif()
|
||||
target_link_libraries(uv_a ${uv_libraries})
|
||||
|
||||
if(LIBUV_BUILD_TESTS)
|
||||
@ -448,6 +489,9 @@ if(LIBUV_BUILD_TESTS)
|
||||
test/test-metrics.c
|
||||
test/test-multiple-listen.c
|
||||
test/test-mutexes.c
|
||||
test/test-not-readable-nor-writable-on-read-error.c
|
||||
test/test-not-readable-on-eof.c
|
||||
test/test-not-writable-after-shutdown.c
|
||||
test/test-osx-select.c
|
||||
test/test-pass-always.c
|
||||
test/test-ping-pong.c
|
||||
@ -466,6 +510,7 @@ if(LIBUV_BUILD_TESTS)
|
||||
test/test-poll-close-doesnt-corrupt-stack.c
|
||||
test/test-poll-close.c
|
||||
test/test-poll-closesocket.c
|
||||
test/test-poll-multiple-handles.c
|
||||
test/test-poll-oob.c
|
||||
test/test-poll.c
|
||||
test/test-process-priority.c
|
||||
@ -479,6 +524,7 @@ if(LIBUV_BUILD_TESTS)
|
||||
test/test-semaphore.c
|
||||
test/test-shutdown-close.c
|
||||
test/test-shutdown-eof.c
|
||||
test/test-shutdown-simultaneous.c
|
||||
test/test-shutdown-twice.c
|
||||
test/test-signal-multiple-loops.c
|
||||
test/test-signal-pending-on-close.c
|
||||
@ -572,6 +618,11 @@ if(LIBUV_BUILD_TESTS)
|
||||
add_test(NAME uv_test_a
|
||||
COMMAND uv_run_tests_a
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
set_target_properties(uv_run_benchmarks_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||
set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX)
|
||||
set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
|
8
deps/libuv/CONTRIBUTING.md
vendored
8
deps/libuv/CONTRIBUTING.md
vendored
@ -23,11 +23,11 @@ The stable branch is effectively frozen; patches that change the libuv
|
||||
API/ABI or affect the run-time behavior of applications get rejected.
|
||||
|
||||
In case of doubt, open an issue in the [issue tracker][], post your question
|
||||
to the [libuv mailing list], or contact one of [project maintainers][] on [IRC][].
|
||||
to the [libuv discussions forum], or message the [libuv mailing list].
|
||||
|
||||
Especially do so if you plan to work on something big. Nothing is more
|
||||
frustrating than seeing your hard work go to waste because your vision
|
||||
does not align with that of a project maintainers.
|
||||
frustrating than seeing your hard work go to waste because your vision does not
|
||||
align with that of the [project maintainers].
|
||||
|
||||
|
||||
### BRANCH
|
||||
@ -166,6 +166,6 @@ not send out notifications when you add commits.
|
||||
|
||||
[issue tracker]: https://github.com/libuv/libuv/issues
|
||||
[libuv mailing list]: http://groups.google.com/group/libuv
|
||||
[IRC]: http://webchat.freenode.net/?channels=libuv
|
||||
[libuv discussions forum]: https://github.com/libuv/libuv/discussions
|
||||
[Google C/C++ style guide]: https://google.github.io/styleguide/cppguide.html
|
||||
[project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md
|
||||
|
236
deps/libuv/ChangeLog
vendored
236
deps/libuv/ChangeLog
vendored
@ -1,4 +1,238 @@
|
||||
2020.09.26, Version 1.40.0 (Stable)
|
||||
2021.07.21, Version 1.42.0 (Stable)
|
||||
|
||||
Changes since version 1.41.0:
|
||||
|
||||
* doc: fix code highlighting (Darshan Sen)
|
||||
|
||||
* test: move to ASSERT_NULL and ASSERT_NOT_NULL test macros (tjarlama)
|
||||
|
||||
* zos: build in ascii code page (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: don't use nanosecond timestamp fields (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: introduce zoslib (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use strnlen() from zoslib (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use nanosleep() from zoslib (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use __getargv() from zoslib to get exe path (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: treat __rfim_utok as binary (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use execvpe() to set environ explictly (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use custom proctitle implementation (Shuowang (Wayne) Zhang)
|
||||
|
||||
* doc: add instructions for building on z/OS (Shuowang (Wayne) Zhang)
|
||||
|
||||
* linux,udp: enable full ICMP error reporting (Ondřej Surý)
|
||||
|
||||
* test: fix test-udp-send-unreachable (Ondřej Surý)
|
||||
|
||||
* include: fix typo in documentation (Tobias Nießen)
|
||||
|
||||
* chore: use for(;;) instead of while (Yash Ladha)
|
||||
|
||||
* test: remove string + int warning on udp-pummel (Juan José Arboleda)
|
||||
|
||||
* cmake: fix linker flags (Zhao Zhili)
|
||||
|
||||
* test: fix stack-use-after-scope (Zhao Zhili)
|
||||
|
||||
* unix: expose thread_stack_size() internally (Brandon Cheng)
|
||||
|
||||
* darwin: use RLIMIT_STACK for fsevents pthread (Brandon Cheng)
|
||||
|
||||
* darwin: abort on pthread_attr_init fail (Brandon Cheng)
|
||||
|
||||
* benchmark: remove unreachable code (Matvii Hodovaniuk)
|
||||
|
||||
* macos: fix memleaks in uv__get_cpu_speed (George Zhao)
|
||||
|
||||
* Make Thread Sanitizer aware of file descriptor close in uv__close() (Ondřej
|
||||
Surý)
|
||||
|
||||
* darwin: fix iOS compilation and functionality (Hayden)
|
||||
|
||||
* linux: work around copy_file_range() cephfs bug (Ben Noordhuis)
|
||||
|
||||
* zos: implement uv_get_constrained_memory() (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: fix uv_get_free_memory() (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use CVTRLSTG to get total memory accurately (Shuowang (Wayne) Zhang)
|
||||
|
||||
* ibmi: Handle interface names longer than 10 chars (Kevin Adler)
|
||||
|
||||
* docs: update read-the-docs version of sphinx (Jameson Nash)
|
||||
|
||||
* unix: refactor uv_try_write (twosee)
|
||||
|
||||
* linux-core: add proper divide by zero assert (yiyuaner)
|
||||
|
||||
* misc: remove unnecessary _GNU_SOURCE macros (Darshan Sen)
|
||||
|
||||
* test: log to stdout to conform TAP spec (bbara)
|
||||
|
||||
* win,fs: fix C4090 warning with MSVC (SeverinLeonhardt)
|
||||
|
||||
* build: some systems provide dlopen() in libc (Andy Fiddaman)
|
||||
|
||||
* include: add EOVERFLOW status code mapping (Darshan Sen)
|
||||
|
||||
* unix,fs: use uv__load_relaxed and uv__store_relaxed (Darshan Sen)
|
||||
|
||||
* win: fix string encoding issue of uv_os_gethostname (Eagle Liang)
|
||||
|
||||
* unix,process: add uv__write_errno helper function (Ricky Zhou)
|
||||
|
||||
* Re-merge "unix,stream: clear read/write states on close/eof" (Jameson Nash)
|
||||
|
||||
* unix,core: fix errno handling in uv__getpwuid_r (Darshan Sen)
|
||||
|
||||
* errors: map ESOCKTNOSUPPORT errno (Ryan Liptak)
|
||||
|
||||
* doc: uv_read_stop always succeeds (Simon Kissane)
|
||||
|
||||
* inet: fix inconsistent return value of inet_ntop6 (twosee)
|
||||
|
||||
* darwin: fix -Wsometimes-uninitialized warning (twosee)
|
||||
|
||||
* stream: introduce uv_try_write2 function (twosee)
|
||||
|
||||
* poll,win: UV_PRIORITIZED option should not assert (twosee)
|
||||
|
||||
* src: DragonFlyBSD has mmsghdr struct too (David Carlier)
|
||||
|
||||
* cleanup,win: Remove _WIN32 guards on threadpool (James M Snell)
|
||||
|
||||
* freebsd: fix an incompatible pointer type warning (Darshan Sen)
|
||||
|
||||
* core: Correct the conditionals for {cloexec,nonblock}_ioctl (Ali Mohammad
|
||||
Pur)
|
||||
|
||||
* win,tcp: make uv_close work more like unix (Jameson Nash)
|
||||
|
||||
* doc: more accurate list of valid send_handle's (twosee)
|
||||
|
||||
* win,tcp: translate system errors correctly (twosee)
|
||||
|
||||
* unix: implement cpu_relax() on ppc64 (Ben Noordhuis)
|
||||
|
||||
* docs: move list of project links under PR control (Jameson Nash)
|
||||
|
||||
* test: wrong pointer arithmetic multiplier (Erkhes N)
|
||||
|
||||
* doc: switch discussion forum to github (Jameson Nash)
|
||||
|
||||
* idna: fix OOB read in punycode decoder (Ben Noordhuis)
|
||||
|
||||
* build: make sure -fvisibility=hidden is set (Santiago Gimeno)
|
||||
|
||||
* illumos: event ports to epoll (tjarlama)
|
||||
|
||||
* illumos,tty: UV_TTY_MODE_IO waits for 4 bytes (Joshua M. Clulow)
|
||||
|
||||
* doc: add vtjnash GPG ID (Jameson Nash)
|
||||
|
||||
* linux: read CPU model information on ppc (Richard Lau)
|
||||
|
||||
* darwin: fix uv_barrier race condition (Guilherme Íscaro)
|
||||
|
||||
* unix,stream: fix loop hang after uv_shutdown (Jameson Nash)
|
||||
|
||||
* doc,udp: note that suggested_size is 1 max-sized dgram (Ryan Liptak)
|
||||
|
||||
* mingw: fix building for ARM/AArch64 (Martin Storsjö)
|
||||
|
||||
* unix: strnlen is not available on Solaris 10 (Claes Nästén)
|
||||
|
||||
* sunos: restore use of event ports (Andy Fiddaman)
|
||||
|
||||
* sunos,cmake: use thread-safe errno (Andy Fiddaman)
|
||||
|
||||
|
||||
2021.02.14, Version 1.41.0 (Stable), 1dff88e5161cba5c59276d2070d2e304e4dcb242
|
||||
|
||||
Changes since version 1.40.0:
|
||||
|
||||
* mailmap: update contact information for richardlau (Richard Lau)
|
||||
|
||||
* build: add asan checks (gengjiawen)
|
||||
|
||||
* unix: report bind error in uv_tcp_connect() (Ben Noordhuis)
|
||||
|
||||
* doc: uv_tcp_bind() never returns UV_EADDRINUSE (Ben Noordhuis)
|
||||
|
||||
* test: fix pump and tcp_write_batch benchmarks (Santiago Gimeno)
|
||||
|
||||
* doc: mark IBM i as Tier 2 support (Jesse Gorzinski)
|
||||
|
||||
* doc,poll: add notes (repeated cb & cancel pending cb) (Elad Nachmias)
|
||||
|
||||
* linux: fix -Wincompatible-pointer-types warning (Ben Noordhuis)
|
||||
|
||||
* linux: fix -Wsign-compare warning (Ben Noordhuis)
|
||||
|
||||
* android: add system call api guards (Ben Noordhuis)
|
||||
|
||||
* unix,win: harmonize uv_read_start() error handling (Ben Noordhuis)
|
||||
|
||||
* unix,win: more uv_read_start() argument validation (Ben Noordhuis)
|
||||
|
||||
* build: turn on -fno-strict-aliasing (Ben Noordhuis)
|
||||
|
||||
* stream: add uv_pipe and uv_socketpair to the API (Jameson Nash)
|
||||
|
||||
* unix,win: initialize timer `timeout` field (Ben Noordhuis)
|
||||
|
||||
* bsd-ifaddrs: improve comments (Darshan Sen)
|
||||
|
||||
* test: remove unnecessary uv_fs_stat() calls (Ben Noordhuis)
|
||||
|
||||
* fs: fix utime/futime timestamp rounding errors (Ben Noordhuis)
|
||||
|
||||
* test: ensure reliable floating point comparison (Jameson Nash)
|
||||
|
||||
* unix,fs: fix uv_fs_sendfile() (Santiago Gimeno)
|
||||
|
||||
* unix: fix uv_fs_stat when using statx (Simon Kadisch)
|
||||
|
||||
* linux,macos: fix uv_set_process_title regression (Momtchil Momtchev)
|
||||
|
||||
* doc: clarify UDP errors and recvmmsg (Ethel Weston)
|
||||
|
||||
* test-getaddrinfo: use example.invalid (Drew DeVault)
|
||||
|
||||
* Revert "build: fix android autotools build" (Bernardo Ramos)
|
||||
|
||||
* unix,fs: on DVS fs, statx returns EOPNOTSUPP (Mark Klein)
|
||||
|
||||
* win, fs: mkdir really return UV_EINVAL for invalid names (Nicholas Vavilov)
|
||||
|
||||
* tools: migrate tools/make_dist_html.py to python3 (Dominique Dumont)
|
||||
|
||||
* unix: fix uv_uptime() on linux (schamberg97)
|
||||
|
||||
* unix: check for partial copy_file_range support (Momtchil Momtchev)
|
||||
|
||||
* win: bump minimum supported version to windows 8 (Ben Noordhuis)
|
||||
|
||||
* poll,unix: ensure safety of rapid fd reuse (Bob Weinand)
|
||||
|
||||
* test: fix some warnings (Issam E. Maghni)
|
||||
|
||||
* unix: fix uv_uptime() regression (Santiago Gimeno)
|
||||
|
||||
* doc: fix versionadded metadata (cjihrig)
|
||||
|
||||
* test: fix 'incompatible pointer types' warnings (cjihrig)
|
||||
|
||||
* unix: check for EXDEV in uv__fs_sendfile() (Darshan Sen)
|
||||
|
||||
|
||||
2020.09.26, Version 1.40.0 (Stable), 4e69e333252693bd82d6338d6124f0416538dbfc
|
||||
|
||||
Changes since version 1.39.0:
|
||||
|
||||
|
101
deps/libuv/LINKS.md
vendored
Normal file
101
deps/libuv/LINKS.md
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
### Apps / VM
|
||||
* [BIND 9](https://bind.isc.org/): DNS software system including an authoritative server, a recursive resolver and related utilities.
|
||||
* [cjdns](https://github.com/cjdelisle/cjdns): Encrypted self-configuring network/VPN routing engine
|
||||
* [clearskies_core](https://github.com/larroy/clearskies_core): Clearskies file synchronization program. (C++11)
|
||||
* [CMake](https://cmake.org) open-source, cross-platform family of tools designed to build, test and package software
|
||||
* [Coherence](https://github.com/liesware/coherence/): Cryptographic server for modern web apps.
|
||||
* [DPS-For-IoT](https://github.com/intel/dps-for-iot/wiki): Fully distributed publish/subscribe protocol.
|
||||
* [HashLink](https://github.com/HaxeFoundation/hashlink): Haxe run-time with libuv support included.
|
||||
* [Haywire](https://github.com/kellabyte/Haywire): Asynchronous HTTP server.
|
||||
* [H2O](https://github.com/h2o/h2o): An optimized HTTP server with support for HTTP/1.x and HTTP/2.
|
||||
* [Igropyr](https://github.com/guenchi/Igropyr): a async Scheme http server base on libuv.
|
||||
* [Julia](http://julialang.org/): Scientific computing programming language
|
||||
* [Kestrel](https://github.com/aspnet/AspNetCore/tree/master/src/Servers/Kestrel): web server (C# + libuv + [ASP.NET Core](http://github.com/aspnet))
|
||||
* [Knot DNS Resolver](https://www.knot-resolver.cz/): A minimalistic DNS caching resolver
|
||||
* [Lever](http://leverlanguage.com): runtime, libuv at the 0.9.0 release
|
||||
* [libnode](https://github.com/plenluno/libnode): C++ implementation of Node.js
|
||||
* [libstorj](https://github.com/Storj/libstorj): Library for interacting with Storj network
|
||||
* [libuv_message_framing](https://github.com/litesync/libuv_message_framing) Message-based communication for libuv
|
||||
* [luaw](https://github.com/raksoras/luaw): Lua web server backed by libuv
|
||||
* [Luvit](http://luvit.io): Node.JS for the Lua Inventor
|
||||
* [mo](https://github.com/wehu/mo): Scheme (guile) + libuv runtime
|
||||
* [MoarVM](https://github.com/MoarVM/MoarVM): a VM for [Rakudo](http://rakudo.org/) [Raku](http://raku.org)
|
||||
* [Mysocks](https://github.com/zhou0/mysocks): a cross-platform [Shadowsocks](https://shadowsocks.org) client
|
||||
* [mediasoup](http://mediasoup.org): Powerful WebRTC SFU for Node.js
|
||||
* [Neovim](https://neovim.io/): A major refactor of Vim.
|
||||
* [node9](https://github.com/jvburnes/node9): A portable, hybrid, distributed OS based on Inferno, LuaJIT and Libuv
|
||||
* [node.js](http://www.nodejs.org/): Javascript (using Google's V8) + libuv
|
||||
* [node.native](https://github.com/d5/node.native): node.js-like API for C++11
|
||||
* [nodeuv](https://github.com/nodeuv): An organization with several c++ wrappers for libs which are used in node.js.
|
||||
* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js
|
||||
* [pilight](https://www.pilight.org/): home automation ("domotica")
|
||||
* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT
|
||||
* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime
|
||||
* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension
|
||||
* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings
|
||||
* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition
|
||||
* [Swish](https://github.com/becls/swish/): Concurrency engine with Erlang-like concepts. Includes a web server.
|
||||
* [Trevi](https://github.com/Yoseob/Trevi): A powerful Swift Web Application Server Framework Project
|
||||
* [Urbit](http://urbit.org): runtime
|
||||
* [uv_callback](https://github.com/litesync/uv_callback) libuv thread communication
|
||||
* [uvloop](https://github.com/MagicStack/uvloop): Ultra fast implementation of python's asyncio event loop on top of libuv
|
||||
* [Wren CLI](https://github.com/wren-lang/wren-cli): For io, process, scheduler and timer modules
|
||||
|
||||
### Other
|
||||
* [libtuv](https://github.com/Samsung/libtuv): libuv fork for IoT and embedded systems
|
||||
|
||||
### Bindings
|
||||
* [Ring](http://ring-lang.net)
|
||||
* [RingLibuv](http://ring-lang.sourceforge.net/doc1.7/libuv.html)
|
||||
* Ruby
|
||||
* [libuv](https://github.com/cotag/libuv)
|
||||
* [uvrb](https://github.com/avalanche123/uvrb)
|
||||
* [ruv](https://github.com/aq1018/ruv)
|
||||
* [rbuv](https://github.com/rbuv/rbuv)
|
||||
* [mruby-uv](https://github.com/mattn/mruby-uv): mruby binding
|
||||
* Lua
|
||||
* [luv](https://github.com/creationix/luv)
|
||||
* [lev](https://github.com/connectFree/lev)
|
||||
* [lluv](https://github.com/moteus/lua-lluv)
|
||||
* C++11
|
||||
* [uvpp](https://github.com/larroy/uvpp) - Not complete, exposes very few aspects of `libuv`
|
||||
* C++17
|
||||
* [uvw](https://github.com/skypjack/uvw) - Header-only, event based, tiny and easy to use *libuv* wrapper in modern C++.
|
||||
* Python
|
||||
* [Pyuv](https://github.com/saghul/pyuv)
|
||||
* [uvloop](https://github.com/MagicStack/uvloop) - Ultra fast asyncio event loop.
|
||||
* [gevent](http://www.gevent.org) - Coroutine-based concurrency library for Python
|
||||
* C#
|
||||
* [NetUV](http://github.com/StormHub/NetUV)
|
||||
* [LibuvSharp](http://github.com/txdv/LibuvSharp)
|
||||
* Perl 5
|
||||
* [UV](https://metacpan.org/pod/UV)
|
||||
* [Raku](https://raku.org/)
|
||||
* [MoarVM](https://github.com/MoarVM/MoarVM) [uses](http://6guts.wordpress.com/2013/05/31/moarvm-a-virtual-machine-for-nqp-and-rakudo/) libuv
|
||||
* PHP
|
||||
* [php-uv](https://github.com/bwoebi/php-uv)
|
||||
* Go
|
||||
* [go-uv](https://github.com/mattn/go-uv)
|
||||
* OCaml
|
||||
* [luv](https://github.com/aantron/luv)
|
||||
* [uwt](https://github.com/fdopen/uwt)
|
||||
* ooc
|
||||
* [ooc-uv](https://github.com/nddrylliog/ooc-uv)
|
||||
* dylan
|
||||
* [uv-dylan](https://github.com/waywardmonkeys/uv-dylan)
|
||||
* R
|
||||
* [httpuv](https://github.com/rstudio/httpuv): HTTP and WebSocket server library for R
|
||||
* [fs](https://fs.r-lib.org/): Cross-platform file system operations
|
||||
* Java
|
||||
* [libuv-java](https://java.net/projects/avatar-js/sources/libuv-java/show): Java bindings
|
||||
* Nim
|
||||
* [nimuv](https://github.com/2vg/nimuv): Nim bindings
|
||||
* Lisp
|
||||
* [cl-libuv](https://github.com/orthecreedence/cl-libuv) Common Lisp bindings
|
||||
* [cl-async](https://github.com/orthecreedence/cl-async) Common Lisp async abstraction on top of cl-libuv
|
||||
* [Céu](http://www.ceu-lang.org)
|
||||
* [Céu-libuv](https://github.com/fsantanna/ceu-libuv)
|
||||
* Delphi
|
||||
* [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem
|
||||
* Haskell
|
||||
* [Z.Haskell](https://z.haskell.world)
|
1
deps/libuv/MAINTAINERS.md
vendored
1
deps/libuv/MAINTAINERS.md
vendored
@ -16,6 +16,7 @@ libuv is currently managed by the following individuals:
|
||||
* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq))
|
||||
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
|
||||
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
|
||||
- GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash)
|
||||
* **John Barboza** ([@jbarz](https://github.com/jbarz))
|
||||
* **Kaoru Takanashi** ([@erw7](https://github.com/erw7))
|
||||
- GPG Key: 5804 F999 8A92 2AFB A398 47A0 7183 5090 6134 887F (pubkey-erw7)
|
||||
|
17
deps/libuv/Makefile.am
vendored
17
deps/libuv/Makefile.am
vendored
@ -56,7 +56,7 @@ if WINNT
|
||||
uvinclude_HEADERS += include/uv/win.h include/uv/tree.h
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/src/win \
|
||||
-DWIN32_LEAN_AND_MEAN \
|
||||
-D_WIN32_WINNT=0x0600
|
||||
-D_WIN32_WINNT=0x0602
|
||||
libuv_la_SOURCES += src/win/async.c \
|
||||
src/win/atomicops-inl.h \
|
||||
src/win/core.c \
|
||||
@ -206,6 +206,9 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-metrics.c \
|
||||
test/test-multiple-listen.c \
|
||||
test/test-mutexes.c \
|
||||
test/test-not-readable-nor-writable-on-read-error.c \
|
||||
test/test-not-readable-on-eof.c \
|
||||
test/test-not-writable-after-shutdown.c \
|
||||
test/test-osx-select.c \
|
||||
test/test-pass-always.c \
|
||||
test/test-ping-pong.c \
|
||||
@ -225,6 +228,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-poll-close.c \
|
||||
test/test-poll-close-doesnt-corrupt-stack.c \
|
||||
test/test-poll-closesocket.c \
|
||||
test/test-poll-multiple-handles.c \
|
||||
test/test-poll-oob.c \
|
||||
test/test-process-priority.c \
|
||||
test/test-process-title.c \
|
||||
@ -237,6 +241,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-semaphore.c \
|
||||
test/test-shutdown-close.c \
|
||||
test/test-shutdown-eof.c \
|
||||
test/test-shutdown-simultaneous.c \
|
||||
test/test-shutdown-twice.c \
|
||||
test/test-signal-multiple-loops.c \
|
||||
test/test-signal-pending-on-close.c \
|
||||
@ -385,13 +390,10 @@ if ANDROID
|
||||
uvinclude_HEADERS += include/uv/android-ifaddrs.h
|
||||
libuv_la_CFLAGS += -D_GNU_SOURCE
|
||||
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
|
||||
src/unix/linux-core.c \
|
||||
src/unix/linux-inotify.c \
|
||||
src/unix/linux-syscalls.c \
|
||||
src/unix/procfs-exepath.c \
|
||||
src/unix/pthread-fixes.c \
|
||||
src/unix/random-getrandom.c \
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/random-sysctl-linux.c \
|
||||
src/unix/epoll.c
|
||||
endif
|
||||
|
||||
if CYGWIN
|
||||
@ -472,7 +474,8 @@ libuv_la_SOURCES += src/unix/linux-core.c \
|
||||
src/unix/procfs-exepath.c \
|
||||
src/unix/proctitle.c \
|
||||
src/unix/random-getrandom.c \
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/random-sysctl-linux.c \
|
||||
src/unix/epoll.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
endif
|
||||
|
||||
|
22
deps/libuv/README.md
vendored
22
deps/libuv/README.md
vendored
@ -5,7 +5,7 @@
|
||||
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 [Luvit](http://luvit.io/), [Julia](http://julialang.org/),
|
||||
[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/wiki/Projects-that-use-libuv).
|
||||
[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/blob/v1.x/LINKS.md).
|
||||
|
||||
## Feature highlights
|
||||
|
||||
@ -48,9 +48,8 @@ The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-do
|
||||
|
||||
## Community
|
||||
|
||||
* [Support](https://github.com/libuv/help)
|
||||
* [Support](https://github.com/libuv/libuv/discussions)
|
||||
* [Mailing list](http://groups.google.com/group/libuv)
|
||||
* [IRC chatroom (#libuv@irc.freenode.org)](http://webchat.freenode.net?channels=libuv&uio=d4)
|
||||
|
||||
## Documentation
|
||||
|
||||
@ -286,6 +285,16 @@ listed in `test/benchmark-list.h`.
|
||||
|
||||
Check the [SUPPORTED_PLATFORMS file](SUPPORTED_PLATFORMS.md).
|
||||
|
||||
### `-fno-strict-aliasing`
|
||||
|
||||
It is recommended to turn on the `-fno-strict-aliasing` compiler flag in
|
||||
projects that use libuv. The use of ad hoc "inheritance" in the libuv API
|
||||
may not be safe in the presence of compiler optimizations that depend on
|
||||
strict aliasing.
|
||||
|
||||
MSVC does not have an equivalent flag but it also does not appear to need it
|
||||
at the time of writing (December 2019.)
|
||||
|
||||
### AIX Notes
|
||||
|
||||
AIX compilation using IBM XL C/C++ requires version 12.1 or greater.
|
||||
@ -298,6 +307,13 @@ describes the package in more detail.
|
||||
|
||||
### z/OS Notes
|
||||
|
||||
z/OS compilation requires [ZOSLIB](https://github.com/ibmruntimes/zoslib) to be installed. When building with [CMake][], use the flag `-DZOSLIB_DIR` to specify the path to [ZOSLIB](https://github.com/ibmruntimes/zoslib):
|
||||
|
||||
```bash
|
||||
$ (cd build && cmake .. -DBUILD_TESTING=ON -DZOSLIB_DIR=/path/to/zoslib)
|
||||
$ cmake --build build
|
||||
```
|
||||
|
||||
z/OS creates System V semaphores and message queues. These persist on the system
|
||||
after the process terminates unless the event loop is closed.
|
||||
|
||||
|
4
deps/libuv/SUPPORTED_PLATFORMS.md
vendored
4
deps/libuv/SUPPORTED_PLATFORMS.md
vendored
@ -4,14 +4,14 @@
|
||||
|---|---|---|---|
|
||||
| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | |
|
||||
| macOS | Tier 1 | macOS >= 10.7 | |
|
||||
| Windows | Tier 1 | >= Windows 7 | MSVC 2008 and later are supported |
|
||||
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
||||
| FreeBSD | Tier 1 | >= 10 | |
|
||||
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
||||
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
||||
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
|
||||
| Linux with musl | Tier 2 | musl >= 1.0 | |
|
||||
| SmartOS | Tier 2 | >= 14.4 | Maintainers: @libuv/smartos |
|
||||
| Android | Tier 3 | NDK >= r15b | |
|
||||
| IBM i | Tier 3 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
||||
| MinGW | Tier 3 | MinGW32 and MinGW-w64 | |
|
||||
| SunOS | Tier 3 | Solaris 121 and later | |
|
||||
| Other | Tier 3 | N/A | |
|
||||
|
10
deps/libuv/configure.ac
vendored
10
deps/libuv/configure.ac
vendored
@ -13,7 +13,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [1.40.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_INIT([libuv], [1.42.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
m4_include([m4/as_case.m4])
|
||||
@ -24,7 +24,11 @@ AC_ENABLE_SHARED
|
||||
AC_ENABLE_STATIC
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
CC_FLAG_VISIBILITY #[-fvisibility=hidden]
|
||||
|
||||
CC_ATTRIBUTE_VISIBILITY([default], [
|
||||
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"])
|
||||
])
|
||||
CC_CHECK_CFLAGS_APPEND([-fno-strict-aliasing])
|
||||
CC_CHECK_CFLAGS_APPEND([-g])
|
||||
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wall])
|
||||
@ -42,7 +46,7 @@ AX_PTHREAD([
|
||||
LIBS="$LIBS $PTHREAD_LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
])
|
||||
AC_CHECK_LIB([dl], [dlopen])
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
AC_SEARCH_LIBS([kstat_lookup], [kstat])
|
||||
AC_SEARCH_LIBS([gethostbyname], [nsl])
|
||||
AC_SEARCH_LIBS([perfstat_cpu], [perfstat])
|
||||
|
4
deps/libuv/docs/code/dns/main.c
vendored
4
deps/libuv/docs/code/dns/main.c
vendored
@ -69,8 +69,8 @@ int main() {
|
||||
hints.ai_flags = 0;
|
||||
|
||||
uv_getaddrinfo_t resolver;
|
||||
fprintf(stderr, "irc.freenode.net is... ");
|
||||
int r = uv_getaddrinfo(loop, &resolver, on_resolved, "irc.freenode.net", "6667", &hints);
|
||||
fprintf(stderr, "irc.libera.chat is... ");
|
||||
int r = uv_getaddrinfo(loop, &resolver, on_resolved, "irc.libera.chat", "6667", &hints);
|
||||
|
||||
if (r) {
|
||||
fprintf(stderr, "getaddrinfo call error %s\n", uv_err_name(r));
|
||||
|
42
deps/libuv/docs/requirements.txt
vendored
Normal file
42
deps/libuv/docs/requirements.txt
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
# primary
|
||||
Sphinx==3.5.4
|
||||
|
||||
# dependencies
|
||||
alabaster==0.7.12
|
||||
appdirs==1.4.3
|
||||
Babel==2.9.0
|
||||
CacheControl==0.12.6
|
||||
certifi==2019.11.28
|
||||
chardet==3.0.4
|
||||
colorama==0.4.3
|
||||
contextlib2==0.6.0
|
||||
distlib==0.3.0
|
||||
distro==1.4.0
|
||||
docutils==0.16
|
||||
html5lib==1.0.1
|
||||
idna==2.8
|
||||
imagesize==1.2.0
|
||||
ipaddr==2.2.0
|
||||
Jinja2==2.11.3
|
||||
lockfile==0.12.2
|
||||
MarkupSafe==1.1.1
|
||||
msgpack==0.6.2
|
||||
packaging==20.3
|
||||
pep517==0.8.2
|
||||
progress==1.5
|
||||
Pygments==2.8.1
|
||||
pyparsing==2.4.6
|
||||
pytoml==0.1.21
|
||||
pytz==2021.1
|
||||
requests==2.22.0
|
||||
retrying==1.3.3
|
||||
six==1.14.0
|
||||
snowballstemmer==2.1.0
|
||||
sphinxcontrib-applehelp==1.0.2
|
||||
sphinxcontrib-devhelp==1.0.2
|
||||
sphinxcontrib-htmlhelp==1.0.3
|
||||
sphinxcontrib-jsmath==1.0.1
|
||||
sphinxcontrib-qthelp==1.0.3
|
||||
sphinxcontrib-serializinghtml==1.1.4
|
||||
urllib3==1.25.8
|
||||
webencodings==0.5.1
|
8
deps/libuv/docs/src/errors.rst
vendored
8
deps/libuv/docs/src/errors.rst
vendored
@ -251,6 +251,10 @@ Error constants
|
||||
|
||||
operation not supported on socket
|
||||
|
||||
.. c:macro:: UV_EOVERFLOW
|
||||
|
||||
value too large for defined data type
|
||||
|
||||
.. c:macro:: UV_EPERM
|
||||
|
||||
operation not permitted
|
||||
@ -331,6 +335,10 @@ Error constants
|
||||
|
||||
illegal byte sequence
|
||||
|
||||
.. c:macro:: UV_ESOCKTNOSUPPORT
|
||||
|
||||
socket type not supported
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
2
deps/libuv/docs/src/guide/basics.rst
vendored
2
deps/libuv/docs/src/guide/basics.rst
vendored
@ -87,6 +87,7 @@ nothing, except start a loop which will exit immediately.
|
||||
|
||||
.. rubric:: helloworld/main.c
|
||||
.. literalinclude:: ../../code/helloworld/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
|
||||
This program quits immediately because it has no events to process. A libuv
|
||||
@ -202,6 +203,7 @@ event watchers are active.
|
||||
|
||||
.. rubric:: idle-basic/main.c
|
||||
.. literalinclude:: ../../code/idle-basic/main.c
|
||||
:language: c
|
||||
:emphasize-lines: 6,10,14-17
|
||||
|
||||
Storing context
|
||||
|
2
deps/libuv/docs/src/guide/eventloops.rst
vendored
2
deps/libuv/docs/src/guide/eventloops.rst
vendored
@ -20,6 +20,7 @@ these things can be a bit difficult to understand, so let's look at
|
||||
|
||||
.. rubric:: src/unix/core.c - uv_run
|
||||
.. literalinclude:: ../../../src/unix/core.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 304-324
|
||||
:emphasize-lines: 10,19,21
|
||||
@ -43,6 +44,7 @@ iteration of the loop still takes places.
|
||||
|
||||
.. rubric:: uvstop/main.c
|
||||
.. literalinclude:: ../../code/uvstop/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:emphasize-lines: 11
|
||||
|
||||
|
9
deps/libuv/docs/src/guide/filesystem.rst
vendored
9
deps/libuv/docs/src/guide/filesystem.rst
vendored
@ -54,6 +54,7 @@ a callback for when the file is opened:
|
||||
|
||||
.. rubric:: uvcat/main.c - opening a file
|
||||
.. literalinclude:: ../../code/uvcat/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 41-53
|
||||
:emphasize-lines: 4, 6-7
|
||||
@ -63,6 +64,7 @@ The ``result`` field of a ``uv_fs_t`` is the file descriptor in case of the
|
||||
|
||||
.. rubric:: uvcat/main.c - read callback
|
||||
.. literalinclude:: ../../code/uvcat/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 26-40
|
||||
:emphasize-lines: 2,8,12
|
||||
@ -87,6 +89,7 @@ callbacks.
|
||||
|
||||
.. rubric:: uvcat/main.c - write callback
|
||||
.. literalinclude:: ../../code/uvcat/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 16-24
|
||||
:emphasize-lines: 6
|
||||
@ -100,6 +103,7 @@ We set the dominos rolling in ``main()``:
|
||||
|
||||
.. rubric:: uvcat/main.c
|
||||
.. literalinclude:: ../../code/uvcat/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 55-
|
||||
:emphasize-lines: 2
|
||||
@ -203,6 +207,7 @@ opened as bidirectional by default.
|
||||
|
||||
.. rubric:: uvtee/main.c - read on pipes
|
||||
.. literalinclude:: ../../code/uvtee/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 61-80
|
||||
:emphasize-lines: 4,5,15
|
||||
@ -218,6 +223,7 @@ these buffers.
|
||||
|
||||
.. rubric:: uvtee/main.c - reading buffers
|
||||
.. literalinclude:: ../../code/uvtee/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 19-22,44-60
|
||||
|
||||
@ -242,6 +248,7 @@ point there is nothing to be read. Most applications will just ignore this.
|
||||
|
||||
.. rubric:: uvtee/main.c - Write to pipe
|
||||
.. literalinclude:: ../../code/uvtee/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 9-13,23-42
|
||||
|
||||
@ -282,6 +289,7 @@ The file change notification is started using ``uv_fs_event_init()``:
|
||||
|
||||
.. rubric:: onchange/main.c - The setup
|
||||
.. literalinclude:: ../../code/onchange/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 26-
|
||||
:emphasize-lines: 15
|
||||
@ -320,6 +328,7 @@ In our example we simply print the arguments and run the command using
|
||||
|
||||
.. rubric:: onchange/main.c - file change notification callback
|
||||
.. literalinclude:: ../../code/onchange/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 9-24
|
||||
|
||||
|
2
deps/libuv/docs/src/guide/introduction.rst
vendored
2
deps/libuv/docs/src/guide/introduction.rst
vendored
@ -72,4 +72,4 @@ There is no need to ``make install``. To build the examples run ``make`` in the
|
||||
.. _node.js: https://www.nodejs.org
|
||||
.. _libev was removed: https://github.com/joyent/libuv/issues/485
|
||||
.. _Rust: https://www.rust-lang.org
|
||||
.. _variety: https://github.com/libuv/libuv/wiki/Projects-that-use-libuv
|
||||
.. _variety: https://github.com/libuv/libuv/blob/v1.x/LINKS.md
|
||||
|
9
deps/libuv/docs/src/guide/networking.rst
vendored
9
deps/libuv/docs/src/guide/networking.rst
vendored
@ -38,6 +38,7 @@ Here is a simple echo server
|
||||
|
||||
.. rubric:: tcp-echo-server/main.c - The listen socket
|
||||
.. literalinclude:: ../../code/tcp-echo-server/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 68-
|
||||
:emphasize-lines: 4-5,7-10
|
||||
@ -60,6 +61,7 @@ In this case we also establish interest in reading from this stream.
|
||||
|
||||
.. rubric:: tcp-echo-server/main.c - Accepting the client
|
||||
.. literalinclude:: ../../code/tcp-echo-server/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 51-66
|
||||
:emphasize-lines: 9-10
|
||||
@ -108,6 +110,7 @@ address from a `DHCP`_ server -- DHCP Discover.
|
||||
|
||||
.. rubric:: udp-dhcp/main.c - Setup and send UDP packets
|
||||
.. literalinclude:: ../../code/udp-dhcp/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 7-11,104-
|
||||
:emphasize-lines: 8,10-11,17-18,21
|
||||
@ -143,6 +146,7 @@ the OS will discard the data that could not fit* (That's UDP for you!).
|
||||
|
||||
.. rubric:: udp-dhcp/main.c - Reading packets
|
||||
.. literalinclude:: ../../code/udp-dhcp/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 17-40
|
||||
:emphasize-lines: 1,23
|
||||
@ -189,10 +193,11 @@ Querying DNS
|
||||
libuv provides asynchronous DNS resolution. For this it provides its own
|
||||
``getaddrinfo`` replacement [#]_. In the callback you can
|
||||
perform normal socket operations on the retrieved addresses. Let's connect to
|
||||
Freenode to see an example of DNS resolution.
|
||||
Libera.chat to see an example of DNS resolution.
|
||||
|
||||
.. rubric:: dns/main.c
|
||||
.. literalinclude:: ../../code/dns/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 61-
|
||||
:emphasize-lines: 12
|
||||
@ -209,6 +214,7 @@ call ``uv_freeaddrinfo`` in the callback.
|
||||
|
||||
.. rubric:: dns/main.c
|
||||
.. literalinclude:: ../../code/dns/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 42-60
|
||||
:emphasize-lines: 8,16
|
||||
@ -227,6 +233,7 @@ useful to allow your service to bind to IP addresses when it starts.
|
||||
|
||||
.. rubric:: interfaces/main.c
|
||||
.. literalinclude:: ../../code/interfaces/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:emphasize-lines: 9,17
|
||||
|
||||
|
15
deps/libuv/docs/src/guide/processes.rst
vendored
15
deps/libuv/docs/src/guide/processes.rst
vendored
@ -27,6 +27,7 @@ exits. This is achieved using ``uv_spawn``.
|
||||
|
||||
.. rubric:: spawn/main.c
|
||||
.. literalinclude:: ../../code/spawn/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 6-8,15-
|
||||
:emphasize-lines: 11,13-17
|
||||
@ -54,6 +55,7 @@ which caused the exit.
|
||||
|
||||
.. rubric:: spawn/main.c
|
||||
.. literalinclude:: ../../code/spawn/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 9-12
|
||||
:emphasize-lines: 3
|
||||
@ -104,6 +106,7 @@ does not affect it.
|
||||
|
||||
.. rubric:: detach/main.c
|
||||
.. literalinclude:: ../../code/detach/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 9-30
|
||||
:emphasize-lines: 12,19
|
||||
@ -140,6 +143,7 @@ stop watching. Here is a small example demonstrating the various possibilities:
|
||||
|
||||
.. rubric:: signal/main.c
|
||||
.. literalinclude:: ../../code/signal/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:emphasize-lines: 17-18,27-28
|
||||
|
||||
@ -172,6 +176,7 @@ which is:
|
||||
|
||||
.. rubric:: proc-streams/test.c
|
||||
.. literalinclude:: ../../code/proc-streams/test.c
|
||||
:language: c
|
||||
|
||||
The actual program ``proc-streams`` runs this while sharing only ``stderr``.
|
||||
The file descriptors of the child process are set using the ``stdio`` field in
|
||||
@ -199,6 +204,7 @@ Then we set the ``fd`` to ``stderr``.
|
||||
|
||||
.. rubric:: proc-streams/main.c
|
||||
.. literalinclude:: ../../code/proc-streams/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 15-17,27-
|
||||
:emphasize-lines: 6,10,11,12
|
||||
@ -217,12 +223,14 @@ A sample CGI script/executable is:
|
||||
|
||||
.. rubric:: cgi/tick.c
|
||||
.. literalinclude:: ../../code/cgi/tick.c
|
||||
:language: c
|
||||
|
||||
The CGI server combines the concepts from this chapter and :doc:`networking` so
|
||||
that every client is sent ten ticks after which that connection is closed.
|
||||
|
||||
.. rubric:: cgi/main.c
|
||||
.. literalinclude:: ../../code/cgi/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 49-63
|
||||
:emphasize-lines: 10
|
||||
@ -232,6 +240,7 @@ Here we simply accept the TCP connection and pass on the socket (*stream*) to
|
||||
|
||||
.. rubric:: cgi/main.c
|
||||
.. literalinclude:: ../../code/cgi/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 16, 25-45
|
||||
:emphasize-lines: 8-9,18,20
|
||||
@ -291,6 +300,7 @@ messaging is no different from TCP, so we'll re-use the echo server example.
|
||||
|
||||
.. rubric:: pipe-echo-server/main.c
|
||||
.. literalinclude:: ../../code/pipe-echo-server/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 70-
|
||||
:emphasize-lines: 5,10,14
|
||||
@ -330,6 +340,7 @@ it by the master.
|
||||
|
||||
.. rubric:: multi-echo-server/worker.c
|
||||
.. literalinclude:: ../../code/multi-echo-server/worker.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 7-9,81-
|
||||
:emphasize-lines: 6-8
|
||||
@ -343,6 +354,7 @@ standard input of the worker, we connect the pipe to ``stdin`` using
|
||||
|
||||
.. rubric:: multi-echo-server/worker.c
|
||||
.. literalinclude:: ../../code/multi-echo-server/worker.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 51-79
|
||||
:emphasize-lines: 10,15,20
|
||||
@ -361,6 +373,7 @@ allow load balancing.
|
||||
|
||||
.. rubric:: multi-echo-server/main.c
|
||||
.. literalinclude:: ../../code/multi-echo-server/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 9-13
|
||||
|
||||
@ -369,6 +382,7 @@ master and the individual process.
|
||||
|
||||
.. rubric:: multi-echo-server/main.c
|
||||
.. literalinclude:: ../../code/multi-echo-server/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 51,61-95
|
||||
:emphasize-lines: 17,20-21
|
||||
@ -387,6 +401,7 @@ worker in the round-robin.
|
||||
|
||||
.. rubric:: multi-echo-server/main.c
|
||||
.. literalinclude:: ../../code/multi-echo-server/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 31-49
|
||||
:emphasize-lines: 9,12-13
|
||||
|
12
deps/libuv/docs/src/guide/threads.rst
vendored
12
deps/libuv/docs/src/guide/threads.rst
vendored
@ -39,6 +39,7 @@ wait for it to close using ``uv_thread_join()``.
|
||||
|
||||
.. rubric:: thread-create/main.c
|
||||
.. literalinclude:: ../../code/thread-create/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 26-36
|
||||
:emphasize-lines: 3-7
|
||||
@ -55,6 +56,7 @@ thread, scheduled pre-emptively by the operating system:
|
||||
|
||||
.. rubric:: thread-create/main.c
|
||||
.. literalinclude:: ../../code/thread-create/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 6-14
|
||||
:emphasize-lines: 2
|
||||
@ -124,6 +126,7 @@ example.
|
||||
|
||||
.. rubric:: locks/main.c - simple rwlocks
|
||||
.. literalinclude:: ../../code/locks/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:emphasize-lines: 13,16,27,31,42,55
|
||||
|
||||
@ -208,6 +211,7 @@ event loop from performing other activities.
|
||||
|
||||
.. rubric:: queue-work/main.c - lazy fibonacci
|
||||
.. literalinclude:: ../../code/queue-work/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 17-29
|
||||
|
||||
@ -221,6 +225,7 @@ The trigger is ``uv_queue_work``:
|
||||
|
||||
.. rubric:: queue-work/main.c
|
||||
.. literalinclude:: ../../code/queue-work/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 31-44
|
||||
:emphasize-lines: 10
|
||||
@ -248,6 +253,7 @@ up a signal handler for termination.
|
||||
|
||||
.. rubric:: queue-cancel/main.c
|
||||
.. literalinclude:: ../../code/queue-cancel/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 43-
|
||||
|
||||
@ -256,6 +262,7 @@ When the user triggers the signal by pressing ``Ctrl+C`` we send
|
||||
|
||||
.. rubric:: queue-cancel/main.c
|
||||
.. literalinclude:: ../../code/queue-cancel/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 33-41
|
||||
:emphasize-lines: 6
|
||||
@ -265,6 +272,7 @@ with ``status`` set to ``UV_ECANCELED``.
|
||||
|
||||
.. rubric:: queue-cancel/main.c
|
||||
.. literalinclude:: ../../code/queue-cancel/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 28-31
|
||||
:emphasize-lines: 2
|
||||
@ -292,6 +300,7 @@ informing the user of the status of running downloads.
|
||||
|
||||
.. rubric:: progress/main.c
|
||||
.. literalinclude:: ../../code/progress/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 7-8,35-
|
||||
:emphasize-lines: 2,11
|
||||
@ -317,6 +326,7 @@ with the async watcher whenever it receives a message.
|
||||
|
||||
.. rubric:: progress/main.c
|
||||
.. literalinclude:: ../../code/progress/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 10-24
|
||||
:emphasize-lines: 7-8
|
||||
@ -327,6 +337,7 @@ non-blocking and will return immediately.
|
||||
|
||||
.. rubric:: progress/main.c
|
||||
.. literalinclude:: ../../code/progress/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 31-34
|
||||
|
||||
@ -336,6 +347,7 @@ Finally it is important to remember to clean up the watcher.
|
||||
|
||||
.. rubric:: progress/main.c
|
||||
.. literalinclude:: ../../code/progress/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 26-29
|
||||
:emphasize-lines: 3
|
||||
|
13
deps/libuv/docs/src/guide/utilities.rst
vendored
13
deps/libuv/docs/src/guide/utilities.rst
vendored
@ -87,6 +87,7 @@ JS object and can be ref/unrefed.
|
||||
|
||||
.. rubric:: ref-timer/main.c
|
||||
.. literalinclude:: ../../code/ref-timer/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 5-8, 17-
|
||||
:emphasize-lines: 9
|
||||
@ -111,6 +112,7 @@ idle watcher to keep the UI operational.
|
||||
|
||||
.. rubric:: idle-compute/main.c
|
||||
.. literalinclude:: ../../code/idle-compute/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 5-9, 34-
|
||||
:emphasize-lines: 13
|
||||
@ -123,6 +125,7 @@ keep calling the idle callback again.
|
||||
|
||||
.. rubric:: idle-compute/main.c
|
||||
.. literalinclude:: ../../code/idle-compute/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 10-19
|
||||
|
||||
@ -215,6 +218,7 @@ progress with the download whenever libuv notifies of I/O readiness.
|
||||
|
||||
.. rubric:: uvwget/main.c - The setup
|
||||
.. literalinclude:: ../../code/uvwget/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 1-9,140-
|
||||
:emphasize-lines: 7,21,24-25
|
||||
@ -235,6 +239,7 @@ So we add each argument as an URL
|
||||
|
||||
.. rubric:: uvwget/main.c - Adding urls
|
||||
.. literalinclude:: ../../code/uvwget/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 39-56
|
||||
:emphasize-lines: 13-14
|
||||
@ -251,6 +256,7 @@ on sockets whenever ``handle_socket`` is called.
|
||||
|
||||
.. rubric:: uvwget/main.c - Setting up polling
|
||||
.. literalinclude:: ../../code/uvwget/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 102-140
|
||||
:emphasize-lines: 9,11,15,21,24
|
||||
@ -271,6 +277,7 @@ mask with the new value. ``curl_perform`` is the crux of this program.
|
||||
|
||||
.. rubric:: uvwget/main.c - Driving libcurl.
|
||||
.. literalinclude:: ../../code/uvwget/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 81-95
|
||||
:emphasize-lines: 2,6-7,12
|
||||
@ -288,6 +295,7 @@ transfers are done.
|
||||
|
||||
.. rubric:: uvwget/main.c - Reading transfer status.
|
||||
.. literalinclude:: ../../code/uvwget/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 58-79
|
||||
:emphasize-lines: 6,9-10,13-14
|
||||
@ -312,6 +320,7 @@ Let us first look at the interface provided to plugin authors.
|
||||
|
||||
.. rubric:: plugin/plugin.h
|
||||
.. literalinclude:: ../../code/plugin/plugin.h
|
||||
:language: c
|
||||
:linenos:
|
||||
|
||||
You can similarly add more functions that plugin authors can use to do useful
|
||||
@ -319,6 +328,7 @@ things in your application [#]_. A sample plugin using this API is:
|
||||
|
||||
.. rubric:: plugin/hello.c
|
||||
.. literalinclude:: ../../code/plugin/hello.c
|
||||
:language: c
|
||||
:linenos:
|
||||
|
||||
Our interface defines that all plugins should have an ``initialize`` function
|
||||
@ -340,6 +350,7 @@ This is done by using ``uv_dlopen`` to first load the shared library
|
||||
|
||||
.. rubric:: plugin/main.c
|
||||
.. literalinclude:: ../../code/plugin/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:lines: 7-
|
||||
:emphasize-lines: 15, 18, 24
|
||||
@ -393,6 +404,7 @@ Here is a simple example which prints white text on a red background:
|
||||
|
||||
.. rubric:: tty/main.c
|
||||
.. literalinclude:: ../../code/tty/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:emphasize-lines: 11-12,14,17,27
|
||||
|
||||
@ -403,6 +415,7 @@ escape codes.
|
||||
|
||||
.. rubric:: tty-gravity/main.c
|
||||
.. literalinclude:: ../../code/tty-gravity/main.c
|
||||
:language: c
|
||||
:linenos:
|
||||
:emphasize-lines: 19,25,38
|
||||
|
||||
|
2
deps/libuv/docs/src/index.rst
vendored
2
deps/libuv/docs/src/index.rst
vendored
@ -17,7 +17,7 @@ was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_,
|
||||
.. _Luvit: https://luvit.io
|
||||
.. _Julia: https://julialang.org
|
||||
.. _pyuv: https://github.com/saghul/pyuv
|
||||
.. _others: https://github.com/libuv/libuv/wiki/Projects-that-use-libuv
|
||||
.. _others: https://github.com/libuv/libuv/blob/v1.x/LINKS.md
|
||||
|
||||
|
||||
Features
|
||||
|
2
deps/libuv/docs/src/misc.rst
vendored
2
deps/libuv/docs/src/misc.rst
vendored
@ -533,7 +533,7 @@ API
|
||||
|
||||
.. note::
|
||||
This function currently only returns a non-zero value on Linux, based
|
||||
on cgroups if it is present.
|
||||
on cgroups if it is present, and on z/OS based on RLIMIT_MEMLIMIT.
|
||||
|
||||
.. versionadded:: 1.29.0
|
||||
|
||||
|
18
deps/libuv/docs/src/pipe.rst
vendored
18
deps/libuv/docs/src/pipe.rst
vendored
@ -118,3 +118,21 @@ API
|
||||
function is blocking.
|
||||
|
||||
.. versionadded:: 1.16.0
|
||||
|
||||
.. c:function:: int uv_pipe(uv_file fds[2], int read_flags, int write_flags)
|
||||
|
||||
Create a pair of connected pipe handles.
|
||||
Data may be written to `fds[1]` and read from `fds[0]`.
|
||||
The resulting handles can be passed to `uv_pipe_open`, used with `uv_spawn`,
|
||||
or for any other purpose.
|
||||
|
||||
Valid values for `flags` are:
|
||||
|
||||
- UV_NONBLOCK_PIPE: Opens the specified socket handle for `OVERLAPPED`
|
||||
or `FIONBIO`/`O_NONBLOCK` I/O usage.
|
||||
This is recommended for handles that will be used by libuv,
|
||||
and not usually recommended otherwise.
|
||||
|
||||
Equivalent to :man:`pipe(2)` with the `O_CLOEXEC` flag set.
|
||||
|
||||
.. versionadded:: 1.41.0
|
||||
|
61
deps/libuv/docs/src/poll.rst
vendored
61
deps/libuv/docs/src/poll.rst
vendored
@ -86,36 +86,63 @@ API
|
||||
.. 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 made up of
|
||||
UV_READABLE, UV_WRITABLE, UV_PRIORITIZED and UV_DISCONNECT. 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.
|
||||
`UV_READABLE`, `UV_WRITABLE`, `UV_PRIORITIZED` and `UV_DISCONNECT`. 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.
|
||||
|
||||
The UV_PRIORITIZED event is used to watch for sysfs interrupts or TCP out-of-band
|
||||
messages.
|
||||
The `UV_PRIORITIZED` event is used to watch for sysfs interrupts or TCP
|
||||
out-of-band messages.
|
||||
|
||||
The UV_DISCONNECT event is optional in the sense that it may not be
|
||||
reported and the user is free to ignore it, but it can help optimize the shutdown
|
||||
path because an extra read or write call might be avoided.
|
||||
The `UV_DISCONNECT` event is optional in the sense that it may not be
|
||||
reported and the user is free to ignore it, but it can help optimize the
|
||||
shutdown path because an extra read or write call might be avoided.
|
||||
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
.. note::
|
||||
Though UV_DISCONNECT can be set, it is unsupported on AIX and as such will not be set
|
||||
on the `events` field in the callback.
|
||||
Though `UV_DISCONNECT` can be set, it is unsupported on AIX and as such
|
||||
will not be set on the `events` field in the callback.
|
||||
|
||||
.. versionchanged:: 1.9.0 Added the UV_DISCONNECT event.
|
||||
.. versionchanged:: 1.14.0 Added the UV_PRIORITIZED event.
|
||||
.. note::
|
||||
If one of the events `UV_READABLE` or `UV_WRITABLE` are set, the
|
||||
callback will be called again, as long as the given fd/socket remains
|
||||
readable or writable accordingly. Particularly in each of the following
|
||||
scenarios:
|
||||
|
||||
* The callback has been called because the socket became
|
||||
readable/writable and the callback did not conduct a read/write on
|
||||
this socket at all.
|
||||
* The callback committed a read on the socket, and has not read all the
|
||||
available data (when `UV_READABLE` is set).
|
||||
* The callback committed a write on the socket, but it remained
|
||||
writable afterwards (when `UV_WRITABLE` is set).
|
||||
* The socket has already became readable/writable before calling
|
||||
:c:func:`uv_poll_start` on a poll handle associated with this socket,
|
||||
and since then the state of the socket did not changed.
|
||||
|
||||
In all of the above listed scenarios, the socket remains readable or
|
||||
writable and hence the callback will be called again (depending on the
|
||||
events set in the bitmask). This behaviour is known as level
|
||||
triggering.
|
||||
|
||||
.. versionchanged:: 1.9.0 Added the `UV_DISCONNECT` event.
|
||||
.. versionchanged:: 1.14.0 Added the `UV_PRIORITIZED` event.
|
||||
|
||||
.. c:function:: int uv_poll_stop(uv_poll_t* poll)
|
||||
|
||||
Stop polling the file descriptor, the callback will no longer be called.
|
||||
|
||||
.. note::
|
||||
Calling :c:func:`uv_poll_stop` is effective immediately: any pending
|
||||
callback is also canceled, even if the socket state change notification
|
||||
was already pending.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
||||
|
10
deps/libuv/docs/src/process.rst
vendored
10
deps/libuv/docs/src/process.rst
vendored
@ -119,12 +119,14 @@ Data types
|
||||
* flags may be specified to create a duplex data stream.
|
||||
*/
|
||||
UV_READABLE_PIPE = 0x10,
|
||||
UV_WRITABLE_PIPE = 0x20
|
||||
UV_WRITABLE_PIPE = 0x20,
|
||||
/*
|
||||
* Open the child pipe handle in overlapped mode on Windows.
|
||||
* On Unix it is silently ignored.
|
||||
* When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the
|
||||
* handle in non-blocking mode in the child. This may cause loss of data,
|
||||
* if the child is not designed to handle to encounter this mode,
|
||||
* but can also be significantly more efficient.
|
||||
*/
|
||||
UV_OVERLAPPED_PIPE = 0x40
|
||||
UV_NONBLOCK_PIPE = 0x40
|
||||
} uv_stdio_flags;
|
||||
|
||||
|
||||
|
25
deps/libuv/docs/src/stream.rst
vendored
25
deps/libuv/docs/src/stream.rst
vendored
@ -139,6 +139,11 @@ API
|
||||
be made several times until there is no more data to read or
|
||||
:c:func:`uv_read_stop` is called.
|
||||
|
||||
.. versionchanged:: 1.38.0 :c:func:`uv_read_start()` now consistently
|
||||
returns `UV_EALREADY` when called twice, and `UV_EINVAL` when the
|
||||
stream is closing. With older libuv versions, it returns `UV_EALREADY`
|
||||
on Windows but not UNIX, and `UV_EINVAL` on UNIX but not Windows.
|
||||
|
||||
.. c:function:: int uv_read_stop(uv_stream_t*)
|
||||
|
||||
Stop reading data from the stream. The :c:type:`uv_read_cb` callback will
|
||||
@ -146,6 +151,11 @@ API
|
||||
|
||||
This function is idempotent and may be safely called on a stopped stream.
|
||||
|
||||
This function will always succeed; hence, checking its return value is
|
||||
unnecessary. A non-zero return indicates that finishing releasing resources
|
||||
may be pending on the next input event on that TTY on Windows, and does not
|
||||
indicate failure.
|
||||
|
||||
.. 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:
|
||||
@ -183,8 +193,9 @@ API
|
||||
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.
|
||||
`send_handle` must be a TCP, pipe and UDP handle on Unix, or a TCP
|
||||
handle on Windows, 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)
|
||||
|
||||
@ -197,6 +208,16 @@ API
|
||||
* < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent
|
||||
immediately).
|
||||
|
||||
.. c:function:: int uv_try_write2(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle)
|
||||
|
||||
Same as :c:func:`uv_try_write` and extended write function for sending
|
||||
handles over a pipe like c:func:`uv_write2`.
|
||||
|
||||
Try to send a handle is not supported on Windows,
|
||||
where it returns ``UV_EAGAIN``.
|
||||
|
||||
.. versionadded:: 1.42.0
|
||||
|
||||
.. c:function:: int uv_is_readable(const uv_stream_t* handle)
|
||||
|
||||
Returns 1 if the stream is readable, 0 otherwise.
|
||||
|
24
deps/libuv/docs/src/tcp.rst
vendored
24
deps/libuv/docs/src/tcp.rst
vendored
@ -81,10 +81,9 @@ API
|
||||
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.
|
||||
error from :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` can contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
|
||||
is disabled and only IPv6 is used.
|
||||
@ -128,3 +127,20 @@ API
|
||||
:c:func:`uv_tcp_close_reset` calls is not allowed.
|
||||
|
||||
.. versionadded:: 1.32.0
|
||||
|
||||
.. c:function:: int uv_socketpair(int type, int protocol, uv_os_sock_t socket_vector[2], int flags0, int flags1)
|
||||
|
||||
Create a pair of connected sockets with the specified properties.
|
||||
The resulting handles can be passed to `uv_tcp_open`, used with `uv_spawn`,
|
||||
or for any other purpose.
|
||||
|
||||
Valid values for `flags0` and `flags1` are:
|
||||
|
||||
- UV_NONBLOCK_PIPE: Opens the specified socket handle for `OVERLAPPED`
|
||||
or `FIONBIO`/`O_NONBLOCK` I/O usage.
|
||||
This is recommended for handles that will be used by libuv,
|
||||
and not usually recommended otherwise.
|
||||
|
||||
Equivalent to :man:`socketpair(2)` with a domain of AF_UNIX.
|
||||
|
||||
.. versionadded:: 1.41.0
|
||||
|
28
deps/libuv/docs/src/udp.rst
vendored
28
deps/libuv/docs/src/udp.rst
vendored
@ -53,6 +53,14 @@ Data types
|
||||
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
|
||||
*/
|
||||
UV_UDP_MMSG_FREE = 16,
|
||||
/*
|
||||
* Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
|
||||
* This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
|
||||
* Linux. This stops the Linux kernel from supressing some ICMP error messages
|
||||
* and enables full ICMP error reporting for faster failover.
|
||||
* This flag is no-op on platforms other than Linux.
|
||||
*/
|
||||
UV_UDP_LINUX_RECVERR = 32,
|
||||
/*
|
||||
* Indicates that recvmmsg should be used, if available.
|
||||
*/
|
||||
@ -73,7 +81,8 @@ Data types
|
||||
* `nread`: Number of bytes that have been received.
|
||||
0 if there is no more data to read. 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.
|
||||
a transmission error was detected; if using :man:`recvmmsg(2)` no more
|
||||
chunks will be received and the buffer can be freed safely.
|
||||
* `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.
|
||||
@ -84,10 +93,11 @@ Data types
|
||||
on error.
|
||||
|
||||
When using :man:`recvmmsg(2)`, chunks will have the `UV_UDP_MMSG_CHUNK` flag set,
|
||||
those must not be freed. There will be a final callback with `nread` set to 0,
|
||||
`addr` set to NULL and the buffer pointing at the initially allocated data with
|
||||
the `UV_UDP_MMSG_CHUNK` flag cleared and the `UV_UDP_MMSG_FREE` flag set.
|
||||
The callee can now safely free the provided buffer.
|
||||
those must not be freed. If no errors occur, there will be a final callback with
|
||||
`nread` set to 0, `addr` set to NULL and the buffer pointing at the initially
|
||||
allocated data with the `UV_UDP_MMSG_CHUNK` flag cleared and the `UV_UDP_MMSG_FREE`
|
||||
flag set. If a UDP socket error occurs, `nread` will be < 0. In either scenario,
|
||||
the callee can now safely free the provided buffer.
|
||||
|
||||
.. versionchanged:: 1.40.0 added the `UV_UDP_MMSG_FREE` flag.
|
||||
|
||||
@ -176,7 +186,8 @@ API
|
||||
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.
|
||||
``UV_UDP_IPV6ONLY``, ``UV_UDP_REUSEADDR``, and ``UV_UDP_RECVERR``
|
||||
are supported.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
@ -393,6 +404,11 @@ API
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. note::
|
||||
When using :man:`recvmmsg(2)`, the number of messages received at a time is limited
|
||||
by the number of max size dgrams that will fit into the buffer allocated in `alloc_cb`, and
|
||||
`suggested_size` in `alloc_cb` for udp_recv is always set to the size of 1 max size dgram.
|
||||
|
||||
.. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms).
|
||||
The use of this feature requires a buffer larger than
|
||||
2 * 64KB to be passed to `alloc_cb`.
|
||||
|
30
deps/libuv/include/uv.h
vendored
30
deps/libuv/include/uv.h
vendored
@ -126,6 +126,7 @@ extern "C" {
|
||||
XX(ENOTEMPTY, "directory not empty") \
|
||||
XX(ENOTSOCK, "socket operation on non-socket") \
|
||||
XX(ENOTSUP, "operation not supported on socket") \
|
||||
XX(EOVERFLOW, "value too large for defined data type") \
|
||||
XX(EPERM, "operation not permitted") \
|
||||
XX(EPIPE, "broken pipe") \
|
||||
XX(EPROTO, "protocol error") \
|
||||
@ -148,6 +149,7 @@ extern "C" {
|
||||
XX(ENOTTY, "inappropriate ioctl for device") \
|
||||
XX(EFTYPE, "inappropriate file type or format") \
|
||||
XX(EILSEQ, "illegal byte sequence") \
|
||||
XX(ESOCKTNOSUPPORT, "socket type not supported") \
|
||||
|
||||
#define UV_HANDLE_TYPE_MAP(XX) \
|
||||
XX(ASYNC, async) \
|
||||
@ -475,6 +477,12 @@ UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd);
|
||||
|
||||
UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
|
||||
|
||||
UV_EXTERN int uv_pipe(uv_file fds[2], int read_flags, int write_flags);
|
||||
UV_EXTERN int uv_socketpair(int type,
|
||||
int protocol,
|
||||
uv_os_sock_t socket_vector[2],
|
||||
int flags0,
|
||||
int flags1);
|
||||
|
||||
#define UV_STREAM_FIELDS \
|
||||
/* number of bytes queued for writing */ \
|
||||
@ -520,6 +528,10 @@ UV_EXTERN int uv_write2(uv_write_t* req,
|
||||
UV_EXTERN int uv_try_write(uv_stream_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs);
|
||||
UV_EXTERN int uv_try_write2(uv_stream_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle);
|
||||
|
||||
/* uv_write_t is a subclass of uv_req_t. */
|
||||
struct uv_write_s {
|
||||
@ -620,7 +632,14 @@ enum uv_udp_flags {
|
||||
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
|
||||
*/
|
||||
UV_UDP_MMSG_FREE = 16,
|
||||
|
||||
/*
|
||||
* Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
|
||||
* This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
|
||||
* Linux. This stops the Linux kernel from suppressing some ICMP error
|
||||
* messages and enables full ICMP error reporting for faster failover.
|
||||
* This flag is no-op on platforms other than Linux.
|
||||
*/
|
||||
UV_UDP_LINUX_RECVERR = 32,
|
||||
/*
|
||||
* Indicates that recvmmsg should be used, if available.
|
||||
*/
|
||||
@ -933,10 +952,13 @@ typedef enum {
|
||||
UV_WRITABLE_PIPE = 0x20,
|
||||
|
||||
/*
|
||||
* Open the child pipe handle in overlapped mode on Windows.
|
||||
* On Unix it is silently ignored.
|
||||
* When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the
|
||||
* handle in non-blocking mode in the child. This may cause loss of data,
|
||||
* if the child is not designed to handle to encounter this mode,
|
||||
* but can also be significantly more efficient.
|
||||
*/
|
||||
UV_OVERLAPPED_PIPE = 0x40
|
||||
UV_NONBLOCK_PIPE = 0x40,
|
||||
UV_OVERLAPPED_PIPE = 0x40 /* old name, for compatibility */
|
||||
} uv_stdio_flags;
|
||||
|
||||
typedef struct uv_stdio_container_s {
|
||||
|
12
deps/libuv/include/uv/errno.h
vendored
12
deps/libuv/include/uv/errno.h
vendored
@ -445,4 +445,16 @@
|
||||
# define UV__EILSEQ (-4027)
|
||||
#endif
|
||||
|
||||
#if defined(EOVERFLOW) && !defined(_WIN32)
|
||||
# define UV__EOVERFLOW UV__ERR(EOVERFLOW)
|
||||
#else
|
||||
# define UV__EOVERFLOW (-4026)
|
||||
#endif
|
||||
|
||||
#if defined(ESOCKTNOSUPPORT) && !defined(_WIN32)
|
||||
# define UV__ESOCKTNOSUPPORT UV__ERR(ESOCKTNOSUPPORT)
|
||||
#else
|
||||
# define UV__ESOCKTNOSUPPORT (-4025)
|
||||
#endif
|
||||
|
||||
#endif /* UV_ERRNO_H_ */
|
||||
|
2
deps/libuv/include/uv/tree.h
vendored
2
deps/libuv/include/uv/tree.h
vendored
@ -251,7 +251,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while (1) { \
|
||||
for (;;) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
|
2
deps/libuv/include/uv/version.h
vendored
2
deps/libuv/include/uv/version.h
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 40
|
||||
#define UV_VERSION_MINOR 42
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
|
49
deps/libuv/src/idna.c
vendored
49
deps/libuv/src/idna.c
vendored
@ -19,6 +19,7 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "idna.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
@ -32,7 +33,7 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
if (a > 0xF7)
|
||||
return -1;
|
||||
|
||||
switch (*p - pe) {
|
||||
switch (pe - *p) {
|
||||
default:
|
||||
if (a > 0xEF) {
|
||||
min = 0x10000;
|
||||
@ -62,6 +63,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
a = 0;
|
||||
break;
|
||||
}
|
||||
/* Fall through. */
|
||||
case 0:
|
||||
return -1; /* Invalid continuation byte. */
|
||||
}
|
||||
|
||||
@ -88,6 +91,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
||||
unsigned a;
|
||||
|
||||
assert(*p < pe);
|
||||
|
||||
a = (unsigned char) *(*p)++;
|
||||
|
||||
if (a < 128)
|
||||
@ -96,9 +101,6 @@ unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
||||
return uv__utf8_decode1_slow(p, pe, a);
|
||||
}
|
||||
|
||||
#define foreach_codepoint(c, p, pe) \
|
||||
for (; (void) (*p <= pe && (c = uv__utf8_decode1(p, pe))), *p <= pe;)
|
||||
|
||||
static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
char** d, char* de) {
|
||||
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
@ -121,15 +123,22 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
ss = s;
|
||||
todo = 0;
|
||||
|
||||
foreach_codepoint(c, &s, se) {
|
||||
/* Note: after this loop we've visited all UTF-8 characters and know
|
||||
* they're legal so we no longer need to check for decode errors.
|
||||
*/
|
||||
while (s < se) {
|
||||
c = uv__utf8_decode1(&s, se);
|
||||
|
||||
if (c == -1u)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (c < 128)
|
||||
h++;
|
||||
else if (c == (unsigned) -1)
|
||||
return UV_EINVAL;
|
||||
else
|
||||
todo++;
|
||||
}
|
||||
|
||||
/* Only write "xn--" when there are non-ASCII characters. */
|
||||
if (todo > 0) {
|
||||
if (*d < de) *(*d)++ = 'x';
|
||||
if (*d < de) *(*d)++ = 'n';
|
||||
@ -137,9 +146,13 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
if (*d < de) *(*d)++ = '-';
|
||||
}
|
||||
|
||||
/* Write ASCII characters. */
|
||||
x = 0;
|
||||
s = ss;
|
||||
foreach_codepoint(c, &s, se) {
|
||||
while (s < se) {
|
||||
c = uv__utf8_decode1(&s, se);
|
||||
assert(c != -1u);
|
||||
|
||||
if (c > 127)
|
||||
continue;
|
||||
|
||||
@ -166,10 +179,15 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
while (todo > 0) {
|
||||
m = -1;
|
||||
s = ss;
|
||||
foreach_codepoint(c, &s, se)
|
||||
|
||||
while (s < se) {
|
||||
c = uv__utf8_decode1(&s, se);
|
||||
assert(c != -1u);
|
||||
|
||||
if (c >= n)
|
||||
if (c < m)
|
||||
m = c;
|
||||
}
|
||||
|
||||
x = m - n;
|
||||
y = h + 1;
|
||||
@ -181,7 +199,10 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
n = m;
|
||||
|
||||
s = ss;
|
||||
foreach_codepoint(c, &s, se) {
|
||||
while (s < se) {
|
||||
c = uv__utf8_decode1(&s, se);
|
||||
assert(c != -1u);
|
||||
|
||||
if (c < n)
|
||||
if (++delta == 0)
|
||||
return UV_E2BIG; /* Overflow. */
|
||||
@ -245,8 +266,6 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef foreach_codepoint
|
||||
|
||||
long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
||||
const char* si;
|
||||
const char* st;
|
||||
@ -256,10 +275,14 @@ long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
||||
|
||||
ds = d;
|
||||
|
||||
for (si = s; si < se; /* empty */) {
|
||||
si = s;
|
||||
while (si < se) {
|
||||
st = si;
|
||||
c = uv__utf8_decode1(&si, se);
|
||||
|
||||
if (c == -1u)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (c != '.')
|
||||
if (c != 0x3002) /* 。 */
|
||||
if (c != 0xFF0E) /* . */
|
||||
|
3
deps/libuv/src/inet.c
vendored
3
deps/libuv/src/inet.c
vendored
@ -141,8 +141,9 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
|
||||
if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
if (UV_E2BIG == uv__strscpy(dst, tmp, size))
|
||||
if ((size_t) (tp - tmp) > size)
|
||||
return UV_ENOSPC;
|
||||
uv__strscpy(dst, tmp, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
2
deps/libuv/src/threadpool.c
vendored
2
deps/libuv/src/threadpool.c
vendored
@ -161,7 +161,6 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
|
||||
|
||||
|
||||
void uv__threadpool_cleanup(void) {
|
||||
#ifndef _WIN32
|
||||
unsigned int i;
|
||||
|
||||
if (nthreads == 0)
|
||||
@ -181,7 +180,6 @@ void uv__threadpool_cleanup(void) {
|
||||
|
||||
threads = NULL;
|
||||
nthreads = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
1
deps/libuv/src/timer.c
vendored
1
deps/libuv/src/timer.c
vendored
@ -58,6 +58,7 @@ static int timer_less_than(const struct heap_node* ha,
|
||||
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
|
||||
handle->timer_cb = NULL;
|
||||
handle->timeout = 0;
|
||||
handle->repeat = 0;
|
||||
return 0;
|
||||
}
|
||||
|
2
deps/libuv/src/unix/async.c
vendored
2
deps/libuv/src/unix/async.c
vendored
@ -214,7 +214,7 @@ static int uv__async_start(uv_loop_t* loop) {
|
||||
pipefd[0] = err;
|
||||
pipefd[1] = -1;
|
||||
#else
|
||||
err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
|
||||
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#endif
|
||||
|
6
deps/libuv/src/unix/atomic-ops.h
vendored
6
deps/libuv/src/unix/atomic-ops.h
vendored
@ -52,9 +52,11 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
|
||||
|
||||
UV_UNUSED(static void cpu_relax(void)) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
__asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
|
||||
__asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
|
||||
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
|
||||
__asm__ volatile("yield");
|
||||
__asm__ __volatile__ ("yield" ::: "memory");
|
||||
#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
|
||||
__asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
4
deps/libuv/src/unix/bsd-ifaddrs.c
vendored
4
deps/libuv/src/unix/bsd-ifaddrs.c
vendored
@ -42,8 +42,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
|
||||
return 1;
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
||||
/*
|
||||
* If `exclude_type` is `UV__EXCLUDE_IFPHYS`, just see whether `sa_family`
|
||||
* equals to `AF_LINK` or not. Otherwise, the result depends on the operation
|
||||
* If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family`
|
||||
* equals `AF_LINK`. Otherwise, the result depends on the operating
|
||||
* system with `AF_LINK` or `PF_INET`.
|
||||
*/
|
||||
if (exclude_type == UV__EXCLUDE_IFPHYS)
|
||||
|
24
deps/libuv/src/unix/core.c
vendored
24
deps/libuv/src/unix/core.c
vendored
@ -88,6 +88,10 @@ extern char** environ;
|
||||
# define uv__accept4 accept4
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
|
||||
# include <sanitizer/linux_syscall_hooks.h>
|
||||
#endif
|
||||
|
||||
static int uv__run_pending(uv_loop_t* loop);
|
||||
|
||||
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
|
||||
@ -539,7 +543,13 @@ int uv__close_nocancel(int fd) {
|
||||
return close$NOCANCEL$UNIX2003(fd);
|
||||
#endif
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
|
||||
long rc;
|
||||
__sanitizer_syscall_pre_close(fd);
|
||||
rc = syscall(SYS_close, fd);
|
||||
__sanitizer_syscall_post_close(rc, fd);
|
||||
return rc;
|
||||
#elif defined(__linux__) && !defined(__SANITIZE_THREAD__)
|
||||
return syscall(SYS_close, fd);
|
||||
#else
|
||||
return close(fd);
|
||||
@ -574,7 +584,7 @@ int uv__close(int fd) {
|
||||
return uv__close_nocheckstdio(fd);
|
||||
}
|
||||
|
||||
|
||||
#if UV__NONBLOCK_IS_IOCTL
|
||||
int uv__nonblock_ioctl(int fd, int set) {
|
||||
int r;
|
||||
|
||||
@ -589,7 +599,6 @@ int uv__nonblock_ioctl(int fd, int set) {
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__)
|
||||
int uv__cloexec_ioctl(int fd, int set) {
|
||||
int r;
|
||||
|
||||
@ -925,13 +934,12 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
if (w->pevents == 0) {
|
||||
QUEUE_REMOVE(&w->watcher_queue);
|
||||
QUEUE_INIT(&w->watcher_queue);
|
||||
w->events = 0;
|
||||
|
||||
if (loop->watchers[w->fd] != NULL) {
|
||||
assert(loop->watchers[w->fd] == w);
|
||||
if (w == loop->watchers[w->fd]) {
|
||||
assert(loop->nfds > 0);
|
||||
loop->watchers[w->fd] = NULL;
|
||||
loop->nfds--;
|
||||
w->events = 0;
|
||||
}
|
||||
}
|
||||
else if (QUEUE_EMPTY(&w->watcher_queue))
|
||||
@ -1175,7 +1183,9 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
if (buf == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
do
|
||||
r = getpwuid_r(uid, &pw, buf, bufsize, &result);
|
||||
while (r == EINTR);
|
||||
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
@ -1185,7 +1195,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
|
||||
if (r != 0) {
|
||||
uv__free(buf);
|
||||
return -r;
|
||||
return UV__ERR(r);
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
|
12
deps/libuv/src/unix/darwin.c
vendored
12
deps/libuv/src/unix/darwin.c
vendored
@ -33,9 +33,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h> /* sysconf */
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
#include "darwin-stub.h"
|
||||
#endif
|
||||
|
||||
static uv_once_t once = UV_ONCE_INIT;
|
||||
static uint64_t (*time_func)(void);
|
||||
@ -223,10 +221,10 @@ static int uv__get_cpu_speed(uint64_t* speed) {
|
||||
err = UV_ENOENT;
|
||||
core_foundation_handle = dlopen("/System/Library/Frameworks/"
|
||||
"CoreFoundation.framework/"
|
||||
"Versions/A/CoreFoundation",
|
||||
"CoreFoundation",
|
||||
RTLD_LAZY | RTLD_LOCAL);
|
||||
iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/"
|
||||
"Versions/A/IOKit",
|
||||
"IOKit",
|
||||
RTLD_LAZY | RTLD_LOCAL);
|
||||
|
||||
if (core_foundation_handle == NULL || iokit_handle == NULL)
|
||||
@ -304,6 +302,12 @@ static int uv__get_cpu_speed(uint64_t* speed) {
|
||||
pIOObjectRelease(it);
|
||||
|
||||
err = 0;
|
||||
|
||||
if (device_type_str != NULL)
|
||||
pCFRelease(device_type_str);
|
||||
if (clock_frequency_str != NULL)
|
||||
pCFRelease(clock_frequency_str);
|
||||
|
||||
out:
|
||||
if (core_foundation_handle != NULL)
|
||||
dlclose(core_foundation_handle);
|
||||
|
422
deps/libuv/src/unix/epoll.c
vendored
Normal file
422
deps/libuv/src/unix/epoll.c
vendored
Normal file
@ -0,0 +1,422 @@
|
||||
/* Copyright libuv contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include <errno.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
int uv__epoll_init(uv_loop_t* loop) {
|
||||
int fd;
|
||||
fd = epoll_create1(O_CLOEXEC);
|
||||
|
||||
/* epoll_create1() can fail either because it's not implemented (old kernel)
|
||||
* or because it doesn't understand the O_CLOEXEC flag.
|
||||
*/
|
||||
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
|
||||
fd = epoll_create(256);
|
||||
|
||||
if (fd != -1)
|
||||
uv__cloexec(fd, 1);
|
||||
}
|
||||
|
||||
loop->backend_fd = fd;
|
||||
if (fd == -1)
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event* events;
|
||||
struct epoll_event dummy;
|
||||
uintptr_t i;
|
||||
uintptr_t nfds;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
assert(fd >= 0);
|
||||
|
||||
events = (struct epoll_event*) loop->watchers[loop->nwatchers];
|
||||
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
|
||||
if (events != NULL)
|
||||
/* Invalidate events with same file descriptor */
|
||||
for (i = 0; i < nfds; i++)
|
||||
if (events[i].data.fd == fd)
|
||||
events[i].data.fd = -1;
|
||||
|
||||
/* Remove the file descriptor from the epoll.
|
||||
* This avoids a problem where the same file description remains open
|
||||
* in another process, causing repeated junk epoll events.
|
||||
*
|
||||
* We pass in a dummy epoll_event, to work around a bug in old kernels.
|
||||
*/
|
||||
if (loop->backend_fd >= 0) {
|
||||
/* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
|
||||
* has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
|
||||
*/
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event e;
|
||||
int rc;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.events = POLLIN;
|
||||
e.data.fd = -1;
|
||||
|
||||
rc = 0;
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e))
|
||||
if (errno != EEXIST)
|
||||
rc = UV__ERR(errno);
|
||||
|
||||
if (rc == 0)
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e))
|
||||
abort();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
/* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
|
||||
* effectively infinite on 32 bits architectures. To avoid blocking
|
||||
* indefinitely, we cap the timeout and poll again if necessary.
|
||||
*
|
||||
* Note that "30 minutes" is a simplification because it depends on
|
||||
* the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200,
|
||||
* that being the largest value I have seen in the wild (and only once.)
|
||||
*/
|
||||
static const int max_safe_timeout = 1789569;
|
||||
static int no_epoll_pwait_cached;
|
||||
static int no_epoll_wait_cached;
|
||||
int no_epoll_pwait;
|
||||
int no_epoll_wait;
|
||||
struct epoll_event events[1024];
|
||||
struct epoll_event* pe;
|
||||
struct epoll_event e;
|
||||
int real_timeout;
|
||||
QUEUE* q;
|
||||
uv__io_t* w;
|
||||
sigset_t sigset;
|
||||
uint64_t sigmask;
|
||||
uint64_t base;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int nfds;
|
||||
int fd;
|
||||
int op;
|
||||
int i;
|
||||
int user_timeout;
|
||||
int reset_timeout;
|
||||
|
||||
if (loop->nfds == 0) {
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
|
||||
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
|
||||
q = QUEUE_HEAD(&loop->watcher_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INIT(q);
|
||||
|
||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
||||
assert(w->pevents != 0);
|
||||
assert(w->fd >= 0);
|
||||
assert(w->fd < (int) loop->nwatchers);
|
||||
|
||||
e.events = w->pevents;
|
||||
e.data.fd = w->fd;
|
||||
|
||||
if (w->events == 0)
|
||||
op = EPOLL_CTL_ADD;
|
||||
else
|
||||
op = EPOLL_CTL_MOD;
|
||||
|
||||
/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
|
||||
* events, skip the syscall and squelch the events after epoll_wait().
|
||||
*/
|
||||
if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
|
||||
if (errno != EEXIST)
|
||||
abort();
|
||||
|
||||
assert(op == EPOLL_CTL_ADD);
|
||||
|
||||
/* We've reactivated a file descriptor that's been watched before. */
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e))
|
||||
abort();
|
||||
}
|
||||
|
||||
w->events = w->pevents;
|
||||
}
|
||||
|
||||
sigmask = 0;
|
||||
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGPROF);
|
||||
sigmask |= 1 << (SIGPROF - 1);
|
||||
}
|
||||
|
||||
assert(timeout >= -1);
|
||||
base = loop->time;
|
||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||
real_timeout = timeout;
|
||||
|
||||
if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
|
||||
reset_timeout = 1;
|
||||
user_timeout = timeout;
|
||||
timeout = 0;
|
||||
} else {
|
||||
reset_timeout = 0;
|
||||
user_timeout = 0;
|
||||
}
|
||||
|
||||
/* You could argue there is a dependency between these two but
|
||||
* ultimately we don't care about their ordering with respect
|
||||
* to one another. Worst case, we make a few system calls that
|
||||
* could have been avoided because another thread already knows
|
||||
* they fail with ENOSYS. Hardly the end of the world.
|
||||
*/
|
||||
no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached);
|
||||
no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached);
|
||||
|
||||
for (;;) {
|
||||
/* Only need to set the provider_entry_time if timeout != 0. The function
|
||||
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
|
||||
*/
|
||||
if (timeout != 0)
|
||||
uv__metrics_set_provider_entry_time(loop);
|
||||
|
||||
/* See the comment for max_safe_timeout for an explanation of why
|
||||
* this is necessary. Executive summary: kernel bug workaround.
|
||||
*/
|
||||
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
|
||||
timeout = max_safe_timeout;
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
|
||||
abort();
|
||||
|
||||
if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
|
||||
nfds = epoll_pwait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout,
|
||||
&sigset);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_pwait_cached, 1);
|
||||
no_epoll_pwait = 1;
|
||||
}
|
||||
} else {
|
||||
nfds = epoll_wait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_wait_cached, 1);
|
||||
no_epoll_wait = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL))
|
||||
abort();
|
||||
|
||||
/* 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
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
|
||||
if (nfds == 0) {
|
||||
assert(timeout != -1);
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* We may have been inside the system call for longer than |timeout|
|
||||
* milliseconds so we need to update the timestamp to avoid drift.
|
||||
*/
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
if (nfds == -1) {
|
||||
if (errno == ENOSYS) {
|
||||
/* epoll_wait() or epoll_pwait() failed, try the other system call. */
|
||||
assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno != EINTR)
|
||||
abort();
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* Interrupted by a signal. Update timeout and poll again. */
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
{
|
||||
/* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */
|
||||
union {
|
||||
struct epoll_event* events;
|
||||
uv__io_t* watchers;
|
||||
} x;
|
||||
|
||||
x.events = events;
|
||||
assert(loop->watchers != NULL);
|
||||
loop->watchers[loop->nwatchers] = x.watchers;
|
||||
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
pe = events + i;
|
||||
fd = pe->data.fd;
|
||||
|
||||
/* Skip invalidated events, see uv__platform_invalidate_fd */
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert((unsigned) fd < loop->nwatchers);
|
||||
|
||||
w = loop->watchers[fd];
|
||||
|
||||
if (w == NULL) {
|
||||
/* File descriptor that we've stopped watching, disarm it.
|
||||
*
|
||||
* Ignore all errors because we may be racing with another thread
|
||||
* when the file descriptor is closed.
|
||||
*/
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Give users only events they're interested in. Prevents spurious
|
||||
* callbacks when previous callback invocation in this loop has stopped
|
||||
* the current watcher. Also, filters out events that users has not
|
||||
* requested us to watch.
|
||||
*/
|
||||
pe->events &= w->pevents | POLLERR | POLLHUP;
|
||||
|
||||
/* Work around an epoll quirk where it sometimes reports just the
|
||||
* EPOLLERR or EPOLLHUP event. In order to force the event loop to
|
||||
* move forward, we merge in the read/write events that the watcher
|
||||
* is interested in; uv__read() and uv__write() will then deal with
|
||||
* the error or hangup in the usual fashion.
|
||||
*
|
||||
* Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
|
||||
* reads the available data, calls uv_read_stop(), then sometime later
|
||||
* calls uv_read_start() again. By then, libuv has forgotten about the
|
||||
* hangup and the kernel won't report EPOLLIN again because there's
|
||||
* nothing left to read. If anything, libuv is to blame here. The
|
||||
* current hack is just a quick bandaid; to properly fix it, libuv
|
||||
* needs to remember the error/hangup event. We should get that for
|
||||
* free when we switch over to edge-triggered I/O.
|
||||
*/
|
||||
if (pe->events == POLLERR || pe->events == POLLHUP)
|
||||
pe->events |=
|
||||
w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
|
||||
|
||||
if (pe->events != 0) {
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->events);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
timeout = 0;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
update_timeout:
|
||||
assert(timeout > 0);
|
||||
|
||||
real_timeout -= (loop->time - base);
|
||||
if (real_timeout <= 0)
|
||||
return;
|
||||
|
||||
timeout = real_timeout;
|
||||
}
|
||||
}
|
||||
|
15
deps/libuv/src/unix/freebsd.c
vendored
15
deps/libuv/src/unix/freebsd.c
vendored
@ -265,8 +265,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
|
||||
|
||||
int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
#if __FreeBSD__ >= 11
|
||||
return sendmmsg(fd, mmsg, vlen, /* flags */ 0);
|
||||
#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
|
||||
return sendmmsg(fd,
|
||||
(struct mmsghdr*) mmsg,
|
||||
vlen,
|
||||
0 /* flags */);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
@ -274,8 +277,12 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
|
||||
|
||||
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
#if __FreeBSD__ >= 11
|
||||
return recvmmsg(fd, mmsg, vlen, 0 /* flags */, NULL /* timeout */);
|
||||
#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
|
||||
return recvmmsg(fd,
|
||||
(struct mmsghdr*) mmsg,
|
||||
vlen,
|
||||
0 /* flags */,
|
||||
NULL /* timeout */);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
|
106
deps/libuv/src/unix/fs.c
vendored
106
deps/libuv/src/unix/fs.c
vendored
@ -56,8 +56,13 @@
|
||||
# define HAVE_PREADV 0
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# include "sys/utsname.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__sun)
|
||||
# include <sys/sendfile.h>
|
||||
# include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@ -212,14 +217,30 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
|
||||
UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = time;
|
||||
ts.tv_nsec = (uint64_t)(time * 1000000) % 1000000 * 1000;
|
||||
ts.tv_nsec = (time - ts.tv_sec) * 1e9;
|
||||
|
||||
/* TODO(bnoordhuis) Remove this. utimesat() has nanosecond resolution but we
|
||||
* stick to microsecond resolution for the sake of consistency with other
|
||||
* platforms. I'm the original author of this compatibility hack but I'm
|
||||
* less convinced it's useful nowadays.
|
||||
*/
|
||||
ts.tv_nsec -= ts.tv_nsec % 1000;
|
||||
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1e9;
|
||||
ts.tv_sec -= 1;
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = time;
|
||||
tv.tv_usec = (uint64_t)(time * 1000000) % 1000000;
|
||||
tv.tv_usec = (time - tv.tv_sec) * 1e6;
|
||||
if (tv.tv_usec < 0) {
|
||||
tv.tv_usec += 1e6;
|
||||
tv.tv_sec -= 1;
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
|
||||
@ -227,9 +248,6 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
|
||||
#if defined(__linux__) \
|
||||
|| defined(_AIX71) \
|
||||
|| defined(__HAIKU__)
|
||||
/* utimesat() has nanosecond resolution but we stick to microseconds
|
||||
* for the sake of consistency with other platforms.
|
||||
*/
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
@ -887,6 +905,50 @@ out:
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static unsigned uv__kernel_version(void) {
|
||||
static unsigned cached_version;
|
||||
struct utsname u;
|
||||
unsigned version;
|
||||
unsigned major;
|
||||
unsigned minor;
|
||||
unsigned patch;
|
||||
|
||||
version = uv__load_relaxed(&cached_version);
|
||||
if (version != 0)
|
||||
return version;
|
||||
|
||||
if (-1 == uname(&u))
|
||||
return 0;
|
||||
|
||||
if (3 != sscanf(u.release, "%u.%u.%u", &major, &minor, &patch))
|
||||
return 0;
|
||||
|
||||
version = major * 65536 + minor * 256 + patch;
|
||||
uv__store_relaxed(&cached_version, version);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
/* Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from command
|
||||
* in copy_file_range() when it shouldn't. There is no workaround except to
|
||||
* fall back to a regular copy.
|
||||
*/
|
||||
static int uv__is_buggy_cephfs(int fd) {
|
||||
struct statfs s;
|
||||
|
||||
if (-1 == fstatfs(fd, &s))
|
||||
return 0;
|
||||
|
||||
if (s.f_type != /* CephFS */ 0xC36400)
|
||||
return 0;
|
||||
|
||||
return uv__kernel_version() < /* 4.20.0 */ 0x041400;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
int in_fd;
|
||||
int out_fd;
|
||||
@ -903,14 +965,25 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
|
||||
#ifdef __linux__
|
||||
{
|
||||
static int copy_file_range_support = 1;
|
||||
static int no_copy_file_range_support;
|
||||
|
||||
if (copy_file_range_support) {
|
||||
r = uv__fs_copy_file_range(in_fd, NULL, out_fd, &off, req->bufsml[0].len, 0);
|
||||
if (uv__load_relaxed(&no_copy_file_range_support) == 0) {
|
||||
r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0);
|
||||
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
/* ENOSYS - it will never work */
|
||||
errno = 0;
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
} else if (r == -1 && errno == EACCES && uv__is_buggy_cephfs(in_fd)) {
|
||||
/* EACCES - pre-4.20 kernels have a bug where CephFS uses the RADOS
|
||||
copy-from command when it shouldn't */
|
||||
errno = 0;
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
} else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) {
|
||||
/* ENOTSUP - it could work on another file system type */
|
||||
/* EXDEV - it will not work when in_fd and out_fd are not on the same
|
||||
mounted filesystem (pre Linux 5.3) */
|
||||
errno = 0;
|
||||
copy_file_range_support = 0;
|
||||
} else {
|
||||
goto ok;
|
||||
}
|
||||
@ -1010,9 +1083,6 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|
||||
|| defined(_AIX71) \
|
||||
|| defined(__sun) \
|
||||
|| defined(__HAIKU__)
|
||||
/* utimesat() has nanosecond resolution but we stick to microseconds
|
||||
* for the sake of consistency with other platforms.
|
||||
*/
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
@ -1220,7 +1290,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
||||
if (fstatfs(dstfd, &s) == -1)
|
||||
goto out;
|
||||
|
||||
if (s.f_type != /* CIFS */ 0xFF534D42u)
|
||||
if ((unsigned) s.f_type != /* CIFS */ 0xFF534D42u)
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1340,7 +1410,8 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
|
||||
dst->st_birthtim.tv_nsec = src->st_ctimensec;
|
||||
dst->st_flags = 0;
|
||||
dst->st_gen = 0;
|
||||
#elif !defined(_AIX) && ( \
|
||||
#elif !defined(_AIX) && \
|
||||
!defined(__MVS__) && ( \
|
||||
defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
@ -1420,8 +1491,9 @@ static int uv__fs_statx(int fd,
|
||||
case -1:
|
||||
/* EPERM happens when a seccomp filter rejects the system call.
|
||||
* Has been observed with libseccomp < 2.3.3 and docker < 18.04.
|
||||
* EOPNOTSUPP is used on DVS exported filesystems
|
||||
*/
|
||||
if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
|
||||
if (errno != EINVAL && errno != EPERM && errno != ENOSYS && errno != EOPNOTSUPP)
|
||||
return -1;
|
||||
/* Fall through. */
|
||||
default:
|
||||
@ -1434,12 +1506,12 @@ static int uv__fs_statx(int fd,
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
buf->st_dev = 256 * statxbuf.stx_dev_major + statxbuf.stx_dev_minor;
|
||||
buf->st_dev = makedev(statxbuf.stx_dev_major, statxbuf.stx_dev_minor);
|
||||
buf->st_mode = statxbuf.stx_mode;
|
||||
buf->st_nlink = statxbuf.stx_nlink;
|
||||
buf->st_uid = statxbuf.stx_uid;
|
||||
buf->st_gid = statxbuf.stx_gid;
|
||||
buf->st_rdev = statxbuf.stx_rdev_major;
|
||||
buf->st_rdev = makedev(statxbuf.stx_rdev_major, statxbuf.stx_rdev_minor);
|
||||
buf->st_ino = statxbuf.stx_ino;
|
||||
buf->st_size = statxbuf.stx_size;
|
||||
buf->st_blksize = statxbuf.stx_blksize;
|
||||
|
21
deps/libuv/src/unix/fsevents.c
vendored
21
deps/libuv/src/unix/fsevents.c
vendored
@ -595,8 +595,7 @@ out:
|
||||
static int uv__fsevents_loop_init(uv_loop_t* loop) {
|
||||
CFRunLoopSourceContext ctx;
|
||||
uv__cf_loop_state_t* state;
|
||||
pthread_attr_t attr_storage;
|
||||
pthread_attr_t* attr;
|
||||
pthread_attr_t attr;
|
||||
int err;
|
||||
|
||||
if (loop->cf_state != NULL)
|
||||
@ -641,25 +640,19 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
|
||||
goto fail_signal_source_create;
|
||||
}
|
||||
|
||||
/* In the unlikely event that pthread_attr_init() fails, create the thread
|
||||
* with the default stack size. We'll use a little more address space but
|
||||
* that in itself is not a fatal error.
|
||||
*/
|
||||
attr = &attr_storage;
|
||||
if (pthread_attr_init(attr))
|
||||
attr = NULL;
|
||||
if (pthread_attr_init(&attr))
|
||||
abort();
|
||||
|
||||
if (attr != NULL)
|
||||
if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN))
|
||||
if (pthread_attr_setstacksize(&attr, uv__thread_stack_size()))
|
||||
abort();
|
||||
|
||||
loop->cf_state = state;
|
||||
|
||||
/* uv_thread_t is an alias for pthread_t. */
|
||||
err = UV__ERR(pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop));
|
||||
err = UV__ERR(pthread_create(&loop->cf_thread, &attr, uv__cf_loop_runner, loop));
|
||||
|
||||
if (attr != NULL)
|
||||
pthread_attr_destroy(attr);
|
||||
if (pthread_attr_destroy(&attr))
|
||||
abort();
|
||||
|
||||
if (err)
|
||||
goto fail_thread_create;
|
||||
|
3
deps/libuv/src/unix/getaddrinfo.c
vendored
3
deps/libuv/src/unix/getaddrinfo.c
vendored
@ -21,9 +21,6 @@
|
||||
/* 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"
|
||||
|
46
deps/libuv/src/unix/ibmi.c
vendored
46
deps/libuv/src/unix/ibmi.c
vendored
@ -26,7 +26,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -166,7 +165,7 @@ static void iconv_a2e(const char* src, unsigned char dst[], size_t length) {
|
||||
|
||||
srclen = strlen(src);
|
||||
if (srclen > length)
|
||||
abort();
|
||||
srclen = length;
|
||||
for (i = 0; i < srclen; i++)
|
||||
dst[i] = a2e[src[i]];
|
||||
/* padding the remaining part with spaces */
|
||||
@ -360,6 +359,10 @@ static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
if (err.bytes_available > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* convert ebcdic loca_adapter_address to ascii first */
|
||||
iconv_e2a(rcvr.loca_adapter_address, mac_addr,
|
||||
sizeof(rcvr.loca_adapter_address));
|
||||
@ -443,9 +446,42 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
}
|
||||
address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0;
|
||||
if (!address->is_internal) {
|
||||
int rc = get_ibmi_physical_address(address->name, &address->phys_addr);
|
||||
if (rc != 0)
|
||||
r = rc;
|
||||
int rc = -1;
|
||||
size_t name_len = strlen(address->name);
|
||||
/* To get the associated MAC address, we must convert the address to a
|
||||
* line description. Normally, the name field contains the line
|
||||
* description name, but for VLANs it has the VLAN appended with a
|
||||
* period. Since object names can also contain periods and numbers, there
|
||||
* is no way to know if a returned name is for a VLAN or not. eg.
|
||||
* *LIND ETH1.1 and *LIND ETH1, VLAN 1 both have the same name: ETH1.1
|
||||
*
|
||||
* Instead, we apply the same heuristic used by some of the XPF ioctls:
|
||||
* - names > 10 *must* contain a VLAN
|
||||
* - assume names <= 10 do not contain a VLAN and try directly
|
||||
* - if >10 or QDCRLIND returned an error, try to strip off a VLAN
|
||||
* and try again
|
||||
* - if we still get an error or couldn't find a period, leave the MAC as
|
||||
* 00:00:00:00:00:00
|
||||
*/
|
||||
if (name_len <= 10) {
|
||||
/* Assume name does not contain a VLAN ID */
|
||||
rc = get_ibmi_physical_address(address->name, &address->phys_addr);
|
||||
}
|
||||
|
||||
if (name_len > 10 || rc != 0) {
|
||||
/* The interface name must contain a VLAN ID suffix. Attempt to strip
|
||||
* it off so we can get the line description to pass to QDCRLIND.
|
||||
*/
|
||||
char* temp_name = uv__strdup(address->name);
|
||||
char* dot = strrchr(temp_name, '.');
|
||||
if (dot != NULL) {
|
||||
*dot = '\0';
|
||||
if (strlen(temp_name) <= 10) {
|
||||
rc = get_ibmi_physical_address(temp_name, &address->phys_addr);
|
||||
}
|
||||
}
|
||||
uv__free(temp_name);
|
||||
}
|
||||
}
|
||||
|
||||
address++;
|
||||
|
30
deps/libuv/src/unix/internal.h
vendored
30
deps/libuv/src/unix/internal.h
vendored
@ -62,6 +62,17 @@
|
||||
# include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define common detection for active Thread Sanitizer
|
||||
* - clang uses __has_feature(thread_sanitizer)
|
||||
* - gcc-7+ uses __SANITIZE_THREAD__
|
||||
*/
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(thread_sanitizer)
|
||||
# define __SANITIZE_THREAD__ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(PATH_MAX)
|
||||
# define UV__PATH_MAX PATH_MAX
|
||||
#else
|
||||
@ -165,9 +176,11 @@ struct uv__stream_queued_fds_s {
|
||||
defined(__NetBSD__)
|
||||
#define uv__cloexec uv__cloexec_ioctl
|
||||
#define uv__nonblock uv__nonblock_ioctl
|
||||
#define UV__NONBLOCK_IS_IOCTL 1
|
||||
#else
|
||||
#define uv__cloexec uv__cloexec_fcntl
|
||||
#define uv__nonblock uv__nonblock_fcntl
|
||||
#define UV__NONBLOCK_IS_IOCTL 0
|
||||
#endif
|
||||
|
||||
/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute
|
||||
@ -246,6 +259,7 @@ int uv__signal_loop_fork(uv_loop_t* loop);
|
||||
/* platform specific */
|
||||
uint64_t uv__hrtime(uv_clocktype_t type);
|
||||
int uv__kqueue_init(uv_loop_t* loop);
|
||||
int uv__epoll_init(uv_loop_t* loop);
|
||||
int uv__platform_loop_init(uv_loop_t* loop);
|
||||
void uv__platform_loop_delete(uv_loop_t* loop);
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd);
|
||||
@ -261,6 +275,7 @@ void uv__prepare_close(uv_prepare_t* handle);
|
||||
void uv__process_close(uv_process_t* handle);
|
||||
void uv__stream_close(uv_stream_t* handle);
|
||||
void uv__tcp_close(uv_tcp_t* handle);
|
||||
size_t uv__thread_stack_size(void);
|
||||
void uv__udp_close(uv_udp_t* handle);
|
||||
void uv__udp_finish_close(uv_udp_t* handle);
|
||||
uv_handle_type uv__handle_type(int fd);
|
||||
@ -282,12 +297,6 @@ int uv___stream_fd(const uv_stream_t* handle);
|
||||
#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
#ifdef O_NONBLOCK
|
||||
# define UV__F_NONBLOCK O_NONBLOCK
|
||||
#else
|
||||
# define UV__F_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
int uv__make_pipe(int fds[2], int flags);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@ -327,7 +336,8 @@ int uv__getsockpeername(const uv_handle_t* handle,
|
||||
|
||||
#if defined(__linux__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel__)
|
||||
defined(__FreeBSD_kernel__) || \
|
||||
defined(__DragonFly__)
|
||||
#define HAVE_MMSG 1
|
||||
struct uv__mmsghdr {
|
||||
struct msghdr msg_hdr;
|
||||
@ -340,5 +350,11 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen);
|
||||
#define HAVE_MMSG 0
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
||||
size_t strnlen(const char* s, size_t maxlen);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
|
468
deps/libuv/src/unix/linux-core.c
vendored
468
deps/libuv/src/unix/linux-core.c
vendored
@ -82,29 +82,12 @@ static int read_times(FILE* statfile_fp,
|
||||
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
|
||||
static uint64_t read_cpufreq(unsigned int cpunum);
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
int fd;
|
||||
fd = epoll_create1(O_CLOEXEC);
|
||||
|
||||
/* epoll_create1() can fail either because it's not implemented (old kernel)
|
||||
* or because it doesn't understand the O_CLOEXEC flag.
|
||||
*/
|
||||
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
|
||||
fd = epoll_create(256);
|
||||
|
||||
if (fd != -1)
|
||||
uv__cloexec(fd, 1);
|
||||
}
|
||||
|
||||
loop->backend_fd = fd;
|
||||
loop->inotify_fd = -1;
|
||||
loop->inotify_watchers = NULL;
|
||||
|
||||
if (fd == -1)
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
return uv__epoll_init(loop);
|
||||
}
|
||||
|
||||
|
||||
@ -134,380 +117,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event* events;
|
||||
struct epoll_event dummy;
|
||||
uintptr_t i;
|
||||
uintptr_t nfds;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
assert(fd >= 0);
|
||||
|
||||
events = (struct epoll_event*) loop->watchers[loop->nwatchers];
|
||||
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
|
||||
if (events != NULL)
|
||||
/* Invalidate events with same file descriptor */
|
||||
for (i = 0; i < nfds; i++)
|
||||
if (events[i].data.fd == fd)
|
||||
events[i].data.fd = -1;
|
||||
|
||||
/* Remove the file descriptor from the epoll.
|
||||
* This avoids a problem where the same file description remains open
|
||||
* in another process, causing repeated junk epoll events.
|
||||
*
|
||||
* We pass in a dummy epoll_event, to work around a bug in old kernels.
|
||||
*/
|
||||
if (loop->backend_fd >= 0) {
|
||||
/* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
|
||||
* has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
|
||||
*/
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event e;
|
||||
int rc;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.events = POLLIN;
|
||||
e.data.fd = -1;
|
||||
|
||||
rc = 0;
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e))
|
||||
if (errno != EEXIST)
|
||||
rc = UV__ERR(errno);
|
||||
|
||||
if (rc == 0)
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e))
|
||||
abort();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
/* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
|
||||
* effectively infinite on 32 bits architectures. To avoid blocking
|
||||
* indefinitely, we cap the timeout and poll again if necessary.
|
||||
*
|
||||
* Note that "30 minutes" is a simplification because it depends on
|
||||
* the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200,
|
||||
* that being the largest value I have seen in the wild (and only once.)
|
||||
*/
|
||||
static const int max_safe_timeout = 1789569;
|
||||
static int no_epoll_pwait_cached;
|
||||
static int no_epoll_wait_cached;
|
||||
int no_epoll_pwait;
|
||||
int no_epoll_wait;
|
||||
struct epoll_event events[1024];
|
||||
struct epoll_event* pe;
|
||||
struct epoll_event e;
|
||||
int real_timeout;
|
||||
QUEUE* q;
|
||||
uv__io_t* w;
|
||||
sigset_t sigset;
|
||||
uint64_t sigmask;
|
||||
uint64_t base;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int nfds;
|
||||
int fd;
|
||||
int op;
|
||||
int i;
|
||||
int user_timeout;
|
||||
int reset_timeout;
|
||||
|
||||
if (loop->nfds == 0) {
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
|
||||
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
|
||||
q = QUEUE_HEAD(&loop->watcher_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INIT(q);
|
||||
|
||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
||||
assert(w->pevents != 0);
|
||||
assert(w->fd >= 0);
|
||||
assert(w->fd < (int) loop->nwatchers);
|
||||
|
||||
e.events = w->pevents;
|
||||
e.data.fd = w->fd;
|
||||
|
||||
if (w->events == 0)
|
||||
op = EPOLL_CTL_ADD;
|
||||
else
|
||||
op = EPOLL_CTL_MOD;
|
||||
|
||||
/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
|
||||
* events, skip the syscall and squelch the events after epoll_wait().
|
||||
*/
|
||||
if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
|
||||
if (errno != EEXIST)
|
||||
abort();
|
||||
|
||||
assert(op == EPOLL_CTL_ADD);
|
||||
|
||||
/* We've reactivated a file descriptor that's been watched before. */
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e))
|
||||
abort();
|
||||
}
|
||||
|
||||
w->events = w->pevents;
|
||||
}
|
||||
|
||||
sigmask = 0;
|
||||
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGPROF);
|
||||
sigmask |= 1 << (SIGPROF - 1);
|
||||
}
|
||||
|
||||
assert(timeout >= -1);
|
||||
base = loop->time;
|
||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||
real_timeout = timeout;
|
||||
|
||||
if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
|
||||
reset_timeout = 1;
|
||||
user_timeout = timeout;
|
||||
timeout = 0;
|
||||
} else {
|
||||
reset_timeout = 0;
|
||||
user_timeout = 0;
|
||||
}
|
||||
|
||||
/* You could argue there is a dependency between these two but
|
||||
* ultimately we don't care about their ordering with respect
|
||||
* to one another. Worst case, we make a few system calls that
|
||||
* could have been avoided because another thread already knows
|
||||
* they fail with ENOSYS. Hardly the end of the world.
|
||||
*/
|
||||
no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached);
|
||||
no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached);
|
||||
|
||||
for (;;) {
|
||||
/* Only need to set the provider_entry_time if timeout != 0. The function
|
||||
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
|
||||
*/
|
||||
if (timeout != 0)
|
||||
uv__metrics_set_provider_entry_time(loop);
|
||||
|
||||
/* See the comment for max_safe_timeout for an explanation of why
|
||||
* this is necessary. Executive summary: kernel bug workaround.
|
||||
*/
|
||||
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
|
||||
timeout = max_safe_timeout;
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
|
||||
abort();
|
||||
|
||||
if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
|
||||
nfds = epoll_pwait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout,
|
||||
&sigset);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_pwait_cached, 1);
|
||||
no_epoll_pwait = 1;
|
||||
}
|
||||
} else {
|
||||
nfds = epoll_wait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_wait_cached, 1);
|
||||
no_epoll_wait = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL))
|
||||
abort();
|
||||
|
||||
/* 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
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
|
||||
if (nfds == 0) {
|
||||
assert(timeout != -1);
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* We may have been inside the system call for longer than |timeout|
|
||||
* milliseconds so we need to update the timestamp to avoid drift.
|
||||
*/
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
if (nfds == -1) {
|
||||
if (errno == ENOSYS) {
|
||||
/* epoll_wait() or epoll_pwait() failed, try the other system call. */
|
||||
assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno != EINTR)
|
||||
abort();
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* Interrupted by a signal. Update timeout and poll again. */
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
{
|
||||
/* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */
|
||||
union {
|
||||
struct epoll_event* events;
|
||||
uv__io_t* watchers;
|
||||
} x;
|
||||
|
||||
x.events = events;
|
||||
assert(loop->watchers != NULL);
|
||||
loop->watchers[loop->nwatchers] = x.watchers;
|
||||
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
pe = events + i;
|
||||
fd = pe->data.fd;
|
||||
|
||||
/* Skip invalidated events, see uv__platform_invalidate_fd */
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert((unsigned) fd < loop->nwatchers);
|
||||
|
||||
w = loop->watchers[fd];
|
||||
|
||||
if (w == NULL) {
|
||||
/* File descriptor that we've stopped watching, disarm it.
|
||||
*
|
||||
* Ignore all errors because we may be racing with another thread
|
||||
* when the file descriptor is closed.
|
||||
*/
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Give users only events they're interested in. Prevents spurious
|
||||
* callbacks when previous callback invocation in this loop has stopped
|
||||
* the current watcher. Also, filters out events that users has not
|
||||
* requested us to watch.
|
||||
*/
|
||||
pe->events &= w->pevents | POLLERR | POLLHUP;
|
||||
|
||||
/* Work around an epoll quirk where it sometimes reports just the
|
||||
* EPOLLERR or EPOLLHUP event. In order to force the event loop to
|
||||
* move forward, we merge in the read/write events that the watcher
|
||||
* is interested in; uv__read() and uv__write() will then deal with
|
||||
* the error or hangup in the usual fashion.
|
||||
*
|
||||
* Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
|
||||
* reads the available data, calls uv_read_stop(), then sometime later
|
||||
* calls uv_read_start() again. By then, libuv has forgotten about the
|
||||
* hangup and the kernel won't report EPOLLIN again because there's
|
||||
* nothing left to read. If anything, libuv is to blame here. The
|
||||
* current hack is just a quick bandaid; to properly fix it, libuv
|
||||
* needs to remember the error/hangup event. We should get that for
|
||||
* free when we switch over to edge-triggered I/O.
|
||||
*/
|
||||
if (pe->events == POLLERR || pe->events == POLLHUP)
|
||||
pe->events |=
|
||||
w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
|
||||
|
||||
if (pe->events != 0) {
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->events);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
timeout = 0;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
update_timeout:
|
||||
assert(timeout > 0);
|
||||
|
||||
real_timeout -= (loop->time - base);
|
||||
if (real_timeout <= 0)
|
||||
return;
|
||||
|
||||
timeout = real_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
static clock_t fast_clock_id = -1;
|
||||
@ -602,22 +211,53 @@ err:
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
static int uv__slurp(const char* filename, char* buf, size_t len) {
|
||||
ssize_t n;
|
||||
int fd;
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
fd = uv__open_cloexec(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
do
|
||||
n = read(fd, buf, len - 1);
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (uv__close_nocheckstdio(fd))
|
||||
abort();
|
||||
|
||||
if (n < 0)
|
||||
return UV__ERR(errno);
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_uptime(double* uptime) {
|
||||
static volatile int no_clock_boottime;
|
||||
char buf[128];
|
||||
struct timespec now;
|
||||
int r;
|
||||
|
||||
/* Try /proc/uptime first, then fallback to clock_gettime(). */
|
||||
|
||||
if (0 == uv__slurp("/proc/uptime", buf, sizeof(buf)))
|
||||
if (1 == sscanf(buf, "%lf", uptime))
|
||||
return 0;
|
||||
|
||||
/* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available
|
||||
* (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system
|
||||
* is suspended.
|
||||
*/
|
||||
if (no_clock_boottime) {
|
||||
retry: r = clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
retry_clock_gettime: r = clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
}
|
||||
else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) {
|
||||
no_clock_boottime = 1;
|
||||
goto retry;
|
||||
goto retry_clock_gettime;
|
||||
}
|
||||
|
||||
if (r)
|
||||
@ -709,14 +349,19 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
}
|
||||
|
||||
|
||||
/* Also reads the CPU frequency on x86. The other architectures only have
|
||||
* a BogoMIPS field, which may not be very accurate.
|
||||
/* Also reads the CPU frequency on ppc and x86. The other architectures only
|
||||
* have a BogoMIPS field, which may not be very accurate.
|
||||
*
|
||||
* Note: Simply returns on error, uv_cpu_info() takes care of the cleanup.
|
||||
*/
|
||||
static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
#if defined(__PPC__)
|
||||
static const char model_marker[] = "cpu\t\t: ";
|
||||
static const char speed_marker[] = "clock\t\t: ";
|
||||
#else
|
||||
static const char model_marker[] = "model name\t: ";
|
||||
static const char speed_marker[] = "cpu MHz\t\t: ";
|
||||
#endif
|
||||
const char* inferred_model;
|
||||
unsigned int model_idx;
|
||||
unsigned int speed_idx;
|
||||
@ -738,6 +383,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
#if defined(__arm__) || \
|
||||
defined(__i386__) || \
|
||||
defined(__mips__) || \
|
||||
defined(__PPC__) || \
|
||||
defined(__x86_64__)
|
||||
fp = uv__open_file("/proc/cpuinfo");
|
||||
if (fp == NULL)
|
||||
@ -786,7 +432,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
#endif /* __arm__ || __i386__ || __mips__ || __x86_64__ */
|
||||
#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ */
|
||||
|
||||
/* Now we want to make sure that all the models contain *something* because
|
||||
* it's not safe to leave them as null. Copy the last entry unless there
|
||||
@ -824,9 +470,9 @@ static int read_times(FILE* statfile_fp,
|
||||
char buf[1024];
|
||||
|
||||
ticks = (unsigned int)sysconf(_SC_CLK_TCK);
|
||||
multiplier = ((uint64_t)1000L / ticks);
|
||||
assert(ticks != (unsigned int) -1);
|
||||
assert(ticks != 0);
|
||||
multiplier = ((uint64_t)1000L / ticks);
|
||||
|
||||
rewind(statfile_fp);
|
||||
|
||||
@ -1025,32 +671,6 @@ void uv__set_process_title(const char* title) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__slurp(const char* filename, char* buf, size_t len) {
|
||||
ssize_t n;
|
||||
int fd;
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
fd = uv__open_cloexec(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
do
|
||||
n = read(fd, buf, len - 1);
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (uv__close_nocheckstdio(fd))
|
||||
abort();
|
||||
|
||||
if (n < 0)
|
||||
return UV__ERR(errno);
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t uv__read_proc_meminfo(const char* what) {
|
||||
uint64_t rc;
|
||||
char* p;
|
||||
|
2
deps/libuv/src/unix/linux-inotify.c
vendored
2
deps/libuv/src/unix/linux-inotify.c
vendored
@ -178,7 +178,7 @@ static void uv__inotify_read(uv_loop_t* loop,
|
||||
/* needs to be large enough for sizeof(inotify_event) + strlen(path) */
|
||||
char buf[4096];
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
do
|
||||
size = read(loop->inotify_fd, buf, sizeof(buf));
|
||||
while (size == -1 && errno == EINTR);
|
||||
|
37
deps/libuv/src/unix/linux-syscalls.c
vendored
37
deps/libuv/src/unix/linux-syscalls.c
vendored
@ -194,37 +194,37 @@ int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
|
||||
|
||||
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
|
||||
#if defined(__NR_preadv)
|
||||
return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
|
||||
#else
|
||||
#if !defined(__NR_preadv) || defined(__ANDROID_API__) && __ANDROID_API__ < 24
|
||||
return errno = ENOSYS, -1;
|
||||
#else
|
||||
return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
|
||||
#if defined(__NR_pwritev)
|
||||
return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
|
||||
#else
|
||||
#if !defined(__NR_pwritev) || defined(__ANDROID_API__) && __ANDROID_API__ < 24
|
||||
return errno = ENOSYS, -1;
|
||||
#else
|
||||
return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int uv__dup3(int oldfd, int newfd, int flags) {
|
||||
#if defined(__NR_dup3)
|
||||
return syscall(__NR_dup3, oldfd, newfd, flags);
|
||||
#else
|
||||
#if !defined(__NR_dup3) || defined(__ANDROID_API__) && __ANDROID_API__ < 21
|
||||
return errno = ENOSYS, -1;
|
||||
#else
|
||||
return syscall(__NR_dup3, oldfd, newfd, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
uv__fs_copy_file_range(int fd_in,
|
||||
ssize_t* off_in,
|
||||
off_t* off_in,
|
||||
int fd_out,
|
||||
ssize_t* off_out,
|
||||
off_t* off_out,
|
||||
size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
@ -247,21 +247,18 @@ int uv__statx(int dirfd,
|
||||
int flags,
|
||||
unsigned int mask,
|
||||
struct uv__statx* statxbuf) {
|
||||
/* __NR_statx make Android box killed by SIGSYS.
|
||||
* That looks like a seccomp2 sandbox filter rejecting the system call.
|
||||
*/
|
||||
#if defined(__NR_statx) && !defined(__ANDROID__)
|
||||
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
|
||||
#else
|
||||
#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30
|
||||
return errno = ENOSYS, -1;
|
||||
#else
|
||||
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
|
||||
#if defined(__NR_getrandom)
|
||||
return syscall(__NR_getrandom, buf, buflen, flags);
|
||||
#else
|
||||
#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28
|
||||
return errno = ENOSYS, -1;
|
||||
#else
|
||||
return syscall(__NR_getrandom, buf, buflen, flags);
|
||||
#endif
|
||||
}
|
||||
|
7
deps/libuv/src/unix/linux-syscalls.h
vendored
7
deps/libuv/src/unix/linux-syscalls.h
vendored
@ -22,9 +22,6 @@
|
||||
#ifndef UV_LINUX_SYSCALL_H_
|
||||
#define UV_LINUX_SYSCALL_H_
|
||||
|
||||
#undef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
@ -66,9 +63,9 @@ ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset)
|
||||
int uv__dup3(int oldfd, int newfd, int flags);
|
||||
ssize_t
|
||||
uv__fs_copy_file_range(int fd_in,
|
||||
ssize_t* off_in,
|
||||
off_t* off_in,
|
||||
int fd_out,
|
||||
ssize_t* off_out,
|
||||
off_t* off_out,
|
||||
size_t len,
|
||||
unsigned int flags);
|
||||
int uv__statx(int dirfd,
|
||||
|
136
deps/libuv/src/unix/os390-proctitle.c
vendored
Normal file
136
deps/libuv/src/unix/os390-proctitle.c
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
/* Copyright libuv project contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static uv_mutex_t process_title_mutex;
|
||||
static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
|
||||
static char* process_title = NULL;
|
||||
static void* args_mem = NULL;
|
||||
|
||||
|
||||
static void init_process_title_mutex_once(void) {
|
||||
uv_mutex_init(&process_title_mutex);
|
||||
}
|
||||
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
char** new_argv;
|
||||
size_t size;
|
||||
char* s;
|
||||
int i;
|
||||
|
||||
if (argc <= 0)
|
||||
return argv;
|
||||
|
||||
/* Calculate how much memory we need for the argv strings. */
|
||||
size = 0;
|
||||
for (i = 0; i < argc; i++)
|
||||
size += strlen(argv[i]) + 1;
|
||||
|
||||
/* Add space for the argv pointers. */
|
||||
size += (argc + 1) * sizeof(char*);
|
||||
|
||||
new_argv = uv__malloc(size);
|
||||
if (new_argv == NULL)
|
||||
return argv;
|
||||
|
||||
/* Copy over the strings and set up the pointer table. */
|
||||
s = (char*) &new_argv[argc + 1];
|
||||
for (i = 0; i < argc; i++) {
|
||||
size = strlen(argv[i]) + 1;
|
||||
memcpy(s, argv[i], size);
|
||||
new_argv[i] = s;
|
||||
s += size;
|
||||
}
|
||||
new_argv[i] = NULL;
|
||||
|
||||
args_mem = new_argv;
|
||||
process_title = uv__strdup(argv[0]);
|
||||
|
||||
return new_argv;
|
||||
}
|
||||
|
||||
|
||||
int uv_set_process_title(const char* title) {
|
||||
char* new_title;
|
||||
|
||||
/* If uv_setup_args wasn't called or failed, we can't continue. */
|
||||
if (args_mem == NULL)
|
||||
return UV_ENOBUFS;
|
||||
|
||||
/* We cannot free this pointer when libuv shuts down,
|
||||
* the process may still be using it.
|
||||
*/
|
||||
new_title = uv__strdup(title);
|
||||
if (new_title == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
|
||||
uv_mutex_lock(&process_title_mutex);
|
||||
|
||||
if (process_title != NULL)
|
||||
uv__free(process_title);
|
||||
|
||||
process_title = new_title;
|
||||
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_get_process_title(char* buffer, size_t size) {
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* If uv_setup_args wasn't called or failed, we can't continue. */
|
||||
if (args_mem == NULL || process_title == NULL)
|
||||
return UV_ENOBUFS;
|
||||
|
||||
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
|
||||
uv_mutex_lock(&process_title_mutex);
|
||||
|
||||
len = strlen(process_title);
|
||||
|
||||
if (size <= len) {
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
strcpy(buffer, process_title);
|
||||
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__process_title_cleanup(void) {
|
||||
uv__free(args_mem); /* Keep valgrind happy. */
|
||||
args_mem = NULL;
|
||||
}
|
57
deps/libuv/src/unix/os390-syscalls.c
vendored
57
deps/libuv/src/unix/os390-syscalls.c
vendored
@ -27,12 +27,6 @@
|
||||
#include <termios.h>
|
||||
#include <sys/msg.h>
|
||||
|
||||
#define CW_INTRPT 1
|
||||
#define CW_CONDVAR 32
|
||||
|
||||
#pragma linkage(BPX4CTW, OS)
|
||||
#pragma linkage(BPX1CTW, OS)
|
||||
|
||||
static QUEUE global_epoll_queue;
|
||||
static uv_mutex_t global_epoll_lock;
|
||||
static uv_once_t once = UV_ONCE_INIT;
|
||||
@ -55,7 +49,7 @@ int scandir(const char* maindir, struct dirent*** namelist,
|
||||
if (!mdir)
|
||||
return -1;
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
dirent = readdir(mdir);
|
||||
if (!dirent)
|
||||
break;
|
||||
@ -381,46 +375,6 @@ void epoll_queue_close(uv__os390_epoll* lst) {
|
||||
}
|
||||
|
||||
|
||||
int nanosleep(const struct timespec* req, struct timespec* rem) {
|
||||
unsigned nano;
|
||||
unsigned seconds;
|
||||
unsigned events;
|
||||
unsigned secrem;
|
||||
unsigned nanorem;
|
||||
int rv;
|
||||
int err;
|
||||
int rsn;
|
||||
|
||||
nano = (int)req->tv_nsec;
|
||||
seconds = req->tv_sec;
|
||||
events = CW_CONDVAR | CW_INTRPT;
|
||||
secrem = 0;
|
||||
nanorem = 0;
|
||||
|
||||
#if defined(_LP64)
|
||||
BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
|
||||
#else
|
||||
BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
|
||||
#endif
|
||||
|
||||
/* Don't clobber errno unless BPX1CTW/BPX4CTW errored.
|
||||
* Don't leak EAGAIN, that just means the timeout expired.
|
||||
*/
|
||||
if (rv == -1)
|
||||
if (err == EAGAIN)
|
||||
rv = 0;
|
||||
else
|
||||
errno = err;
|
||||
|
||||
if (rem != NULL && (rv == 0 || err == EINTR)) {
|
||||
rem->tv_nsec = nanorem;
|
||||
rem->tv_sec = secrem;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char* mkdtemp(char* path) {
|
||||
static const char* tempchars =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
@ -550,15 +504,6 @@ ssize_t os390_readlink(const char* path, char* buf, size_t len) {
|
||||
}
|
||||
|
||||
|
||||
size_t strnlen(const char* str, size_t maxlen) {
|
||||
char* p = memchr(str, 0, maxlen);
|
||||
if (p == NULL)
|
||||
return maxlen;
|
||||
else
|
||||
return p - str;
|
||||
}
|
||||
|
||||
|
||||
int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
2
deps/libuv/src/unix/os390-syscalls.h
vendored
2
deps/libuv/src/unix/os390-syscalls.h
vendored
@ -28,6 +28,7 @@
|
||||
#include <dirent.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include "zos-base.h"
|
||||
|
||||
#define EPOLL_CTL_ADD 1
|
||||
#define EPOLL_CTL_DEL 2
|
||||
@ -57,7 +58,6 @@ int epoll_wait(uv__os390_epoll* ep, struct epoll_event *events, int maxevents, i
|
||||
int epoll_file_close(int fd);
|
||||
|
||||
/* utility functions */
|
||||
int nanosleep(const struct timespec* req, struct timespec* rem);
|
||||
int scandir(const char* maindir, struct dirent*** namelist,
|
||||
int (*filter)(const struct dirent *),
|
||||
int (*compar)(const struct dirent **,
|
||||
|
136
deps/libuv/src/unix/os390.c
vendored
136
deps/libuv/src/unix/os390.c
vendored
@ -28,6 +28,8 @@
|
||||
#include <builtins.h>
|
||||
#include <termios.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/resource.h>
|
||||
#include "zos-base.h"
|
||||
#if defined(__clang__)
|
||||
#include "csrsic.h"
|
||||
#else
|
||||
@ -61,12 +63,6 @@
|
||||
/* Address of the rsm control and enumeration area. */
|
||||
#define CVTRCEP_OFFSET 0x490
|
||||
|
||||
/*
|
||||
Number of frames currently available to system.
|
||||
Excluded are frames backing perm storage, frames offline, and bad frames.
|
||||
*/
|
||||
#define RCEPOOL_OFFSET 0x004
|
||||
|
||||
/* Total number of frames currently on all available frame queues. */
|
||||
#define RCEAFC_OFFSET 0x088
|
||||
|
||||
@ -144,102 +140,8 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get the exe path using the thread entry information
|
||||
in the address space.
|
||||
*/
|
||||
static int getexe(const int pid, char* buf, size_t len) {
|
||||
struct {
|
||||
int pid;
|
||||
int thid[2];
|
||||
char accesspid;
|
||||
char accessthid;
|
||||
char asid[2];
|
||||
char loginname[8];
|
||||
char flag;
|
||||
char len;
|
||||
} Input_data;
|
||||
|
||||
union {
|
||||
struct {
|
||||
char gthb[4];
|
||||
int pid;
|
||||
int thid[2];
|
||||
char accesspid;
|
||||
char accessthid[3];
|
||||
int lenused;
|
||||
int offsetProcess;
|
||||
int offsetConTTY;
|
||||
int offsetPath;
|
||||
int offsetCommand;
|
||||
int offsetFileData;
|
||||
int offsetThread;
|
||||
} Output_data;
|
||||
char buf[2048];
|
||||
} Output_buf;
|
||||
|
||||
struct Output_path_type {
|
||||
char gthe[4];
|
||||
short int len;
|
||||
char path[1024];
|
||||
};
|
||||
|
||||
int Input_length;
|
||||
int Output_length;
|
||||
void* Input_address;
|
||||
void* Output_address;
|
||||
struct Output_path_type* Output_path;
|
||||
int rv;
|
||||
int rc;
|
||||
int rsn;
|
||||
|
||||
Input_length = PGTH_LEN;
|
||||
Output_length = sizeof(Output_buf);
|
||||
Output_address = &Output_buf;
|
||||
Input_address = &Input_data;
|
||||
memset(&Input_data, 0, sizeof Input_data);
|
||||
Input_data.flag |= PGTHAPATH;
|
||||
Input_data.pid = pid;
|
||||
Input_data.accesspid = PGTH_CURRENT;
|
||||
|
||||
#ifdef _LP64
|
||||
BPX4GTH(&Input_length,
|
||||
&Input_address,
|
||||
&Output_length,
|
||||
&Output_address,
|
||||
&rv,
|
||||
&rc,
|
||||
&rsn);
|
||||
#else
|
||||
BPX1GTH(&Input_length,
|
||||
&Input_address,
|
||||
&Output_length,
|
||||
&Output_address,
|
||||
&rv,
|
||||
&rc,
|
||||
&rsn);
|
||||
#endif
|
||||
|
||||
if (rv == -1) {
|
||||
errno = rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check highest byte to ensure data availability */
|
||||
assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A');
|
||||
|
||||
/* Get the offset from the lowest 3 bytes */
|
||||
Output_path = (struct Output_path_type*) ((char*) (&Output_buf) +
|
||||
(Output_buf.Output_data.offsetPath & 0x00FFFFFF));
|
||||
|
||||
if (Output_path->len >= len) {
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uv__strscpy(buf, Output_path->path, len);
|
||||
|
||||
return 0;
|
||||
static int getexe(char* buf, size_t len) {
|
||||
return uv__strscpy(buf, __getargv()[0], len);
|
||||
}
|
||||
|
||||
|
||||
@ -259,8 +161,7 @@ int uv_exepath(char* buffer, size_t* size) {
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
pid = getpid();
|
||||
res = getexe(pid, args, sizeof(args));
|
||||
res = getexe(args, sizeof(args));
|
||||
if (res < 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
@ -275,25 +176,25 @@ uint64_t uv_get_free_memory(void) {
|
||||
data_area_ptr rcep = {0};
|
||||
cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
|
||||
rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
|
||||
freeram = *((uint64_t*)(rcep.deref + RCEAFC_OFFSET)) * 4;
|
||||
freeram = (uint64_t)*((uint32_t*)(rcep.deref + RCEAFC_OFFSET)) * 4096;
|
||||
return freeram;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
uint64_t totalram;
|
||||
|
||||
data_area_ptr cvt = {0};
|
||||
data_area_ptr rcep = {0};
|
||||
cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
|
||||
rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
|
||||
totalram = *((uint64_t*)(rcep.deref + RCEPOOL_OFFSET)) * 4;
|
||||
return totalram;
|
||||
/* Use CVTRLSTG to get the size of actual real storage online at IPL in K. */
|
||||
return (uint64_t)((int)((char *__ptr32 *__ptr32 *)0)[4][214]) * 1024;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
struct rlimit rl;
|
||||
|
||||
/* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */
|
||||
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0)
|
||||
return rl.rlim_cur * 1024 * 1024;
|
||||
|
||||
return 0; /* There is no memory limit set. */
|
||||
}
|
||||
|
||||
|
||||
@ -733,6 +634,10 @@ static int os390_message_queue_handler(uv__os390_epoll* ep) {
|
||||
/* Some event that we are not interested in. */
|
||||
return 0;
|
||||
|
||||
/* `__rfim_utok` is treated as text when it should be treated as binary while
|
||||
* running in ASCII mode, resulting in an unwanted autoconversion.
|
||||
*/
|
||||
__a2e_l(msg.__rfim_utok, sizeof(msg.__rfim_utok));
|
||||
handle = *(uv_fs_event_t**)(msg.__rfim_utok);
|
||||
handle->cb(handle, uv__basename_r(handle->path), events, 0);
|
||||
return 1;
|
||||
@ -959,9 +864,6 @@ update_timeout:
|
||||
}
|
||||
}
|
||||
|
||||
void uv__set_process_title(const char* title) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
/*
|
||||
|
54
deps/libuv/src/unix/pipe.c
vendored
54
deps/libuv/src/unix/pipe.c
vendored
@ -379,3 +379,57 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
||||
|
||||
return r != -1 ? 0 : UV__ERR(errno);
|
||||
}
|
||||
|
||||
|
||||
int uv_pipe(uv_os_fd_t fds[2], int read_flags, int write_flags) {
|
||||
uv_os_fd_t temp[2];
|
||||
int err;
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
int flags = O_CLOEXEC;
|
||||
|
||||
if ((read_flags & UV_NONBLOCK_PIPE) && (write_flags & UV_NONBLOCK_PIPE))
|
||||
flags |= UV_FS_O_NONBLOCK;
|
||||
|
||||
if (pipe2(temp, flags))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if (flags & UV_FS_O_NONBLOCK) {
|
||||
fds[0] = temp[0];
|
||||
fds[1] = temp[1];
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (pipe(temp))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if ((err = uv__cloexec(temp[0], 1)))
|
||||
goto fail;
|
||||
|
||||
if ((err = uv__cloexec(temp[1], 1)))
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
if (read_flags & UV_NONBLOCK_PIPE)
|
||||
if ((err = uv__nonblock(temp[0], 1)))
|
||||
goto fail;
|
||||
|
||||
if (write_flags & UV_NONBLOCK_PIPE)
|
||||
if ((err = uv__nonblock(temp[1], 1)))
|
||||
goto fail;
|
||||
|
||||
fds[0] = temp[0];
|
||||
fds[1] = temp[1];
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
uv__close(temp[0]);
|
||||
uv__close(temp[1]);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int uv__make_pipe(int fds[2], int flags) {
|
||||
return uv_pipe(fds,
|
||||
flags & UV_NONBLOCK_PIPE,
|
||||
flags & UV_NONBLOCK_PIPE);
|
||||
}
|
||||
|
12
deps/libuv/src/unix/poll.c
vendored
12
deps/libuv/src/unix/poll.c
vendored
@ -79,9 +79,10 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
||||
* Workaround for e.g. kqueue fds not supporting ioctls.
|
||||
*/
|
||||
err = uv__nonblock(fd, 1);
|
||||
#if UV__NONBLOCK_IS_IOCTL
|
||||
if (err == UV_ENOTTY)
|
||||
if (uv__nonblock == uv__nonblock_ioctl)
|
||||
err = uv__nonblock_fcntl(fd, 1);
|
||||
#endif
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
@ -116,12 +117,21 @@ int uv_poll_stop(uv_poll_t* handle) {
|
||||
|
||||
|
||||
int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
|
||||
uv__io_t** watchers;
|
||||
uv__io_t* w;
|
||||
int events;
|
||||
|
||||
assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
|
||||
UV_PRIORITIZED)) == 0);
|
||||
assert(!uv__is_closing(handle));
|
||||
|
||||
watchers = handle->loop->watchers;
|
||||
w = &handle->io_watcher;
|
||||
|
||||
if (uv__fd_exists(handle->loop, w->fd))
|
||||
if (watchers[w->fd] != w)
|
||||
return UV_EEXIST;
|
||||
|
||||
uv__poll_stop(handle);
|
||||
|
||||
if (pevents == 0)
|
||||
|
127
deps/libuv/src/unix/process.c
vendored
127
deps/libuv/src/unix/process.c
vendored
@ -44,6 +44,10 @@ extern char **environ;
|
||||
# include <grp.h>
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# include "zos-base.h"
|
||||
#endif
|
||||
|
||||
|
||||
static void uv__chld(uv_signal_t* handle, int signum) {
|
||||
uv_process_t* process;
|
||||
@ -111,68 +115,6 @@ static void uv__chld(uv_signal_t* handle, int signum) {
|
||||
assert(QUEUE_EMPTY(&pending));
|
||||
}
|
||||
|
||||
|
||||
static int uv__make_socketpair(int fds[2]) {
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds))
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
int err;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
||||
return UV__ERR(errno);
|
||||
|
||||
err = uv__cloexec(fds[0], 1);
|
||||
if (err == 0)
|
||||
err = uv__cloexec(fds[1], 1);
|
||||
|
||||
if (err != 0) {
|
||||
uv__close(fds[0]);
|
||||
uv__close(fds[1]);
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int uv__make_pipe(int fds[2], int flags) {
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
if (pipe2(fds, flags | O_CLOEXEC))
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
if (pipe(fds))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if (uv__cloexec(fds[0], 1))
|
||||
goto fail;
|
||||
|
||||
if (uv__cloexec(fds[1], 1))
|
||||
goto fail;
|
||||
|
||||
if (flags & UV__F_NONBLOCK) {
|
||||
if (uv__nonblock(fds[0], 1))
|
||||
goto fail;
|
||||
|
||||
if (uv__nonblock(fds[1], 1))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
uv__close(fds[0]);
|
||||
uv__close(fds[1]);
|
||||
return UV__ERR(errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Used for initializing stdio streams like options.stdin_stream. Returns
|
||||
* zero on success. See also the cleanup section in uv_spawn().
|
||||
@ -192,7 +134,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
|
||||
if (container->data.stream->type != UV_NAMED_PIPE)
|
||||
return UV_EINVAL;
|
||||
else
|
||||
return uv__make_socketpair(fds);
|
||||
return uv_socketpair(SOCK_STREAM, 0, fds, 0, 0);
|
||||
|
||||
case UV_INHERIT_FD:
|
||||
case UV_INHERIT_STREAM:
|
||||
@ -259,6 +201,12 @@ static void uv__write_int(int fd, int val) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__write_errno(int error_fd) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
|
||||
#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
|
||||
/* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be
|
||||
* avoided. Since this isn't called on those targets, the function
|
||||
@ -287,10 +235,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
if (use_fd < 0 || use_fd >= fd)
|
||||
continue;
|
||||
pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
|
||||
if (pipes[fd][1] == -1) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (pipes[fd][1] == -1)
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
|
||||
for (fd = 0; fd < stdio_count; fd++) {
|
||||
@ -307,10 +253,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
|
||||
close_fd = use_fd;
|
||||
|
||||
if (use_fd < 0) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (use_fd < 0)
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,10 +263,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
else
|
||||
fd = dup2(use_fd, fd);
|
||||
|
||||
if (fd == -1) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (fd == -1)
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if (fd <= 2)
|
||||
uv__nonblock_fcntl(fd, 0);
|
||||
@ -338,10 +280,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
uv__close(use_fd);
|
||||
}
|
||||
|
||||
if (options->cwd != NULL && chdir(options->cwd)) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (options->cwd != NULL && chdir(options->cwd))
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
|
||||
/* When dropping privileges from root, the `setgroups` call will
|
||||
@ -354,15 +294,11 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
SAVE_ERRNO(setgroups(0, NULL));
|
||||
}
|
||||
|
||||
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid))
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid))
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if (options->env != NULL) {
|
||||
environ = options->env;
|
||||
@ -385,22 +321,23 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
if (SIG_ERR != signal(n, SIG_DFL))
|
||||
continue;
|
||||
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
|
||||
/* Reset signal mask. */
|
||||
sigemptyset(&set);
|
||||
err = pthread_sigmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
if (err != 0) {
|
||||
uv__write_int(error_fd, UV__ERR(err));
|
||||
_exit(127);
|
||||
}
|
||||
if (err != 0)
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
#ifdef __MVS__
|
||||
execvpe(options->file, options->args, environ);
|
||||
#else
|
||||
execvp(options->file, options->args);
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
#endif
|
||||
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
4
deps/libuv/src/unix/proctitle.c
vendored
4
deps/libuv/src/unix/proctitle.c
vendored
@ -84,10 +84,7 @@ char** uv_setup_args(int argc, char** argv) {
|
||||
}
|
||||
new_argv[i] = NULL;
|
||||
|
||||
/* argv is not adjacent on z/os, we use just argv[0] on that platform. */
|
||||
#ifndef __MVS__
|
||||
pt.cap = argv[i - 1] + size - argv[0];
|
||||
#endif
|
||||
|
||||
args_mem = new_argv;
|
||||
process_title = pt;
|
||||
@ -119,6 +116,7 @@ int uv_set_process_title(const char* title) {
|
||||
memcpy(pt->str, title, len);
|
||||
memset(pt->str + len, '\0', pt->cap - len);
|
||||
pt->len = len;
|
||||
uv__set_process_title(pt->str);
|
||||
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
|
||||
|
2
deps/libuv/src/unix/signal.c
vendored
2
deps/libuv/src/unix/signal.c
vendored
@ -265,7 +265,7 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
|
||||
if (loop->signal_pipefd[0] != -1)
|
||||
return 0;
|
||||
|
||||
err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK);
|
||||
err = uv__make_pipe(loop->signal_pipefd, UV_NONBLOCK_PIPE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
185
deps/libuv/src/unix/stream.c
vendored
185
deps/libuv/src/unix/stream.c
vendored
@ -164,7 +164,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
else
|
||||
max_fd = s->int_fd;
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
/* Terminate on semaphore */
|
||||
if (uv_sem_trywait(&s->close_sem) == 0)
|
||||
break;
|
||||
@ -195,7 +195,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
|
||||
/* Empty socketpair's buffer in case of interruption */
|
||||
if (FD_ISSET(s->int_fd, s->sread))
|
||||
while (1) {
|
||||
for (;;) {
|
||||
r = read(s->int_fd, buf, sizeof(buf));
|
||||
|
||||
if (r == sizeof(buf))
|
||||
@ -799,33 +799,21 @@ static int uv__handle_fd(uv_handle_t* handle) {
|
||||
}
|
||||
}
|
||||
|
||||
static void uv__write(uv_stream_t* stream) {
|
||||
static int uv__try_write(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
struct iovec* iov;
|
||||
QUEUE* q;
|
||||
uv_write_t* req;
|
||||
int iovmax;
|
||||
int iovcnt;
|
||||
ssize_t n;
|
||||
int err;
|
||||
|
||||
start:
|
||||
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
|
||||
if (QUEUE_EMPTY(&stream->write_queue))
|
||||
return;
|
||||
|
||||
q = QUEUE_HEAD(&stream->write_queue);
|
||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||
assert(req->handle == stream);
|
||||
|
||||
/*
|
||||
* Cast to iovec. We had to have our own uv_buf_t instead of iovec
|
||||
* because Windows's WSABUF is not an iovec.
|
||||
*/
|
||||
assert(sizeof(uv_buf_t) == sizeof(struct iovec));
|
||||
iov = (struct iovec*) &(req->bufs[req->write_index]);
|
||||
iovcnt = req->nbufs - req->write_index;
|
||||
iov = (struct iovec*) bufs;
|
||||
iovcnt = nbufs;
|
||||
|
||||
iovmax = uv__getiovmax();
|
||||
|
||||
@ -837,8 +825,7 @@ start:
|
||||
* Now do the actual writev. Note that we've been updating the pointers
|
||||
* inside the iov each time we write. So there is no need to offset it.
|
||||
*/
|
||||
|
||||
if (req->send_handle) {
|
||||
if (send_handle != NULL) {
|
||||
int fd_to_send;
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
@ -847,12 +834,10 @@ start:
|
||||
struct cmsghdr alias;
|
||||
} scratch;
|
||||
|
||||
if (uv__is_closing(req->send_handle)) {
|
||||
err = UV_EBADF;
|
||||
goto error;
|
||||
}
|
||||
if (uv__is_closing(send_handle))
|
||||
return UV_EBADF;
|
||||
|
||||
fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
|
||||
fd_to_send = uv__handle_fd((uv_handle_t*) send_handle);
|
||||
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
|
||||
@ -882,29 +867,54 @@ start:
|
||||
do
|
||||
n = sendmsg(uv__stream_fd(stream), &msg, 0);
|
||||
while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
|
||||
/* Ensure the handle isn't sent again in case this is a partial write. */
|
||||
if (n >= 0)
|
||||
req->send_handle = NULL;
|
||||
} else {
|
||||
do
|
||||
n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
|
||||
while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
}
|
||||
|
||||
if (n == -1 && !IS_TRANSIENT_WRITE_ERROR(errno, req->send_handle)) {
|
||||
err = UV__ERR(errno);
|
||||
goto error;
|
||||
if (n >= 0)
|
||||
return n;
|
||||
|
||||
if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle))
|
||||
return UV_EAGAIN;
|
||||
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
if (n >= 0 && uv__write_req_update(stream, req, n)) {
|
||||
static void uv__write(uv_stream_t* stream) {
|
||||
QUEUE* q;
|
||||
uv_write_t* req;
|
||||
ssize_t n;
|
||||
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
|
||||
for (;;) {
|
||||
if (QUEUE_EMPTY(&stream->write_queue))
|
||||
return;
|
||||
|
||||
q = QUEUE_HEAD(&stream->write_queue);
|
||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||
assert(req->handle == stream);
|
||||
|
||||
n = uv__try_write(stream,
|
||||
&(req->bufs[req->write_index]),
|
||||
req->nbufs - req->write_index,
|
||||
req->send_handle);
|
||||
|
||||
/* Ensure the handle isn't sent again in case this is a partial write. */
|
||||
if (n >= 0) {
|
||||
req->send_handle = NULL;
|
||||
if (uv__write_req_update(stream, req, n)) {
|
||||
uv__write_req_finish(req);
|
||||
return; /* TODO(bnoordhuis) Start trying to write the next request. */
|
||||
}
|
||||
} else if (n != UV_EAGAIN)
|
||||
break;
|
||||
|
||||
/* If this is a blocking stream, try again. */
|
||||
if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
|
||||
goto start;
|
||||
continue;
|
||||
|
||||
/* We're not done. */
|
||||
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
@ -913,13 +923,12 @@ start:
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
error:
|
||||
req->error = err;
|
||||
req->error = n;
|
||||
// XXX(jwn): this must call uv__stream_flush_write_queue(stream, n) here, since we won't generate any more events
|
||||
uv__write_req_finish(req);
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLIN))
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
|
||||
@ -1001,8 +1010,8 @@ uv_handle_type uv__handle_type(int fd) {
|
||||
static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
|
||||
stream->flags |= UV_HANDLE_READ_EOF;
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
stream->flags &= ~UV_HANDLE_READABLE;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
stream->read_cb(stream, UV_EOF, buf);
|
||||
@ -1188,11 +1197,11 @@ static void uv__read(uv_stream_t* stream) {
|
||||
#endif
|
||||
} else {
|
||||
/* Error. User should call uv_close(). */
|
||||
stream->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
stream->read_cb(stream, UV__ERR(errno), &buf);
|
||||
if (stream->flags & UV_HANDLE_READING) {
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
@ -1276,6 +1285,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
||||
req->cb = cb;
|
||||
stream->shutdown_req = req;
|
||||
stream->flags |= UV_HANDLE_SHUTTING;
|
||||
stream->flags &= ~UV_HANDLE_WRITABLE;
|
||||
|
||||
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
@ -1390,14 +1400,9 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
||||
}
|
||||
|
||||
|
||||
int uv_write2(uv_write_t* req,
|
||||
uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
static int uv__check_before_write(uv_stream_t* stream,
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle,
|
||||
uv_write_cb cb) {
|
||||
int empty_queue;
|
||||
|
||||
uv_stream_t* send_handle) {
|
||||
assert(nbufs > 0);
|
||||
assert((stream->type == UV_TCP ||
|
||||
stream->type == UV_NAMED_PIPE ||
|
||||
@ -1410,7 +1415,7 @@ int uv_write2(uv_write_t* req,
|
||||
if (!(stream->flags & UV_HANDLE_WRITABLE))
|
||||
return UV_EPIPE;
|
||||
|
||||
if (send_handle) {
|
||||
if (send_handle != NULL) {
|
||||
if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
|
||||
return UV_EINVAL;
|
||||
|
||||
@ -1430,6 +1435,22 @@ int uv_write2(uv_write_t* req,
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_write2(uv_write_t* req,
|
||||
uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle,
|
||||
uv_write_cb cb) {
|
||||
int empty_queue;
|
||||
int err;
|
||||
|
||||
err = uv__check_before_write(stream, nbufs, send_handle);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* It's legal for write_queue_size > 0 even when the write_queue is empty;
|
||||
* it means there are error-state requests in the write_completed_queue that
|
||||
* will touch up write_queue_size later, see also uv__write_req_finish().
|
||||
@ -1498,72 +1519,37 @@ int uv_write(uv_write_t* req,
|
||||
}
|
||||
|
||||
|
||||
void uv_try_write_cb(uv_write_t* req, int status) {
|
||||
/* Should not be called */
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
int uv_try_write(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs) {
|
||||
int r;
|
||||
int has_pollout;
|
||||
size_t written;
|
||||
size_t req_size;
|
||||
uv_write_t req;
|
||||
return uv_try_write2(stream, bufs, nbufs, NULL);
|
||||
}
|
||||
|
||||
|
||||
int uv_try_write2(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
int err;
|
||||
|
||||
/* Connecting or already writing some data */
|
||||
if (stream->connect_req != NULL || stream->write_queue_size != 0)
|
||||
return UV_EAGAIN;
|
||||
|
||||
has_pollout = uv__io_active(&stream->io_watcher, POLLOUT);
|
||||
err = uv__check_before_write(stream, nbufs, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
/* Remove not written bytes from write queue size */
|
||||
written = uv__count_bufs(bufs, nbufs);
|
||||
if (req.bufs != NULL)
|
||||
req_size = uv__write_req_size(&req);
|
||||
else
|
||||
req_size = 0;
|
||||
written -= req_size;
|
||||
stream->write_queue_size -= req_size;
|
||||
|
||||
/* Unqueue request, regardless of immediateness */
|
||||
QUEUE_REMOVE(&req.queue);
|
||||
uv__req_unregister(stream->loop, &req);
|
||||
if (req.bufs != req.bufsml)
|
||||
uv__free(req.bufs);
|
||||
req.bufs = NULL;
|
||||
|
||||
/* Do not poll for writable, if we wasn't before calling this */
|
||||
if (!has_pollout) {
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
|
||||
if (written == 0 && req_size != 0)
|
||||
return req.error < 0 ? req.error : UV_EAGAIN;
|
||||
else
|
||||
return written;
|
||||
return uv__try_write(stream, bufs, nbufs, send_handle);
|
||||
}
|
||||
|
||||
|
||||
int uv_read_start(uv_stream_t* stream,
|
||||
int uv__read_start(uv_stream_t* stream,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb) {
|
||||
assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
|
||||
stream->type == UV_TTY);
|
||||
|
||||
if (stream->flags & UV_HANDLE_CLOSING)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (!(stream->flags & UV_HANDLE_READABLE))
|
||||
return UV_ENOTCONN;
|
||||
|
||||
/* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just
|
||||
* expresses the desired state of the user.
|
||||
*/
|
||||
@ -1593,7 +1579,6 @@ int uv_read_stop(uv_stream_t* stream) {
|
||||
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
|
||||
|
11
deps/libuv/src/unix/sunos.c
vendored
11
deps/libuv/src/unix/sunos.c
vendored
@ -865,3 +865,14 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
||||
size_t strnlen(const char* s, size_t maxlen) {
|
||||
const char* end;
|
||||
end = memchr(s, '\0', maxlen);
|
||||
if (end == NULL)
|
||||
return maxlen;
|
||||
return end - s;
|
||||
}
|
||||
#endif
|
||||
|
53
deps/libuv/src/unix/tcp.c
vendored
53
deps/libuv/src/unix/tcp.c
vendored
@ -214,14 +214,15 @@ int uv__tcp_connect(uv_connect_t* req,
|
||||
if (handle->connect_req != NULL)
|
||||
return UV_EALREADY; /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */
|
||||
|
||||
if (handle->delayed_error != 0)
|
||||
goto out;
|
||||
|
||||
err = maybe_new_socket(handle,
|
||||
addr->sa_family,
|
||||
UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
handle->delayed_error = 0;
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
r = connect(uv__stream_fd(handle), addr, addrlen);
|
||||
@ -249,6 +250,8 @@ int uv__tcp_connect(uv_connect_t* req,
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
uv__req_init(handle->loop, req, UV_CONNECT);
|
||||
req->cb = cb;
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
@ -459,3 +462,49 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
|
||||
void uv__tcp_close(uv_tcp_t* handle) {
|
||||
uv__stream_close((uv_stream_t*)handle);
|
||||
}
|
||||
|
||||
|
||||
int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) {
|
||||
uv_os_sock_t temp[2];
|
||||
int err;
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
int flags;
|
||||
|
||||
flags = type | SOCK_CLOEXEC;
|
||||
if ((flags0 & UV_NONBLOCK_PIPE) && (flags1 & UV_NONBLOCK_PIPE))
|
||||
flags |= SOCK_NONBLOCK;
|
||||
|
||||
if (socketpair(AF_UNIX, flags, protocol, temp))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if (flags & UV_FS_O_NONBLOCK) {
|
||||
fds[0] = temp[0];
|
||||
fds[1] = temp[1];
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (socketpair(AF_UNIX, type, protocol, temp))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if ((err = uv__cloexec(temp[0], 1)))
|
||||
goto fail;
|
||||
if ((err = uv__cloexec(temp[1], 1)))
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
if (flags0 & UV_NONBLOCK_PIPE)
|
||||
if ((err = uv__nonblock(temp[0], 1)))
|
||||
goto fail;
|
||||
if (flags1 & UV_NONBLOCK_PIPE)
|
||||
if ((err = uv__nonblock(temp[1], 1)))
|
||||
goto fail;
|
||||
|
||||
fds[0] = temp[0];
|
||||
fds[1] = temp[1];
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
uv__close(temp[0]);
|
||||
uv__close(temp[1]);
|
||||
return err;
|
||||
}
|
||||
|
12
deps/libuv/src/unix/thread.c
vendored
12
deps/libuv/src/unix/thread.c
vendored
@ -107,8 +107,7 @@ int uv_barrier_wait(uv_barrier_t* barrier) {
|
||||
}
|
||||
|
||||
last = (--b->out == 0);
|
||||
if (!last)
|
||||
uv_cond_signal(&b->cond); /* Not needed for last thread. */
|
||||
uv_cond_signal(&b->cond);
|
||||
|
||||
uv_mutex_unlock(&b->mutex);
|
||||
return last;
|
||||
@ -122,9 +121,10 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
|
||||
uv_mutex_lock(&b->mutex);
|
||||
|
||||
assert(b->in == 0);
|
||||
assert(b->out == 0);
|
||||
while (b->out != 0)
|
||||
uv_cond_wait(&b->cond, &b->mutex);
|
||||
|
||||
if (b->in != 0 || b->out != 0)
|
||||
if (b->in != 0)
|
||||
abort();
|
||||
|
||||
uv_mutex_unlock(&b->mutex);
|
||||
@ -168,7 +168,7 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
|
||||
* On Linux, threads created by musl have a much smaller stack than threads
|
||||
* created by glibc (80 vs. 2048 or 4096 kB.) Follow glibc for consistency.
|
||||
*/
|
||||
static size_t thread_stack_size(void) {
|
||||
size_t uv__thread_stack_size(void) {
|
||||
#if defined(__APPLE__) || defined(__linux__)
|
||||
struct rlimit lim;
|
||||
|
||||
@ -234,7 +234,7 @@ int uv_thread_create_ex(uv_thread_t* tid,
|
||||
|
||||
attr = NULL;
|
||||
if (stack_size == 0) {
|
||||
stack_size = thread_stack_size();
|
||||
stack_size = uv__thread_stack_size();
|
||||
} else {
|
||||
pagesize = (size_t)getpagesize();
|
||||
/* Round up to the nearest page boundary. */
|
||||
|
18
deps/libuv/src/unix/tty.c
vendored
18
deps/libuv/src/unix/tty.c
vendored
@ -242,6 +242,24 @@ static void uv__tty_make_raw(struct termios* tio) {
|
||||
tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
tio->c_cflag &= ~(CSIZE | PARENB);
|
||||
tio->c_cflag |= CS8;
|
||||
|
||||
/*
|
||||
* By default, most software expects a pending read to block until at
|
||||
* least one byte becomes available. As per termio(7I), this requires
|
||||
* setting the MIN and TIME parameters appropriately.
|
||||
*
|
||||
* As a somewhat unfortunate artifact of history, the MIN and TIME slots
|
||||
* in the control character array overlap with the EOF and EOL slots used
|
||||
* for canonical mode processing. Because the EOF character needs to be
|
||||
* the ASCII EOT value (aka Control-D), it has the byte value 4. When
|
||||
* switching to raw mode, this is interpreted as a MIN value of 4; i.e.,
|
||||
* reads will block until at least four bytes have been input.
|
||||
*
|
||||
* Other platforms with a distinct MIN slot like Linux and FreeBSD appear
|
||||
* to default to a MIN value of 1, so we'll force that value here:
|
||||
*/
|
||||
tio->c_cc[VMIN] = 1;
|
||||
tio->c_cc[VTIME] = 0;
|
||||
#else
|
||||
cfmakeraw(tio);
|
||||
#endif /* #ifdef __sun */
|
||||
|
32
deps/libuv/src/unix/udp.c
vendored
32
deps/libuv/src/unix/udp.c
vendored
@ -32,8 +32,6 @@
|
||||
#endif
|
||||
#include <sys/un.h>
|
||||
|
||||
#define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
|
||||
|
||||
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
|
||||
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#endif
|
||||
@ -504,6 +502,28 @@ static int uv__set_reuse(int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Linux kernel suppresses some ICMP error messages by default for UDP
|
||||
* sockets. Setting IP_RECVERR/IPV6_RECVERR on the socket enables full ICMP
|
||||
* error reporting, hopefully resulting in faster failover to working name
|
||||
* servers.
|
||||
*/
|
||||
static int uv__set_recverr(int fd, sa_family_t ss_family) {
|
||||
#if defined(__linux__)
|
||||
int yes;
|
||||
|
||||
yes = 1;
|
||||
if (ss_family == AF_INET) {
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_RECVERR, &yes, sizeof(yes)))
|
||||
return UV__ERR(errno);
|
||||
} else if (ss_family == AF_INET6) {
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, &yes, sizeof(yes)))
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_bind(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
@ -514,7 +534,7 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
int fd;
|
||||
|
||||
/* Check for bad flags. */
|
||||
if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR))
|
||||
if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR | UV_UDP_LINUX_RECVERR))
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Cannot set IPv6-only mode on non-IPv6 socket. */
|
||||
@ -530,6 +550,12 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
handle->io_watcher.fd = fd;
|
||||
}
|
||||
|
||||
if (flags & UV_UDP_LINUX_RECVERR) {
|
||||
err = uv__set_recverr(fd, addr->sa_family);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (flags & UV_UDP_REUSEADDR) {
|
||||
err = uv__set_reuse(fd);
|
||||
if (err)
|
||||
|
25
deps/libuv/src/uv-common.c
vendored
25
deps/libuv/src/uv-common.c
vendored
@ -832,6 +832,25 @@ void uv_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv_read_start(uv_stream_t* stream,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb) {
|
||||
if (stream == NULL || alloc_cb == NULL || read_cb == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (stream->flags & UV_HANDLE_CLOSING)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (stream->flags & UV_HANDLE_READING)
|
||||
return UV_EALREADY;
|
||||
|
||||
if (!(stream->flags & UV_HANDLE_READABLE))
|
||||
return UV_ENOTCONN;
|
||||
|
||||
return uv__read_start(stream, alloc_cb, read_cb);
|
||||
}
|
||||
|
||||
|
||||
void uv_os_free_environ(uv_env_item_t* envitems, int count) {
|
||||
int i;
|
||||
|
||||
@ -853,7 +872,11 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */
|
||||
/* Also covers __clang__ and __INTEL_COMPILER. Disabled on Windows because
|
||||
* threads have already been forcibly terminated by the operating system
|
||||
* by the time destructors run, ergo, it's not safe to try to clean them up.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(_WIN32)
|
||||
__attribute__((destructor))
|
||||
#endif
|
||||
void uv_library_shutdown(void) {
|
||||
|
9
deps/libuv/src/uv-common.h
vendored
9
deps/libuv/src/uv-common.h
vendored
@ -68,6 +68,8 @@ extern int snprintf(char*, size_t, const char*, ...);
|
||||
#define uv__store_relaxed(p, v) do *p = v; while (0)
|
||||
#endif
|
||||
|
||||
#define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
|
||||
|
||||
/* Handle flags. Some flags are specific to Windows or UNIX. */
|
||||
enum {
|
||||
/* Used by all handles. */
|
||||
@ -106,8 +108,7 @@ enum {
|
||||
UV_HANDLE_TCP_KEEPALIVE = 0x02000000,
|
||||
UV_HANDLE_TCP_SINGLE_ACCEPT = 0x04000000,
|
||||
UV_HANDLE_TCP_ACCEPT_STATE_CHANGING = 0x08000000,
|
||||
UV_HANDLE_TCP_SOCKET_CLOSED = 0x10000000,
|
||||
UV_HANDLE_SHARED_TCP_SOCKET = 0x20000000,
|
||||
UV_HANDLE_SHARED_TCP_SOCKET = 0x10000000,
|
||||
|
||||
/* Only used by uv_udp_t handles. */
|
||||
UV_HANDLE_UDP_PROCESSING = 0x01000000,
|
||||
@ -136,6 +137,10 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
|
||||
|
||||
void uv__loop_close(uv_loop_t* loop);
|
||||
|
||||
int uv__read_start(uv_stream_t* stream,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
|
||||
int uv__tcp_bind(uv_tcp_t* tcp,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int addrlen,
|
||||
|
8
deps/libuv/src/win/atomicops-inl.h
vendored
8
deps/libuv/src/win/atomicops-inl.h
vendored
@ -39,10 +39,11 @@ static char INLINE uv__atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
#else /* GCC */
|
||||
#else /* GCC, Clang in mingw mode */
|
||||
|
||||
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
|
||||
static inline char uv__atomic_exchange_set(char volatile* target) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
|
||||
const char one = 1;
|
||||
char old_value;
|
||||
__asm__ __volatile__ ("lock xchgb %0, %1\n\t"
|
||||
@ -50,6 +51,9 @@ static inline char uv__atomic_exchange_set(char volatile* target) {
|
||||
: "0"(one), "m"(*target)
|
||||
: "memory");
|
||||
return old_value;
|
||||
#else
|
||||
return __sync_fetch_and_or(target, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
2
deps/libuv/src/win/error.c
vendored
2
deps/libuv/src/win/error.c
vendored
@ -105,7 +105,6 @@ int uv_translate_sys_error(int sys_errno) {
|
||||
case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
|
||||
case WSAEINVAL: return UV_EINVAL;
|
||||
case WSAEPFNOSUPPORT: return UV_EINVAL;
|
||||
case WSAESOCKTNOSUPPORT: return UV_EINVAL;
|
||||
case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
|
||||
case ERROR_BUS_RESET: return UV_EIO;
|
||||
case ERROR_CRC: return UV_EIO;
|
||||
@ -168,6 +167,7 @@ int uv_translate_sys_error(int sys_errno) {
|
||||
case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
|
||||
case ERROR_INVALID_FUNCTION: return UV_EISDIR;
|
||||
case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG;
|
||||
case WSAESOCKTNOSUPPORT: return UV_ESOCKTNOSUPPORT;
|
||||
default: return UV_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
51
deps/libuv/src/win/fs.c
vendored
51
deps/libuv/src/win/fs.c
vendored
@ -92,30 +92,24 @@
|
||||
return; \
|
||||
}
|
||||
|
||||
#define MILLIONu (1000U * 1000U)
|
||||
#define BILLIONu (1000U * 1000U * 1000U)
|
||||
#define MILLION ((int64_t) 1000 * 1000)
|
||||
#define BILLION ((int64_t) 1000 * 1000 * 1000)
|
||||
|
||||
#define FILETIME_TO_UINT(filetime) \
|
||||
(*((uint64_t*) &(filetime)) - (uint64_t) 116444736 * BILLIONu)
|
||||
|
||||
#define FILETIME_TO_TIME_T(filetime) \
|
||||
(FILETIME_TO_UINT(filetime) / (10u * MILLIONu))
|
||||
|
||||
#define FILETIME_TO_TIME_NS(filetime, secs) \
|
||||
((FILETIME_TO_UINT(filetime) - (secs * (uint64_t) 10 * MILLIONu)) * 100U)
|
||||
|
||||
#define FILETIME_TO_TIMESPEC(ts, filetime) \
|
||||
do { \
|
||||
(ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \
|
||||
(ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \
|
||||
} while(0)
|
||||
static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) {
|
||||
filetime -= 116444736 * BILLION;
|
||||
ts->tv_sec = (long) (filetime / (10 * MILLION));
|
||||
ts->tv_nsec = (long) ((filetime - ts->tv_sec * 10 * MILLION) * 100U);
|
||||
if (ts->tv_nsec < 0) {
|
||||
ts->tv_sec -= 1;
|
||||
ts->tv_nsec += 1e9;
|
||||
}
|
||||
}
|
||||
|
||||
#define TIME_T_TO_FILETIME(time, filetime_ptr) \
|
||||
do { \
|
||||
uint64_t bigtime = ((uint64_t) ((time) * (uint64_t) 10 * MILLIONu)) + \
|
||||
(uint64_t) 116444736 * BILLIONu; \
|
||||
(filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \
|
||||
(filetime_ptr)->dwHighDateTime = bigtime >> 32; \
|
||||
int64_t bigtime = ((time) * 10 * MILLION + 116444736 * BILLION); \
|
||||
(filetime_ptr)->dwLowDateTime = (uint64_t) bigtime & 0xFFFFFFFF; \
|
||||
(filetime_ptr)->dwHighDateTime = (uint64_t) bigtime >> 32; \
|
||||
} while(0)
|
||||
|
||||
#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/')
|
||||
@ -1224,7 +1218,8 @@ void fs__mkdir(uv_fs_t* req) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
} else {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
if (req->sys_errno_ == ERROR_INVALID_NAME)
|
||||
if (req->sys_errno_ == ERROR_INVALID_NAME ||
|
||||
req->sys_errno_ == ERROR_DIRECTORY)
|
||||
req->result = UV_EINVAL;
|
||||
}
|
||||
}
|
||||
@ -1243,7 +1238,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
|
||||
uint64_t v;
|
||||
char* path;
|
||||
|
||||
path = req->path;
|
||||
path = (char*)req->path;
|
||||
len = wcslen(req->file.pathw);
|
||||
ep = req->file.pathw + len;
|
||||
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
|
||||
@ -1791,10 +1786,14 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
|
||||
statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
|
||||
((_S_IREAD | _S_IWRITE) >> 6);
|
||||
|
||||
FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime);
|
||||
FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime);
|
||||
FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime);
|
||||
FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime);
|
||||
uv__filetime_to_timespec(&statbuf->st_atim,
|
||||
file_info.BasicInformation.LastAccessTime.QuadPart);
|
||||
uv__filetime_to_timespec(&statbuf->st_ctim,
|
||||
file_info.BasicInformation.ChangeTime.QuadPart);
|
||||
uv__filetime_to_timespec(&statbuf->st_mtim,
|
||||
file_info.BasicInformation.LastWriteTime.QuadPart);
|
||||
uv__filetime_to_timespec(&statbuf->st_birthtim,
|
||||
file_info.BasicInformation.CreationTime.QuadPart);
|
||||
|
||||
statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart;
|
||||
|
||||
|
4
deps/libuv/src/win/internal.h
vendored
4
deps/libuv/src/win/internal.h
vendored
@ -115,8 +115,8 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
|
||||
/*
|
||||
* Pipes
|
||||
*/
|
||||
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
char* name, size_t nameSize);
|
||||
int uv__create_stdio_pipe_pair(uv_loop_t* loop,
|
||||
uv_pipe_t* parent_pipe, HANDLE* child_pipe_ptr, unsigned int flags);
|
||||
|
||||
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
|
||||
int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
|
||||
|
236
deps/libuv/src/win/pipe.c
vendored
236
deps/libuv/src/win/pipe.c
vendored
@ -202,17 +202,17 @@ static void close_pipe(uv_pipe_t* pipe) {
|
||||
}
|
||||
|
||||
|
||||
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
char* name, size_t nameSize) {
|
||||
static int uv__pipe_server(
|
||||
HANDLE* pipeHandle_ptr, DWORD access,
|
||||
char* name, size_t nameSize, char* random) {
|
||||
HANDLE pipeHandle;
|
||||
int err;
|
||||
char* ptr = (char*)handle;
|
||||
|
||||
for (;;) {
|
||||
uv_unique_pipe_name(ptr, name, nameSize);
|
||||
uv_unique_pipe_name(random, name, nameSize);
|
||||
|
||||
pipeHandle = CreateNamedPipeA(name,
|
||||
access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
|
||||
access | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
|
||||
NULL);
|
||||
|
||||
@ -226,20 +226,11 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Pipe name collision. Increment the pointer and try again. */
|
||||
ptr++;
|
||||
/* Pipe name collision. Increment the random number and try again. */
|
||||
random++;
|
||||
}
|
||||
|
||||
if (CreateIoCompletionPort(pipeHandle,
|
||||
loop->iocp,
|
||||
(ULONG_PTR)handle,
|
||||
0) == NULL) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
uv_pipe_connection_init(handle);
|
||||
handle->handle = pipeHandle;
|
||||
*pipeHandle_ptr = pipeHandle;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -251,6 +242,214 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
}
|
||||
|
||||
|
||||
static int uv__create_pipe_pair(
|
||||
HANDLE* server_pipe_ptr, HANDLE* client_pipe_ptr,
|
||||
unsigned int server_flags, unsigned int client_flags,
|
||||
int inherit_client, char* random) {
|
||||
/* allowed flags are: UV_READABLE_PIPE | UV_WRITABLE_PIPE | UV_NONBLOCK_PIPE */
|
||||
char pipe_name[64];
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
DWORD server_access;
|
||||
DWORD client_access;
|
||||
HANDLE server_pipe;
|
||||
HANDLE client_pipe;
|
||||
int err;
|
||||
|
||||
server_pipe = INVALID_HANDLE_VALUE;
|
||||
client_pipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
server_access = 0;
|
||||
if (server_flags & UV_READABLE_PIPE)
|
||||
server_access |= PIPE_ACCESS_INBOUND;
|
||||
if (server_flags & UV_WRITABLE_PIPE)
|
||||
server_access |= PIPE_ACCESS_OUTBOUND;
|
||||
if (server_flags & UV_NONBLOCK_PIPE)
|
||||
server_access |= FILE_FLAG_OVERLAPPED;
|
||||
server_access |= WRITE_DAC;
|
||||
|
||||
client_access = 0;
|
||||
if (client_flags & UV_READABLE_PIPE)
|
||||
client_access |= GENERIC_READ;
|
||||
else
|
||||
client_access |= FILE_READ_ATTRIBUTES;
|
||||
if (client_flags & UV_WRITABLE_PIPE)
|
||||
client_access |= GENERIC_WRITE;
|
||||
else
|
||||
client_access |= FILE_WRITE_ATTRIBUTES;
|
||||
client_access |= WRITE_DAC;
|
||||
|
||||
/* Create server pipe handle. */
|
||||
err = uv__pipe_server(&server_pipe,
|
||||
server_access,
|
||||
pipe_name,
|
||||
sizeof(pipe_name),
|
||||
random);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
/* Create client pipe handle. */
|
||||
sa.nLength = sizeof sa;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = inherit_client;
|
||||
|
||||
client_pipe = CreateFileA(pipe_name,
|
||||
client_access,
|
||||
0,
|
||||
&sa,
|
||||
OPEN_EXISTING,
|
||||
(client_flags & UV_NONBLOCK_PIPE) ? FILE_FLAG_OVERLAPPED : 0,
|
||||
NULL);
|
||||
if (client_pipe == INVALID_HANDLE_VALUE) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Validate that the pipe was opened in the right mode. */
|
||||
{
|
||||
DWORD mode;
|
||||
BOOL r;
|
||||
r = GetNamedPipeHandleState(client_pipe, &mode, NULL, NULL, NULL, NULL, 0);
|
||||
if (r == TRUE) {
|
||||
assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
|
||||
} else {
|
||||
fprintf(stderr, "libuv assertion failure: GetNamedPipeHandleState failed\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do a blocking ConnectNamedPipe. This should not block because we have
|
||||
* both ends of the pipe created. */
|
||||
if (!ConnectNamedPipe(server_pipe, NULL)) {
|
||||
if (GetLastError() != ERROR_PIPE_CONNECTED) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
*client_pipe_ptr = client_pipe;
|
||||
*server_pipe_ptr = server_pipe;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (server_pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(server_pipe);
|
||||
|
||||
if (client_pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(client_pipe);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int uv_pipe(uv_file fds[2], int read_flags, int write_flags) {
|
||||
uv_file temp[2];
|
||||
int err;
|
||||
HANDLE readh;
|
||||
HANDLE writeh;
|
||||
|
||||
/* Make the server side the inbound (read) end, */
|
||||
/* so that both ends will have FILE_READ_ATTRIBUTES permission. */
|
||||
/* TODO: better source of local randomness than &fds? */
|
||||
read_flags |= UV_READABLE_PIPE;
|
||||
write_flags |= UV_WRITABLE_PIPE;
|
||||
err = uv__create_pipe_pair(&readh, &writeh, read_flags, write_flags, 0, (char*) &fds[0]);
|
||||
if (err != 0)
|
||||
return err;
|
||||
temp[0] = _open_osfhandle((intptr_t) readh, 0);
|
||||
if (temp[0] == -1) {
|
||||
if (errno == UV_EMFILE)
|
||||
err = UV_EMFILE;
|
||||
else
|
||||
err = UV_UNKNOWN;
|
||||
CloseHandle(readh);
|
||||
CloseHandle(writeh);
|
||||
return err;
|
||||
}
|
||||
temp[1] = _open_osfhandle((intptr_t) writeh, 0);
|
||||
if (temp[1] == -1) {
|
||||
if (errno == UV_EMFILE)
|
||||
err = UV_EMFILE;
|
||||
else
|
||||
err = UV_UNKNOWN;
|
||||
_close(temp[0]);
|
||||
CloseHandle(writeh);
|
||||
return err;
|
||||
}
|
||||
fds[0] = temp[0];
|
||||
fds[1] = temp[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__create_stdio_pipe_pair(uv_loop_t* loop,
|
||||
uv_pipe_t* parent_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
|
||||
/* The parent_pipe is always the server_pipe and kept by libuv.
|
||||
* The child_pipe is always the client_pipe and is passed to the child.
|
||||
* The flags are specified with respect to their usage in the child. */
|
||||
HANDLE server_pipe;
|
||||
HANDLE client_pipe;
|
||||
unsigned int server_flags;
|
||||
unsigned int client_flags;
|
||||
int err;
|
||||
|
||||
server_pipe = INVALID_HANDLE_VALUE;
|
||||
client_pipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
server_flags = 0;
|
||||
client_flags = 0;
|
||||
if (flags & UV_READABLE_PIPE) {
|
||||
/* The server needs inbound (read) access too, otherwise CreateNamedPipe()
|
||||
* won't give us the FILE_READ_ATTRIBUTES permission. We need that to probe
|
||||
* the state of the write buffer when we're trying to shutdown the pipe. */
|
||||
server_flags |= UV_READABLE_PIPE | UV_WRITABLE_PIPE;
|
||||
client_flags |= UV_READABLE_PIPE;
|
||||
}
|
||||
if (flags & UV_WRITABLE_PIPE) {
|
||||
server_flags |= UV_READABLE_PIPE;
|
||||
client_flags |= UV_WRITABLE_PIPE;
|
||||
}
|
||||
server_flags |= UV_NONBLOCK_PIPE;
|
||||
if (flags & UV_NONBLOCK_PIPE || parent_pipe->ipc) {
|
||||
client_flags |= UV_NONBLOCK_PIPE;
|
||||
}
|
||||
|
||||
err = uv__create_pipe_pair(&server_pipe, &client_pipe,
|
||||
server_flags, client_flags, 1, (char*) server_pipe);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
if (CreateIoCompletionPort(server_pipe,
|
||||
loop->iocp,
|
||||
(ULONG_PTR) parent_pipe,
|
||||
0) == NULL) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
uv_pipe_connection_init(parent_pipe);
|
||||
parent_pipe->handle = server_pipe;
|
||||
*child_pipe_ptr = client_pipe;
|
||||
|
||||
/* The server end is now readable and/or writable. */
|
||||
if (flags & UV_READABLE_PIPE)
|
||||
parent_pipe->flags |= UV_HANDLE_WRITABLE;
|
||||
if (flags & UV_WRITABLE_PIPE)
|
||||
parent_pipe->flags |= UV_HANDLE_READABLE;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (server_pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(server_pipe);
|
||||
|
||||
if (client_pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(client_pipe);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int uv_set_pipe_handle(uv_loop_t* loop,
|
||||
uv_pipe_t* handle,
|
||||
HANDLE pipeHandle,
|
||||
@ -712,9 +911,8 @@ error:
|
||||
handle->name = NULL;
|
||||
}
|
||||
|
||||
if (pipeHandle != INVALID_HANDLE_VALUE) {
|
||||
if (pipeHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pipeHandle);
|
||||
}
|
||||
|
||||
/* Make this req pending reporting an error. */
|
||||
SET_REQ_ERROR(req, err);
|
||||
|
3
deps/libuv/src/win/poll.c
vendored
3
deps/libuv/src/win/poll.c
vendored
@ -488,7 +488,8 @@ static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) {
|
||||
|
||||
assert(handle->type == UV_POLL);
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSING));
|
||||
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
|
||||
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
|
||||
UV_PRIORITIZED)) == 0);
|
||||
|
||||
handle->events = events;
|
||||
handle->poll_cb = cb;
|
||||
|
96
deps/libuv/src/win/process-stdio.c
vendored
96
deps/libuv/src/win/process-stdio.c
vendored
@ -95,102 +95,6 @@ void uv_disable_stdio_inheritance(void) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
|
||||
uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
|
||||
char pipe_name[64];
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
DWORD server_access = 0;
|
||||
DWORD client_access = 0;
|
||||
HANDLE child_pipe = INVALID_HANDLE_VALUE;
|
||||
int err;
|
||||
int overlap;
|
||||
|
||||
if (flags & UV_READABLE_PIPE) {
|
||||
/* The server needs inbound access too, otherwise CreateNamedPipe() won't
|
||||
* give us the FILE_READ_ATTRIBUTES permission. We need that to probe the
|
||||
* state of the write buffer when we're trying to shutdown the pipe. */
|
||||
server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
|
||||
client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
|
||||
}
|
||||
if (flags & UV_WRITABLE_PIPE) {
|
||||
server_access |= PIPE_ACCESS_INBOUND;
|
||||
client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
|
||||
}
|
||||
|
||||
/* Create server pipe handle. */
|
||||
err = uv_stdio_pipe_server(loop,
|
||||
server_pipe,
|
||||
server_access,
|
||||
pipe_name,
|
||||
sizeof(pipe_name));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
/* Create child pipe handle. */
|
||||
sa.nLength = sizeof sa;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
overlap = server_pipe->ipc || (flags & UV_OVERLAPPED_PIPE);
|
||||
child_pipe = CreateFileA(pipe_name,
|
||||
client_access,
|
||||
0,
|
||||
&sa,
|
||||
OPEN_EXISTING,
|
||||
overlap ? FILE_FLAG_OVERLAPPED : 0,
|
||||
NULL);
|
||||
if (child_pipe == INVALID_HANDLE_VALUE) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Validate that the pipe was opened in the right mode. */
|
||||
{
|
||||
DWORD mode;
|
||||
BOOL r = GetNamedPipeHandleState(child_pipe,
|
||||
&mode,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
assert(r == TRUE);
|
||||
assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do a blocking ConnectNamedPipe. This should not block because we have both
|
||||
* ends of the pipe created. */
|
||||
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
|
||||
if (GetLastError() != ERROR_PIPE_CONNECTED) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* The server end is now readable and/or writable. */
|
||||
if (flags & UV_READABLE_PIPE)
|
||||
server_pipe->flags |= UV_HANDLE_WRITABLE;
|
||||
if (flags & UV_WRITABLE_PIPE)
|
||||
server_pipe->flags |= UV_HANDLE_READABLE;
|
||||
|
||||
*child_pipe_ptr = child_pipe;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (server_pipe->handle != INVALID_HANDLE_VALUE) {
|
||||
uv_pipe_cleanup(loop, server_pipe);
|
||||
}
|
||||
|
||||
if (child_pipe != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(child_pipe);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
|
||||
HANDLE current_process;
|
||||
|
||||
|
2
deps/libuv/src/win/process.c
vendored
2
deps/libuv/src/win/process.c
vendored
@ -642,7 +642,7 @@ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) {
|
||||
assert(r==nb);
|
||||
B[nb] = L'\0';
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
wchar_t AA = *A++;
|
||||
wchar_t BB = *B++;
|
||||
if (AA < BB) {
|
||||
|
21
deps/libuv/src/win/stream.c
vendored
21
deps/libuv/src/win/stream.c
vendored
@ -65,18 +65,11 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
|
||||
}
|
||||
|
||||
|
||||
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
|
||||
int uv__read_start(uv_stream_t* handle,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb) {
|
||||
int err;
|
||||
|
||||
if (handle->flags & UV_HANDLE_READING) {
|
||||
return UV_EALREADY;
|
||||
}
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_READABLE)) {
|
||||
return UV_ENOTCONN;
|
||||
}
|
||||
|
||||
err = ERROR_INVALID_PARAMETER;
|
||||
switch (handle->type) {
|
||||
case UV_TCP:
|
||||
@ -195,6 +188,16 @@ int uv_try_write(uv_stream_t* stream,
|
||||
}
|
||||
|
||||
|
||||
int uv_try_write2(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
if (send_handle != NULL)
|
||||
return UV_EAGAIN;
|
||||
return uv_try_write(stream, bufs, nbufs);
|
||||
}
|
||||
|
||||
|
||||
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
|
||||
|
258
deps/libuv/src/win/tcp.c
vendored
258
deps/libuv/src/win/tcp.c
vendored
@ -236,12 +236,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING &&
|
||||
handle->reqs_pending == 0) {
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
||||
closesocket(handle->socket);
|
||||
handle->socket = INVALID_SOCKET;
|
||||
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||
}
|
||||
assert(handle->socket == INVALID_SOCKET);
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
|
||||
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
||||
@ -599,6 +594,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
}
|
||||
}
|
||||
|
||||
/* If this flag is set, we already made this listen call in xfer. */
|
||||
if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
|
||||
listen(handle->socket, backlog) == SOCKET_ERROR) {
|
||||
return WSAGetLastError();
|
||||
@ -769,7 +765,7 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) {
|
||||
}
|
||||
|
||||
// Check if Windows version is 10.0.16299 or later
|
||||
static int uv__is_fast_loopback_fail_supported() {
|
||||
static int uv__is_fast_loopback_fail_supported(void) {
|
||||
OSVERSIONINFOW os_info;
|
||||
if (!pRtlGetVersion)
|
||||
return 0;
|
||||
@ -800,9 +796,8 @@ static int uv_tcp_try_connect(uv_connect_t* req,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (handle->delayed_error) {
|
||||
return handle->delayed_error;
|
||||
}
|
||||
if (handle->delayed_error != 0)
|
||||
goto out;
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
||||
if (addrlen == sizeof(uv_addr_ip4_any_)) {
|
||||
@ -815,8 +810,8 @@ static int uv_tcp_try_connect(uv_connect_t* req,
|
||||
err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0);
|
||||
if (err)
|
||||
return err;
|
||||
if (handle->delayed_error)
|
||||
return handle->delayed_error;
|
||||
if (handle->delayed_error != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!handle->tcp.conn.func_connectex) {
|
||||
@ -844,11 +839,21 @@ static int uv_tcp_try_connect(uv_connect_t* req,
|
||||
NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
UV_REQ_INIT(req, UV_CONNECT);
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
req->cb = cb;
|
||||
memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
|
||||
|
||||
if (handle->delayed_error != 0) {
|
||||
/* Process the req without IOCP. */
|
||||
handle->reqs_pending++;
|
||||
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||
uv_insert_pending_req(loop, (uv_req_t*)req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
success = handle->tcp.conn.func_connectex(handle->socket,
|
||||
(const struct sockaddr*) &converted,
|
||||
addrlen,
|
||||
@ -1015,6 +1020,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
*/
|
||||
err = WSAECONNRESET;
|
||||
}
|
||||
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
|
||||
handle->read_cb((uv_stream_t*)handle,
|
||||
uv_translate_sys_error(err),
|
||||
@ -1096,6 +1102,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
* Unix. */
|
||||
err = WSAECONNRESET;
|
||||
}
|
||||
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
|
||||
handle->read_cb((uv_stream_t*)handle,
|
||||
uv_translate_sys_error(err),
|
||||
@ -1149,10 +1156,15 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
}
|
||||
|
||||
handle->stream.conn.write_reqs_pending--;
|
||||
if (handle->stream.conn.shutdown_req != NULL &&
|
||||
handle->stream.conn.write_reqs_pending == 0) {
|
||||
if (handle->stream.conn.write_reqs_pending == 0) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
closesocket(handle->socket);
|
||||
handle->socket = INVALID_SOCKET;
|
||||
}
|
||||
if (handle->stream.conn.shutdown_req != NULL) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
}
|
||||
}
|
||||
|
||||
DECREASE_PENDING_REQ_COUNT(handle);
|
||||
}
|
||||
@ -1215,7 +1227,14 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||
|
||||
err = 0;
|
||||
if (REQ_SUCCESS(req)) {
|
||||
if (handle->delayed_error) {
|
||||
/* To smooth over the differences between unixes errors that
|
||||
* were reported synchronously on the first connect can be delayed
|
||||
* until the next tick--which is now.
|
||||
*/
|
||||
err = handle->delayed_error;
|
||||
handle->delayed_error = 0;
|
||||
} else if (REQ_SUCCESS(req)) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
/* use UV_ECANCELED for consistency with Unix */
|
||||
err = ERROR_OPERATION_ABORTED;
|
||||
@ -1320,7 +1339,7 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
|
||||
if (handle->socket != INVALID_SOCKET) {
|
||||
err = uv__tcp_nodelay(handle, handle->socket, enable);
|
||||
if (err)
|
||||
return err;
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
@ -1339,7 +1358,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
|
||||
if (handle->socket != INVALID_SOCKET) {
|
||||
err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
|
||||
if (err)
|
||||
return err;
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
@ -1386,9 +1405,24 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
|
||||
}
|
||||
|
||||
|
||||
static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
|
||||
SOCKET socket = tcp->socket;
|
||||
static void uv_tcp_try_cancel_reqs(uv_tcp_t* tcp) {
|
||||
SOCKET socket;
|
||||
int non_ifs_lsp;
|
||||
int reading;
|
||||
int writing;
|
||||
|
||||
socket = tcp->socket;
|
||||
reading = tcp->flags & UV_HANDLE_READING;
|
||||
writing = tcp->stream.conn.write_reqs_pending > 0;
|
||||
if (!reading && !writing)
|
||||
return;
|
||||
|
||||
/* TODO: in libuv v2, keep explicit track of write_reqs, so we can cancel
|
||||
* them each explicitly with CancelIoEx (like unix). */
|
||||
if (reading)
|
||||
CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped);
|
||||
if (writing)
|
||||
CancelIo((HANDLE) socket);
|
||||
|
||||
/* Check if we have any non-IFS LSPs stacked on top of TCP */
|
||||
non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
|
||||
@ -1408,71 +1442,41 @@ static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
|
||||
NULL,
|
||||
NULL) != 0) {
|
||||
/* Failed. We can't do CancelIo. */
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(socket != 0 && socket != INVALID_SOCKET);
|
||||
|
||||
if (!CancelIo((HANDLE) socket)) {
|
||||
return GetLastError();
|
||||
if (socket != tcp->socket) {
|
||||
if (reading)
|
||||
CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped);
|
||||
if (writing)
|
||||
CancelIo((HANDLE) socket);
|
||||
}
|
||||
|
||||
/* It worked. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||
int close_socket = 1;
|
||||
|
||||
if (tcp->flags & UV_HANDLE_READ_PENDING) {
|
||||
/* In order for winsock to do a graceful close there must not be any any
|
||||
* pending reads, or the socket must be shut down for writing */
|
||||
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
|
||||
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
|
||||
shutdown(tcp->socket, SD_SEND);
|
||||
|
||||
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
|
||||
/* In case of a shared socket, we try to cancel all outstanding I/O,. If
|
||||
* that works, don't close the socket yet - wait for the read req to
|
||||
* return and close the socket in uv_tcp_endgame. */
|
||||
close_socket = 0;
|
||||
|
||||
} else {
|
||||
/* When cancelling isn't possible - which could happen when an LSP is
|
||||
* present on an old Windows version, we will have to close the socket
|
||||
* with a read pending. That is not nice because trailing sent bytes may
|
||||
* not make it to the other side. */
|
||||
if (tcp->flags & UV_HANDLE_CONNECTION) {
|
||||
uv_tcp_try_cancel_reqs(tcp);
|
||||
if (tcp->flags & UV_HANDLE_READING) {
|
||||
uv_read_stop((uv_stream_t*) tcp);
|
||||
}
|
||||
|
||||
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
|
||||
tcp->tcp.serv.accept_reqs != NULL) {
|
||||
/* Under normal circumstances closesocket() will ensure that all pending
|
||||
* accept reqs are canceled. However, when the socket is shared the
|
||||
* presence of another reference to the socket in another process will keep
|
||||
* the accept reqs going, so we have to ensure that these are canceled. */
|
||||
if (uv_tcp_try_cancel_io(tcp) != 0) {
|
||||
/* When cancellation is not possible, there is another option: we can
|
||||
* close the incoming sockets, which will also cancel the accept
|
||||
* operations. However this is not cool because we might inadvertently
|
||||
* close a socket that just accepted a new connection, which will cause
|
||||
* the connection to be aborted. */
|
||||
} else {
|
||||
if (tcp->tcp.serv.accept_reqs != NULL) {
|
||||
/* First close the incoming sockets to cancel the accept operations before
|
||||
* we free their resources. */
|
||||
unsigned int i;
|
||||
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
|
||||
uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
|
||||
if (req->accept_socket != INVALID_SOCKET &&
|
||||
!HasOverlappedIoCompleted(&req->u.io.overlapped)) {
|
||||
if (req->accept_socket != INVALID_SOCKET) {
|
||||
closesocket(req->accept_socket);
|
||||
req->accept_socket = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tcp->flags & UV_HANDLE_READING) {
|
||||
tcp->flags &= ~UV_HANDLE_READING;
|
||||
DECREASE_ACTIVE_COUNT(loop, tcp);
|
||||
assert(!(tcp->flags & UV_HANDLE_READING));
|
||||
}
|
||||
|
||||
if (tcp->flags & UV_HANDLE_LISTENING) {
|
||||
@ -1480,10 +1484,15 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||
DECREASE_ACTIVE_COUNT(loop, tcp);
|
||||
}
|
||||
|
||||
if (close_socket) {
|
||||
/* If any overlapped req failed to cancel, calling `closesocket` now would
|
||||
* cause Win32 to send an RST packet. Try to avoid that for writes, if
|
||||
* possibly applicable, by waiting to process the completion notifications
|
||||
* first (which typically should be cancellations). There's not much we can
|
||||
* do about canceled reads, which also will generate an RST packet. */
|
||||
if (!(tcp->flags & UV_HANDLE_CONNECTION) ||
|
||||
tcp->stream.conn.write_reqs_pending == 0) {
|
||||
closesocket(tcp->socket);
|
||||
tcp->socket = INVALID_SOCKET;
|
||||
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||
}
|
||||
|
||||
tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
@ -1571,3 +1580,118 @@ int uv__tcp_connect(uv_connect_t* req,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef WSA_FLAG_NO_HANDLE_INHERIT
|
||||
/* Added in Windows 7 SP1. Specify this to avoid race conditions, */
|
||||
/* but also manually clear the inherit flag in case this failed. */
|
||||
#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
|
||||
#endif
|
||||
|
||||
int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) {
|
||||
SOCKET server = INVALID_SOCKET;
|
||||
SOCKET client0 = INVALID_SOCKET;
|
||||
SOCKET client1 = INVALID_SOCKET;
|
||||
SOCKADDR_IN name;
|
||||
LPFN_ACCEPTEX func_acceptex;
|
||||
WSAOVERLAPPED overlap;
|
||||
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32];
|
||||
int namelen;
|
||||
int err;
|
||||
DWORD bytes;
|
||||
DWORD flags;
|
||||
DWORD client0_flags = WSA_FLAG_NO_HANDLE_INHERIT;
|
||||
DWORD client1_flags = WSA_FLAG_NO_HANDLE_INHERIT;
|
||||
|
||||
if (flags0 & UV_NONBLOCK_PIPE)
|
||||
client0_flags |= WSA_FLAG_OVERLAPPED;
|
||||
if (flags1 & UV_NONBLOCK_PIPE)
|
||||
client1_flags |= WSA_FLAG_OVERLAPPED;
|
||||
|
||||
server = WSASocketW(AF_INET, type, protocol, NULL, 0,
|
||||
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
|
||||
if (server == INVALID_SOCKET)
|
||||
goto wsaerror;
|
||||
if (!SetHandleInformation((HANDLE) server, HANDLE_FLAG_INHERIT, 0))
|
||||
goto error;
|
||||
name.sin_family = AF_INET;
|
||||
name.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
name.sin_port = 0;
|
||||
if (bind(server, (SOCKADDR*) &name, sizeof(name)) != 0)
|
||||
goto wsaerror;
|
||||
if (listen(server, 1) != 0)
|
||||
goto wsaerror;
|
||||
namelen = sizeof(name);
|
||||
if (getsockname(server, (SOCKADDR*) &name, &namelen) != 0)
|
||||
goto wsaerror;
|
||||
client0 = WSASocketW(AF_INET, type, protocol, NULL, 0, client0_flags);
|
||||
if (client0 == INVALID_SOCKET)
|
||||
goto wsaerror;
|
||||
if (!SetHandleInformation((HANDLE) client0, HANDLE_FLAG_INHERIT, 0))
|
||||
goto error;
|
||||
if (connect(client0, (SOCKADDR*) &name, sizeof(name)) != 0)
|
||||
goto wsaerror;
|
||||
client1 = WSASocketW(AF_INET, type, protocol, NULL, 0, client1_flags);
|
||||
if (client1 == INVALID_SOCKET)
|
||||
goto wsaerror;
|
||||
if (!SetHandleInformation((HANDLE) client1, HANDLE_FLAG_INHERIT, 0))
|
||||
goto error;
|
||||
if (!uv_get_acceptex_function(server, &func_acceptex)) {
|
||||
err = WSAEAFNOSUPPORT;
|
||||
goto cleanup;
|
||||
}
|
||||
memset(&overlap, 0, sizeof(overlap));
|
||||
if (!func_acceptex(server,
|
||||
client1,
|
||||
accept_buffer,
|
||||
0,
|
||||
sizeof(struct sockaddr_storage),
|
||||
sizeof(struct sockaddr_storage),
|
||||
&bytes,
|
||||
&overlap)) {
|
||||
err = WSAGetLastError();
|
||||
if (err == ERROR_IO_PENDING) {
|
||||
/* Result should complete immediately, since we already called connect,
|
||||
* but emperically, we sometimes have to poll the kernel a couple times
|
||||
* until it notices that. */
|
||||
while (!WSAGetOverlappedResult(client1, &overlap, &bytes, FALSE, &flags)) {
|
||||
err = WSAGetLastError();
|
||||
if (err != WSA_IO_INCOMPLETE)
|
||||
goto cleanup;
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
else {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (setsockopt(client1, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
|
||||
(char*) &server, sizeof(server)) != 0) {
|
||||
goto wsaerror;
|
||||
}
|
||||
|
||||
closesocket(server);
|
||||
|
||||
fds[0] = client0;
|
||||
fds[1] = client1;
|
||||
|
||||
return 0;
|
||||
|
||||
wsaerror:
|
||||
err = WSAGetLastError();
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
err = GetLastError();
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
if (server != INVALID_SOCKET)
|
||||
closesocket(server);
|
||||
if (client0 != INVALID_SOCKET)
|
||||
closesocket(client0);
|
||||
if (client1 != INVALID_SOCKET)
|
||||
closesocket(client1);
|
||||
|
||||
assert(err);
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
4
deps/libuv/src/win/udp.c
vendored
4
deps/libuv/src/win/udp.c
vendored
@ -284,7 +284,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
|
||||
handle->flags &= ~UV_HANDLE_ZERO_READ;
|
||||
|
||||
handle->recv_buffer = uv_buf_init(NULL, 0);
|
||||
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer);
|
||||
handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &handle->recv_buffer);
|
||||
if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) {
|
||||
handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0);
|
||||
return;
|
||||
@ -501,7 +501,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
|
||||
/* Do a nonblocking receive.
|
||||
* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
|
||||
buf = uv_buf_init(NULL, 0);
|
||||
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
|
||||
handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf);
|
||||
if (buf.base == NULL || buf.len == 0) {
|
||||
handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
|
||||
goto done;
|
||||
|
17
deps/libuv/src/win/util.c
vendored
17
deps/libuv/src/win/util.c
vendored
@ -1664,26 +1664,33 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
char buf[UV_MAXHOSTNAMESIZE];
|
||||
WCHAR buf[UV_MAXHOSTNAMESIZE];
|
||||
size_t len;
|
||||
char* utf8_str;
|
||||
int convert_result;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
uv__once_init(); /* Initialize winsock */
|
||||
|
||||
if (gethostname(buf, sizeof(buf)) != 0)
|
||||
if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
|
||||
len = strlen(buf);
|
||||
convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str);
|
||||
|
||||
if (convert_result != 0)
|
||||
return convert_result;
|
||||
|
||||
len = strlen(utf8_str);
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
uv__free(utf8_str);
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, buf, len + 1);
|
||||
memcpy(buffer, utf8_str, len + 1);
|
||||
uv__free(utf8_str);
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
2
deps/libuv/test/benchmark-async-pummel.c
vendored
2
deps/libuv/test/benchmark-async-pummel.c
vendored
@ -68,7 +68,7 @@ static int test_async_pummel(int nthreads) {
|
||||
int i;
|
||||
|
||||
tids = calloc(nthreads, sizeof(tids[0]));
|
||||
ASSERT(tids != NULL);
|
||||
ASSERT_NOT_NULL(tids);
|
||||
|
||||
ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb));
|
||||
ACCESS_ONCE(const char*, handle.data) = running;
|
||||
|
2
deps/libuv/test/benchmark-async.c
vendored
2
deps/libuv/test/benchmark-async.c
vendored
@ -79,7 +79,7 @@ static int test_async(int nthreads) {
|
||||
int i;
|
||||
|
||||
threads = calloc(nthreads, sizeof(threads[0]));
|
||||
ASSERT(threads != NULL);
|
||||
ASSERT_NOT_NULL(threads);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
ctx = threads + i;
|
||||
|
2
deps/libuv/test/benchmark-million-async.c
vendored
2
deps/libuv/test/benchmark-million-async.c
vendored
@ -86,7 +86,7 @@ BENCHMARK_IMPL(million_async) {
|
||||
timeout = 5000;
|
||||
|
||||
container = malloc(sizeof(*container));
|
||||
ASSERT(container != NULL);
|
||||
ASSERT_NOT_NULL(container);
|
||||
container->async_events = 0;
|
||||
container->handles_seen = 0;
|
||||
|
||||
|
2
deps/libuv/test/benchmark-million-timers.c
vendored
2
deps/libuv/test/benchmark-million-timers.c
vendored
@ -49,7 +49,7 @@ BENCHMARK_IMPL(million_timers) {
|
||||
int i;
|
||||
|
||||
timers = malloc(NUM_TIMERS * sizeof(timers[0]));
|
||||
ASSERT(timers != NULL);
|
||||
ASSERT_NOT_NULL(timers);
|
||||
|
||||
loop = uv_default_loop();
|
||||
timeout = 0;
|
||||
|
8
deps/libuv/test/benchmark-multi-accept.c
vendored
8
deps/libuv/test/benchmark-multi-accept.c
vendored
@ -114,7 +114,7 @@ static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) {
|
||||
buf = uv_buf_init("PING", 4);
|
||||
sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe);
|
||||
pc = calloc(1, sizeof(*pc));
|
||||
ASSERT(pc != NULL);
|
||||
ASSERT_NOT_NULL(pc);
|
||||
|
||||
if (ipc_pipe->type == UV_TCP)
|
||||
ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle));
|
||||
@ -295,7 +295,7 @@ static void sv_connection_cb(uv_stream_t* server_handle, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
storage = malloc(sizeof(*storage));
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT_NOT_NULL(storage);
|
||||
|
||||
if (server_handle->type == UV_TCP)
|
||||
ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage));
|
||||
@ -372,8 +372,8 @@ static int test_tcp(unsigned int num_servers, unsigned int num_clients) {
|
||||
|
||||
servers = calloc(num_servers, sizeof(servers[0]));
|
||||
clients = calloc(num_clients, sizeof(clients[0]));
|
||||
ASSERT(servers != NULL);
|
||||
ASSERT(clients != NULL);
|
||||
ASSERT_NOT_NULL(servers);
|
||||
ASSERT_NOT_NULL(clients);
|
||||
|
||||
/* We're making the assumption here that from the perspective of the
|
||||
* OS scheduler, threads are functionally equivalent to and interchangeable
|
||||
|
8
deps/libuv/test/benchmark-pound.c
vendored
8
deps/libuv/test/benchmark-pound.c
vendored
@ -114,11 +114,11 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
|
||||
conn = (conn_rec*)req->data;
|
||||
ASSERT(conn != NULL);
|
||||
ASSERT_NOT_NULL(conn);
|
||||
|
||||
#if DEBUG
|
||||
printf("connect_cb %d\n", conn->i);
|
||||
@ -137,7 +137,7 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
|
||||
static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
|
||||
|
||||
ASSERT(stream != NULL);
|
||||
ASSERT_NOT_NULL(stream);
|
||||
|
||||
#if DEBUG
|
||||
printf("read_cb %d\n", p->i);
|
||||
@ -161,7 +161,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
conn_rec* p = (conn_rec*)handle->data;
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
closed_streams++;
|
||||
|
||||
#if DEBUG
|
||||
|
2
deps/libuv/test/benchmark-pump.c
vendored
2
deps/libuv/test/benchmark-pump.c
vendored
@ -390,6 +390,7 @@ HELPER_IMPL(tcp_pump_server) {
|
||||
r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
notify_parent_process();
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
return 0;
|
||||
@ -411,6 +412,7 @@ HELPER_IMPL(pipe_pump_server) {
|
||||
r = uv_listen((uv_stream_t*)&pipeServer, MAX_WRITE_HANDLES, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
notify_parent_process();
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
|
4
deps/libuv/test/benchmark-tcp-write-batch.c
vendored
4
deps/libuv/test/benchmark-tcp-write-batch.c
vendored
@ -71,7 +71,7 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
|
||||
|
||||
static void write_cb(uv_write_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
write_cb_called++;
|
||||
}
|
||||
@ -103,7 +103,7 @@ BENCHMARK_IMPL(tcp_write_batch) {
|
||||
int r;
|
||||
|
||||
write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS);
|
||||
ASSERT(write_reqs != NULL);
|
||||
ASSERT_NOT_NULL(write_reqs);
|
||||
|
||||
/* Prepare the data to write out. */
|
||||
for (i = 0; i < NUM_WRITE_REQS; i++) {
|
||||
|
14
deps/libuv/test/benchmark-udp-pummel.c
vendored
14
deps/libuv/test/benchmark-udp-pummel.c
vendored
@ -72,7 +72,7 @@ static void alloc_cb(uv_handle_t* handle,
|
||||
static void send_cb(uv_udp_send_t* req, int status) {
|
||||
struct sender_state* s;
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
|
||||
if (status != 0) {
|
||||
ASSERT(status == UV_ECANCELED);
|
||||
@ -127,7 +127,7 @@ static void recv_cb(uv_udp_t* handle,
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
@ -179,11 +179,11 @@ static int pummel(unsigned int n_senders,
|
||||
uv_unref((uv_handle_t*)&s->udp_handle);
|
||||
}
|
||||
|
||||
bufs[0] = uv_buf_init(EXPECTED + 0, 10);
|
||||
bufs[1] = uv_buf_init(EXPECTED + 10, 10);
|
||||
bufs[2] = uv_buf_init(EXPECTED + 20, 10);
|
||||
bufs[3] = uv_buf_init(EXPECTED + 30, 10);
|
||||
bufs[4] = uv_buf_init(EXPECTED + 40, 5);
|
||||
bufs[0] = uv_buf_init(&EXPECTED[0], 10);
|
||||
bufs[1] = uv_buf_init(&EXPECTED[10], 10);
|
||||
bufs[2] = uv_buf_init(&EXPECTED[20], 10);
|
||||
bufs[3] = uv_buf_init(&EXPECTED[30], 10);
|
||||
bufs[4] = uv_buf_init(&EXPECTED[40], 5);
|
||||
|
||||
for (i = 0; i < n_senders; i++) {
|
||||
struct sender_state* s = senders + i;
|
||||
|
3
deps/libuv/test/blackhole-server.c
vendored
3
deps/libuv/test/blackhole-server.c
vendored
@ -47,7 +47,7 @@ static void connection_cb(uv_stream_t* stream, int status) {
|
||||
ASSERT(stream == (uv_stream_t*)&tcp_server);
|
||||
|
||||
conn = malloc(sizeof *conn);
|
||||
ASSERT(conn != NULL);
|
||||
ASSERT_NOT_NULL(conn);
|
||||
|
||||
r = uv_tcp_init(stream->loop, &conn->handle);
|
||||
ASSERT(r == 0);
|
||||
@ -114,6 +114,7 @@ HELPER_IMPL(tcp4_blackhole_server) {
|
||||
r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
notify_parent_process();
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(0 && "Blackhole server dropped out of event loop.");
|
||||
|
||||
|
2
deps/libuv/test/dns-server.c
vendored
2
deps/libuv/test/dns-server.c
vendored
@ -280,7 +280,7 @@ static void on_connection(uv_stream_t* server, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
handle = (dnshandle*) malloc(sizeof *handle);
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
|
||||
/* initialize read buffer state */
|
||||
handle->state.prevbuf_ptr = 0;
|
||||
|
50
deps/libuv/test/echo-server.c
vendored
50
deps/libuv/test/echo-server.c
vendored
@ -65,25 +65,35 @@ static void after_write(uv_write_t* req, int status) {
|
||||
|
||||
|
||||
static void after_shutdown(uv_shutdown_t* req, int status) {
|
||||
ASSERT_EQ(status, 0);
|
||||
uv_close((uv_handle_t*) req->handle, on_close);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void on_shutdown(uv_shutdown_t* req, int status) {
|
||||
ASSERT_EQ(status, 0);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void after_read(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf) {
|
||||
int i;
|
||||
write_req_t *wr;
|
||||
uv_shutdown_t* sreq;
|
||||
int shutdown = 0;
|
||||
|
||||
if (nread < 0) {
|
||||
/* Error or EOF */
|
||||
ASSERT(nread == UV_EOF);
|
||||
ASSERT_EQ(nread, UV_EOF);
|
||||
|
||||
free(buf->base);
|
||||
sreq = malloc(sizeof* sreq);
|
||||
ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown));
|
||||
if (uv_is_writable(handle)) {
|
||||
ASSERT_EQ(0, uv_shutdown(sreq, handle, after_shutdown));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -96,29 +106,42 @@ static void after_read(uv_stream_t* handle,
|
||||
/*
|
||||
* Scan for the letter Q which signals that we should quit the server.
|
||||
* If we get QS it means close the stream.
|
||||
* If we get QSS it means shutdown the stream.
|
||||
* If we get QSH it means disable linger before close the socket.
|
||||
*/
|
||||
if (!server_closed) {
|
||||
for (i = 0; i < nread; i++) {
|
||||
if (buf->base[i] == 'Q') {
|
||||
if (i + 1 < nread && buf->base[i + 1] == 'S') {
|
||||
free(buf->base);
|
||||
int reset = 0;
|
||||
if (i + 2 < nread && buf->base[i + 2] == 'S')
|
||||
shutdown = 1;
|
||||
if (i + 2 < nread && buf->base[i + 2] == 'H')
|
||||
reset = 1;
|
||||
if (reset && handle->type == UV_TCP)
|
||||
ASSERT_EQ(0, uv_tcp_close_reset((uv_tcp_t*) handle, on_close));
|
||||
else if (shutdown)
|
||||
break;
|
||||
else
|
||||
uv_close((uv_handle_t*) handle, on_close);
|
||||
free(buf->base);
|
||||
return;
|
||||
} else {
|
||||
} else if (!server_closed) {
|
||||
uv_close(server, on_server_close);
|
||||
server_closed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wr = (write_req_t*) malloc(sizeof *wr);
|
||||
ASSERT(wr != NULL);
|
||||
ASSERT_NOT_NULL(wr);
|
||||
wr->buf = uv_buf_init(buf->base, nread);
|
||||
|
||||
if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
|
||||
if (shutdown)
|
||||
ASSERT_EQ(0, uv_shutdown(malloc(sizeof* sreq), handle, on_shutdown));
|
||||
}
|
||||
|
||||
|
||||
@ -155,14 +178,14 @@ static void on_connection(uv_stream_t* server, int status) {
|
||||
switch (serverType) {
|
||||
case TCP:
|
||||
stream = malloc(sizeof(uv_tcp_t));
|
||||
ASSERT(stream != NULL);
|
||||
ASSERT_NOT_NULL(stream);
|
||||
r = uv_tcp_init(loop, (uv_tcp_t*)stream);
|
||||
ASSERT(r == 0);
|
||||
break;
|
||||
|
||||
case PIPE:
|
||||
stream = malloc(sizeof(uv_pipe_t));
|
||||
ASSERT(stream != NULL);
|
||||
ASSERT_NOT_NULL(stream);
|
||||
r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
|
||||
ASSERT(r == 0);
|
||||
break;
|
||||
@ -197,7 +220,7 @@ static uv_udp_send_t* send_alloc(void) {
|
||||
}
|
||||
|
||||
static void on_send(uv_udp_send_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
req->data = send_freelist;
|
||||
send_freelist = req;
|
||||
@ -209,6 +232,7 @@ static void on_recv(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
uv_buf_t sndbuf;
|
||||
uv_udp_send_t* req;
|
||||
|
||||
if (nread == 0) {
|
||||
/* Everything OK, but nothing read. */
|
||||
@ -218,8 +242,8 @@ static void on_recv(uv_udp_t* handle,
|
||||
ASSERT(nread > 0);
|
||||
ASSERT(addr->sa_family == AF_INET);
|
||||
|
||||
uv_udp_send_t* req = send_alloc();
|
||||
ASSERT(req != NULL);
|
||||
req = send_alloc();
|
||||
ASSERT_NOT_NULL(req);
|
||||
sndbuf = uv_buf_init(rcvbuf->base, nread);
|
||||
ASSERT(0 <= uv_udp_send(req, handle, &sndbuf, 1, addr, on_send));
|
||||
}
|
||||
@ -228,7 +252,7 @@ static int tcp4_echo_start(int port) {
|
||||
struct sockaddr_in addr;
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr));
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", port, &addr));
|
||||
|
||||
server = (uv_handle_t*)&tcpServer;
|
||||
serverType = TCP;
|
||||
|
12
deps/libuv/test/run-benchmarks.c
vendored
12
deps/libuv/test/run-benchmarks.c
vendored
@ -28,6 +28,16 @@
|
||||
/* Actual benchmarks and helpers are defined in benchmark-list.h */
|
||||
#include "benchmark-list.h"
|
||||
|
||||
#ifdef __MVS__
|
||||
#include "zos-base.h"
|
||||
/* Initialize environment and zoslib */
|
||||
__attribute__((constructor)) void init() {
|
||||
zoslib_config_t config;
|
||||
init_zoslib_config(&config);
|
||||
init_zoslib(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int maybe_run_test(int argc, char **argv);
|
||||
|
||||
@ -44,8 +54,6 @@ int main(int argc, char **argv) {
|
||||
fflush(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user