Commit 4d960ad4 authored by Jason Madden's avatar Jason Madden

Update libuv to 1.36.0

Fixes #1597
parent 80b1b825
......@@ -23,7 +23,7 @@ files::
Check if 'config.guess' and/or 'config.sub' went backwards in time
(the 'timestamp' and copyright dates'). If so, revert it (or update
(the 'timestamp' and 'copyright' dates). If so, revert it (or update
from the latest source
http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree )
......@@ -62,7 +62,7 @@ Updating libuv
- Clean up the libuv tree, and apply the patches to libuv (this whole
sequence is meant to be copied and pasted into the terminal)::
export LIBUV_VER=v1.27.0
export LIBUV_VER=v1.36.0
cd deps/
wget https://dist.libuv.org/dist/$LIBUV_VER/libuv-$LIBUV_VER.tar.gz
......
......@@ -37,11 +37,6 @@ vgcore.*
Makefile
Makefile.in
# Generated by gyp for android
*.target.mk
/android-toolchain
/out/
/build/
/test/.libs/
......
......@@ -17,6 +17,7 @@ Imran Iqbal <imrani@ca.ibm.com> <imran@imraniqbal.org>
Isaac Z. Schlueter <i@izs.me>
Jason Williams <necmon@yahoo.com>
Jesse Gorzinski <jgorzinski@gmail.com>
Jesse Gorzinski <jgorzinski@gmail.com> <jgorzins@us.ibm.com>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
......
......@@ -412,3 +412,15 @@ ZYSzys <zyszys98@gmail.com>
Carl Lei <xecycle@gmail.com>
Stefan Bender <stefan.bender@ntnu.no>
nia <nia@NetBSD.org>
virtualyw <virtualyw@gmail.com>
Witold Kręcicki <wpk@isc.org>
Dominique Dumont <dod@debian.org>
Manuel BACHMANN <tarnyko@tarnyko.net>
Marek Vavrusa <marek@vavrusa.com>
TK-one <tk5641@naver.com>
Irek Fakhrutdinov <ifakhrutdinov@rocketsoftware.com>
Lin Zhang <linroid@gmail.com>
毛毛 <srayuws@users.noreply.github.com>
Sk Sajidul Kadir <sheikh.sajid522@gmail.com>
twosee <twose@qq.com>
Rikard Falkeborn <rikard.falkeborn@gmail.com>
This diff is collapsed.
......@@ -48,11 +48,11 @@ the [Google C/C++ style guide]. Some of the key points, as well as some
additional guidelines, are enumerated below.
* Code that is specific to unix-y platforms should be placed in `src/unix`, and
declarations go into `include/uv-unix.h`.
declarations go into `include/uv/unix.h`.
* Source code that is Windows-specific goes into `src/win`, and related
publicly exported types, functions and macro declarations should generally
be declared in `include/uv-win.h`.
be declared in `include/uv/win.h`.
* Names should be descriptive and concise.
......@@ -142,7 +142,6 @@ Bug fixes and features should come with tests. Add your tests in the
If you add a new test file, it needs to be registered in three places:
- `CMakeLists.txt`: add the file's name to the `uv_test_sources` list.
- `Makefile.am`: add the file's name to the `test_run_tests_SOURCES` list.
- `uv.gyp`: add the file's name to the `sources` list in the `run-tests` target.
Look at other tests to see how they should be structured (license boilerplate,
the way entry points are declared, etc.).
......
2019.12.05, Version 1.34.0 (Stable)
2020.04.16, Version 1.36.0 (Stable)
Changes since version 1.35.0:
* build: add aix-common.c for AIX cmake build (Jesse Gorzinski)
* zos: explicitly mark message queue events (Irek Fakhrutdinov)
* zos: move mq check out of loop to save cpu cycles (Irek Fakhrutdinov)
* zos: add checks to ensure behavior of epoll_wait (Irek Fakhrutdinov)
* src: add uv__reallocf() (Ben Noordhuis)
* build: ibmi support for cmake (Jesse Gorzinski)
* build: fix gyp build for Android API >= 28 (Lin Zhang)
* udp: return recvmmsg-ed datagrams in order (Saúl Ibarra Corretgé)
* zos,test: fix spawn_empty_env for shared library build (Richard Lau)
* zos: fix non-Release builds (Richard Lau)
* zos: fix return value on expired nanosleep() call (Richard Lau)
* build: fix z/OS cmake build (Richard Lau)
* test: add a bunch of ASSERT macros (Santiago Gimeno)
* test: remove unused extern declaration (Ben Noordhuis)
* test: canonicalize argv[0] in exepath test (Ben Noordhuis)
* test: simplify platform_init() (Ben Noordhuis)
* ibmi: Fix isatty EBADF handling and refactor (Kevin Adler)
* test: Test EBADF tty handling (Kevin Adler)
* build: make cmake build benchmarks (Ben Noordhuis)
* win: use RtlGenRandom from advapi32.dll directly (Ben Noordhuis)
* android: fix OOB write in uv_interface_addresses() (Lin Zhang)
* test: pass test when hostname is single character (毛毛)
* ibmi: set the highest process priority to -10 (Xu Meng)
* build: remove support for gyp (Ben Noordhuis)
* doc: add note to README on cross-compiling (Ben Noordhuis)
* fs: add uv_fs_lutime() (Sk Sajidul Kadir)
* unix: implement cpu_relax() for arm (David Carlier)
* linux: fix uv__accept4() (twosee)
* win: handle file paths in uv_fs_statfs() (erw7)
* unix: fix uv_os_environ() null pointer check (Rikard Falkeborn)
* win: fix uv_os_environ() null pointer check (Rikard Falkeborn)
* unix: fix compilation on macOS 32-bit architectures (Brad King)
* win: replace alloca() with stack-based array (Ben Noordhuis)
2020.03.12, Version 1.35.0 (Stable), e45f1ec38db882f8dc17b51f51a6684027034609
Changes since version 1.34.2:
* src: android build fix (David Carlier)
* build: make code compilable for iOS on Xcode (ssrlive)
* ibmi: skip unsupported fs test cases (Xu Meng)
* ibmi: ensure that pipe backlog is not zero (Xu Meng)
* test,udp6: fix udp_ipv6 test flakiness (Jameson Nash)
* test: fix fs_event_watch_dir_recursive flakiness (Santiago Gimeno)
* pipe: disallow listening on an IPC pipe (Witold Kręcicki)
* build,cmake: improve buil experience (Isabella Muerte)
* unix: remove support for FreeBSD < 10 (Saúl Ibarra Corretgé)
* linux: simplify uv__accept() (Ben Noordhuis)
* linux: assume presence of SOCK_CLOEXEC flag (Ben Noordhuis)
* linux: simplify uv__dup2_cloexec() (Ben Noordhuis)
* freebsd,linux: simplify uv__make_socketpair() (Ben Noordhuis)
* unix: fix error handling in uv__make_socketpair() (Ben Noordhuis)
* freebsd,linux: simplify uv__make_pipe() (Ben Noordhuis)
* unix: fix error handling in uv__make_pipe() (Ben Noordhuis)
* linux: simplify uv__async_eventfd() (Ben Noordhuis)
* linux: assume the presence of inotify system calls (Ben Noordhuis)
* doc: strip ICC profile from 2 jpg files (Dominique Dumont)
* unix: make uv_tcp_keepalive predictable (Manuel BACHMANN)
* docs: uv_setup_args() may take ownership of argv (Ben Noordhuis)
* unix: fix error path in uv_setup_args() (Ben Noordhuis)
* unix: fix size check in uv_get_process_title() (Ben Noordhuis)
* doc: add erw7 to maintainers (erw7)
* test: fixed udp4_echo_server implementation (Marek Vavrusa)
* test: added udp ping benchmark (1,10,100 pingers) (Marek Vavrusa)
* freebsd,linux: add recvmmsg() + sendmmsg() udp implementation (Marek Vavrusa)
* win,pipe: DRY/simplify some code paths (Jameson Nash)
* win: address some style nits (Jameson Nash)
* win,pipe: ensure `req->event_handle` is defined (Elliot Saba)
* win,pipe: consolidate overlapped initialization (Elliot Saba)
* win,pipe: erase event_handle after deleting pointer (Jameson Nash)
* build: fix android cmake build, build missing file (Ben Noordhuis)
* test: skip some UDP tests on IBMi (Xu Meng)
* test: skip some spawn test cases on IBMi (Xu Meng)
* src: fix wrong method name in comment (TK-one)
* test: add UV_TIMEOUT_MULTIPLIER environment var (Ben Noordhuis)
* unix: fix uv_cpu_info always returning UV_ENOTDIR on OpenBSD (Ben Davies)
* test: skip the pwd_shell test on IBMi (Xu Meng)
* win,tty: Change to restore cursor shape with uv_tty_reset() (erw7)
* win,tty: Added set cursor style to CSI sequences (erw7)
* test: handle EINTR, fix EOF check in poll test (Ben Noordhuis)
* unix: use socklen_t instead of size_t (Ben Noordhuis)
* doc: fix header file location (TK-one)
* unix: fix signal handle closing deferral (Ben Noordhuis)
* ibmi: set the amount of memory in use to zero (Xu Meng)
* zos: return on realloc failure in scandir() (Milad Farazmand)
* zos: fix scandir() error path NULL pointer deref (Ben Noordhuis)
2020.01.24, Version 1.34.2 (Stable), f868c9ab0c307525a16fff99fd21e32a6ebc3837
Changes since version 1.34.1:
* misc: adjust stalebot deadlines (Jameson Nash)
* test: fix env-vars flakiness (cjihrig)
* test: avoid truncating output lines (Jameson Nash)
* darwin: stop calling SetApplicationIsDaemon() (Ben Noordhuis)
* ibmi: implement uv_interface_addresses() (Xu Meng)
* osx,fsevent: fix race during uv_loop_close (Jameson Nash)
* osx,fsevent: clear pointer when deleting it [NFCI] (Jameson Nash)
* Revert "aix: replace ECONNRESET with EOF if already closed" (Jameson Nash)
* unix: handle uv__open_cloexec return value correctly (Anna Henningsen)
2020.01.13, Version 1.34.1 (Stable), 8aa5636ec72990bb2856f81e14c95813024a5c2b
Changes since version 1.34.0:
* unix: fix -Wstrict-aliasing compiler warning (Ben Noordhuis)
* unix: cache address of dlsym("mkostemp") (Ben Noordhuis)
* build: remove -pedantic from compiler flags (Ben Noordhuis)
* Revert "darwin: assume pthread_setname_np() is available" (Ben Noordhuis)
* Revert "darwin: speed up uv_set_process_title()" (Ben Noordhuis)
* darwin: assume pthread_setname_np() is available (Ben Noordhuis)
* ibmi: fix the false isatty() issue on IBMi (Xu Meng)
* test: fix test failure under NetBSD and OpenBSD (David Carlier)
* test: skip some test cases on IBMi (Xu Meng)
* test: skip uv_(get|set)_process_title on IBMi (Xu Meng)
* doc: remove binaries for Windows from README (Richard Lau)
* unix: fix -Wunused-but-set-variable warning (George Zhao)
* unix: pass sysctl size arg using ARRAY_SIZE macro (David Carlier)
* test: disallow running the test suite as root (cjihrig)
* unix: suppress -Waddress-of-packed-member warning (Ben Noordhuis)
* misc: make more tags "not-stale" (Jameson Nash)
* test: fix pthread memory leak (Trevor Norris)
* docs: delete socks5-proxy sample (Jameson Nash)
* ibmi: fix the CMSG length issue (Xu Meng)
* docs: fix formatting (Jameson Nash)
* unix: squelch fchmod() EPERM on CIFS share (Ben Noordhuis)
* docs: fix linkcheck (Jameson Nash)
* docs: switch from linux.die.net to man7.org (Jameson Nash)
* win: remove abort when non-IFS LSP detection fails (virtualyw)
* docs: clarify that uv_pipe_t is a pipe (Jameson Nash)
* win,tty: avoid regressions in utf-8 handling (Jameson Nash)
* win: remove bad assert in uv_loop_close (Jameson Nash)
* test: fix -fno-common build errors (Ben Noordhuis)
* build: turn on -fno-common to catch regressions (Ben Noordhuis)
* test: fix fs birth time test failure (Ben Noordhuis)
* tty,unix: avoid affecting controlling TTY (Jameson Nash)
2019.12.05, Version 1.34.0 (Stable), 15ae750151ac9341e5945eb38f8982d59fb99201
Changes since version 1.33.1:
......
......@@ -17,6 +17,8 @@ libuv is currently managed by the following individuals:
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
* **Jameson Nash** ([@vtjnash](https://github.com/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)
* **Richard Lau** ([@richardlau](https://github.com/richardlau))
- GPG key: C82F A3AE 1CBE DC6B E46B 9360 C43C EC45 C17A B93C (pubkey-richardlau)
* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
......
......@@ -123,18 +123,9 @@ EXTRA_DIST = test/fixtures/empty_file \
include \
docs \
img \
samples \
android-configure-arm \
android-configure-arm64 \
android-configure-x86 \
android-configure-x86_64 \
CONTRIBUTING.md \
LICENSE \
README.md \
vcbuild.bat \
common.gypi \
gyp_uv.py \
uv.gyp
README.md
......@@ -287,6 +278,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-timer.c \
test/test-tmpdir.c \
test/test-tty-duplicate-key.c \
test/test-tty-escape-sequence-processing.c \
test/test-tty.c \
test/test-udp-alloc-cb-fail.c \
test/test-udp-bind.c \
......@@ -346,7 +338,8 @@ test_run_tests_CFLAGS += -D__EXTENSIONS__ \
endif
if OS390
test_run_tests_CFLAGS += -D_UNIX03_THREADS \
test_run_tests_CFLAGS += -D_ISOC99_SOURCE \
-D_UNIX03_THREADS \
-D_UNIX03_SOURCE \
-D_OPEN_SYS_IF_EXT=1 \
-D_OPEN_SYS_SOCK_IPV6 \
......
......@@ -116,9 +116,6 @@ libuv can be downloaded either from the
[GitHub repository](https://github.com/libuv/libuv)
or from the [downloads site](http://dist.libuv.org/dist/).
Starting with libuv 1.7.0, binaries for Windows are also provided. This is to
be considered EXPERIMENTAL.
Before verifying the git tags or signature files, importing the relevant keys
is necessary. Key IDs are listed in the
[MAINTAINERS](https://github.com/libuv/libuv/blob/master/MAINTAINERS.md)
......@@ -155,47 +152,14 @@ $ gpg --verify libuv-1.7.0.tar.gz.sign
## Build Instructions
For GCC there are two build methods: via autotools or via [GYP][].
GYP is a meta-build system which can generate MSVS, Makefile, and XCode
backends. It is best used for integration into other projects.
To build with autotools:
```bash
$ sh autogen.sh
$ ./configure
$ make
$ make check
$ make install
```
To build with [CMake](https://cmake.org/):
```bash
$ mkdir -p out/cmake ; cd out/cmake # create build directory
$ cmake ../.. -DBUILD_TESTING=ON # generate project with test
$ cmake --build . # build
$ ctest -C Debug --output-on-failure # run tests
# Or manually run tests:
$ ./out/cmake/uv_run_tests # shared library build
$ ./out/cmake/uv_run_tests_a # static library build
```
To build with GYP, first run:
```bash
$ git clone https://chromium.googlesource.com/external/gyp build/gyp
```
For UNIX-like platforms, including macOS, there are two build methods:
autotools or [CMake][].
### Windows
For Windows, [CMake][] is the only supported build method and has the
following prerequisites:
Prerequisites:
<details>
* [Python 2.6 or 2.7][] as it is required
by [GYP][].
If python is not in your path, set the environment variable `PYTHON` to its
location. For example: `set PYTHON=C:\Python27\python.exe`
* One of:
* [Visual C++ Build Tools][]
* [Visual Studio 2015 Update 3][], all editions
......@@ -208,67 +172,44 @@ Prerequisites:
[Git for Windows][] includes Git Bash
and tools which can be included in the global `PATH`.
To build, launch a git shell (e.g. Cmd or PowerShell), run `vcbuild.bat`
(to build with VS2017 you need to explicitly add a `vs2017` argument),
which will checkout the GYP code into `build/gyp`, generate `uv.sln`
as well as the necesery related project files, and start building.
```console
> vcbuild
```
Or:
```console
> vcbuild vs2017
```
To run the tests:
```console
> vcbuild test
```
To see all the options that could passed to `vcbuild`:
</details>
```console
> vcbuild help
vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared]
Examples:
vcbuild.bat : builds debug build
vcbuild.bat test : builds debug build and runs tests
vcbuild.bat release bench: builds release build and runs benchmarks
```
### Unix
For Debug builds (recommended) run:
To build with autotools:
```bash
$ ./gyp_uv.py -f make
$ make -C out
$ sh autogen.sh
$ ./configure
$ make
$ make check
$ make install
```
For Release builds run:
To build with [CMake][]:
```bash
$ ./gyp_uv.py -f make
$ BUILDTYPE=Release make -C out
```
$ mkdir -p build
Run `./gyp_uv.py -f make -Dtarget_arch=x32` to build [x32][] binaries.
$ (cd build && cmake .. -DBUILD_TESTING=ON) # generate project with tests
$ cmake --build build # add `-j <n>` with cmake >= 3.12
### OS X
# Run tests:
$ (cd build && ctest -C Debug --output-on-failure)
Run:
# Or manually run tests:
$ build/uv_run_tests # shared library build
$ build/uv_run_tests_a # static library build
```
To cross-compile with [CMake][] (unsupported but generally works):
```bash
$ ./gyp_uv.py -f xcode
$ xcodebuild -ARCHS="x86_64" -project out/uv.xcodeproj -configuration Release -alltargets
$ cmake ../.. \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_SYSTEM_VERSION=6.1 \
-DCMAKE_C_COMPILER=i686-w64-mingw32-gcc
```
Using Homebrew:
### Install with Homebrew
```bash
$ brew install --HEAD libuv
......@@ -280,103 +221,48 @@ Make sure that you specify the architecture you wish to build for in the
"ARCHS" flag. You can specify more than one by delimiting with a space
(e.g. "x86_64 i386").
### Android
Run:
For arm
```bash
$ source ./android-configure-arm NDK_PATH gyp [API_LEVEL]
$ make -C out
```
or for arm64
```bash
$ source ./android-configure-arm64 NDK_PATH gyp [API_LEVEL]
$ make -C out
```
or for x86
```bash
$ source ./android-configure-x86 NDK_PATH gyp [API_LEVEL]
$ make -C out
```
or for x86_64
```bash
$ source ./android-configure-x86_64 NDK_PATH gyp [API_LEVEL]
$ make -C out
```
The default API level is 24, but a different one can be selected as follows:
```bash
$ source ./android-configure-arm ~/android-ndk-r15b gyp 21
$ make -C out
```
Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
### Using Ninja
To use ninja for build on ninja supported platforms, run:
```bash
$ ./gyp_uv.py -f ninja
$ ninja -C out/Debug #for debug build OR
$ ninja -C out/Release
```
### Running tests
#### Build
Build (includes tests):
```bash
$ ./gyp_uv.py -f make
$ make -C out
```
#### Run all tests
Some tests are timing sensitive. Relaxing test timeouts may be necessary
on slow or overloaded machines:
```bash
$ ./out/Debug/run-tests
$ env UV_TEST_TIMEOUT_MULTIPLIER=2 build/uv_run_tests # 10s instead of 5s
```
#### Run one test
The list of all tests is in `test/test-list.h`.
This invocation will cause the `run-tests` driver to fork and execute `TEST_NAME` in a child process:
This invocation will cause the test driver to fork and execute `TEST_NAME` in
a child process:
```bash
$ ./out/Debug/run-tests TEST_NAME
$ build/uv_run_tests_a TEST_NAME
```
This invocation will cause the `run-tests` driver to execute the test within the `run-tests` process:
This invocation will cause the test driver to execute the test in
the same process:
```bash
$ ./out/Debug/run-tests TEST_NAME TEST_NAME
$ build/uv_run_tests_a TEST_NAME TEST_NAME
```
#### Debugging tools
When running the test from within the `run-tests` process (`run-tests TEST_NAME TEST_NAME`), tools like gdb and valgrind work normally.
When running the test from a child of the `run-tests` process (`run-tests TEST_NAME`), use these tools in a fork-aware manner.
When running the test from within the test driver process
(`build/uv_run_tests_a TEST_NAME TEST_NAME`), tools like gdb and valgrind
work normally.
When running the test from a child of the test driver process
(`build/uv_run_tests_a TEST_NAME`), use these tools in a fork-aware manner.
##### Fork-aware gdb
Use the [follow-fork-mode](https://sourceware.org/gdb/onlinedocs/gdb/Forks.html) setting:
```
$ gdb --args out/Debug/run-tests TEST_NAME
$ gdb --args build/uv_run_tests_a TEST_NAME
(gdb) set follow-fork-mode child
...
......@@ -387,13 +273,14 @@ $ gdb --args out/Debug/run-tests TEST_NAME
Use the `--trace-children=yes` parameter:
```bash
$ valgrind --trace-children=yes -v --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memcheck-%p.log out/Debug/run-tests TEST_NAME
$ valgrind --trace-children=yes -v --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memcheck-%p.log build/uv_run_tests_a TEST_NAME
```
### Running benchmarks
See the section on running tests.
The benchmark driver is `out/Debug/run-benchmarks` and the benchmarks are listed in `test/benchmark-list.h`.
The benchmark driver is `./uv_run_benchmarks_a` and the benchmarks are
listed in `test/benchmark-list.h`.
## Supported Platforms
......@@ -409,8 +296,6 @@ that is detected by `autoconf`.
[IBM documentation](http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/)
describes the package in more detail.
AIX support for filesystem events is not compiled when building with `gyp`.
### z/OS Notes
z/OS creates System V semaphores and message queues. These persist on the system
......@@ -422,12 +307,10 @@ Use the `ipcrm` command to manually clear up System V resources.
See the [guidelines for contributing][].
[CMake]: https://cmake.org/
[node.js]: http://nodejs.org/
[GYP]: http://code.google.com/p/gyp/
[guidelines for contributing]: https://github.com/libuv/libuv/blob/master/CONTRIBUTING.md
[libuv_banner]: https://raw.githubusercontent.com/libuv/libuv/master/img/banner.png
[x32]: https://en.wikipedia.org/wiki/X32_ABI
[Python 2.6 or 2.7]: https://www.python.org/downloads/
[Visual C++ Build Tools]: https://visualstudio.microsoft.com/visual-cpp-build-tools/
[Visual Studio 2015 Update 3]: https://www.visualstudio.com/vs/older-downloads/
[Visual Studio 2017]: https://www.visualstudio.com/downloads/
......
......@@ -47,8 +47,9 @@ All functionality related to the new platform must be implemented in its own
file inside ``src/unix/`` unless it's already done in a common file, in which
case adding an `ifdef` is fine.
Two build systems are supported: autotools and GYP. Ideally both need to be
supported, but if GYP does not support the new platform it can be left out.
Two build systems are supported: autotools and cmake. Ideally both need to be
supported, but if one of the two does not support the new platform it can be
left out.
### Windows
......
version: v1.18.0.build{build}
init:
- git config --global core.autocrlf true
install:
- cinst -y nsis
matrix:
fast_finish: true
allow_failures:
- platform: x86
configuration: Release
- platform: x64
configuration: Release
platform:
- x86
- x64
configuration:
- Release
build_script:
# Fixed tag version number if using a tag.
- cmd: if "%APPVEYOR_REPO_TAG%" == "true" set APPVEYOR_BUILD_VERSION=%APPVEYOR_REPO_TAG_NAME%
# vcbuild overwrites the platform variable.
- cmd: set ARCH=%platform%
- cmd: vcbuild.bat release %ARCH% shared
cache:
- C:\projects\libuv\build\gyp
{
'variables': {
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'uv_library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
},
'target_defaults': {
'default_configuration': 'Debug',
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'cflags': [ '-g' ],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
['uv_library=="static_library"', {
'RuntimeLibrary': 1, # /MTd static debug
}, {
'RuntimeLibrary': 3, # /MDd DLL debug
}],
],
'Optimization': 0, # /Od, no optimization
'MinimalRebuild': 'false',
'OmitFramePointers': 'false',
'BasicRuntimeChecks': 3, # /RTC1
},
'VCLinkerTool': {
'LinkIncremental': 2, # enable incremental linking
},
},
'xcode_settings': {
'GCC_OPTIMIZATION_LEVEL': '0',
},
'conditions': [
['OS != "zos"', {
'cflags': [ '-O0', '-fwrapv' ]
}],
['OS == "android"', {
'cflags': [ '-fPIE' ],
'ldflags': [ '-fPIE', '-pie' ]
}]
]
},
'Release': {
'defines': [ 'NDEBUG' ],
'cflags': [
'-O3',
],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
['uv_library=="static_library"', {
'RuntimeLibrary': 0, # /MT static release
}, {
'RuntimeLibrary': 2, # /MD DLL release
}],
],
'Optimization': 3, # /Ox, full optimization
'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
'OmitFramePointers': 'true',
'EnableFunctionLevelLinking': 'true',
'EnableIntrinsicFunctions': 'true',
},
'VCLibrarianTool': {
'AdditionalOptions': [
'/LTCG', # link time code generation
],
},
'VCLinkerTool': {
'LinkTimeCodeGeneration': 1, # link-time code generation
'OptimizeReferences': 2, # /OPT:REF
'EnableCOMDATFolding': 2, # /OPT:ICF
'LinkIncremental': 1, # disable incremental linking
},
},
'conditions': [
['OS != "zos"', {
'cflags': [
'-fomit-frame-pointer',
'-fdata-sections',
'-ffunction-sections',
],
}],
]
}
},
'msvs_settings': {
'VCCLCompilerTool': {
'StringPooling': 'true', # pool string literals
'DebugInformationFormat': 3, # Generate a PDB
'WarningLevel': 3,
'BufferSecurityCheck': 'true',
'ExceptionHandling': 1, # /EHsc
'SuppressStartupBanner': 'true',
'WarnAsError': 'false',
'AdditionalOptions': [
'/MP', # compile across multiple CPUs
],
},
'VCLibrarianTool': {
},
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
'RandomizedBaseAddress': 2, # enable ASLR
'DataExecutionPrevention': 2, # enable DEP
'AllowIsolation': 'true',
'SuppressStartupBanner': 'true',
'target_conditions': [
['_type=="executable"', {
'SubSystem': 1, # console executable
}],
],
},
},
'conditions': [
['OS == "win"', {
'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
'defines': [
'WIN32',
# we don't really want VC++ warning us about
# how dangerous C functions are...
'_CRT_SECURE_NO_DEPRECATE',
# ... or that C implementations shouldn't use
# POSIX names
'_CRT_NONSTDC_NO_DEPRECATE',
],
'target_conditions': [
['target_arch=="x64"', {
'msvs_configuration_platform': 'x64'
}]
]
}],
['OS in "freebsd dragonflybsd linux openbsd solaris android aix"', {
'cflags': [ '-Wall' ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
'target_conditions': [
['_type=="static_library"', {
'standalone_static_library': 1, # disable thin archive which needs binutils >= 2.19
}],
],
'conditions': [
[ 'host_arch != target_arch and target_arch=="ia32"', {
'cflags': [ '-m32' ],
'ldflags': [ '-m32' ],
}],
[ 'target_arch=="x32"', {
'cflags': [ '-mx32' ],
'ldflags': [ '-mx32' ],
}],
[ 'OS=="linux"', {
'cflags': [ '-ansi' ],
}],
[ 'OS=="solaris"', {
'cflags': [ '-pthreads' ],
'ldflags': [ '-pthreads' ],
}],
[ 'OS not in "solaris android zos"', {
'cflags': [ '-pthread' ],
'ldflags': [ '-pthread' ],
}],
[ 'OS=="aix" and target_arch=="ppc64"', {
'cflags': [ '-maix64' ],
'ldflags': [ '-maix64' ],
}],
],
}],
['OS=="mac"', {
'xcode_settings': {
'ALWAYS_SEARCH_USER_PATHS': 'NO',
'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
# (Equivalent to -fPIC)
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
'PREBINDING': 'NO', # No -Wl,-prebind
'USE_HEADERMAP': 'NO',
'WARNING_CFLAGS': [
'-Wall',
'-Wendif-labels',
'-W',
'-Wno-unused-parameter',
'-Wstrict-prototypes',
],
},
'conditions': [
['target_arch=="ia32"', {
'xcode_settings': {'ARCHS': ['i386']},
}],
['target_arch=="x64"', {
'xcode_settings': {'ARCHS': ['x86_64']},
}],
],
'target_conditions': [
['_type!="static_library"', {
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
}],
],
}],
['OS=="solaris"', {
'cflags': [ '-fno-omit-frame-pointer' ],
# pull in V8's postmortem metadata
'ldflags': [ '-Wl,-z,allextract' ]
}],
],
},
}
This diff is collapsed.
......@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.34.0], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.36.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
......@@ -24,9 +24,6 @@ AC_ENABLE_SHARED
AC_ENABLE_STATIC
AC_PROG_CC
AM_PROG_CC_C_O
AS_IF([AS_CASE([$host_os],[openedition*], [false], [true])], [
CC_CHECK_CFLAGS_APPEND([-pedantic])
])
CC_FLAG_VISIBILITY #[-fvisibility=hidden]
CC_CHECK_CFLAGS_APPEND([-g])
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
......
#!/usr/bin/env python
import os
import platform
import sys
try:
import multiprocessing.synchronize
gyp_parallel_support = True
except ImportError:
gyp_parallel_support = False
CC = os.environ.get('CC', 'cc')
script_dir = os.path.dirname(__file__)
uv_root = os.path.normpath(script_dir)
output_dir = os.path.join(os.path.abspath(uv_root), 'out')
sys.path.insert(0, os.path.join(uv_root, 'build', 'gyp', 'pylib'))
try:
import gyp
except ImportError:
print('You need to install gyp in build/gyp first. See the README.')
sys.exit(42)
def host_arch():
machine = platform.machine()
if machine == 'i386': return 'ia32'
if machine == 'AMD64': return 'x64'
if machine == 'x86_64': return 'x64'
if machine.startswith('arm'): return 'arm'
if machine.startswith('mips'): return 'mips'
return machine # Return as-is and hope for the best.
def run_gyp(args):
rc = gyp.main(args)
if rc != 0:
print('Error running GYP')
sys.exit(rc)
if __name__ == '__main__':
args = sys.argv[1:]
args.extend('-I common.gypi test/test.gyp'.split(' '))
args.append('--depth=' + uv_root)
# There's a bug with windows which doesn't allow this feature.
if sys.platform != 'win32':
if '-f' not in args:
args.extend('-f make'.split())
if 'eclipse' not in args and 'ninja' not in args:
args.extend(['-Goutput_dir=' + output_dir])
args.extend(['--generator-output', output_dir])
if not any(a.startswith('-Dhost_arch=') for a in args):
args.append('-Dhost_arch=%s' % host_arch())
if not any(a.startswith('-Dtarget_arch=') for a in args):
args.append('-Dtarget_arch=%s' % host_arch())
if not any(a.startswith('-Duv_library=') for a in args):
args.append('-Duv_library=static_library')
# Some platforms (OpenBSD for example) don't have multiprocessing.synchronize
# so gyp must be run with --no-parallel
if not gyp_parallel_support:
args.append('--no-parallel')
gyp_args = list(args)
print(gyp_args)
run_gyp(gyp_args)
......@@ -605,7 +605,12 @@ enum uv_udp_flags {
* (provided they all set the flag) but only the last one to bind will receive
* any traffic, in effect "stealing" the port from the previous listener.
*/
UV_UDP_REUSEADDR = 4
UV_UDP_REUSEADDR = 4,
/*
* Indicates that the message was received by recvmmsg, so the buffer provided
* must not be freed by the recv_cb callback.
*/
UV_UDP_MMSG_CHUNK = 8
};
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
......@@ -1177,12 +1182,22 @@ UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
UV_EXTERN uv_pid_t uv_os_getpid(void);
UV_EXTERN uv_pid_t uv_os_getppid(void);
#define UV_PRIORITY_LOW 19
#define UV_PRIORITY_BELOW_NORMAL 10
#define UV_PRIORITY_NORMAL 0
#define UV_PRIORITY_ABOVE_NORMAL -7
#define UV_PRIORITY_HIGH -14
#define UV_PRIORITY_HIGHEST -20
#if defined(__PASE__)
/* On IBM i PASE, the highest process priority is -10 */
# define UV_PRIORITY_LOW 39 // RUNPTY(99)
# define UV_PRIORITY_BELOW_NORMAL 15 // RUNPTY(50)
# define UV_PRIORITY_NORMAL 0 // RUNPTY(20)
# define UV_PRIORITY_ABOVE_NORMAL -4 // RUNTY(12)
# define UV_PRIORITY_HIGH -7 // RUNPTY(6)
# define UV_PRIORITY_HIGHEST -10 // RUNPTY(1)
#else
# define UV_PRIORITY_LOW 19
# define UV_PRIORITY_BELOW_NORMAL 10
# define UV_PRIORITY_NORMAL 0
# define UV_PRIORITY_ABOVE_NORMAL -7
# define UV_PRIORITY_HIGH -14
# define UV_PRIORITY_HIGHEST -20
#endif
UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
......@@ -1259,7 +1274,8 @@ typedef enum {
UV_FS_READDIR,
UV_FS_CLOSEDIR,
UV_FS_STATFS,
UV_FS_MKSTEMP
UV_FS_MKSTEMP,
UV_FS_LUTIME
} uv_fs_type;
struct uv_dir_s {
......@@ -1432,6 +1448,12 @@ UV_EXTERN int uv_fs_futime(uv_loop_t* loop,
double atime,
double mtime,
uv_fs_cb cb);
UV_EXTERN int uv_fs_lutime(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
double atime,
double mtime,
uv_fs_cb cb);
UV_EXTERN int uv_fs_lstat(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
......
......@@ -26,12 +26,12 @@
* Versions with the same major number are ABI stable. API is allowed to
* evolve between minor releases, but only in a backwards compatible way.
* Make sure you update the -soname directives in configure.ac
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* not UV_VERSION_PATCH.)
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 34
#define UV_VERSION_MINOR 36
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
......
......@@ -517,7 +517,7 @@ typedef struct {
/* eol conversion state */ \
unsigned char previous_eol; \
/* ansi parser state */ \
unsigned char ansi_parser_state; \
unsigned short ansi_parser_state; \
unsigned char ansi_csi_argc; \
unsigned short ansi_csi_argv[4]; \
COORD saved_position; \
......
......@@ -87,7 +87,7 @@ int uv_timer_start(uv_timer_t* handle,
handle->timer_cb = cb;
handle->timeout = clamped_timeout;
handle->repeat = repeat;
/* start_id is the second index to be compared in uv__timer_cmp() */
/* start_id is the second index to be compared in timer_less_than() */
handle->start_id = handle->loop->timer_counter++;
heap_insert(timer_heap(handle->loop),
......
......@@ -155,183 +155,3 @@ int uv_exepath(char* buffer, size_t* size) {
return UV_EINVAL;
}
}
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int sockfd, sock6fd, inet6, i, r, size = 1;
struct ifconf ifc;
struct ifreq *ifr, *p, flg;
struct in6_ifreq if6;
struct sockaddr_dl* sa_addr;
ifc.ifc_req = NULL;
sock6fd = -1;
r = 0;
*count = 0;
*addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
r = UV__ERR(errno);
goto cleanup;
}
if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) {
r = UV__ERR(errno);
goto cleanup;
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
r = UV__ERR(errno);
goto cleanup;
}
ifc.ifc_req = (struct ifreq*)uv__malloc(size);
if (ifc.ifc_req == NULL) {
r = UV_ENOMEM;
goto cleanup;
}
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
r = UV__ERR(errno);
goto cleanup;
}
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
/* Count all up and running ipv4/ipv6 addresses */
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
ifr = (struct ifreq*)
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
if (!(p->ifr_addr.sa_family == AF_INET6 ||
p->ifr_addr.sa_family == AF_INET))
continue;
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
r = UV__ERR(errno);
goto cleanup;
}
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
(*count)++;
}
if (*count == 0)
goto cleanup;
/* Alloc the return interface structs */
*addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
r = UV_ENOMEM;
goto cleanup;
}
address = *addresses;
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
ifr = (struct ifreq*)
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
if (!(p->ifr_addr.sa_family == AF_INET6 ||
p->ifr_addr.sa_family == AF_INET))
continue;
inet6 = (p->ifr_addr.sa_family == AF_INET6);
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1)
goto syserror;
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
/* All conditions above must match count loop */
address->name = uv__strdup(p->ifr_name);
if (inet6)
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
else
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
if (inet6) {
memset(&if6, 0, sizeof(if6));
r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name));
if (r == UV_E2BIG)
goto cleanup;
r = 0;
memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr));
if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1)
goto syserror;
address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr);
/* Explicitly set family as the ioctl call appears to return it as 0. */
address->netmask.netmask6.sin6_family = AF_INET6;
} else {
if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1)
goto syserror;
address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
/* Explicitly set family as the ioctl call appears to return it as 0. */
address->netmask.netmask4.sin_family = AF_INET;
}
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
address++;
}
/* Fill in physical addresses. */
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
ifr = (struct ifreq*)
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
if (p->ifr_addr.sa_family != AF_LINK)
continue;
address = *addresses;
for (i = 0; i < *count; i++) {
if (strcmp(address->name, p->ifr_name) == 0) {
sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
}
address++;
}
}
#undef ADDR_SIZE
goto cleanup;
syserror:
uv_free_interface_addresses(*addresses, *count);
*addresses = NULL;
*count = 0;
r = UV_ENOSYS;
cleanup:
if (sockfd != -1)
uv__close(sockfd);
if (sock6fd != -1)
uv__close(sock6fd);
uv__free(ifc.ifc_req);
return r;
}
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
int i;
for (i = 0; i < count; ++i) {
uv__free(addresses[i].name);
}
uv__free(addresses);
}
......@@ -1039,6 +1039,186 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
}
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int sockfd, sock6fd, inet6, i, r, size = 1;
struct ifconf ifc;
struct ifreq *ifr, *p, flg;
struct in6_ifreq if6;
struct sockaddr_dl* sa_addr;
ifc.ifc_req = NULL;
sock6fd = -1;
r = 0;
*count = 0;
*addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
r = UV__ERR(errno);
goto cleanup;
}
if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) {
r = UV__ERR(errno);
goto cleanup;
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
r = UV__ERR(errno);
goto cleanup;
}
ifc.ifc_req = (struct ifreq*)uv__malloc(size);
if (ifc.ifc_req == NULL) {
r = UV_ENOMEM;
goto cleanup;
}
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
r = UV__ERR(errno);
goto cleanup;
}
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
/* Count all up and running ipv4/ipv6 addresses */
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
ifr = (struct ifreq*)
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
if (!(p->ifr_addr.sa_family == AF_INET6 ||
p->ifr_addr.sa_family == AF_INET))
continue;
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
r = UV__ERR(errno);
goto cleanup;
}
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
(*count)++;
}
if (*count == 0)
goto cleanup;
/* Alloc the return interface structs */
*addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
r = UV_ENOMEM;
goto cleanup;
}
address = *addresses;
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
ifr = (struct ifreq*)
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
if (!(p->ifr_addr.sa_family == AF_INET6 ||
p->ifr_addr.sa_family == AF_INET))
continue;
inet6 = (p->ifr_addr.sa_family == AF_INET6);
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1)
goto syserror;
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
/* All conditions above must match count loop */
address->name = uv__strdup(p->ifr_name);
if (inet6)
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
else
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
if (inet6) {
memset(&if6, 0, sizeof(if6));
r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name));
if (r == UV_E2BIG)
goto cleanup;
r = 0;
memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr));
if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1)
goto syserror;
address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr);
/* Explicitly set family as the ioctl call appears to return it as 0. */
address->netmask.netmask6.sin6_family = AF_INET6;
} else {
if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1)
goto syserror;
address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
/* Explicitly set family as the ioctl call appears to return it as 0. */
address->netmask.netmask4.sin_family = AF_INET;
}
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
address++;
}
/* Fill in physical addresses. */
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
ifr = (struct ifreq*)
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
if (p->ifr_addr.sa_family != AF_LINK)
continue;
address = *addresses;
for (i = 0; i < *count; i++) {
if (strcmp(address->name, p->ifr_name) == 0) {
sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
}
address++;
}
}
#undef ADDR_SIZE
goto cleanup;
syserror:
uv_free_interface_addresses(*addresses, *count);
*addresses = NULL;
*count = 0;
r = UV_ENOSYS;
cleanup:
if (sockfd != -1)
uv__close(sockfd);
if (sock6fd != -1)
uv__close(sock6fd);
uv__free(ifc.ifc_req);
return r;
}
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
int i;
for (i = 0; i < count; ++i) {
uv__free(addresses[i].name);
}
uv__free(addresses);
}
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct pollfd* events;
uintptr_t i;
......
......@@ -470,13 +470,14 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
{
case IFA_ADDRESS:
case IFA_LOCAL:
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
{
/* Make room for netmask */
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
l_addedNetmask = 1;
}
break;
break;
case IFA_BROADCAST:
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
break;
......
......@@ -33,9 +33,12 @@
#include <string.h>
#include <unistd.h>
#ifdef __linux__
#include <sys/eventfd.h>
#endif
static void uv__async_send(uv_loop_t* loop);
static int uv__async_start(uv_loop_t* loop);
static int uv__async_eventfd(void);
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
......@@ -190,36 +193,18 @@ static int uv__async_start(uv_loop_t* loop) {
if (loop->async_io_watcher.fd != -1)
return 0;
err = uv__async_eventfd();
if (err >= 0) {
pipefd[0] = err;
pipefd[1] = -1;
}
else if (err == UV_ENOSYS) {
err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
#if defined(__linux__)
/* Save a file descriptor by opening one of the pipe descriptors as
* read/write through the procfs. That file descriptor can then
* function as both ends of the pipe.
*/
if (err == 0) {
char buf[32];
int fd;
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]);
fd = uv__open_cloexec(buf, O_RDWR);
if (fd >= 0) {
uv__close(pipefd[0]);
uv__close(pipefd[1]);
pipefd[0] = fd;
pipefd[1] = fd;
}
}
#endif
}
#ifdef __linux__
err = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (err < 0)
return UV__ERR(errno);
pipefd[0] = err;
pipefd[1] = -1;
#else
err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
if (err < 0)
return err;
#endif
uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]);
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
......@@ -253,46 +238,3 @@ void uv__async_stop(uv_loop_t* loop) {
uv__close(loop->async_io_watcher.fd);
loop->async_io_watcher.fd = -1;
}
static int uv__async_eventfd(void) {
#if defined(__linux__)
static int no_eventfd2;
static int no_eventfd;
int fd;
if (no_eventfd2)
goto skip_eventfd2;
fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK);
if (fd != -1)
return fd;
if (errno != ENOSYS)
return UV__ERR(errno);
no_eventfd2 = 1;
skip_eventfd2:
if (no_eventfd)
goto skip_eventfd;
fd = uv__eventfd(0);
if (fd != -1) {
uv__cloexec(fd, 1);
uv__nonblock(fd, 1);
return fd;
}
if (errno != ENOSYS)
return UV__ERR(errno);
no_eventfd = 1;
skip_eventfd:
#endif
return UV_ENOSYS;
}
......@@ -53,6 +53,8 @@ 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 */
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
__asm__ volatile("yield");
#endif
}
......
......@@ -71,20 +71,12 @@ extern char** environ;
# include <sys/sysctl.h>
# include <sys/filio.h>
# include <sys/wait.h>
# if defined(__FreeBSD__) && __FreeBSD__ >= 10
# if defined(__FreeBSD__)
# define uv__accept4 accept4
# endif
# if defined(__NetBSD__)
# define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d))
# endif
# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \
defined(__NetBSD__) || defined(__OpenBSD__)
# define UV__SOCK_NONBLOCK SOCK_NONBLOCK
# define UV__SOCK_CLOEXEC SOCK_CLOEXEC
# endif
# if !defined(F_DUP2FD_CLOEXEC) && defined(_F_DUP2FD_CLOEXEC)
# define F_DUP2FD_CLOEXEC _F_DUP2FD_CLOEXEC
# endif
#endif
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
......@@ -96,7 +88,8 @@ extern char** environ;
#endif
#if defined(__linux__)
#include <sys/syscall.h>
# include <sys/syscall.h>
# define uv__accept4 accept4
#endif
static int uv__run_pending(uv_loop_t* loop);
......@@ -179,9 +172,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
case UV_SIGNAL:
uv__signal_close((uv_signal_t*) handle);
/* Signal handles may not be closed immediately. The signal code will
* itself close uv__make_close_pending whenever appropriate. */
return;
break;
default:
assert(0);
......@@ -246,6 +237,8 @@ int uv__getiovmax(void) {
static void uv__finish_close(uv_handle_t* handle) {
uv_signal_t* sh;
/* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still
* possible for it to be active in the sense that uv__is_active() returns
* true.
......@@ -268,7 +261,20 @@ static void uv__finish_close(uv_handle_t* handle) {
case UV_FS_EVENT:
case UV_FS_POLL:
case UV_POLL:
break;
case UV_SIGNAL:
/* If there are any caught signals "trapped" in the signal pipe,
* we can't call the close callback yet. Reinserting the handle
* into the closing queue makes the event loop spin but that's
* okay because we only need to deliver the pending events.
*/
sh = (uv_signal_t*) handle;
if (sh->caught_signals > sh->dispatched_signals) {
handle->flags ^= UV_HANDLE_CLOSED;
uv__make_close_pending(handle); /* Back into the queue. */
return;
}
break;
case UV_NAMED_PIPE:
......@@ -472,52 +478,32 @@ int uv__accept(int sockfd) {
int peerfd;
int err;
(void) &err;
assert(sockfd >= 0);
while (1) {
#if defined(__linux__) || \
(defined(__FreeBSD__) && __FreeBSD__ >= 10) || \
defined(__NetBSD__)
static int no_accept4;
if (no_accept4)
goto skip;
peerfd = uv__accept4(sockfd,
NULL,
NULL,
UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
if (peerfd != -1)
return peerfd;
if (errno == EINTR)
continue;
if (errno != ENOSYS)
return UV__ERR(errno);
no_accept4 = 1;
skip:
#endif
do
#ifdef uv__accept4
peerfd = uv__accept4(sockfd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
#else
peerfd = accept(sockfd, NULL, NULL);
if (peerfd == -1) {
if (errno == EINTR)
continue;
return UV__ERR(errno);
}
#endif
while (peerfd == -1 && errno == EINTR);
err = uv__cloexec(peerfd, 1);
if (err == 0)
err = uv__nonblock(peerfd, 1);
if (peerfd == -1)
return UV__ERR(errno);
if (err) {
uv__close(peerfd);
return err;
}
#ifndef uv__accept4
err = uv__cloexec(peerfd, 1);
if (err == 0)
err = uv__nonblock(peerfd, 1);
return peerfd;
if (err != 0) {
uv__close(peerfd);
return err;
}
#endif
return peerfd;
}
......@@ -533,7 +519,7 @@ int uv__close_nocancel(int fd) {
#if defined(__APPLE__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
#if defined(__LP64__)
#if defined(__LP64__) || TARGET_OS_IPHONE
extern int close$NOCANCEL(int);
return close$NOCANCEL(fd);
#else
......@@ -849,8 +835,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
}
nwatchers = next_power_of_two(len + 2) - 2;
watchers = uv__realloc(loop->watchers,
(nwatchers + 2) * sizeof(loop->watchers[0]));
watchers = uv__reallocf(loop->watchers,
(nwatchers + 2) * sizeof(loop->watchers[0]));
if (watchers == NULL)
abort();
......@@ -1031,54 +1017,30 @@ int uv__open_cloexec(const char* path, int flags) {
int uv__dup2_cloexec(int oldfd, int newfd) {
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
int r;
#if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__)
r = dup3(oldfd, newfd, O_CLOEXEC);
if (r == -1)
return UV__ERR(errno);
return r;
#elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
if (r != -1)
return r;
if (errno != EINVAL)
return UV__ERR(errno);
/* Fall through. */
#elif defined(__linux__)
static int no_dup3;
if (!no_dup3) {
do
r = uv__dup3(oldfd, newfd, O_CLOEXEC);
while (r == -1 && errno == EBUSY);
if (r != -1)
return r;
if (errno != ENOSYS)
return UV__ERR(errno);
/* Fall through. */
no_dup3 = 1;
}
#endif
{
int err;
do
r = dup2(oldfd, newfd);
#if defined(__linux__)
while (r == -1 && errno == EBUSY);
#else
while (0); /* Never retry. */
#endif
if (r == -1)
return UV__ERR(errno);
int err;
int r;
err = uv__cloexec(newfd, 1);
if (err) {
uv__close(newfd);
return err;
}
r = dup2(oldfd, newfd); /* Never retry. */
if (r == -1)
return UV__ERR(errno);
return r;
err = uv__cloexec(newfd, 1);
if (err != 0) {
uv__close(newfd);
return err;
}
return r;
#endif
}
......@@ -1296,7 +1258,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
*envitems = uv__calloc(i, sizeof(**envitems));
if (envitems == NULL)
if (*envitems == NULL)
return UV_ENOMEM;
for (j = 0, cnt = 0; j < i; j++) {
......
......@@ -34,52 +34,51 @@
# include <ApplicationServices/ApplicationServices.h>
#endif
#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
static int uv__pthread_setname_np(const char* name) {
char namebuf[64]; /* MAXTHREADNAMESIZE */
int err;
#if !TARGET_OS_IPHONE
static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
const char*,
CFStringEncoding);
static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
static CFTypeRef (*pLSGetCurrentApplicationASN)(void);
static OSStatus (*pLSSetApplicationInformationItem)(int,
CFTypeRef,
CFStringRef,
CFStringRef,
CFDictionaryRef*);
static void* application_services_handle;
static void* core_foundation_handle;
static CFBundleRef launch_services_bundle;
static CFStringRef* display_name_key;
static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
static CFBundleRef (*pCFBundleGetMainBundle)(void);
static CFBundleRef hi_services_bundle;
static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
void*);
UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) {
if (core_foundation_handle != NULL) {
dlclose(core_foundation_handle);
core_foundation_handle = NULL;
}
strncpy(namebuf, name, sizeof(namebuf) - 1);
namebuf[sizeof(namebuf) - 1] = '\0';
if (application_services_handle != NULL) {
dlclose(application_services_handle);
application_services_handle = NULL;
}
err = pthread_setname_np(namebuf);
if (err)
return UV__ERR(err);
return 0;
}
#endif /* !TARGET_OS_IPHONE */
void uv__set_process_title_platform_init(void) {
#if !TARGET_OS_IPHONE
OSStatus (*pSetApplicationIsDaemon)(int);
int uv__set_process_title(const char* title) {
#if TARGET_OS_IPHONE
return uv__pthread_setname_np(title);
#else
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
const char*,
CFStringEncoding);
CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
CFTypeRef (*pLSGetCurrentApplicationASN)(void);
OSStatus (*pLSSetApplicationInformationItem)(int,
CFTypeRef,
CFStringRef,
CFStringRef,
CFDictionaryRef*);
void* application_services_handle;
void* core_foundation_handle;
CFBundleRef launch_services_bundle;
CFStringRef* display_name_key;
CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
CFBundleRef (*pCFBundleGetMainBundle)(void);
CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
void*);
CFTypeRef asn;
int err;
err = UV_ENOENT;
application_services_handle = dlopen("/System/Library/Frameworks/"
"ApplicationServices.framework/"
"Versions/A/ApplicationServices",
......@@ -108,6 +107,8 @@ void uv__set_process_title_platform_init(void) {
goto out;
}
#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
launch_services_bundle =
pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
......@@ -138,59 +139,55 @@ void uv__set_process_title_platform_init(void) {
"CFBundleGetInfoDictionary");
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
"CFBundleGetMainBundle");
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
goto out;
/* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
hi_services_bundle =
pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
if (hi_services_bundle == NULL)
goto out;
*(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName(
hi_services_bundle,
S("SetApplicationIsDaemon"));
*(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
launch_services_bundle,
S("_LSApplicationCheckIn"));
if (pLSApplicationCheckIn == NULL)
goto out;
*(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
pCFBundleGetFunctionPointerForName(
launch_services_bundle,
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
if (pSetApplicationIsDaemon == NULL ||
pLSApplicationCheckIn == NULL ||
pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
if (pLSSetApplicationLaunchServicesServerConnectionStatus == NULL)
goto out;
}
/* Prevent crash when LaunchServices cannot be connected to. */
pSetApplicationIsDaemon(1);
return;
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
out:
uv__set_process_title_platform_fini();
#endif /* !TARGET_OS_IPHONE */
}
/* Check into process manager?! */
pLSApplicationCheckIn(-2,
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
asn = pLSGetCurrentApplicationASN();
void uv__set_process_title(const char* title) {
char namebuf[64 /* MAXTHREADNAMESIZE */];
err = UV_EBUSY;
if (asn == NULL)
goto out;
#if !TARGET_OS_IPHONE
if (core_foundation_handle != NULL) {
CFTypeRef asn;
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
pLSApplicationCheckIn(/* Magic value */ -2,
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
asn = pLSGetCurrentApplicationASN();
pLSSetApplicationInformationItem(/* Magic value */ -2, asn,
*display_name_key, S(title), NULL);
err = UV_EINVAL;
if (pLSSetApplicationInformationItem(-2, /* Magic value. */
asn,
*display_name_key,
S(title),
NULL) != noErr) {
goto out;
}
#endif /* !TARGET_OS_IPHONE */
uv__strscpy(namebuf, title, sizeof(namebuf));
pthread_setname_np(namebuf);
uv__pthread_setname_np(title); /* Don't care if it fails. */
err = 0;
out:
if (core_foundation_handle != NULL)
dlclose(core_foundation_handle);
if (application_services_handle != NULL)
dlclose(application_services_handle);
return err;
#endif /* !TARGET_OS_IPHONE */
}
......@@ -110,7 +110,7 @@ uint64_t uv_get_total_memory(void) {
int which[] = {CTL_HW, HW_MEMSIZE};
size_t size = sizeof(info);
if (sysctl(which, 2, &info, &size, NULL, 0))
if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
return UV__ERR(errno);
return (uint64_t) info;
......@@ -127,7 +127,7 @@ void uv_loadavg(double avg[3]) {
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_LOADAVG};
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return;
avg[0] = (double) info.ldavg[0] / info.fscale;
avg[1] = (double) info.ldavg[1] / info.fscale;
......@@ -162,7 +162,7 @@ int uv_uptime(double* uptime) {
size_t size = sizeof(info);
static int which[] = {CTL_KERN, KERN_BOOTTIME};
if (sysctl(which, 2, &info, &size, NULL, 0))
if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
return UV__ERR(errno);
now = time(NULL);
......
......@@ -95,7 +95,7 @@ int uv_exepath(char* buffer, size_t* size) {
mib[3] = -1;
abspath_size = sizeof abspath;
if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0))
if (sysctl(mib, ARRAY_SIZE(mib), abspath, &abspath_size, NULL, 0))
return UV__ERR(errno);
assert(abspath_size > 0);
......@@ -130,7 +130,7 @@ uint64_t uv_get_total_memory(void) {
size_t size = sizeof(info);
if (sysctl(which, 2, &info, &size, NULL, 0))
if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
return UV__ERR(errno);
return (uint64_t) info;
......@@ -147,7 +147,7 @@ void uv_loadavg(double avg[3]) {
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_LOADAVG};
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return;
avg[0] = (double) info.ldavg[0] / info.fscale;
avg[1] = (double) info.ldavg[1] / info.fscale;
......@@ -168,7 +168,7 @@ int uv_resident_set_memory(size_t* rss) {
kinfo_size = sizeof(kinfo);
if (sysctl(mib, 4, &kinfo, &kinfo_size, NULL, 0))
if (sysctl(mib, ARRAY_SIZE(mib), &kinfo, &kinfo_size, NULL, 0))
return UV__ERR(errno);
page_size = getpagesize();
......@@ -288,3 +288,28 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uv__free(cp_times);
return 0;
}
int uv__sendmmsg(int fd,
struct uv__mmsghdr* mmsg,
unsigned int vlen,
unsigned int flags) {
#if __FreeBSD__ >= 11
return sendmmsg(fd, mmsg, vlen, flags);
#else
return errno = ENOSYS, -1;
#endif
}
int uv__recvmmsg(int fd,
struct uv__mmsghdr* mmsg,
unsigned int vlen,
unsigned int flags,
struct timespec* timeout) {
#if __FreeBSD__ >= 11
return recvmmsg(fd, mmsg, vlen, flags, timeout);
#else
return errno = ENOSYS, -1;
#endif
}
......@@ -205,6 +205,20 @@ 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;
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;
return tv;
}
static ssize_t uv__fs_futime(uv_fs_t* req) {
#if defined(__linux__) \
|| defined(_AIX71) \
......@@ -213,10 +227,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
* for the sake of consistency with other platforms.
*/
struct timespec ts[2];
ts[0].tv_sec = req->atime;
ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
return utimensat(req->file, NULL, ts, 0);
#else
......@@ -230,10 +242,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
|| defined(__OpenBSD__) \
|| defined(__sun)
struct timeval tv[2];
tv[0].tv_sec = req->atime;
tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
tv[0] = uv__fs_to_timeval(req->atime);
tv[1] = uv__fs_to_timeval(req->mtime);
# if defined(__sun)
return futimesat(req->file, NULL, tv);
# else
......@@ -259,10 +269,29 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
}
static int (*uv__mkostemp)(char*, int);
static void uv__mkostemp_initonce(void) {
/* z/os doesn't have RTLD_DEFAULT but that's okay
* because it doesn't have mkostemp(O_CLOEXEC) either.
*/
#ifdef RTLD_DEFAULT
uv__mkostemp = (int (*)(char*, int)) dlsym(RTLD_DEFAULT, "mkostemp");
/* We don't care about errors, but we do want to clean them up.
* If there has been no error, then dlerror() will just return
* NULL.
*/
dlerror();
#endif /* RTLD_DEFAULT */
}
static int uv__fs_mkstemp(uv_fs_t* req) {
static uv_once_t once = UV_ONCE_INIT;
int r;
#ifdef O_CLOEXEC
int (*mkostemp_function)(char*, int);
static int no_cloexec_support;
#endif
static const char pattern[] = "XXXXXX";
......@@ -284,30 +313,23 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
return -1;
}
#ifdef O_CLOEXEC
if (no_cloexec_support == 0) {
*(int**)(&mkostemp_function) = dlsym(RTLD_DEFAULT, "mkostemp");
uv_once(&once, uv__mkostemp_initonce);
/* We don't care about errors, but we do want to clean them up.
If there has been no error, then dlerror() will just return
NULL. */
dlerror();
if (mkostemp_function != NULL) {
r = mkostemp_function(path, O_CLOEXEC);
#ifdef O_CLOEXEC
if (no_cloexec_support == 0 && uv__mkostemp != NULL) {
r = uv__mkostemp(path, O_CLOEXEC);
if (r >= 0)
return r;
if (r >= 0)
return r;
/* If mkostemp() returns EINVAL, it means the kernel doesn't
support O_CLOEXEC, so we just fallback to mkstemp() below. */
if (errno != EINVAL)
return r;
/* If mkostemp() returns EINVAL, it means the kernel doesn't
support O_CLOEXEC, so we just fallback to mkstemp() below. */
if (errno != EINVAL)
return r;
/* We set the static variable so that next calls don't even
try to use mkostemp. */
no_cloexec_support = 1;
}
/* We set the static variable so that next calls don't even
try to use mkostemp. */
no_cloexec_support = 1;
}
#endif /* O_CLOEXEC */
......@@ -654,7 +676,6 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
ssize_t maxlen;
ssize_t len;
char* buf;
char* newbuf;
#if defined(_POSIX_PATH_MAX) || defined(PATH_MAX)
maxlen = uv__fs_pathmax_size(req->path);
......@@ -698,14 +719,10 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
/* Uncommon case: resize to make room for the trailing nul byte. */
if (len == maxlen) {
newbuf = uv__realloc(buf, len + 1);
buf = uv__reallocf(buf, len + 1);
if (newbuf == NULL) {
uv__free(buf);
if (buf == NULL)
return -1;
}
buf = newbuf;
}
buf[len] = '\0';
......@@ -965,10 +982,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
* for the sake of consistency with other platforms.
*/
struct timespec ts[2];
ts[0].tv_sec = req->atime;
ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
return utimensat(AT_FDCWD, req->path, ts, 0);
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
......@@ -977,10 +992,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|| defined(__NetBSD__) \
|| defined(__OpenBSD__)
struct timeval tv[2];
tv[0].tv_sec = req->atime;
tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
tv[0] = uv__fs_to_timeval(req->atime);
tv[1] = uv__fs_to_timeval(req->mtime);
return utimes(req->path, tv);
#elif defined(_AIX) \
&& !defined(_AIX71)
......@@ -1003,6 +1016,31 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
}
static ssize_t uv__fs_lutime(uv_fs_t* req) {
#if defined(__linux__) || \
defined(_AIX71) || \
defined(__sun) || \
defined(__HAIKU__)
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
return utimensat(AT_FDCWD, req->path, ts, AT_SYMLINK_NOFOLLOW);
#elif defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
defined(__NetBSD__)
struct timeval tv[2];
tv[0] = uv__fs_to_timeval(req->atime);
tv[1] = uv__fs_to_timeval(req->mtime);
return lutimes(req->path, tv);
#else
errno = ENOSYS;
return -1;
#endif
}
static ssize_t uv__fs_write(uv_fs_t* req) {
#if defined(__linux__)
static int no_pwritev;
......@@ -1125,7 +1163,28 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
err = UV__ERR(errno);
#ifdef __linux__
if (err != UV_EPERM)
goto out;
{
struct statfs s;
/* fchmod() on CIFS shares always fails with EPERM unless the share is
* mounted with "noperm". As fchmod() is a meaningless operation on such
* shares anyway, detect that condition and squelch the error.
*/
if (fstatfs(dstfd, &s) == -1)
goto out;
if (s.f_type != /* CIFS */ 0xFF534D42u)
goto out;
}
err = 0;
#else /* !__linux__ */
goto out;
#endif /* !__linux__ */
}
#ifdef FICLONE
......@@ -1495,6 +1554,7 @@ static void uv__fs_work(struct uv__work* w) {
X(FSYNC, uv__fs_fsync(req));
X(FTRUNCATE, ftruncate(req->file, req->off));
X(FUTIME, uv__fs_futime(req));
X(LUTIME, uv__fs_lutime(req));
X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode));
......@@ -1681,6 +1741,19 @@ int uv_fs_futime(uv_loop_t* loop,
POST;
}
int uv_fs_lutime(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
double atime,
double mtime,
uv_fs_cb cb) {
INIT(LUTIME);
PATH;
req->atime = atime;
req->mtime = mtime;
POST;
}
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(LSTAT);
......
......@@ -747,6 +747,8 @@ static void* uv__cf_loop_runner(void* arg) {
state->signal_source,
*pkCFRunLoopDefaultMode);
state->loop = NULL;
return NULL;
}
......@@ -799,13 +801,14 @@ int uv__cf_loop_signal(uv_loop_t* loop,
uv_mutex_lock(&loop->cf_mutex);
QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
uv_mutex_unlock(&loop->cf_mutex);
state = loop->cf_state;
assert(state != NULL);
pCFRunLoopSourceSignal(state->signal_source);
pCFRunLoopWakeUp(state->loop);
uv_mutex_unlock(&loop->cf_mutex);
return 0;
}
......
/* 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 <FindDirectory.h> /* find_path() */
#include <OS.h>
void uv_loadavg(double avg[3]) {
avg[0] = 0;
avg[1] = 0;
avg[2] = 0;
}
int uv_exepath(char* buffer, size_t* size) {
char abspath[B_PATH_NAME_LENGTH];
status_t status;
ssize_t abspath_len;
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
status = find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, abspath,
sizeof(abspath));
if (status != B_OK)
return UV__ERR(status);
abspath_len = uv__strscpy(buffer, abspath, *size);
*size -= 1;
if (abspath_len >= 0 && *size > (size_t)abspath_len)
*size = (size_t)abspath_len;
return 0;
}
uint64_t uv_get_free_memory(void) {
status_t status;
system_info sinfo;
status = get_system_info(&sinfo);
if (status != B_OK)
return 0;
return (sinfo.max_pages - sinfo.used_pages) * B_PAGE_SIZE;
}
uint64_t uv_get_total_memory(void) {
status_t status;
system_info sinfo;
status = get_system_info(&sinfo);
if (status != B_OK)
return 0;
return sinfo.max_pages * B_PAGE_SIZE;
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
area_info area;
ssize_t cookie;
status_t status;
thread_info thread;
status = get_thread_info(find_thread(NULL), &thread);
if (status != B_OK)
return UV__ERR(status);
cookie = 0;
*rss = 0;
while (get_next_area_info(thread.team, &cookie, &area) == B_OK)
*rss += area.ram_size;
return 0;
}
int uv_uptime(double* uptime) {
/* system_time() returns time since booting in microseconds */
*uptime = (double)system_time() / 1000000;
return 0;
}
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
cpu_topology_node_info* topology_infos;
int i;
status_t status;
system_info system;
uint32_t topology_count;
uint64_t cpuspeed;
uv_cpu_info_t* cpu_info;
if (cpu_infos == NULL || count == NULL)
return UV_EINVAL;
status = get_cpu_topology_info(NULL, &topology_count);
if (status != B_OK)
return UV__ERR(status);
topology_infos = uv__malloc(topology_count * sizeof(*topology_infos));
if (topology_infos == NULL)
return UV_ENOMEM;
status = get_cpu_topology_info(topology_infos, &topology_count);
if (status != B_OK) {
uv__free(topology_infos);
return UV__ERR(status);
}
cpuspeed = 0;
for (i = 0; i < (int)topology_count; i++) {
if (topology_infos[i].type == B_TOPOLOGY_CORE) {
cpuspeed = topology_infos[i].data.core.default_frequency;
break;
}
}
uv__free(topology_infos);
status = get_system_info(&system);
if (status != B_OK)
return UV__ERR(status);
*cpu_infos = uv__calloc(system.cpu_count, sizeof(**cpu_infos));
if (*cpu_infos == NULL)
return UV_ENOMEM;
/* CPU time and model are not exposed by Haiku. */
cpu_info = *cpu_infos;
for (i = 0; i < (int)system.cpu_count; i++) {
cpu_info->model = uv__strdup("unknown");
cpu_info->speed = (int)(cpuspeed / 1000000);
cpu_info++;
}
*count = system.cpu_count;
return 0;
}
This diff is collapsed.
This diff is collapsed.
......@@ -359,9 +359,19 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 0;
nevents = 0;
assert(loop->watchers != NULL);
loop->watchers[loop->nwatchers] = (void*) events;
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
{
/* 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;
......@@ -980,7 +990,7 @@ static uint64_t uv__read_proc_meminfo(const char* what) {
rc = 0;
fd = uv__open_cloexec("/proc/meminfo", O_RDONLY);
if (fd == -1)
if (fd < 0)
return 0;
n = read(fd, buf, sizeof(buf) - 1);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -923,7 +923,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
continue;
ep = loop->ep;
if (fd == ep->msg_queue) {
if (pe->is_msg) {
os390_message_queue_handler(ep);
continue;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -322,5 +322,6 @@ char *uv__strndup(const char* s, size_t n);
void* uv__malloc(size_t size);
void uv__free(void* ptr);
void* uv__realloc(void* ptr, size_t size);
void* uv__reallocf(void* ptr, size_t size);
#endif /* UV_COMMON_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment