LIBS: updated libuv

Martin Gerhardy 2020-04-19 08:02:07 +02:00
parent 761d12a390
commit b96230c79e
13 changed files with 251 additions and 88 deletions

View File

@ -1182,12 +1182,22 @@ UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
UV_EXTERN uv_pid_t uv_os_getpid(void);
UV_EXTERN uv_pid_t uv_os_getppid(void);
#define UV_PRIORITY_LOW 19
#define UV_PRIORITY_BELOW_NORMAL 10
#define UV_PRIORITY_NORMAL 0
#define UV_PRIORITY_ABOVE_NORMAL -7
#define UV_PRIORITY_HIGH -14
#define UV_PRIORITY_HIGHEST -20
#if defined(__PASE__)
/* On IBM i PASE, the highest process priority is -10 */
# define UV_PRIORITY_LOW 39 // RUNPTY(99)
# define UV_PRIORITY_BELOW_NORMAL 15 // RUNPTY(50)
# define UV_PRIORITY_NORMAL 0 // RUNPTY(20)
# define UV_PRIORITY_ABOVE_NORMAL -4 // RUNTY(12)
# define UV_PRIORITY_HIGH -7 // RUNPTY(6)
# define UV_PRIORITY_HIGHEST -10 // RUNPTY(1)
#else
# define UV_PRIORITY_LOW 19
# define UV_PRIORITY_BELOW_NORMAL 10
# define UV_PRIORITY_NORMAL 0
# define UV_PRIORITY_ABOVE_NORMAL -7
# define UV_PRIORITY_HIGH -14
# define UV_PRIORITY_HIGHEST -20
#endif
UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
@ -1264,7 +1274,8 @@ typedef enum {
UV_FS_READDIR,
UV_FS_CLOSEDIR,
UV_FS_STATFS,
UV_FS_MKSTEMP
UV_FS_MKSTEMP,
UV_FS_LUTIME
} uv_fs_type;
struct uv_dir_s {
@ -1437,6 +1448,12 @@ UV_EXTERN int uv_fs_futime(uv_loop_t* loop,
double atime,
double mtime,
uv_fs_cb cb);
UV_EXTERN int uv_fs_lutime(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
double atime,
double mtime,
uv_fs_cb cb);
UV_EXTERN int uv_fs_lstat(uv_loop_t* loop,
uv_fs_t* req,
const char* path,

View File

@ -26,12 +26,12 @@
* Versions with the same major number are ABI stable. API is allowed to
* evolve between minor releases, but only in a backwards compatible way.
* Make sure you update the -soname directives in configure.ac
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* not UV_VERSION_PATCH.)
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 35
#define UV_VERSION_MINOR 36
#define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 0
#define UV_VERSION_SUFFIX "dev"

View File

@ -51,12 +51,7 @@ static int timer_less_than(const struct heap_node* ha,
/* Compare start_id when both have the same timeout. start_id is
* allocated with loop->timer_counter in uv_timer_start().
*/
if (a->start_id < b->start_id)
return 1;
if (b->start_id < a->start_id)
return 0;
return 0;
return a->start_id < b->start_id;
}

View File

@ -470,13 +470,14 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
{
case IFA_ADDRESS:
case IFA_LOCAL:
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
{
/* Make room for netmask */
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
l_addedNetmask = 1;
}
break;
break;
case IFA_BROADCAST:
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
break;

View File

@ -53,6 +53,8 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
UV_UNUSED(static void cpu_relax(void)) {
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
__asm__ volatile("yield");
#endif
}

View File

@ -71,7 +71,7 @@ extern char** environ;
# include <sys/sysctl.h>
# include <sys/filio.h>
# include <sys/wait.h>
# if defined(__FreeBSD__) || defined(__linux__)
# if defined(__FreeBSD__)
# define uv__accept4 accept4
# endif
# if defined(__NetBSD__)
@ -88,7 +88,8 @@ extern char** environ;
#endif
#if defined(__linux__)
#include <sys/syscall.h>
# include <sys/syscall.h>
# define uv__accept4 accept4
#endif
static int uv__run_pending(uv_loop_t* loop);
@ -518,7 +519,7 @@ int uv__close_nocancel(int fd) {
#if defined(__APPLE__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
#if defined(__LP64__) || defined(TARGET_OS_IPHONE)
#if defined(__LP64__) || TARGET_OS_IPHONE
extern int close$NOCANCEL(int);
return close$NOCANCEL(fd);
#else
@ -1257,7 +1258,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
*envitems = uv__calloc(i, sizeof(**envitems));
if (envitems == NULL)
if (*envitems == NULL)
return UV_ENOMEM;
for (j = 0, cnt = 0; j < i; j++) {

View File

@ -205,6 +205,20 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
}
UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
struct timespec ts;
ts.tv_sec = time;
ts.tv_nsec = (uint64_t)(time * 1000000) % 1000000 * 1000;
return ts;
}
UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
struct timeval tv;
tv.tv_sec = time;
tv.tv_usec = (uint64_t)(time * 1000000) % 1000000;
return tv;
}
static ssize_t uv__fs_futime(uv_fs_t* req) {
#if defined(__linux__) \
|| defined(_AIX71) \
@ -213,10 +227,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
* for the sake of consistency with other platforms.
*/
struct timespec ts[2];
ts[0].tv_sec = req->atime;
ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
return utimensat(req->file, NULL, ts, 0);
#else
@ -230,10 +242,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
|| defined(__OpenBSD__) \
|| defined(__sun)
struct timeval tv[2];
tv[0].tv_sec = req->atime;
tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
tv[0] = uv__fs_to_timeval(req->atime);
tv[1] = uv__fs_to_timeval(req->mtime);
# if defined(__sun)
return futimesat(req->file, NULL, tv);
# else
@ -972,10 +982,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
* for the sake of consistency with other platforms.
*/
struct timespec ts[2];
ts[0].tv_sec = req->atime;
ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
return utimensat(AT_FDCWD, req->path, ts, 0);
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
@ -984,10 +992,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|| defined(__NetBSD__) \
|| defined(__OpenBSD__)
struct timeval tv[2];
tv[0].tv_sec = req->atime;
tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
tv[0] = uv__fs_to_timeval(req->atime);
tv[1] = uv__fs_to_timeval(req->mtime);
return utimes(req->path, tv);
#elif defined(_AIX) \
&& !defined(_AIX71)
@ -1010,6 +1016,31 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
}
static ssize_t uv__fs_lutime(uv_fs_t* req) {
#if defined(__linux__) || \
defined(_AIX71) || \
defined(__sun) || \
defined(__HAIKU__)
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
return utimensat(AT_FDCWD, req->path, ts, AT_SYMLINK_NOFOLLOW);
#elif defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
defined(__NetBSD__)
struct timeval tv[2];
tv[0] = uv__fs_to_timeval(req->atime);
tv[1] = uv__fs_to_timeval(req->mtime);
return lutimes(req->path, tv);
#else
errno = ENOSYS;
return -1;
#endif
}
static ssize_t uv__fs_write(uv_fs_t* req) {
#if defined(__linux__)
static int no_pwritev;
@ -1523,6 +1554,7 @@ static void uv__fs_work(struct uv__work* w) {
X(FSYNC, uv__fs_fsync(req));
X(FTRUNCATE, ftruncate(req->file, req->off));
X(FUTIME, uv__fs_futime(req));
X(LUTIME, uv__fs_lutime(req));
X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode));
@ -1709,6 +1741,19 @@ int uv_fs_futime(uv_loop_t* loop,
POST;
}
int uv_fs_lutime(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
double atime,
double mtime,
uv_fs_cb cb) {
INIT(LUTIME);
PATH;
req->atime = atime;
req->mtime = mtime;
POST;
}
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(LSTAT);

View File

@ -34,6 +34,34 @@
#define IMAXBEL 0
#endif
#if defined(__PASE__)
/* On IBM i PASE, for better compatibility with running interactive programs in
* a 5250 environment, isatty() will return true for the stdin/stdout/stderr
* streams created by QSH/QP2TERM.
*
* For more, see docs on PASE_STDIO_ISATTY in
* https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/apis/pase_environ.htm
*
* This behavior causes problems for Node as it expects that if isatty() returns
* true that TTY ioctls will be supported by that fd (which is not an
* unreasonable expectation) and when they don't it crashes with assertion
* errors.
*
* Here, we create our own version of isatty() that uses ioctl() to identify
* whether the fd is *really* a TTY or not.
*/
static int isreallyatty(int file) {
int rc;
rc = !ioctl(file, TXISATTY + 0x81, NULL);
if (!rc && errno != EBADF)
errno = ENOTTY;
return rc;
}
#define isatty(fd) isreallyatty(fd)
#endif
static int orig_termios_fd = -1;
static struct termios orig_termios;
static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
@ -293,14 +321,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
if (file < 0)
return UV_UNKNOWN_HANDLE;
#if defined(__PASE__)
/* On IBMi PASE isatty() always returns true for stdin, stdout and stderr.
* Use ioctl() instead to identify whether it's actually a TTY.
*/
if (!ioctl(file, TXISATTY + 0x81, NULL) || errno != ENOTTY)
#else
if (isatty(file))
#endif
return UV_TTY;
if (fstat(file, &s))

View File

@ -2225,34 +2225,68 @@ INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
return 0;
}
static void fs__utime(uv_fs_t* req) {
INLINE static DWORD fs__utime_impl_from_path(WCHAR* path,
double atime,
double mtime,
int do_lutime) {
HANDLE handle;
DWORD flags;
DWORD ret;
handle = CreateFileW(req->file.pathw,
flags = FILE_FLAG_BACKUP_SEMANTICS;
if (do_lutime) {
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
}
handle = CreateFileW(path,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
flags,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
CloseHandle(handle);
return;
ret = GetLastError();
} else if (fs__utime_handle(handle, atime, mtime) != 0) {
ret = GetLastError();
} else {
ret = 0;
}
CloseHandle(handle);
return ret;
}
INLINE static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
DWORD error;
error = fs__utime_impl_from_path(req->file.pathw,
req->fs.time.atime,
req->fs.time.mtime,
do_lutime);
if (error != 0) {
if (do_lutime &&
(error == ERROR_SYMLINK_NOT_SUPPORTED ||
error == ERROR_NOT_A_REPARSE_POINT)) {
/* Opened file is a reparse point but not a symlink. Try again. */
fs__utime_impl(req, 0);
} else {
/* utime failed. */
SET_REQ_WIN32_ERROR(req, error);
}
return;
}
req->result = 0;
}
static void fs__utime(uv_fs_t* req) {
fs__utime_impl(req, /* do_lutime */ 0);
}
static void fs__futime(uv_fs_t* req) {
int fd = req->file.fd;
@ -2274,6 +2308,10 @@ static void fs__futime(uv_fs_t* req) {
req->result = 0;
}
static void fs__lutime(uv_fs_t* req) {
fs__utime_impl(req, /* do_lutime */ 1);
}
static void fs__link(uv_fs_t* req) {
DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL);
@ -2621,14 +2659,62 @@ static void fs__statfs(uv_fs_t* req) {
DWORD bytes_per_sector;
DWORD free_clusters;
DWORD total_clusters;
WCHAR* pathw;
if (0 == GetDiskFreeSpaceW(req->file.pathw,
pathw = req->file.pathw;
retry_get_disk_free_space:
if (0 == GetDiskFreeSpaceW(pathw,
&sectors_per_cluster,
&bytes_per_sector,
&free_clusters,
&total_clusters)) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
DWORD err;
WCHAR* fpart;
size_t len;
DWORD ret;
BOOL is_second;
err = GetLastError();
is_second = pathw != req->file.pathw;
if (err != ERROR_DIRECTORY || is_second) {
if (is_second)
uv__free(pathw);
SET_REQ_WIN32_ERROR(req, err);
return;
}
len = MAX_PATH + 1;
pathw = uv__malloc(len * sizeof(*pathw));
if (pathw == NULL) {
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return;
}
retry_get_full_path_name:
ret = GetFullPathNameW(req->file.pathw,
len,
pathw,
&fpart);
if (ret == 0) {
uv__free(pathw);
SET_REQ_WIN32_ERROR(req, err);
return;
} else if (ret > len) {
len = ret;
pathw = uv__reallocf(pathw, len * sizeof(*pathw));
if (pathw == NULL) {
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return;
}
goto retry_get_full_path_name;
}
if (fpart != 0)
*fpart = L'\0';
goto retry_get_disk_free_space;
}
if (pathw != req->file.pathw) {
uv__free(pathw);
}
stat_fs = uv__malloc(sizeof(*stat_fs));
@ -2670,6 +2756,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(FTRUNCATE, ftruncate)
XX(UTIME, utime)
XX(FUTIME, futime)
XX(LUTIME, lutime)
XX(ACCESS, access)
XX(CHMOD, chmod)
XX(FCHMOD, fchmod)
@ -3222,6 +3309,21 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
POST;
}
int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
int err;
INIT(UV_FS_LUTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
POST;
}
int uv_fs_statfs(uv_loop_t* loop,
uv_fs_t* req,

View File

@ -58,7 +58,6 @@ static const env_var_t required_vars[] = { /* keep me sorted */
E_V("USERPROFILE"),
E_V("WINDIR"),
};
static size_t n_required_vars = ARRAY_SIZE(required_vars);
static HANDLE uv_global_job_handle_;
@ -692,7 +691,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
WCHAR* dst_copy;
WCHAR** ptr_copy;
WCHAR** env_copy;
DWORD* required_vars_value_len = alloca(n_required_vars * sizeof(DWORD*));
DWORD required_vars_value_len[ARRAY_SIZE(required_vars)];
/* first pass: determine size in UTF-16 */
for (env = env_block; *env; env++) {
@ -745,7 +744,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp);
/* third pass: check for required variables */
for (ptr_copy = env_copy, i = 0; i < n_required_vars; ) {
for (ptr_copy = env_copy, i = 0; i < ARRAY_SIZE(required_vars); ) {
int cmp;
if (!*ptr_copy) {
cmp = -1;
@ -778,10 +777,10 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
}
for (ptr = dst, ptr_copy = env_copy, i = 0;
*ptr_copy || i < n_required_vars;
*ptr_copy || i < ARRAY_SIZE(required_vars);
ptr += len) {
int cmp;
if (i >= n_required_vars) {
if (i >= ARRAY_SIZE(required_vars)) {
cmp = 1;
} else if (!*ptr_copy) {
cmp = -1;

View File

@ -63,6 +63,9 @@
/* Maximum environment variable size, including the terminating null */
#define MAX_ENV_VAR_LENGTH 32767
/* A RtlGenRandom() by any other name... */
extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
/* Cached copy of the process title, plus a mutex guarding it. */
static char *process_title;
static CRITICAL_SECTION process_title_lock;
@ -1402,7 +1405,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);
*envitems = uv__calloc(i, sizeof(**envitems));
if (envitems == NULL) {
if (*envitems == NULL) {
FreeEnvironmentStringsW(env);
return UV_ENOMEM;
}
@ -1862,13 +1865,10 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
}
int uv__random_rtlgenrandom(void* buf, size_t buflen) {
if (pRtlGenRandom == NULL)
return UV_ENOSYS;
if (buflen == 0)
return 0;
if (pRtlGenRandom(buf, buflen) == FALSE)
if (SystemFunction036(buf, buflen) == FALSE)
return UV_EIO;
return 0;

View File

@ -36,9 +36,6 @@ sNtQueryDirectoryFile pNtQueryDirectoryFile;
sNtQuerySystemInformation pNtQuerySystemInformation;
sNtQueryInformationProcess pNtQueryInformationProcess;
/* Advapi32 function pointers */
sRtlGenRandom pRtlGenRandom;
/* Kernel32 function pointers */
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
@ -54,7 +51,6 @@ void uv_winapi_init(void) {
HMODULE powrprof_module;
HMODULE user32_module;
HMODULE kernel32_module;
HMODULE advapi32_module;
ntdll_module = GetModuleHandleA("ntdll.dll");
if (ntdll_module == NULL) {
@ -138,12 +134,4 @@ void uv_winapi_init(void) {
pSetWinEventHook = (sSetWinEventHook)
GetProcAddress(user32_module, "SetWinEventHook");
}
advapi32_module = GetModuleHandleA("advapi32.dll");
if (advapi32_module == NULL) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");
}
pRtlGenRandom =
(sRtlGenRandom) GetProcAddress(advapi32_module, "SystemFunction036");
}

View File

@ -4589,11 +4589,6 @@ typedef NTSTATUS (NTAPI *sNtQueryInformationProcess)
ULONG Length,
PULONG ReturnLength);
/*
* Advapi32 headers
*/
typedef BOOLEAN (WINAPI *sRtlGenRandom)(PVOID Buffer, ULONG BufferLength);
/*
* Kernel32 headers
*/
@ -4736,9 +4731,6 @@ extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
extern sNtQuerySystemInformation pNtQuerySystemInformation;
extern sNtQueryInformationProcess pNtQueryInformationProcess;
/* Advapi32 function pointers */
extern sRtlGenRandom pRtlGenRandom;
/* Kernel32 function pointers */
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;