deps: update libuv to 1.51.0

PR-URL: https://github.com/nodejs/node/pull/58124
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Node.js GitHub Bot 2025-05-16 02:39:36 -04:00 committed by GitHub
parent b6189c352c
commit 0315283cbd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 1085 additions and 394 deletions

View file

@ -2,7 +2,7 @@ version: 2
sphinx:
builder: html
configuration: null
configuration: docs/src/conf.py
fail_on_warning: false
build:

12
deps/uv/AUTHORS vendored
View file

@ -592,3 +592,15 @@ Thad House <ThadHouse@users.noreply.github.com>
Julian A Avar C <28635807+julian-a-avar-c@users.noreply.github.com>
amcgoogan <105525867+amcgoogan@users.noreply.github.com>
Rafael Gonzaga <rafael.nunu@hotmail.com>
Morten Engelhardt Olsen <moro.engelhardt@gmail.com>
Andrey <bag@zurbagan.org>
Julio Jordán <juliojjordanp@outlook.com>
Jinho Jang <verycosy@kakao.com>
Velikiy Kirill <kuklix@ya.ru>
rainlow <37818892+rainlow@users.noreply.github.com>
Paolo Insogna <paolo@cowtech.it>
Robert Nagy <robert@openbsd.org>
mugitya03 <mugitya233@outlook.com>
Itay Bookstein <ibookstein@gmail.com>
crupest <crupest@outlook.com>
AE1020 <68134252+AE1020@users.noreply.github.com>

View file

@ -20,7 +20,7 @@ include(CTest)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@ -434,6 +434,7 @@ endif()
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|Linux|NetBSD|OpenBSD")
list(APPEND uv_test_libraries util)
list(APPEND uv_libraries m)
endif()
if(CYGWIN OR MSYS)
@ -583,6 +584,7 @@ if(LIBUV_BUILD_TESTS)
test/test-loop-close.c
test/test-loop-configure.c
test/test-loop-handles.c
test/test-loop-oom.c
test/test-loop-stop.c
test/test-loop-time.c
test/test-metrics.c

92
deps/uv/ChangeLog vendored
View file

@ -1,4 +1,94 @@
2025.01.15, Version 1.50.0 (Stable)
2025.04.25, Version 1.51.0 (Stable)
Changes since version 1.50.0:
* win: fix leak in uv_os_tmpdir (Saúl Ibarra Corretgé)
* docs: fix RTD build (Saúl Ibarra Corretgé)
* win: lazy-load [GS]etThreadDescription symbols (Ben Noordhuis)
* linux: try preadv64/pwritev64 before preadv/pwritev (Ben Noordhuis)
* win: check cwd length before spawning a child process (Morten Engelhardt
Olsen)
* macos,bsd: handle missing /dev/null in chroot env (Andrey)
* doc: fix README link text (Julio Jordán)
* win: fix order of FILE_STAT_BASIC_INFORMATION struct fields (Hüseyin Açacak)
* macos: increase child process stdio buffer size (Jinho Jang)
* doc: add C3 bindings to LINKS.md (Velikiy Kirill)
* unix: remove unnecessary errno.h include in poll.c (Juan José Arboleda)
* win: fix the inconsistency in volume serial number (Hüseyin Açacak)
* unix: add thread affinity support on openharmony (rainlow)
* unix: enable getrusage for SunOS (Paolo Insogna)
* unix,win: accept NAN/INFINITY as file timestamps (Ben Noordhuis)
* win: add ENABLE_VIRTUAL_TERMINAL_INPUT raw tty mode (Anna Henningsen)
* test: handle UV_ENOTSUP in platform_output (cjihrig)
* doc: fix rendering of threading.html (Tobias Nießen)
* unix,sunos: enable use of sendmmsg on Solaris and Illumos (Stacey Marshall)
* unix: handle out of memory in iface name copy (Ben Noordhuis)
* openbsd: do not error out if cpuspeed is not available (Robert Nagy)
* test: skip thread_name_threadpool on AIX/IBMi (Abdirahim Musse)
* aix,ibmi: fix undeclared identifiers (Richard Lau)
* unix,sunos: prefer SO_REUSEPORT for load balancing (Stacey Marshall)
* doc: free lib pointer before function return (mugitya03)
* test: link with libm (Juan José Arboleda)
* style: rename parameter to match definition (Mohammed Keyvanzadeh)
* test: support partial output lines in test runner (cjihrig)
* build: switch from c90 to c11 (Ben Noordhuis)
* linux: allow nul bytes in abstract socket address (Itay Bookstein)
* sunos: use pipe2 on solaris and illumos (Andy Pan)
* unix: remove TOCTOU issues from uv_pipe_chmod (Ben Noordhuis)
* unix: use pipe_fname if getsockname returns nothing (crupest)
* haiku: use uint32 instead of uint32_t (AE1020)
* doc: update thread pool stack size comment (Ben Noordhuis)
* unix: improve uv_loop_init OOM handling (Ben Noordhuis)
* test: merge uv_tcp_connect callbacks (Juan José Arboleda)
* test: skip multievent tests on macOS with TSAN enabled (Juan José Arboleda)
* linux: align CPU quota calculation with Rust (Juan José Arboleda)
* kqueue: improve fs event watcher OOM handling (Juan José Arboleda)
* sunos: improve fs event watcher OOM handling (Juan José Arboleda)
* build: shorten instructions for cmake build (Juan José Arboleda)
2025.01.15, Version 1.50.0 (Stable), 8fb9cb919489a48880680a56efecff6a7dfb4504
Changes since version 1.49.2:

2
deps/uv/LINKS.md vendored
View file

@ -108,3 +108,5 @@
* [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem
* Haskell
* [Z.Haskell](https://z.haskell.world)
* C3
* [libuv.c3l](https://github.com/velikoss/libuv.c3l)

5
deps/uv/Makefile.am vendored
View file

@ -206,12 +206,13 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-ipc-send-recv.c \
test/test-ipc.c \
test/test-list.h \
test/test-loop-handles.c \
test/test-loop-alive.c \
test/test-loop-close.c \
test/test-loop-configure.c \
test/test-loop-handles.c \
test/test-loop-oom.c \
test/test-loop-stop.c \
test/test-loop-time.c \
test/test-loop-configure.c \
test/test-metrics.c \
test/test-multiple-listen.c \
test/test-mutexes.c \

4
deps/uv/README.md vendored
View file

@ -189,9 +189,7 @@ $ make install
To build with [CMake][]:
```bash
$ mkdir -p build
$ (cd build && cmake .. -DBUILD_TESTING=ON) # generate project with tests
$ cmake -B build -DBUILD_TESTING=ON # generate project with tests
$ cmake --build build # add `-j <n>` with cmake >= 3.12
# Run tests:

View file

@ -4,7 +4,7 @@
|---|---|---|---|
| GNU/Linux | Tier 1 | Linux >= 3.10 with glibc >= 2.17 | |
| macOS | Tier 1 | macOS >= 11 | Currently supported macOS releases |
| Windows | Tier 1 | >= Windows 10 | VS 2015 and later are supported |
| Windows | Tier 1 | >= Windows 10 | VS 2017 and later are supported |
| FreeBSD | Tier 2 | >= 12 | |
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |

View file

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.50.0], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.51.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])
@ -33,7 +33,7 @@ CC_ATTRIBUTE_VISIBILITY([default], [
# we exclude -fno-strict-aliasing for xlc
CC_CHECK_FLAG_SUPPORTED_APPEND([-fno-strict-aliasing])
CC_CHECK_CFLAGS_APPEND([-g])
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
CC_CHECK_CFLAGS_APPEND([-std=gnu11])
CC_CHECK_CFLAGS_APPEND([-Wall])
CC_CHECK_CFLAGS_APPEND([-Wextra])
CC_CHECK_CFLAGS_APPEND([-Wno-long-long])

View file

@ -430,6 +430,12 @@ API
Equivalent to :man:`utime(2)`, :man:`futimes(3)` and :man:`lutimes(3)` respectively.
Passing `UV_FS_UTIME_NOW` as the atime or mtime sets the timestamp to the
current time.
Passing `UV_FS_UTIME_OMIT` as the atime or mtime leaves the timestamp
untouched.
.. note::
z/OS: `uv_fs_lutime()` is not implemented for z/OS. It can still be called but will return
``UV_ENOSYS``.

View file

@ -58,5 +58,5 @@ libuv can be downloaded from `here <https://dist.libuv.org/dist/>`_.
Installation
------------
Installation instructions can be found in `the README <https://github.com/libuv/libuv/blob/master/README.md>`_.
Installation instructions can be found in the `README <https://github.com/libuv/libuv/blob/master/README.md>`_.

View file

@ -146,6 +146,8 @@ Threads
a thread name can be: Linux, IBM i (16), macOS (64), Windows (32767), and NetBSD (32), etc. `uv_thread_setname()`
will truncate it in case `name` is larger than the limit of the platform.
Not supported on Windows Server 2016, returns `UV_ENOSYS`.
.. versionadded:: 1.50.0
.. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size)
@ -155,9 +157,12 @@ Threads
The buffer should be large enough to hold the name of the thread plus the trailing NUL, or it will be truncated to fit
with the trailing NUL.
Not supported on Windows Server 2016, returns `UV_ENOSYS`.
.. versionadded:: 1.50.0
.. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority)
If the function succeeds, the return value is 0.
If the function fails, the return value is less than zero.
Sets the scheduling priority of the thread specified by tid. It requires elevated
@ -165,7 +170,9 @@ Threads
The priority can be set to the following constants. UV_THREAD_PRIORITY_HIGHEST,
UV_THREAD_PRIORITY_ABOVE_NORMAL, UV_THREAD_PRIORITY_NORMAL,
UV_THREAD_PRIORITY_BELOW_NORMAL, UV_THREAD_PRIORITY_LOWEST.
.. c:function:: int uv_thread_getpriority(uv_thread_t tid, int* priority)
If the function succeeds, the return value is 0.
If the function fails, the return value is less than zero.
Retrieves the scheduling priority of the thread specified by tid. The value in the

View file

@ -20,10 +20,10 @@ is 1024).
.. versionchanged:: 1.50.0 threads now have a default name of libuv-worker.
The threadpool is global and shared across all event loops. When a particular
function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`)
function makes use of the threadpool (e.g. when using :c:func:`uv_queue_work`)
libuv preallocates and initializes the maximum number of threads allowed by
``UV_THREADPOOL_SIZE``. This causes a relatively minor memory overhead
(~1MB for 128 threads) but increases the performance of threading at runtime.
``UV_THREADPOOL_SIZE``. More threads usually means more throughput but a higher
memory footprint. Thread stacks grow lazily on most platforms though.
.. note::
Note that even though a global thread pool which is shared across all events

View file

@ -27,10 +27,15 @@ Data types
typedef enum {
/* Initial/normal terminal mode */
UV_TTY_MODE_NORMAL,
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
/*
* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled).
* May become equivalent to UV_TTY_MODE_RAW_VT in future libuv versions.
*/
UV_TTY_MODE_RAW,
/* Binary-safe I/O mode for IPC (Unix-only) */
UV_TTY_MODE_IO
UV_TTY_MODE_IO,
/* Raw input mode. On Windows ENABLE_VIRTUAL_TERMINAL_INPUT is also set. */
UV_TTY_MODE_RAW_VT
} uv_tty_mode_t;
.. c:enum:: uv_tty_vtermstate_t

12
deps/uv/include/uv.h vendored
View file

@ -58,6 +58,7 @@ extern "C" {
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
/* Internal type, do not use. */
struct uv__queue {
@ -805,10 +806,15 @@ struct uv_tty_s {
typedef enum {
/* Initial/normal terminal mode */
UV_TTY_MODE_NORMAL,
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
/*
* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled).
* May become equivalent to UV_TTY_MODE_RAW_VT in future libuv versions.
*/
UV_TTY_MODE_RAW,
/* Binary-safe I/O mode for IPC (Unix-only) */
UV_TTY_MODE_IO
UV_TTY_MODE_IO,
/* Raw input mode. On Windows ENABLE_VIRTUAL_TERMINAL_INPUT is also set. */
UV_TTY_MODE_RAW_VT
} uv_tty_mode_t;
typedef enum {
@ -1585,6 +1591,8 @@ UV_EXTERN int uv_fs_chmod(uv_loop_t* loop,
const char* path,
int mode,
uv_fs_cb cb);
#define UV_FS_UTIME_NOW (INFINITY)
#define UV_FS_UTIME_OMIT (NAN)
UV_EXTERN int uv_fs_utime(uv_loop_t* loop,
uv_fs_t* req,
const char* path,

View file

@ -31,7 +31,7 @@
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 50
#define UV_VERSION_MINOR 51
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""

View file

@ -499,8 +499,11 @@ typedef struct {
union { \
struct { \
/* Used for readable TTY handles */ \
/* TODO: remove me in v2.x. */ \
HANDLE unused_; \
union { \
/* TODO: remove me in v2.x. */ \
HANDLE unused_; \
int mode; \
} mode; \
uv_buf_t read_line_buffer; \
HANDLE read_raw_wait; \
/* Fields used for translating win keystrokes into vt100 characters */ \

View file

@ -51,7 +51,7 @@ struct poll_ctx {
static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b);
static void poll_cb(uv_fs_t* req);
static void timer_cb(uv_timer_t* timer);
static void timer_close_cb(uv_handle_t* handle);
static void timer_close_cb(uv_handle_t* timer);
static uv_stat_t zero_statbuf;

View file

@ -1120,6 +1120,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifreq *ifr, *p, flg;
struct in6_ifreq if6;
struct sockaddr_dl* sa_addr;
size_t namelen;
char* name;
ifc.ifc_req = NULL;
sock6fd = -1;
@ -1156,6 +1158,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
/* Count all up and running ipv4/ipv6 addresses */
namelen = 0;
ifr = ifc.ifc_req;
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
p = ifr;
@ -1175,6 +1178,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
namelen += strlen(p->ifr_name) + 1;
(*count)++;
}
@ -1182,11 +1186,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
goto cleanup;
/* Alloc the return interface structs */
*addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
if (*addresses == NULL) {
r = UV_ENOMEM;
goto cleanup;
}
name = (char*) &(*addresses)[*count];
address = *addresses;
ifr = ifc.ifc_req;
@ -1210,7 +1215,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
/* All conditions above must match count loop */
address->name = uv__strdup(p->ifr_name);
namelen = strlen(p->ifr_name) + 1;
address->name = memcpy(name, p->ifr_name, namelen);
name += namelen;
if (inet6)
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
@ -1282,13 +1289,7 @@ cleanup:
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);
}
int count) {
uv__free(addresses);
}

View file

@ -280,7 +280,7 @@ static int uv__async_start(uv_loop_t* loop) {
* thus we create one for that, but this fd will not be actually used,
* it's just a placeholder and magic number which is going to be closed
* during the cleanup, as other FDs. */
err = uv__open_cloexec("/dev/null", O_RDONLY);
err = uv__open_cloexec("/", O_RDONLY);
if (err < 0)
return err;
@ -308,8 +308,14 @@ static int uv__async_start(uv_loop_t* loop) {
return err;
#endif
uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]);
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
err = uv__io_init_start(loop, &loop->async_io_watcher, uv__async_io,
pipefd[0], POLLIN);
if (err < 0) {
uv__close(pipefd[0]);
if (pipefd[1] != -1)
uv__close(pipefd[1]);
return err;
}
loop->async_wfd = pipefd[1];
#if UV__KQUEUE_EVFILT_USER

View file

@ -65,13 +65,13 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
return 0;
}
/* TODO(bnoordhuis) share with linux.c */
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
struct ifaddrs* addrs;
struct ifaddrs* ent;
uv_interface_address_t* address;
#if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__)
int i;
#endif
size_t namelen;
char* name;
*count = 0;
*addresses = NULL;
@ -80,9 +80,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return UV__ERR(errno);
/* Count the number of interfaces */
namelen = 0;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
namelen += strlen(ent->ifa_name) + 1;
(*count)++;
}
@ -92,20 +94,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
/* Make sure the memory is initiallized to zero using calloc() */
*addresses = uv__calloc(*count, sizeof(**addresses));
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
if (*addresses == NULL) {
freeifaddrs(addrs);
return UV_ENOMEM;
}
name = (char*) &(*addresses)[*count];
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
address->name = uv__strdup(ent->ifa_name);
namelen = strlen(ent->ifa_name) + 1;
address->name = memcpy(name, ent->ifa_name, namelen);
name += namelen;
if (ent->ifa_addr->sa_family == AF_INET6) {
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@ -129,6 +133,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
#if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__)
/* Fill in physical addresses for each interface */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
int i;
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
continue;
@ -151,13 +157,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
/* TODO(bnoordhuis) share with linux.c */
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);
}

View file

@ -867,7 +867,7 @@ static unsigned int next_power_of_two(unsigned int val) {
return val;
}
static void maybe_resize(uv_loop_t* loop, unsigned int len) {
static int maybe_resize(uv_loop_t* loop, unsigned int len) {
uv__io_t** watchers;
void* fake_watcher_list;
void* fake_watcher_count;
@ -875,7 +875,7 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
unsigned int i;
if (len <= loop->nwatchers)
return;
return 0;
/* Preserve fake watcher list and count at the end of the watchers */
if (loop->watchers != NULL) {
@ -891,7 +891,7 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
(nwatchers + 2) * sizeof(loop->watchers[0]));
if (watchers == NULL)
abort();
return UV_ENOMEM;
for (i = loop->nwatchers; i < nwatchers; i++)
watchers[i] = NULL;
watchers[nwatchers] = fake_watcher_list;
@ -899,11 +899,11 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
loop->watchers = watchers;
loop->nwatchers = nwatchers;
return 0;
}
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
assert(cb != NULL);
assert(fd >= -1);
uv__queue_init(&w->pending_queue);
uv__queue_init(&w->watcher_queue);
@ -914,14 +914,18 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
}
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int err;
assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
assert(0 != events);
assert(w->fd >= 0);
assert(w->fd < INT_MAX);
w->pevents |= events;
maybe_resize(loop, w->fd + 1);
err = maybe_resize(loop, w->fd + 1);
if (err)
return err;
#if !defined(__sun)
/* The event ports backend needs to rearm all file descriptors on each and
@ -929,7 +933,7 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
* short-circuit here if the event mask is unchanged.
*/
if (w->events == w->pevents)
return;
return 0;
#endif
if (uv__queue_empty(&w->watcher_queue))
@ -939,6 +943,25 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
loop->watchers[w->fd] = w;
loop->nfds++;
}
return 0;
}
int uv__io_init_start(uv_loop_t* loop,
uv__io_t* w,
uv__io_cb cb,
int fd,
unsigned int events) {
int err;
assert(cb != NULL);
assert(fd > -1);
uv__io_init(w, cb, fd);
err = uv__io_start(loop, w, events);
if (err)
uv__io_init(w, NULL, -1);
return err;
}
@ -1078,6 +1101,8 @@ int uv_getrusage_thread(uv_rusage_t* rusage) {
return 0;
#elif defined(RUSAGE_LWP)
return uv__getrusage(RUSAGE_LWP, rusage);
#elif defined(RUSAGE_THREAD)
return uv__getrusage(RUSAGE_THREAD, rusage);
#endif /* defined(__APPLE__) */
@ -2021,14 +2046,11 @@ unsigned int uv_available_parallelism(void) {
#ifdef __linux__
{
double rc_with_cgroup;
uv__cpu_constraint c = {0, 0, 0.0};
long long quota = 0;
if (uv__get_constrained_cpu(&c) == 0 && c.period_length > 0) {
rc_with_cgroup = (double)c.quota_per_period / c.period_length * c.proportions;
if (rc_with_cgroup < rc)
rc = (long)rc_with_cgroup; /* Casting is safe since rc_with_cgroup < rc < LONG_MAX */
}
if (uv__get_constrained_cpu(&quota) == 0)
if (quota > 0 && quota < rc)
rc = quota;
}
#endif /* __linux__ */

116
deps/uv/src/unix/fs.c vendored
View file

@ -203,8 +203,23 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
}
UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
#if defined(__APPLE__) \
|| defined(_AIX71) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__HAIKU__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
static struct timespec uv__fs_to_timespec(double time) {
struct timespec ts;
if (uv__isinf(time))
return (struct timespec){UTIME_NOW, UTIME_NOW};
if (uv__isnan(time))
return (struct timespec){UTIME_OMIT, UTIME_OMIT};
ts.tv_sec = time;
ts.tv_nsec = (time - ts.tv_sec) * 1e9;
@ -221,41 +236,23 @@ UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
}
return ts;
}
#endif
UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
struct timeval tv;
tv.tv_sec = time;
tv.tv_usec = (time - tv.tv_sec) * 1e6;
if (tv.tv_usec < 0) {
tv.tv_usec += 1e6;
tv.tv_sec -= 1;
}
return tv;
}
static ssize_t uv__fs_futime(uv_fs_t* req) {
#if defined(__linux__) \
#if defined(__APPLE__) \
|| defined(_AIX71) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__HAIKU__) \
|| defined(__GNU__)
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
return futimens(req->file, ts);
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__sun)
struct timeval tv[2];
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
return futimes(req->file, tv);
# endif
#elif defined(__MVS__)
attrib_t atr;
memset(&atr, 0, sizeof(atr));
@ -461,12 +458,7 @@ static ssize_t uv__pwritev_emul(int fd,
/* The function pointer cache is an uintptr_t because _Atomic void*
* doesn't work on macos/ios/etc...
* Disable optimization on armv7 to work around the bug described in
* https://github.com/libuv/libuv/issues/4532
*/
#if defined(__arm__) && (__ARM_ARCH == 7)
__attribute__((optimize("O0")))
#endif
static ssize_t uv__preadv_or_pwritev(int fd,
const struct iovec* bufs,
size_t nbufs,
@ -479,7 +471,12 @@ static ssize_t uv__preadv_or_pwritev(int fd,
p = (void*) atomic_load_explicit(cache, memory_order_relaxed);
if (p == NULL) {
#ifdef RTLD_DEFAULT
p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev");
/* Try _LARGEFILE_SOURCE version of preadv/pwritev first,
* then fall back to the plain version, for libcs like musl.
*/
p = dlsym(RTLD_DEFAULT, is_pread ? "preadv64" : "pwritev64");
if (p == NULL)
p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev");
dlerror(); /* Clear errors. */
#endif /* RTLD_DEFAULT */
if (p == NULL)
@ -487,10 +484,7 @@ static ssize_t uv__preadv_or_pwritev(int fd,
atomic_store_explicit(cache, (uintptr_t) p, memory_order_relaxed);
}
/* Use memcpy instead of `f = p` to work around a compiler bug,
* see https://github.com/libuv/libuv/issues/4532
*/
memcpy(&f, &p, sizeof(p));
f = p;
return f(fd, bufs, nbufs, off);
}
@ -1145,25 +1139,20 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
static ssize_t uv__fs_utime(uv_fs_t* req) {
#if defined(__linux__) \
|| defined(_AIX71) \
|| defined(__sun) \
|| defined(__HAIKU__)
#if defined(__APPLE__) \
|| defined(_AIX71) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__HAIKU__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
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, 0);
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__)
struct timeval tv[2];
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)
#elif defined(_AIX) && !defined(_AIX71)
struct utimbuf buf;
buf.actime = req->atime;
buf.modtime = req->mtime;
@ -1184,24 +1173,19 @@ 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__) || \
defined(__GNU__) || \
defined(__OpenBSD__)
#if defined(__APPLE__) \
|| defined(_AIX71) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__HAIKU__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
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(__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;

View file

@ -120,7 +120,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
int i;
status_t status;
system_info system;
uint32_t topology_count;
uint32 topology_count; /* Haiku expects address of uint32, not uint32_t */
uint64_t cpuspeed;
uv_cpu_info_t* cpu_info;

View file

@ -394,6 +394,8 @@ static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
struct ifaddrs_pase *ifap = NULL, *cur;
size_t namelen;
char* name;
int inet6, r = 0;
*count = 0;
@ -403,6 +405,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return UV_ENOSYS;
/* The first loop to get the size of the array to be allocated */
namelen = 0;
for (cur = ifap; cur; cur = cur->ifa_next) {
if (!(cur->ifa_addr->sa_family == AF_INET6 ||
cur->ifa_addr->sa_family == AF_INET))
@ -411,6 +414,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
continue;
namelen += strlen(cur->ifa_name) + 1;
(*count)++;
}
@ -420,11 +424,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
/* Alloc the return interface structs */
*addresses = uv__calloc(*count, sizeof(**addresses));
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
if (*addresses == NULL) {
Qp2freeifaddrs(ifap);
return UV_ENOMEM;
}
name = (char*) &(*addresses)[*count];
address = *addresses;
/* The second loop to fill in the array */
@ -436,7 +442,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
continue;
address->name = uv__strdup(cur->ifa_name);
namelen = strlen(cur->ifa_name) + 1;
address->name = memcpy(name, cur->ifa_name, namelen);
name += namelen;
inet6 = (cur->ifa_addr->sa_family == AF_INET6);
@ -497,13 +505,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
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);
}
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}

View file

@ -257,7 +257,12 @@ void uv__make_close_pending(uv_handle_t* handle);
int uv__getiovmax(void);
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
int uv__io_init_start(uv_loop_t* loop,
uv__io_t* w,
uv__io_cb cb,
int fd,
unsigned int events);
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__io_close(uv_loop_t* loop, uv__io_t* w);
void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
@ -489,13 +494,7 @@ uv__fs_copy_file_range(int fd_in,
#endif
#ifdef __linux__
typedef struct {
long long quota_per_period;
long long period_length;
double proportions;
} uv__cpu_constraint;
int uv__get_constrained_cpu(uv__cpu_constraint* constraint);
int uv__get_constrained_cpu(long long* quota);
#endif
#if defined(__sun) && !defined(__illumos__)

View file

@ -569,6 +569,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
const char* path,
unsigned int flags) {
int fd;
int r;
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
struct stat statbuf;
#endif
@ -604,7 +605,6 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (0 == atomic_load_explicit(&uv__has_forked_with_cfrunloop,
memory_order_relaxed)) {
int r;
/* The fallback fd is no longer needed */
uv__close_nocheckstdio(fd);
handle->event_watcher.fd = -1;
@ -620,11 +620,16 @@ int uv_fs_event_start(uv_fs_event_t* handle,
fallback:
#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
uv__handle_start(handle);
uv__io_init(&handle->event_watcher, uv__fs_event, fd);
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
r = uv__io_init_start(handle->loop,
&handle->event_watcher,
uv__fs_event,
fd,
POLLIN);
return 0;
if (!r)
uv__handle_start(handle);
return r;
}

View file

@ -1954,11 +1954,15 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
return !exclude_type;
}
/* TODO(bnoordhuis) share with bsd-ifaddrs.c */
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifaddrs *addrs, *ent;
uv_interface_address_t* address;
struct sockaddr_ll* sll;
struct ifaddrs* addrs;
struct ifaddrs* ent;
size_t namelen;
char* name;
int i;
struct sockaddr_ll *sll;
*count = 0;
*addresses = NULL;
@ -1967,10 +1971,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return UV__ERR(errno);
/* Count the number of interfaces */
namelen = 0;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
namelen += strlen(ent->ifa_name) + 1;
(*count)++;
}
@ -1980,19 +1986,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
/* Make sure the memory is initiallized to zero using calloc() */
*addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
if (*addresses == NULL) {
freeifaddrs(addrs);
return UV_ENOMEM;
}
name = (char*) &(*addresses)[*count];
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
address->name = uv__strdup(ent->ifa_name);
namelen = strlen(ent->ifa_name) + 1;
address->name = memcpy(name, ent->ifa_name, namelen);
name += namelen;
if (ent->ifa_addr->sa_family == AF_INET6) {
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@ -2036,14 +2045,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
/* TODO(bnoordhuis) share with bsd-ifaddrs.c */
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);
}
int count) {
uv__free(addresses);
}
@ -2301,49 +2305,83 @@ uint64_t uv_get_available_memory(void) {
static int uv__get_cgroupv2_constrained_cpu(const char* cgroup,
uv__cpu_constraint* constraint) {
char path[256];
char buf[1024];
unsigned int weight;
int cgroup_size;
long long* quota) {
static const char cgroup_mount[] = "/sys/fs/cgroup";
const char* cgroup_trimmed;
char buf[1024];
char full_path[256];
char path[256];
char quota_buf[16];
char* last_slash;
int cgroup_size;
long long limit;
long long min_quota;
long long period;
if (strncmp(cgroup, "0::/", 4) != 0)
return UV_EINVAL;
/* Trim ending \n by replacing it with a 0 */
cgroup_trimmed = cgroup + sizeof("0::/") - 1; /* Skip the prefix "0::/" */
cgroup_size = (int)strcspn(cgroup_trimmed, "\n"); /* Find the first slash */
cgroup_size = (int)strcspn(cgroup_trimmed, "\n"); /* Find the first \n */
min_quota = LLONG_MAX;
/* Construct the path to the cpu.max file */
snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.max", cgroup_size,
cgroup_trimmed);
/* Construct the path to the cpu.max files */
snprintf(path, sizeof(path), "%s/%.*s/cgroup.controllers", cgroup_mount,
cgroup_size, cgroup_trimmed);
/* Read cpu.max */
/* Read controllers, if not exists, not really a cgroup */
if (uv__slurp(path, buf, sizeof(buf)) < 0)
return UV_EIO;
if (sscanf(buf, "%15s %llu", quota_buf, &constraint->period_length) != 2)
return UV_EINVAL;
if (strncmp(quota_buf, "max", 3) == 0)
constraint->quota_per_period = LLONG_MAX;
else if (sscanf(quota_buf, "%lld", &constraint->quota_per_period) != 1)
return UV_EINVAL; // conversion failed
/* Construct the path to the cpu.weight file */
snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.weight", cgroup_size,
snprintf(path, sizeof(path), "%s/%.*s", cgroup_mount, cgroup_size,
cgroup_trimmed);
/* Read cpu.weight */
if (uv__slurp(path, buf, sizeof(buf)) < 0)
return UV_EIO;
/*
* Traverse up the cgroup v2 hierarchy, starting from the current cgroup path.
* At each level, attempt to read the "cpu.max" file, which defines the CPU
* quota and period.
*
* This reflects how Linux applies cgroup limits hierarchically.
*
* e.g: given a path like /sys/fs/cgroup/foo/bar/baz, we check:
* - /sys/fs/cgroup/foo/bar/baz/cpu.max
* - /sys/fs/cgroup/foo/bar/cpu.max
* - /sys/fs/cgroup/foo/cpu.max
* - /sys/fs/cgroup/cpu.max
*/
while (strncmp(path, cgroup_mount, strlen(cgroup_mount)) == 0) {
snprintf(full_path, sizeof(full_path), "%s/cpu.max", path);
if (sscanf(buf, "%u", &weight) != 1)
return UV_EINVAL;
/* Silently ignore and continue if the file does not exist */
if (uv__slurp(full_path, quota_buf, sizeof(quota_buf)) < 0)
goto next;
constraint->proportions = (double)weight / 100.0;
/* No limit, move on */
if (strncmp(quota_buf, "max", 3) == 0)
goto next;
/* Read cpu.max */
if (sscanf(quota_buf, "%lld %lld", &limit, &period) != 2)
goto next;
/* Can't divide by 0 */
if (period == 0)
goto next;
*quota = limit / period;
if (*quota < min_quota)
min_quota = *quota;
next:
/* Move up one level in the cgroup hierarchy by trimming the last path.
* The loop ends once we reach the cgroup root mount point.
*/
last_slash = strrchr(path, '/');
if (last_slash == NULL || strcmp(path, cgroup_mount) == 0)
break;
*last_slash = '\0';
}
return 0;
}
@ -2364,12 +2402,13 @@ static char* uv__cgroup1_find_cpu_controller(const char* cgroup,
}
static int uv__get_cgroupv1_constrained_cpu(const char* cgroup,
uv__cpu_constraint* constraint) {
long long* quota) {
char path[256];
char buf[1024];
unsigned int shares;
int cgroup_size;
char* cgroup_cpu;
long long period_length;
long long quota_per_period;
cgroup_cpu = uv__cgroup1_find_cpu_controller(cgroup, &cgroup_size);
@ -2380,10 +2419,11 @@ static int uv__get_cgroupv1_constrained_cpu(const char* cgroup,
snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.cfs_quota_us",
cgroup_size, cgroup_cpu);
/* Read cpu.cfs_quota_us */
if (uv__slurp(path, buf, sizeof(buf)) < 0)
return UV_EIO;
if (sscanf(buf, "%lld", &constraint->quota_per_period) != 1)
if (sscanf(buf, "%lld", &quota_per_period) != 1)
return UV_EINVAL;
/* Construct the path to the cpu.cfs_period_us file */
@ -2394,26 +2434,19 @@ static int uv__get_cgroupv1_constrained_cpu(const char* cgroup,
if (uv__slurp(path, buf, sizeof(buf)) < 0)
return UV_EIO;
if (sscanf(buf, "%lld", &constraint->period_length) != 1)
if (sscanf(buf, "%lld", &period_length) != 1)
return UV_EINVAL;
/* Construct the path to the cpu.shares file */
snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.shares", cgroup_size,
cgroup_cpu);
/* Read cpu.shares */
if (uv__slurp(path, buf, sizeof(buf)) < 0)
return UV_EIO;
if (sscanf(buf, "%u", &shares) != 1)
/* Can't divide by 0 */
if (period_length == 0)
return UV_EINVAL;
constraint->proportions = (double)shares / 1024.0;
*quota = quota_per_period / period_length;
return 0;
}
int uv__get_constrained_cpu(uv__cpu_constraint* constraint) {
int uv__get_constrained_cpu(long long* quota) {
char cgroup[1024];
/* Read the cgroup from /proc/self/cgroup */
@ -2424,9 +2457,9 @@ int uv__get_constrained_cpu(uv__cpu_constraint* constraint) {
* The entry for cgroup v2 is always in the format "0::$PATH"
* see https://docs.kernel.org/admin-guide/cgroup-v2.html */
if (strncmp(cgroup, "0::/", 4) == 0)
return uv__get_cgroupv2_constrained_cpu(cgroup, constraint);
return uv__get_cgroupv2_constrained_cpu(cgroup, quota);
else
return uv__get_cgroupv1_constrained_cpu(cgroup, constraint);
return uv__get_cgroupv1_constrained_cpu(cgroup, quota);
}
@ -2456,6 +2489,7 @@ static int compare_watchers(const struct watcher_list* a,
static int init_inotify(uv_loop_t* loop) {
int err;
int fd;
if (loop->inotify_fd != -1)
@ -2465,10 +2499,14 @@ static int init_inotify(uv_loop_t* loop) {
if (fd < 0)
return UV__ERR(errno);
loop->inotify_fd = fd;
uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
uv__io_start(loop, &loop->inotify_read_watcher, POLLIN);
err = uv__io_init_start(loop, &loop->inotify_read_watcher, uv__inotify_read,
fd, POLLIN);
if (err) {
uv__close(fd);
return err;
}
loop->inotify_fd = fd;
return 0;
}

View file

@ -32,12 +32,11 @@ int uv_loop_init(uv_loop_t* loop) {
void* saved_data;
int err;
saved_data = loop->data;
memset(loop, 0, sizeof(*loop));
loop->data = saved_data;
lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields));
lfields = uv__calloc(1, sizeof(*lfields));
if (lfields == NULL)
return UV_ENOMEM;
loop->internal_fields = lfields;
@ -116,6 +115,11 @@ fail_rwlock_init:
fail_signal_init:
uv__platform_loop_delete(loop);
if (loop->backend_fd != -1) {
uv__close(loop->backend_fd);
loop->backend_fd = -1;
}
fail_platform_init:
uv_mutex_destroy(&lfields->loop_metrics.lock);

View file

@ -211,8 +211,16 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
which[1] = HW_CPUSPEED;
size = sizeof(cpuspeed);
if (sysctl(which, ARRAY_SIZE(which), &cpuspeed, &size, NULL, 0))
cpuspeed = 0;
/*
* HW_CPUSPEED can return EOPNOTSUPP if cpuspeed is 0,
* so ignore that and continue the flow, because we
* still care about the rest of the CPU info.
*/
if (sysctl(which, ARRAY_SIZE(which), &cpuspeed, &size, NULL, 0) &&
(errno != EOPNOTSUPP)) {
goto error;
}
size = sizeof(info);
for (i = 0; i < numcpus; i++) {

View file

@ -31,13 +31,15 @@
/* Does the file path contain embedded nul bytes? */
static int includes_nul(const char *s, size_t n) {
static int includes_invalid_nul(const char *s, size_t n) {
if (n == 0)
return 0;
#ifdef __linux__
/* Accept abstract socket namespace path ("\0/virtual/path"). */
s++;
n--;
/* Accept abstract socket namespace paths, throughout which nul bytes have
* no special significance ("\0foo\0bar").
*/
if (s[0] == '\0')
return 0;
#endif
return NULL != memchr(s, '\0', n);
}
@ -84,7 +86,7 @@ int uv_pipe_bind2(uv_pipe_t* handle,
return UV_EINVAL;
#endif
if (includes_nul(name, namelen))
if (includes_invalid_nul(name, namelen))
return UV_EINVAL;
if (flags & UV_PIPE_NO_TRUNCATE)
@ -271,7 +273,7 @@ int uv_pipe_connect2(uv_connect_t* req,
if (namelen == 0)
return UV_EINVAL;
if (includes_nul(name, namelen))
if (includes_invalid_nul(name, namelen))
return UV_EINVAL;
if (flags & UV_PIPE_NO_TRUNCATE)
@ -445,13 +447,18 @@ uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
unsigned desired_mode;
struct stat pipe_stat;
char name_buffer[1 + UV__PATH_MAX];
int desired_mode;
size_t name_len;
const char* name;
int fd;
int r;
if (handle == NULL || uv__stream_fd(handle) == -1)
if (handle == NULL)
return UV_EBADF;
fd = uv__stream_fd(handle);
if (fd == -1)
return UV_EBADF;
if (mode != UV_READABLE &&
@ -459,31 +466,32 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
mode != (UV_WRITABLE | UV_READABLE))
return UV_EINVAL;
/* Unfortunately fchmod does not work on all platforms, we will use chmod. */
name_len = sizeof(name_buffer);
r = uv_pipe_getsockname(handle, name_buffer, &name_len);
if (r != 0)
return r;
/* stat must be used as fstat has a bug on Darwin */
if (uv__stat(name_buffer, &pipe_stat) == -1)
return UV__ERR(errno);
desired_mode = 0;
if (mode & UV_READABLE)
desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
if (mode & UV_WRITABLE)
desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
/* Exit early if pipe already has desired mode. */
if ((pipe_stat.st_mode & desired_mode) == desired_mode)
return 0;
/* fchmod on macOS and (Free|Net|Open)BSD does not support UNIX sockets. */
if (fchmod(fd, desired_mode))
if (errno != EINVAL && errno != EOPNOTSUPP)
return UV__ERR(errno);
pipe_stat.st_mode |= desired_mode;
/* Fall back to chmod. */
name_len = sizeof(name_buffer);
r = uv_pipe_getsockname(handle, name_buffer, &name_len);
if (r != 0)
return r;
name = name_buffer;
r = chmod(name_buffer, pipe_stat.st_mode);
/* On some platforms, getsockname returns an empty string, and we try with pipe_fname. */
if (name_len == 0 && handle->pipe_fname != NULL)
name = handle->pipe_fname;
return r != -1 ? 0 : UV__ERR(errno);
if (chmod(name, desired_mode))
return UV__ERR(errno);
return 0;
}
@ -494,7 +502,9 @@ int uv_pipe(uv_os_fd_t fds[2], int read_flags, int write_flags) {
defined(__FreeBSD__) || \
defined(__OpenBSD__) || \
defined(__DragonFly__) || \
defined(__NetBSD__)
defined(__NetBSD__) || \
defined(__illumos__) || \
(defined(UV__SOLARIS_11_4) && UV__SOLARIS_11_4)
int flags = O_CLOEXEC;
if ((read_flags & UV_NONBLOCK_PIPE) && (write_flags & UV_NONBLOCK_PIPE))

View file

@ -24,7 +24,6 @@
#include <unistd.h>
#include <assert.h>
#include <errno.h>
static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {

View file

@ -188,8 +188,12 @@ void uv__wait_children(uv_loop_t* loop) {
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
int mask;
int fd;
int ret;
int size;
int i;
mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
size = 64 * 1024;
switch (container->flags & mask) {
case UV_IGNORE:
@ -199,8 +203,17 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
assert(container->data.stream != NULL);
if (container->data.stream->type != UV_NAMED_PIPE)
return UV_EINVAL;
else
return uv_socketpair(SOCK_STREAM, 0, fds, 0, 0);
else {
ret = uv_socketpair(SOCK_STREAM, 0, fds, 0, 0);
if (ret == 0)
for (i = 0; i < 2; i++) {
setsockopt(fds[i], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
setsockopt(fds[i], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
}
}
return ret;
case UV_INHERIT_FD:
case UV_INHERIT_STREAM:

View file

@ -259,22 +259,28 @@ static void uv__signal_unregister_handler(int signum) {
static int uv__signal_loop_once_init(uv_loop_t* loop) {
int* pipefd;
int err;
/* Return if already initialized. */
if (loop->signal_pipefd[0] != -1)
pipefd = loop->signal_pipefd;
if (pipefd[0] != -1)
return 0;
err = uv__make_pipe(loop->signal_pipefd, UV_NONBLOCK_PIPE);
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
if (err)
return err;
uv__io_init(&loop->signal_io_watcher,
uv__signal_event,
loop->signal_pipefd[0]);
uv__io_start(loop, &loop->signal_io_watcher, POLLIN);
err = uv__io_init_start(loop, &loop->signal_io_watcher, uv__signal_event,
pipefd[0], POLLIN);
if (err) {
uv__close(pipefd[0]);
uv__close(pipefd[1]);
pipefd[0] = -1;
pipefd[1] = -1;
}
return 0;
return err;
}

View file

@ -546,8 +546,15 @@ int uv_fs_event_start(uv_fs_event_t* handle,
}
if (first_run) {
uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
uv__io_start(handle->loop, &handle->loop->fs_event_watcher, POLLIN);
err = uv__io_init_start(handle->loop,
&handle->loop->fs_event_watcher,
uv__fs_event_read,
portfd,
POLLIN);
if (err)
uv__handle_stop(handle);
return err;
}
return 0;
@ -826,6 +833,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
struct ifaddrs* addrs;
struct ifaddrs* ent;
size_t namelen;
char* name;
*count = 0;
*addresses = NULL;
@ -834,9 +843,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return UV__ERR(errno);
/* Count the number of interfaces */
namelen = 0;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent))
continue;
namelen += strlen(ent->ifa_name) + 1;
(*count)++;
}
@ -845,19 +856,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return 0;
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
*addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen);
if (*addresses == NULL) {
freeifaddrs(addrs);
return UV_ENOMEM;
}
name = (char*) &(*addresses)[*count];
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent))
continue;
address->name = uv__strdup(ent->ifa_name);
namelen = strlen(ent->ifa_name) + 1;
address->name = memcpy(name, ent->ifa_name, namelen);
name += namelen;
if (ent->ifa_addr->sa_family == AF_INET6) {
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@ -885,13 +899,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
#endif /* SUNOS_NO_IFADDRS */
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);
}
int count) {
uv__free(addresses);
}

View file

@ -214,7 +214,7 @@ int uv_thread_setaffinity(uv_thread_t* tid,
if (cpumask[i])
CPU_SET(i, &cpuset);
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__OHOS__)
if (sched_setaffinity(pthread_gettid_np(*tid), sizeof(cpuset), &cpuset))
r = errno;
else
@ -242,7 +242,7 @@ int uv_thread_getaffinity(uv_thread_t* tid,
return UV_EINVAL;
CPU_ZERO(&cpuset);
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__OHOS__)
if (sched_getaffinity(pthread_gettid_np(*tid), sizeof(cpuset), &cpuset))
r = errno;
else

View file

@ -284,6 +284,11 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
int fd;
int rc;
if (uv__is_raw_tty_mode(mode)) {
/* There is only a single raw TTY mode on UNIX. */
mode = UV_TTY_MODE_RAW;
}
if (tty->mode == (int) mode)
return 0;
@ -324,6 +329,8 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
case UV_TTY_MODE_IO:
uv__tty_make_raw(&tmp);
break;
default:
UNREACHABLE();
}
/* Apply changes after draining */

View file

@ -300,6 +300,9 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
*
* zOS does not support getsockname with SO_REUSEPORT option when using
* AF_UNIX.
*
* Solaris 11.4: SO_REUSEPORT will not load balance when SO_REUSEADDR
* is also set, but it's not valid for every socket type.
*/
static int uv__sock_reuseaddr(int fd) {
int yes;
@ -317,8 +320,18 @@ static int uv__sock_reuseaddr(int fd) {
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
return UV__ERR(errno);
}
#elif defined(SO_REUSEPORT) && !defined(__linux__) && !defined(__GNU__) && \
!defined(__sun__) && !defined(__DragonFly__) && !defined(_AIX73)
#elif defined(SO_REUSEPORT) && defined(UV__SOLARIS_11_4) && UV__SOLARIS_11_4
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) {
if (errno != ENOPROTOOPT)
return UV__ERR(errno);
/* Not all socket types accept SO_REUSEPORT. */
errno = 0;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
return UV__ERR(errno);
}
#elif defined(SO_REUSEPORT) && \
!defined(__linux__) && !defined(__GNU__) && \
!defined(__illumos__) && !defined(__DragonFly__) && !defined(_AIX73)
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
return UV__ERR(errno);
#else
@ -1298,7 +1311,8 @@ static int uv__udp_sendmsgv(int fd,
r = 0;
nsent = 0;
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
(defined(__sun__) && defined(MSG_WAITFORONE))
if (count > 1) {
for (i = 0; i < count; /*empty*/) {
struct mmsghdr m[20];
@ -1325,7 +1339,9 @@ static int uv__udp_sendmsgv(int fd,
goto exit;
}
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||
* (defined(__sun__) && defined(MSG_WAITFORONE))
*/
for (i = 0; i < count; i++, nsent++)
if ((r = uv__udp_sendmsg1(fd, bufs[i], nbufs[i], addrs[i])))

View file

@ -31,6 +31,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "uv.h"
#include "uv/tree.h"
@ -125,7 +126,7 @@ enum {
/* Only used by uv_tty_t handles. */
UV_HANDLE_TTY_READABLE = 0x01000000,
UV_HANDLE_TTY_RAW = 0x02000000,
UV_HANDLE_UNUSED0 = 0x02000000,
UV_HANDLE_TTY_SAVED_POSITION = 0x04000000,
UV_HANDLE_TTY_SAVED_ATTRIBUTES = 0x08000000,
@ -140,6 +141,10 @@ enum {
UV_HANDLE_REAP = 0x10000000
};
static inline int uv__is_raw_tty_mode(uv_tty_mode_t m) {
return m == UV_TTY_MODE_RAW || m == UV_TTY_MODE_RAW_VT;
}
int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
void uv__loop_close(uv_loop_t* loop);
@ -448,4 +453,22 @@ struct uv__loop_internal_fields_s {
# define UV_PTHREAD_MAX_NAMELEN_NP 16
#endif
/* Open-coded so downstream users don't have to link libm. */
static inline int uv__isinf(double d) {
uint64_t v;
STATIC_ASSERT(sizeof(v) == sizeof(d));
memcpy(&v, &d, sizeof(v));
return (v << 1 >> 53) == 2047 && !(v << 12);
}
/* Open-coded so downstream users don't have to link libm. */
static inline int uv__isnan(double d) {
uint64_t v;
STATIC_ASSERT(sizeof(v) == sizeof(d));
memcpy(&v, &d, sizeof(v));
return (v << 1 >> 53) == 2047 && !!(v << 12);
}
#endif /* UV_COMMON_H_ */

View file

@ -114,7 +114,7 @@ static int uv__loops_add(uv_loop_t* loop) {
failed_loops_realloc:
uv_mutex_unlock(&uv__loops_lock);
return ERROR_OUTOFMEMORY;
return UV_ENOMEM;
}

29
deps/uv/src/win/fs.c vendored
View file

@ -1788,7 +1788,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
SetLastError(pRtlNtStatusToDosError(nt_status));
return -1;
} else {
stat_info.VolumeSerialNumber.QuadPart = volume_info.VolumeSerialNumber;
stat_info.VolumeSerialNumber.LowPart = volume_info.VolumeSerialNumber;
}
stat_info.DeviceType = device_info.DeviceType;
@ -1839,7 +1839,7 @@ INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat) {
statbuf->st_dev = stat_info.VolumeSerialNumber.QuadPart;
statbuf->st_dev = stat_info.VolumeSerialNumber.LowPart;
/* Todo: st_mode should probably always be 0666 for everyone. We might also
* want to report 0777 if the file is a .exe or a directory.
@ -2580,14 +2580,29 @@ fchmod_cleanup:
INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
FILETIME filetime_a, filetime_m;
FILETIME filetime_as, *filetime_a = &filetime_as;
FILETIME filetime_ms, *filetime_m = &filetime_ms;
FILETIME now;
TIME_T_TO_FILETIME(atime, &filetime_a);
TIME_T_TO_FILETIME(mtime, &filetime_m);
if (uv__isinf(atime) || uv__isinf(mtime))
GetSystemTimeAsFileTime(&now);
if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) {
if (uv__isinf(atime))
filetime_a = &now;
else if (uv__isnan(atime))
filetime_a = NULL;
else
TIME_T_TO_FILETIME(atime, filetime_a);
if (uv__isinf(mtime))
filetime_m = &now;
else if (uv__isnan(mtime))
filetime_m = NULL;
else
TIME_T_TO_FILETIME(mtime, filetime_m);
if (!SetFileTime(handle, NULL, filetime_a, filetime_m))
return -1;
}
return 0;
}

View file

@ -898,7 +898,7 @@ int uv_spawn(uv_loop_t* loop,
*env = NULL, *cwd = NULL;
STARTUPINFOW startup;
PROCESS_INFORMATION info;
DWORD process_flags;
DWORD process_flags, cwd_len;
BYTE* child_stdio_buffer;
uv__process_init(loop, process);
@ -947,9 +947,10 @@ int uv_spawn(uv_loop_t* loop,
if (err)
goto done_uv;
cwd_len = wcslen(cwd);
} else {
/* Inherit cwd */
DWORD cwd_len, r;
DWORD r;
cwd_len = GetCurrentDirectoryW(0, NULL);
if (!cwd_len) {
@ -970,6 +971,15 @@ int uv_spawn(uv_loop_t* loop,
}
}
/* If cwd is too long, shorten it */
if (cwd_len >= MAX_PATH) {
cwd_len = GetShortPathNameW(cwd, cwd, cwd_len);
if (cwd_len == 0) {
err = GetLastError();
goto done;
}
}
/* Get PATH environment variable. */
path = find_path(env);
if (path == NULL) {

View file

@ -57,6 +57,9 @@ STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*));
static uv_key_t uv__current_thread_key;
static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT;
static uv_once_t uv__thread_name_once = UV_ONCE_INIT;
HRESULT (WINAPI *pGetThreadDescription)(HANDLE, PWSTR*);
HRESULT (WINAPI *pSetThreadDescription)(HANDLE, PCWSTR);
static void uv__init_current_thread_key(void) {
@ -278,12 +281,28 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
}
static void uv__thread_name_init_once(void) {
HMODULE m;
m = GetModuleHandleA("api-ms-win-core-processthreads-l1-1-3.dll");
if (m != NULL) {
pGetThreadDescription = (void*) GetProcAddress(m, "GetThreadDescription");
pSetThreadDescription = (void*) GetProcAddress(m, "SetThreadDescription");
}
}
int uv_thread_setname(const char* name) {
HRESULT hr;
WCHAR* namew;
int err;
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
uv_once(&uv__thread_name_once, uv__thread_name_init_once);
if (pSetThreadDescription == NULL)
return UV_ENOSYS;
if (name == NULL)
return UV_EINVAL;
@ -295,7 +314,7 @@ int uv_thread_setname(const char* name) {
if (err)
return err;
hr = SetThreadDescription(GetCurrentThread(), namew);
hr = pSetThreadDescription(GetCurrentThread(), namew);
uv__free(namew);
if (FAILED(hr))
return uv_translate_sys_error(HRESULT_CODE(hr));
@ -312,6 +331,11 @@ int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) {
int r;
DWORD exit_code;
uv_once(&uv__thread_name_once, uv__thread_name_init_once);
if (pGetThreadDescription == NULL)
return UV_ENOSYS;
if (name == NULL || size == 0)
return UV_EINVAL;
@ -324,7 +348,7 @@ int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) {
namew = NULL;
thread_name = NULL;
hr = GetThreadDescription(*tid, &namew);
hr = pGetThreadDescription(*tid, &namew);
if (FAILED(hr))
return uv_translate_sys_error(HRESULT_CODE(hr));

80
deps/uv/src/win/tty.c vendored
View file

@ -58,6 +58,9 @@
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
#endif
#define CURSOR_SIZE_SMALL 25
#define CURSOR_SIZE_LARGE 100
@ -119,7 +122,10 @@ static int uv_tty_virtual_width = -1;
* handle signalling SIGWINCH
*/
static HANDLE uv__tty_console_handle = INVALID_HANDLE_VALUE;
static HANDLE uv__tty_console_handle_out = INVALID_HANDLE_VALUE;
static HANDLE uv__tty_console_handle_in = INVALID_HANDLE_VALUE;
static DWORD uv__tty_console_in_original_mode = (DWORD)-1;
static volatile LONG uv__tty_console_in_need_mode_reset = 0;
static int uv__tty_console_height = -1;
static int uv__tty_console_width = -1;
static HANDLE uv__tty_console_resized = INVALID_HANDLE_VALUE;
@ -159,19 +165,21 @@ static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED;
static void uv__determine_vterm_state(HANDLE handle);
void uv__console_init(void) {
DWORD dwMode;
if (uv_sem_init(&uv_tty_output_lock, 1))
abort();
uv__tty_console_handle = CreateFileW(L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
0);
if (uv__tty_console_handle != INVALID_HANDLE_VALUE) {
uv__tty_console_handle_out = CreateFileW(L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
0);
if (uv__tty_console_handle_out != INVALID_HANDLE_VALUE) {
CONSOLE_SCREEN_BUFFER_INFO sb_info;
uv_mutex_init(&uv__tty_console_resize_mutex);
if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) {
if (GetConsoleScreenBufferInfo(uv__tty_console_handle_out, &sb_info)) {
uv__tty_console_width = sb_info.dwSize.X;
uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
}
@ -179,6 +187,18 @@ void uv__console_init(void) {
NULL,
WT_EXECUTELONGFUNCTION);
}
uv__tty_console_handle_in = CreateFileW(L"CONIN$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
0,
0);
if (uv__tty_console_handle_in != INVALID_HANDLE_VALUE) {
if (GetConsoleMode(uv__tty_console_handle_in, &dwMode)) {
uv__tty_console_in_original_mode = dwMode;
}
}
}
@ -253,7 +273,9 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) {
/* Initialize TTY input specific fields. */
tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
/* TODO: remove me in v2.x. */
tty->tty.rd.unused_ = NULL;
tty->tty.rd.mode.unused_ = NULL;
/* Partially overwrites unused_ again. */
tty->tty.rd.mode.mode = 0;
tty->tty.rd.read_line_buffer = uv_null_buf_;
tty->tty.rd.read_raw_wait = NULL;
@ -344,6 +366,7 @@ static void uv__tty_capture_initial_style(
int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
DWORD flags;
DWORD try_set_flags;
unsigned char was_reading;
uv_alloc_cb alloc_cb;
uv_read_cb read_cb;
@ -353,14 +376,19 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
return UV_EINVAL;
}
if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
if ((int)mode == tty->tty.rd.mode.mode) {
return 0;
}
try_set_flags = 0;
switch (mode) {
case UV_TTY_MODE_NORMAL:
flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
break;
case UV_TTY_MODE_RAW_VT:
try_set_flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
InterlockedExchange(&uv__tty_console_in_need_mode_reset, 1);
/* fallthrough */
case UV_TTY_MODE_RAW:
flags = ENABLE_WINDOW_INPUT;
break;
@ -386,16 +414,16 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
}
uv_sem_wait(&uv_tty_output_lock);
if (!SetConsoleMode(tty->handle, flags)) {
if (!SetConsoleMode(tty->handle, flags | try_set_flags) &&
!SetConsoleMode(tty->handle, flags)) {
err = uv_translate_sys_error(GetLastError());
uv_sem_post(&uv_tty_output_lock);
return err;
}
uv_sem_post(&uv_tty_output_lock);
/* Update flag. */
tty->flags &= ~UV_HANDLE_TTY_RAW;
tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
/* Update mode. */
tty->tty.rd.mode.mode = mode;
/* If we just stopped reading, restart. */
if (was_reading) {
@ -614,7 +642,7 @@ static void uv__tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
static void uv__tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) {
if (handle->flags & UV_HANDLE_TTY_RAW) {
if (uv__is_raw_tty_mode(handle->tty.rd.mode.mode)) {
uv__tty_queue_read_raw(loop, handle);
} else {
uv__tty_queue_read_line(loop, handle);
@ -702,7 +730,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
handle->flags &= ~UV_HANDLE_READ_PENDING;
if (!(handle->flags & UV_HANDLE_READING) ||
!(handle->flags & UV_HANDLE_TTY_RAW)) {
!(uv__is_raw_tty_mode(handle->tty.rd.mode.mode))) {
goto out;
}
@ -1050,7 +1078,7 @@ int uv__tty_read_stop(uv_tty_t* handle) {
if (!(handle->flags & UV_HANDLE_READ_PENDING))
return 0;
if (handle->flags & UV_HANDLE_TTY_RAW) {
if (uv__is_raw_tty_mode(handle->tty.rd.mode.mode)) {
/* Cancel raw read. Write some bullshit event to force the console wait to
* return. */
memset(&record, 0, sizeof record);
@ -2293,7 +2321,17 @@ void uv__tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
int uv_tty_reset_mode(void) {
/* Not necessary to do anything. */
/**
* Shells on Windows do know to reset output flags after a program exits,
* but not necessarily input flags, so we do that for them.
*/
if (
uv__tty_console_handle_in != INVALID_HANDLE_VALUE &&
uv__tty_console_in_original_mode != (DWORD)-1 &&
InterlockedExchange(&uv__tty_console_in_need_mode_reset, 0) != 0
) {
SetConsoleMode(uv__tty_console_handle_in, uv__tty_console_in_original_mode);
}
return 0;
}
@ -2390,7 +2428,7 @@ static void uv__tty_console_signal_resize(void) {
CONSOLE_SCREEN_BUFFER_INFO sb_info;
int width, height;
if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info))
if (!GetConsoleScreenBufferInfo(uv__tty_console_handle_out, &sb_info))
return;
width = sb_info.dwSize.X;

View file

@ -1016,6 +1016,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
int uv_os_tmpdir(char* buffer, size_t* size) {
int r;
wchar_t *path;
size_t len;
@ -1054,7 +1055,9 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
path[len] = L'\0';
}
return uv__copy_utf16_to_utf8(path, len, buffer, size);
r = uv__copy_utf16_to_utf8(path, len, buffer, size);
uv__free(path);
return r;
}

View file

@ -4145,8 +4145,8 @@ typedef struct _FILE_STAT_BASIC_INFORMATION {
ULONG DeviceType;
ULONG DeviceCharacteristics;
ULONG Reserved;
FILE_ID_128 FileId128;
LARGE_INTEGER VolumeSerialNumber;
FILE_ID_128 FileId128;
} FILE_STAT_BASIC_INFORMATION;
#endif
@ -4828,13 +4828,4 @@ typedef int (WINAPI *uv_sGetHostNameW)
int);
extern uv_sGetHostNameW pGetHostNameW;
/* processthreadsapi.h */
#if defined(__MINGW32__)
WINBASEAPI
HRESULT WINAPI GetThreadDescription(HANDLE hThread,
PWSTR *ppszThreadDescription);
WINBASEAPI
HRESULT WINAPI SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
#endif
#endif /* UV_WIN_WINAPI_H_ */

View file

@ -367,6 +367,7 @@ long int process_output_size(process_info_t *p) {
/* Copy the contents of the stdio output buffer to `fd`. */
int process_copy_output(process_info_t* p, FILE* stream) {
char buf[1024];
int partial;
int r;
r = fseek(p->stdout_file, 0, SEEK_SET);
@ -375,9 +376,9 @@ int process_copy_output(process_info_t* p, FILE* stream) {
return -1;
}
/* TODO: what if the line is longer than buf */
partial = 0;
while ((r = fread(buf, 1, sizeof(buf), p->stdout_file)) != 0)
print_lines(buf, r, stream);
partial = print_lines(buf, r, stream, partial);
if (ferror(p->stdout_file)) {
perror("read");

View file

@ -219,6 +219,7 @@ long int process_output_size(process_info_t *p) {
int process_copy_output(process_info_t* p, FILE* stream) {
char buf[1024];
int partial;
int fd, r;
fd = _open_osfhandle((intptr_t)p->stdio_out, _O_RDONLY | _O_TEXT);
@ -229,8 +230,9 @@ int process_copy_output(process_info_t* p, FILE* stream) {
if (r < 0)
return -1;
partial = 0;
while ((r = _read(fd, buf, sizeof(buf))) != 0)
print_lines(buf, r, stream);
partial = print_lines(buf, r, stream, partial);
_close(fd);
return 0;

16
deps/uv/test/runner.c vendored
View file

@ -426,13 +426,17 @@ void print_tests(FILE* stream) {
}
void print_lines(const char* buffer, size_t size, FILE* stream) {
int print_lines(const char* buffer, size_t size, FILE* stream, int partial) {
const char* start;
const char* end;
start = buffer;
while ((end = memchr(start, '\n', &buffer[size] - start))) {
fputs("# ", stream);
if (partial == 0)
fputs("# ", stream);
else
partial = 0;
fwrite(start, 1, (int)(end - start), stream);
fputs("\n", stream);
fflush(stream);
@ -441,9 +445,13 @@ void print_lines(const char* buffer, size_t size, FILE* stream) {
end = &buffer[size];
if (start < end) {
fputs("# ", stream);
if (partial == 0)
fputs("# ", stream);
fwrite(start, 1, (int)(end - start), stream);
fputs("\n", stream);
fflush(stream);
return 1;
}
return 0;
}

View file

@ -123,7 +123,7 @@ int run_test_part(const char* test, const char* part);
void print_tests(FILE* stream);
/* Print lines in |buffer| as TAP diagnostics to |stream|. */
void print_lines(const char* buffer, size_t size, FILE* stream);
int print_lines(const char* buffer, size_t size, FILE* stream, int partial);
/*
* Stuff that should be implemented by test-runner-<platform>.h

View file

@ -22,11 +22,7 @@
#include "uv.h"
#include "task.h"
static void connect_4(uv_connect_t* req, int status) {
ASSERT_NE(status, UV_EADDRNOTAVAIL);
}
static void connect_6(uv_connect_t* req, int status) {
static void connect_cb(uv_connect_t* req, int status) {
ASSERT_NE(status, UV_EADDRNOTAVAIL);
}
@ -46,7 +42,7 @@ TEST_IMPL(connect_unspecified) {
ASSERT_OK(uv_tcp_connect(&connect4,
&socket4,
(const struct sockaddr*) &addr4,
connect_4));
connect_cb));
if (can_ipv6()) {
ASSERT_OK(uv_tcp_init(loop, &socket6));
@ -54,7 +50,7 @@ TEST_IMPL(connect_unspecified) {
ASSERT_OK(uv_tcp_connect(&connect6,
&socket6,
(const struct sockaddr*) &addr6,
connect_6));
connect_cb));
}
ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));

View file

@ -32,7 +32,7 @@
static uv_fs_event_t fs_event;
static const char file_prefix[] = "fsevent-";
static const int fs_event_file_count = 16;
#if defined(__APPLE__) || defined(_WIN32)
#if (defined(__APPLE__) && !defined(__TSAN__)) || defined(_WIN32)
static const char file_prefix_in_subdir[] = "subdir";
static int fs_multievent_cb_called;
#endif
@ -250,7 +250,7 @@ static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
}
}
#if defined(__APPLE__) || defined(_WIN32)
#if (defined(__APPLE__) && !defined(__TSAN__)) || defined(_WIN32)
static const char* fs_event_get_filename_in_subdir(int i) {
snprintf(fs_event_filename,
sizeof(fs_event_filename),

271
deps/uv/test/test-fs.c vendored
View file

@ -59,6 +59,18 @@
#define TOO_LONG_NAME_LENGTH 65536
#define PATHMAX 4096
#ifdef _WIN32
static const int is_win32 = 1;
#else
static const int is_win32 = 0;
#endif
#if defined(__APPLE__) || defined(__SUNPRO_C)
static const int is_apple_or_sunpro_c = 1;
#else
static const int is_apple_or_sunpro_c = 0;
#endif
typedef struct {
const char* path;
double atime;
@ -827,43 +839,70 @@ static void check_utime(const char* path,
ASSERT_OK(req.result);
s = &req.statbuf;
if (s->st_atim.tv_nsec == 0 && s->st_mtim.tv_nsec == 0) {
/*
* Test sub-second timestamps only when supported (such as Windows with
if (isfinite(atime)) {
/* Test sub-second timestamps only when supported (such as Windows with
* NTFS). Some other platforms support sub-second timestamps, but that
* support is filesystem-dependent. Notably OS X (HFS Plus) does NOT
* support sub-second timestamps. But kernels may round or truncate in
* either direction, so we may accept either possible answer.
*/
#ifdef _WIN32
ASSERT_DOUBLE_EQ(atime, (long) atime);
ASSERT_DOUBLE_EQ(mtime, (long) atime);
#endif
if (atime > 0 || (long) atime == atime)
ASSERT_EQ(s->st_atim.tv_sec, (long) atime);
if (mtime > 0 || (long) mtime == mtime)
ASSERT_EQ(s->st_mtim.tv_sec, (long) mtime);
ASSERT_GE(s->st_atim.tv_sec, (long) atime - 1);
ASSERT_GE(s->st_mtim.tv_sec, (long) mtime - 1);
ASSERT_LE(s->st_atim.tv_sec, (long) atime);
ASSERT_LE(s->st_mtim.tv_sec, (long) mtime);
} else {
double st_atim;
double st_mtim;
#if !defined(__APPLE__) && !defined(__SUNPRO_C)
/* TODO(vtjnash): would it be better to normalize this? */
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
#endif
st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
/*
* Linux does not allow reading reliably the atime of a symlink
* since readlink() can update it
if (s->st_atim.tv_nsec == 0) {
if (is_win32)
ASSERT_DOUBLE_EQ(atime, (long) atime);
if (atime > 0 || (long) atime == atime)
ASSERT_EQ(s->st_atim.tv_sec, (long) atime);
ASSERT_GE(s->st_atim.tv_sec, (long) atime - 1);
ASSERT_LE(s->st_atim.tv_sec, (long) atime);
} else {
double st_atim;
/* TODO(vtjnash): would it be better to normalize this? */
if (!is_apple_or_sunpro_c)
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
/* Linux does not allow reading reliably the atime of a symlink
* since readlink() can update it
*/
if (!test_lutime)
ASSERT_DOUBLE_EQ(st_atim, atime);
}
} else if (isinf(atime)) {
/* We test with timestamps that are in the distant past
* (if you're a Gen Z-er) so check it's more recent than that.
*/
if (!test_lutime)
ASSERT_DOUBLE_EQ(st_atim, atime);
ASSERT_DOUBLE_EQ(st_mtim, mtime);
ASSERT_GT(s->st_atim.tv_sec, 1739710000);
} else {
ASSERT_OK(0);
}
if (isfinite(mtime)) {
/* Test sub-second timestamps only when supported (such as Windows with
* NTFS). Some other platforms support sub-second timestamps, but that
* support is filesystem-dependent. Notably OS X (HFS Plus) does NOT
* support sub-second timestamps. But kernels may round or truncate in
* either direction, so we may accept either possible answer.
*/
if (s->st_mtim.tv_nsec == 0) {
if (is_win32)
ASSERT_DOUBLE_EQ(mtime, (long) atime);
if (mtime > 0 || (long) mtime == mtime)
ASSERT_EQ(s->st_mtim.tv_sec, (long) mtime);
ASSERT_GE(s->st_mtim.tv_sec, (long) mtime - 1);
ASSERT_LE(s->st_mtim.tv_sec, (long) mtime);
} else {
double st_mtim;
/* TODO(vtjnash): would it be better to normalize this? */
if (!is_apple_or_sunpro_c)
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
ASSERT_DOUBLE_EQ(st_mtim, mtime);
}
} else if (isinf(mtime)) {
/* We test with timestamps that are in the distant past
* (if you're a Gen Z-er) so check it's more recent than that.
*/
ASSERT_GT(s->st_mtim.tv_sec, 1739710000);
} else {
ASSERT_OK(0);
}
uv_fs_req_cleanup(&req);
@ -1607,6 +1646,50 @@ TEST_IMPL(fs_fstat) {
}
TEST_IMPL(fs_fstat_st_dev) {
uv_fs_t req;
uv_fs_t req_link;
uv_loop_t* loop = uv_default_loop();
char* test_file = "tmp_st_dev";
char* symlink_file = "tmp_st_dev_link";
unlink(test_file);
unlink(symlink_file);
// Create file
int r = uv_fs_open(NULL, &req, test_file, UV_FS_O_RDWR | UV_FS_O_CREAT,
S_IWUSR | S_IRUSR, NULL);
ASSERT_GE(r, 0);
ASSERT_GE(req.result, 0);
uv_fs_req_cleanup(&req);
// Create a symlink
r = uv_fs_symlink(loop, &req, test_file, symlink_file, 0, NULL);
ASSERT_EQ(r, 0);
uv_fs_req_cleanup(&req);
// Call uv_fs_fstat for file
r = uv_fs_stat(loop, &req, test_file, NULL);
ASSERT_EQ(r, 0);
// Call uv_fs_fstat for symlink
r = uv_fs_stat(loop, &req_link, symlink_file, NULL);
ASSERT_EQ(r, 0);
// Compare st_dev
ASSERT_EQ(((uv_stat_t*)req.ptr)->st_dev, ((uv_stat_t*)req_link.ptr)->st_dev);
// Cleanup
uv_fs_req_cleanup(&req);
uv_fs_req_cleanup(&req_link);
unlink(test_file);
unlink(symlink_file);
MAKE_VALGRIND_HAPPY(loop);
return 0;
}
TEST_IMPL(fs_fstat_stdio) {
int fd;
int res;
@ -2684,13 +2767,46 @@ TEST_IMPL(fs_utime) {
atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL);
ASSERT_OK(r);
ASSERT_OK(uv_fs_utime(NULL, &req, path, atime, mtime, NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_utime(NULL,
&req,
path,
UV_FS_UTIME_OMIT,
UV_FS_UTIME_OMIT,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_utime(NULL,
&req,
path,
UV_FS_UTIME_NOW,
UV_FS_UTIME_OMIT,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, UV_FS_UTIME_NOW, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_utime(NULL, &req, path, atime, mtime, NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_utime(NULL,
&req,
path,
UV_FS_UTIME_OMIT,
UV_FS_UTIME_NOW,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, UV_FS_UTIME_NOW, /* test_lutime */ 0);
atime = mtime = 1291404900.25; /* 2010-12-03 20:35:00.25 - mees <3 */
checkme.path = path;
checkme.atime = atime;
@ -2824,9 +2940,43 @@ TEST_IMPL(fs_futime) {
ASSERT_OK(req.result);
#endif
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_futime(NULL,
&req,
file,
UV_FS_UTIME_OMIT,
UV_FS_UTIME_OMIT,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_futime(NULL,
&req,
file,
UV_FS_UTIME_NOW,
UV_FS_UTIME_OMIT,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, UV_FS_UTIME_NOW, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_futime(NULL, &req, file, atime, mtime, NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, mtime, /* test_lutime */ 0);
ASSERT_OK(uv_fs_futime(NULL,
&req,
file,
UV_FS_UTIME_OMIT,
UV_FS_UTIME_NOW,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(path, atime, UV_FS_UTIME_NOW, /* test_lutime */ 0);
atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
checkme.atime = atime;
@ -2888,20 +3038,50 @@ TEST_IMPL(fs_lutime) {
/* Test the synchronous version. */
atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
checkme.atime = atime;
checkme.mtime = mtime;
checkme.path = symlink_path;
req.data = &checkme;
r = uv_fs_lutime(NULL, &req, symlink_path, atime, mtime, NULL);
#if (defined(_AIX) && !defined(_AIX71)) || \
defined(__MVS__)
#if (defined(_AIX) && !defined(_AIX71)) || defined(__MVS__)
ASSERT_EQ(r, UV_ENOSYS);
RETURN_SKIP("lutime is not implemented for z/OS and AIX versions below 7.1");
#endif
ASSERT_OK(r);
lutime_cb(&req);
ASSERT_EQ(1, lutime_cb_count);
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(symlink_path, atime, mtime, /* test_lutime */ 1);
ASSERT_OK(uv_fs_lutime(NULL,
&req,
symlink_path,
UV_FS_UTIME_OMIT,
UV_FS_UTIME_OMIT,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(symlink_path, atime, mtime, /* test_lutime */ 1);
ASSERT_OK(uv_fs_lutime(NULL,
&req,
symlink_path,
UV_FS_UTIME_NOW,
UV_FS_UTIME_OMIT,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(symlink_path, UV_FS_UTIME_NOW, mtime, /* test_lutime */ 1);
ASSERT_OK(uv_fs_lutime(NULL, &req, symlink_path, atime, mtime, NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(symlink_path, atime, mtime, /* test_lutime */ 1);
ASSERT_OK(uv_fs_lutime(NULL,
&req,
symlink_path,
UV_FS_UTIME_OMIT,
UV_FS_UTIME_NOW,
NULL));
ASSERT_OK(req.result);
uv_fs_req_cleanup(&req);
check_utime(symlink_path, atime, UV_FS_UTIME_NOW, /* test_lutime */ 1);
/* Test the asynchronous version. */
atime = mtime = 1291404900; /* 2010-12-03 20:35:00 */
@ -2909,11 +3089,12 @@ TEST_IMPL(fs_lutime) {
checkme.atime = atime;
checkme.mtime = mtime;
checkme.path = symlink_path;
req.data = &checkme;
r = uv_fs_lutime(loop, &req, symlink_path, atime, mtime, lutime_cb);
ASSERT_OK(r);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT_EQ(2, lutime_cb_count);
ASSERT_EQ(1, lutime_cb_count);
/* Cleanup. */
unlink(path);

View file

@ -33,6 +33,7 @@ TEST_DECLARE (loop_stop_before_run)
TEST_DECLARE (loop_update_time)
TEST_DECLARE (loop_backend_timeout)
TEST_DECLARE (loop_configure)
TEST_DECLARE (loop_init_oom)
TEST_DECLARE (default_loop_close)
TEST_DECLARE (barrier_1)
TEST_DECLARE (barrier_2)
@ -53,7 +54,8 @@ TEST_DECLARE (tty_raw)
TEST_DECLARE (tty_empty_write)
TEST_DECLARE (tty_large_write)
TEST_DECLARE (tty_raw_cancel)
TEST_DECLARE (tty_duplicate_vt100_fn_key)
TEST_DECLARE (tty_duplicate_vt100_fn_key_libuv)
TEST_DECLARE (tty_duplicate_vt100_fn_key_winvt)
TEST_DECLARE (tty_duplicate_alt_modifier_key)
TEST_DECLARE (tty_composing_character)
TEST_DECLARE (tty_cursor_up)
@ -364,6 +366,7 @@ TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_mkstemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_fstat_stdio)
TEST_DECLARE (fs_fstat_st_dev)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_copyfile)
@ -603,6 +606,7 @@ TASK_LIST_START
TEST_ENTRY (loop_update_time)
TEST_ENTRY (loop_backend_timeout)
TEST_ENTRY (loop_configure)
TEST_ENTRY (loop_init_oom)
TEST_ENTRY (default_loop_close)
TEST_ENTRY (barrier_1)
TEST_ENTRY (barrier_2)
@ -635,7 +639,8 @@ TASK_LIST_START
TEST_ENTRY (tty_empty_write)
TEST_ENTRY (tty_large_write)
TEST_ENTRY (tty_raw_cancel)
TEST_ENTRY (tty_duplicate_vt100_fn_key)
TEST_ENTRY (tty_duplicate_vt100_fn_key_libuv)
TEST_ENTRY (tty_duplicate_vt100_fn_key_winvt)
TEST_ENTRY (tty_duplicate_alt_modifier_key)
TEST_ENTRY (tty_composing_character)
TEST_ENTRY (tty_cursor_up)
@ -1083,6 +1088,7 @@ TASK_LIST_START
TEST_ENTRY (fs_mkstemp)
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_fstat_stdio)
TEST_ENTRY (fs_fstat_st_dev)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
TEST_ENTRY (fs_copyfile)

62
deps/uv/test/test-loop-oom.c vendored Normal file
View file

@ -0,0 +1,62 @@
/* 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 "task.h"
#include <stdlib.h>
#include <string.h>
static int limit;
static int alloc;
static void* t_realloc(void* p, size_t n) {
alloc += n;
if (alloc > limit)
return NULL;
p = realloc(p, n);
ASSERT_NOT_NULL(p);
return p;
}
static void* t_calloc(size_t m, size_t n) {
return t_realloc(NULL, m * n);
}
static void* t_malloc(size_t n) {
return t_realloc(NULL, n);
}
TEST_IMPL(loop_init_oom) {
uv_loop_t loop;
int err;
ASSERT_OK(uv_replace_allocator(t_malloc, t_realloc, t_calloc, free));
for (;;) {
err = uv_loop_init(&loop);
if (err == 0)
break;
ASSERT_EQ(err, UV_ENOMEM);
limit += 8;
alloc = 0;
}
ASSERT_OK(uv_loop_close(&loop));
return 0;
}

View file

@ -59,7 +59,7 @@ static void pipe_client_connect_cb(uv_connect_t* req, int status) {
ASSERT_OK(r);
if (*buf == '\0') { /* Linux abstract socket. */
const char expected[] = "\0" TEST_PIPENAME;
const char expected[] = "\0" TEST_PIPENAME "\0";
ASSERT_EQ(len, sizeof(expected) - 1);
ASSERT_MEM_EQ(buf, expected, len);
} else {
@ -223,7 +223,7 @@ TEST_IMPL(pipe_getsockname) {
TEST_IMPL(pipe_getsockname_abstract) {
/* TODO(bnoordhuis) Use unique name, susceptible to concurrent test runs. */
static const char name[] = "\0" TEST_PIPENAME;
static const char name[] = "\0" TEST_PIPENAME "\0";
#if defined(__linux__)
char buf[256];
size_t buflen;

View file

@ -236,21 +236,24 @@ TEST_IMPL(platform_output) {
printf(" version: %s\n", uname.version);
printf(" machine: %s\n", uname.machine);
ASSERT_OK(uv_getrusage_thread(&rusage));
ASSERT_UINT64_GE(rusage.ru_utime.tv_sec, 0);
ASSERT_UINT64_GE(rusage.ru_utime.tv_usec, 0);
ASSERT_UINT64_GE(rusage.ru_stime.tv_sec, 0);
ASSERT_UINT64_GE(rusage.ru_stime.tv_usec, 0);
printf("uv_getrusage_thread:\n");
printf(" user: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_utime.tv_sec,
(unsigned long long) rusage.ru_utime.tv_usec);
printf(" system: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_stime.tv_sec,
(unsigned long long) rusage.ru_stime.tv_usec);
printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt);
printf(" maximum resident set size: %llu\n",
(unsigned long long) rusage.ru_maxrss);
err = uv_getrusage_thread(&rusage);
if (err != UV_ENOTSUP) {
ASSERT_OK(err);
ASSERT_UINT64_GE(rusage.ru_utime.tv_sec, 0);
ASSERT_UINT64_GE(rusage.ru_utime.tv_usec, 0);
ASSERT_UINT64_GE(rusage.ru_stime.tv_sec, 0);
ASSERT_UINT64_GE(rusage.ru_stime.tv_usec, 0);
printf("uv_getrusage_thread:\n");
printf(" user: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_utime.tv_sec,
(unsigned long long) rusage.ru_utime.tv_usec);
printf(" system: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_stime.tv_sec,
(unsigned long long) rusage.ru_stime.tv_usec);
printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt);
printf(" maximum resident set size: %llu\n",
(unsigned long long) rusage.ru_maxrss);
}
return 0;
}

View file

@ -178,6 +178,10 @@ static void after_work_cb(uv_work_t* req, int status) {
}
TEST_IMPL(thread_name_threadpool) {
#if defined(_AIX) || defined(__PASE__)
RETURN_SKIP("API not available on this platform");
#endif
uv_work_t req;
loop = uv_default_loop();
// Just to make sure all workers will be executed

View file

@ -131,7 +131,7 @@ static void make_key_event_records(WORD virt_key, DWORD ctr_key_state,
# undef KEV
}
TEST_IMPL(tty_duplicate_vt100_fn_key) {
TEST_IMPL(tty_duplicate_vt100_fn_key_libuv) {
int r;
int ttyin_fd;
uv_tty_t tty_in;
@ -163,6 +163,10 @@ TEST_IMPL(tty_duplicate_vt100_fn_key) {
r = uv_read_start((uv_stream_t*)&tty_in, tty_alloc, tty_read);
ASSERT_OK(r);
/*
* libuv has chosen to emit ESC[[A, but other terminals, and even
* Windows itself use a different escape sequence, see the test below.
*/
expect_str = ESC"[[A";
expect_nread = strlen(expect_str);
@ -184,6 +188,62 @@ TEST_IMPL(tty_duplicate_vt100_fn_key) {
return 0;
}
TEST_IMPL(tty_duplicate_vt100_fn_key_winvt) {
int r;
int ttyin_fd;
uv_tty_t tty_in;
uv_loop_t* loop;
HANDLE handle;
INPUT_RECORD records[2];
DWORD written;
loop = uv_default_loop();
/* Make sure we have an FD that refers to a tty */
handle = CreateFileA("conin$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
ASSERT_PTR_NE(handle, INVALID_HANDLE_VALUE);
ttyin_fd = _open_osfhandle((intptr_t) handle, 0);
ASSERT_GE(ttyin_fd, 0);
ASSERT_EQ(UV_TTY, uv_guess_handle(ttyin_fd));
r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */
ASSERT_OK(r);
ASSERT(uv_is_readable((uv_stream_t*) &tty_in));
ASSERT(!uv_is_writable((uv_stream_t*) &tty_in));
r = uv_read_start((uv_stream_t*)&tty_in, tty_alloc, tty_read);
ASSERT_OK(r);
/*
* Some keys, like F1, get are assigned a different value by Windows
* in ENABLE_VIRTUAL_TERMINAL_INPUT mode vs. libuv in the test above.
*/
expect_str = ESC"OP";
expect_nread = strlen(expect_str);
/* Turn on raw mode. */
r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW_VT);
ASSERT_OK(r);
/*
* Send F1 keystroke.
*/
make_key_event_records(VK_F1, 0, TRUE, records);
WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written);
ASSERT_EQ(written, ARRAY_SIZE(records));
uv_run(loop, UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY(loop);
return 0;
}
TEST_IMPL(tty_duplicate_alt_modifier_key) {
int r;
int ttyin_fd;