Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d6a0b49d | ||
|
|
436c04048e | ||
|
|
feddddb56b | ||
|
|
f61f9c29d8 | ||
|
|
843b64faf5 | ||
|
|
85b526f56a | ||
|
|
8a94b7b2ec | ||
|
|
b807450e98 | ||
|
|
82cdfb75ff | ||
|
|
dcace2a393 | ||
|
|
378edb28f4 | ||
|
|
7894072528 | ||
|
|
abe59d6319 | ||
|
|
e399e00e78 | ||
|
|
51477bc711 | ||
|
|
23632e9104 | ||
|
|
a6ddf41edf | ||
|
|
82351168b3 | ||
|
|
bc19beadbd | ||
|
|
f15c602bd0 | ||
|
|
0f31978c30 | ||
|
|
a2ba04f83f |
@ -2,7 +2,7 @@ version: 2
|
||||
|
||||
sphinx:
|
||||
builder: html
|
||||
configuration: null
|
||||
configuration: docs/src/conf.py
|
||||
fail_on_warning: false
|
||||
|
||||
build:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
2025.01.15, Version 1.50.0 (Stable)
|
||||
2025.01.15, Version 1.50.0 (Stable), 8fb9cb919489a48880680a56efecff6a7dfb4504
|
||||
|
||||
Changes since version 1.49.2:
|
||||
|
||||
|
||||
2
LINKS.md
2
LINKS.md
@ -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)
|
||||
|
||||
@ -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.50.1-dev], [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])
|
||||
|
||||
@ -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``.
|
||||
|
||||
@ -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>`_.
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
include/uv.h
12
include/uv.h
@ -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,
|
||||
|
||||
@ -32,9 +32,9 @@
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 50
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
#define UV_VERSION_PATCH 1
|
||||
#define UV_VERSION_IS_RELEASE 0
|
||||
#define UV_VERSION_SUFFIX "dev"
|
||||
|
||||
#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \
|
||||
(UV_VERSION_MINOR << 8) | \
|
||||
|
||||
@ -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 */ \
|
||||
|
||||
@ -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(ent->ifa_name) + 1;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
@ -1182,8 +1186,8 @@ 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;
|
||||
}
|
||||
@ -1210,7 +1214,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 +1288,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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -1078,6 +1078,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__) */
|
||||
|
||||
116
src/unix/fs.c
116
src/unix/fs.c
@ -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;
|
||||
|
||||
@ -403,6 +403,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 +412,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 +422,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 +440,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 +503,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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -826,6 +826,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 +836,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 +849,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 +892,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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -1298,7 +1298,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 +1326,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])))
|
||||
|
||||
@ -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_ */
|
||||
|
||||
29
src/win/fs.c
29
src/win/fs.c
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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_ */
|
||||
|
||||
271
test/test-fs.c
271
test/test-fs.c
@ -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);
|
||||
|
||||
@ -53,7 +53,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 +365,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)
|
||||
@ -635,7 +637,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 +1086,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)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user