forked from cory/tildefriends
libuv 1.43.0
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3735 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
7
deps/libuv/src/threadpool.c
vendored
7
deps/libuv/src/threadpool.c
vendored
@ -160,13 +160,20 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef __MVS__
|
||||
/* TODO(itodorov) - zos: revisit when Woz compiler is available. */
|
||||
__attribute__((destructor))
|
||||
#endif
|
||||
void uv__threadpool_cleanup(void) {
|
||||
unsigned int i;
|
||||
|
||||
if (nthreads == 0)
|
||||
return;
|
||||
|
||||
#ifndef __MVS__
|
||||
/* TODO(gabylb) - zos: revisit when Woz compiler is available. */
|
||||
post(&exit_message, UV__WORK_CPU);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < nthreads; i++)
|
||||
if (uv_thread_join(threads + i))
|
||||
|
4
deps/libuv/src/unix/bsd-proctitle.c
vendored
4
deps/libuv/src/unix/bsd-proctitle.c
vendored
@ -38,9 +38,7 @@ static void init_process_title_mutex_once(void) {
|
||||
|
||||
|
||||
void uv__process_title_cleanup(void) {
|
||||
/* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex)
|
||||
* and reset process_title_mutex_once?
|
||||
*/
|
||||
uv_mutex_destroy(&process_title_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
16
deps/libuv/src/unix/darwin.c
vendored
16
deps/libuv/src/unix/darwin.c
vendored
@ -280,14 +280,18 @@ static int uv__get_cpu_speed(uint64_t* speed) {
|
||||
NULL,
|
||||
0);
|
||||
if (freq_ref) {
|
||||
uint32_t freq;
|
||||
const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref);
|
||||
CFIndex len = pCFDataGetLength(freq_ref);
|
||||
CFRange range;
|
||||
range.location = 0;
|
||||
range.length = len;
|
||||
if (len == 8)
|
||||
memcpy(speed, freq_ref_ptr, 8);
|
||||
else if (len == 4) {
|
||||
uint32_t v;
|
||||
memcpy(&v, freq_ref_ptr, 4);
|
||||
*speed = v;
|
||||
} else {
|
||||
*speed = 0;
|
||||
}
|
||||
|
||||
pCFDataGetBytes(freq_ref, range, (UInt8*)&freq);
|
||||
*speed = freq;
|
||||
pCFRelease(freq_ref);
|
||||
pCFRelease(data);
|
||||
break;
|
||||
|
2
deps/libuv/src/unix/dl.c
vendored
2
deps/libuv/src/unix/dl.c
vendored
@ -53,7 +53,7 @@ void uv_dlclose(uv_lib_t* lib) {
|
||||
int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
|
||||
dlerror(); /* Reset error status. */
|
||||
*ptr = dlsym(lib->handle, name);
|
||||
return uv__dlerror(lib);
|
||||
return *ptr ? 0 : uv__dlerror(lib);
|
||||
}
|
||||
|
||||
|
||||
|
119
deps/libuv/src/unix/fs.c
vendored
119
deps/libuv/src/unix/fs.c
vendored
@ -946,6 +946,71 @@ static int uv__is_buggy_cephfs(int fd) {
|
||||
|
||||
return uv__kernel_version() < /* 4.20.0 */ 0x041400;
|
||||
}
|
||||
|
||||
|
||||
static int uv__is_cifs_or_smb(int fd) {
|
||||
struct statfs s;
|
||||
|
||||
if (-1 == fstatfs(fd, &s))
|
||||
return 0;
|
||||
|
||||
switch ((unsigned) s.f_type) {
|
||||
case 0x0000517Bu: /* SMB */
|
||||
case 0xFE534D42u: /* SMB2 */
|
||||
case 0xFF534D42u: /* CIFS */
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t uv__fs_try_copy_file_range(int in_fd, off_t* off,
|
||||
int out_fd, size_t len) {
|
||||
static int no_copy_file_range_support;
|
||||
ssize_t r;
|
||||
|
||||
if (uv__load_relaxed(&no_copy_file_range_support)) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = uv__fs_copy_file_range(in_fd, off, out_fd, NULL, len, 0);
|
||||
|
||||
if (r != -1)
|
||||
return r;
|
||||
|
||||
switch (errno) {
|
||||
case EACCES:
|
||||
/* Pre-4.20 kernels have a bug where CephFS uses the RADOS
|
||||
* copy-from command when it shouldn't.
|
||||
*/
|
||||
if (uv__is_buggy_cephfs(in_fd))
|
||||
errno = ENOSYS; /* Use fallback. */
|
||||
break;
|
||||
case ENOSYS:
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
break;
|
||||
case EPERM:
|
||||
/* It's been reported that CIFS spuriously fails.
|
||||
* Consider it a transient error.
|
||||
*/
|
||||
if (uv__is_cifs_or_smb(out_fd))
|
||||
errno = ENOSYS; /* Use fallback. */
|
||||
break;
|
||||
case ENOTSUP:
|
||||
case EXDEV:
|
||||
/* ENOTSUP - it could work on another file system type.
|
||||
* EXDEV - it will not work when in_fd and out_fd are not on the same
|
||||
* mounted filesystem (pre Linux 5.3)
|
||||
*/
|
||||
errno = ENOSYS; /* Use fallback. */
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
@ -960,40 +1025,21 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
{
|
||||
off_t off;
|
||||
ssize_t r;
|
||||
size_t len;
|
||||
int try_sendfile;
|
||||
|
||||
off = req->off;
|
||||
len = req->bufsml[0].len;
|
||||
try_sendfile = 1;
|
||||
|
||||
#ifdef __linux__
|
||||
{
|
||||
static int no_copy_file_range_support;
|
||||
|
||||
if (uv__load_relaxed(&no_copy_file_range_support) == 0) {
|
||||
r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0);
|
||||
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
/* ENOSYS - it will never work */
|
||||
errno = 0;
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
} else if (r == -1 && errno == EACCES && uv__is_buggy_cephfs(in_fd)) {
|
||||
/* EACCES - pre-4.20 kernels have a bug where CephFS uses the RADOS
|
||||
copy-from command when it shouldn't */
|
||||
errno = 0;
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
} else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) {
|
||||
/* ENOTSUP - it could work on another file system type */
|
||||
/* EXDEV - it will not work when in_fd and out_fd are not on the same
|
||||
mounted filesystem (pre Linux 5.3) */
|
||||
errno = 0;
|
||||
} else {
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
r = uv__fs_try_copy_file_range(in_fd, &off, out_fd, len);
|
||||
try_sendfile = (r == -1 && errno == ENOSYS);
|
||||
#endif
|
||||
|
||||
r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len);
|
||||
if (try_sendfile)
|
||||
r = sendfile(out_fd, in_fd, &off, len);
|
||||
|
||||
ok:
|
||||
/* sendfile() on SunOS returns EINVAL if the target fd is not a socket but
|
||||
* it still writes out data. Fortunately, we can detect it by checking if
|
||||
* the offset has been updated.
|
||||
@ -1277,22 +1323,15 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
||||
if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
|
||||
err = UV__ERR(errno);
|
||||
#ifdef __linux__
|
||||
/* fchmod() on CIFS shares always fails with EPERM unless the share is
|
||||
* mounted with "noperm". As fchmod() is a meaningless operation on such
|
||||
* shares anyway, detect that condition and squelch the error.
|
||||
*/
|
||||
if (err != UV_EPERM)
|
||||
goto out;
|
||||
|
||||
{
|
||||
struct statfs s;
|
||||
|
||||
/* fchmod() on CIFS shares always fails with EPERM unless the share is
|
||||
* mounted with "noperm". As fchmod() is a meaningless operation on such
|
||||
* shares anyway, detect that condition and squelch the error.
|
||||
*/
|
||||
if (fstatfs(dstfd, &s) == -1)
|
||||
goto out;
|
||||
|
||||
if ((unsigned) s.f_type != /* CIFS */ 0xFF534D42u)
|
||||
goto out;
|
||||
}
|
||||
if (!uv__is_cifs_or_smb(dstfd))
|
||||
goto out;
|
||||
|
||||
err = 0;
|
||||
#else /* !__linux__ */
|
||||
|
5
deps/libuv/src/unix/kqueue.c
vendored
5
deps/libuv/src/unix/kqueue.c
vendored
@ -326,6 +326,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
if (errno != ENOENT)
|
||||
abort();
|
||||
}
|
||||
if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP))
|
||||
revents |= UV__POLLRDHUP;
|
||||
}
|
||||
|
||||
if (ev->filter == EV_OOBAND) {
|
||||
@ -359,9 +361,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
if (ev->flags & EV_ERROR)
|
||||
revents |= POLLERR;
|
||||
|
||||
if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP))
|
||||
revents |= UV__POLLRDHUP;
|
||||
|
||||
if (revents == 0)
|
||||
continue;
|
||||
|
||||
|
101
deps/libuv/src/unix/linux-core.c
vendored
101
deps/libuv/src/unix/linux-core.c
vendored
@ -365,24 +365,30 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
const char* inferred_model;
|
||||
unsigned int model_idx;
|
||||
unsigned int speed_idx;
|
||||
unsigned int part_idx;
|
||||
char buf[1024];
|
||||
char* model;
|
||||
FILE* fp;
|
||||
int model_id;
|
||||
|
||||
/* Most are unused on non-ARM, non-MIPS and non-x86 architectures. */
|
||||
(void) &model_marker;
|
||||
(void) &speed_marker;
|
||||
(void) &speed_idx;
|
||||
(void) &part_idx;
|
||||
(void) &model;
|
||||
(void) &buf;
|
||||
(void) &fp;
|
||||
(void) &model_id;
|
||||
|
||||
model_idx = 0;
|
||||
speed_idx = 0;
|
||||
part_idx = 0;
|
||||
|
||||
#if defined(__arm__) || \
|
||||
defined(__i386__) || \
|
||||
defined(__mips__) || \
|
||||
defined(__aarch64__) || \
|
||||
defined(__PPC__) || \
|
||||
defined(__x86_64__)
|
||||
fp = uv__open_file("/proc/cpuinfo");
|
||||
@ -402,11 +408,96 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#if defined(__arm__) || defined(__mips__)
|
||||
#if defined(__arm__) || defined(__mips__) || defined(__aarch64__)
|
||||
if (model_idx < numcpus) {
|
||||
#if defined(__arm__)
|
||||
/* Fallback for pre-3.8 kernels. */
|
||||
static const char model_marker[] = "Processor\t: ";
|
||||
#elif defined(__aarch64__)
|
||||
static const char part_marker[] = "CPU part\t: ";
|
||||
|
||||
/* Adapted from: https://github.com/karelzak/util-linux */
|
||||
struct vendor_part {
|
||||
const int id;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
static const struct vendor_part arm_chips[] = {
|
||||
{ 0x811, "ARM810" },
|
||||
{ 0x920, "ARM920" },
|
||||
{ 0x922, "ARM922" },
|
||||
{ 0x926, "ARM926" },
|
||||
{ 0x940, "ARM940" },
|
||||
{ 0x946, "ARM946" },
|
||||
{ 0x966, "ARM966" },
|
||||
{ 0xa20, "ARM1020" },
|
||||
{ 0xa22, "ARM1022" },
|
||||
{ 0xa26, "ARM1026" },
|
||||
{ 0xb02, "ARM11 MPCore" },
|
||||
{ 0xb36, "ARM1136" },
|
||||
{ 0xb56, "ARM1156" },
|
||||
{ 0xb76, "ARM1176" },
|
||||
{ 0xc05, "Cortex-A5" },
|
||||
{ 0xc07, "Cortex-A7" },
|
||||
{ 0xc08, "Cortex-A8" },
|
||||
{ 0xc09, "Cortex-A9" },
|
||||
{ 0xc0d, "Cortex-A17" }, /* Originally A12 */
|
||||
{ 0xc0f, "Cortex-A15" },
|
||||
{ 0xc0e, "Cortex-A17" },
|
||||
{ 0xc14, "Cortex-R4" },
|
||||
{ 0xc15, "Cortex-R5" },
|
||||
{ 0xc17, "Cortex-R7" },
|
||||
{ 0xc18, "Cortex-R8" },
|
||||
{ 0xc20, "Cortex-M0" },
|
||||
{ 0xc21, "Cortex-M1" },
|
||||
{ 0xc23, "Cortex-M3" },
|
||||
{ 0xc24, "Cortex-M4" },
|
||||
{ 0xc27, "Cortex-M7" },
|
||||
{ 0xc60, "Cortex-M0+" },
|
||||
{ 0xd01, "Cortex-A32" },
|
||||
{ 0xd03, "Cortex-A53" },
|
||||
{ 0xd04, "Cortex-A35" },
|
||||
{ 0xd05, "Cortex-A55" },
|
||||
{ 0xd06, "Cortex-A65" },
|
||||
{ 0xd07, "Cortex-A57" },
|
||||
{ 0xd08, "Cortex-A72" },
|
||||
{ 0xd09, "Cortex-A73" },
|
||||
{ 0xd0a, "Cortex-A75" },
|
||||
{ 0xd0b, "Cortex-A76" },
|
||||
{ 0xd0c, "Neoverse-N1" },
|
||||
{ 0xd0d, "Cortex-A77" },
|
||||
{ 0xd0e, "Cortex-A76AE" },
|
||||
{ 0xd13, "Cortex-R52" },
|
||||
{ 0xd20, "Cortex-M23" },
|
||||
{ 0xd21, "Cortex-M33" },
|
||||
{ 0xd41, "Cortex-A78" },
|
||||
{ 0xd42, "Cortex-A78AE" },
|
||||
{ 0xd4a, "Neoverse-E1" },
|
||||
{ 0xd4b, "Cortex-A78C" },
|
||||
};
|
||||
|
||||
if (strncmp(buf, part_marker, sizeof(part_marker) - 1) == 0) {
|
||||
model = buf + sizeof(part_marker) - 1;
|
||||
|
||||
errno = 0;
|
||||
model_id = strtol(model, NULL, 16);
|
||||
if ((errno != 0) || model_id < 0) {
|
||||
fclose(fp);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
for (part_idx = 0; part_idx < ARRAY_SIZE(arm_chips); part_idx++) {
|
||||
if (model_id == arm_chips[part_idx].id) {
|
||||
model = uv__strdup(arm_chips[part_idx].name);
|
||||
if (model == NULL) {
|
||||
fclose(fp);
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
ci[model_idx++].model = model;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* defined(__mips__) */
|
||||
static const char model_marker[] = "cpu model\t\t: ";
|
||||
#endif
|
||||
@ -421,18 +512,18 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else /* !__arm__ && !__mips__ */
|
||||
#else /* !__arm__ && !__mips__ && !__aarch64__ */
|
||||
if (speed_idx < numcpus) {
|
||||
if (strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0) {
|
||||
ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* __arm__ || __mips__ */
|
||||
#endif /* __arm__ || __mips__ || __aarch64__ */
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ */
|
||||
#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ || __aarch__ */
|
||||
|
||||
/* Now we want to make sure that all the models contain *something* because
|
||||
* it's not safe to leave them as null. Copy the last entry unless there
|
||||
@ -697,7 +788,7 @@ uint64_t uv_get_free_memory(void) {
|
||||
struct sysinfo info;
|
||||
uint64_t rc;
|
||||
|
||||
rc = uv__read_proc_meminfo("MemFree:");
|
||||
rc = uv__read_proc_meminfo("MemAvailable:");
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
5
deps/libuv/src/unix/os390-syscalls.c
vendored
5
deps/libuv/src/unix/os390-syscalls.c
vendored
@ -136,6 +136,11 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) {
|
||||
}
|
||||
|
||||
|
||||
void uv__os390_cleanup(void) {
|
||||
msgctl(uv_backend_fd(uv_default_loop()), IPC_RMID, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void init_message_queue(uv__os390_epoll* lst) {
|
||||
struct {
|
||||
long int header;
|
||||
|
1
deps/libuv/src/unix/os390-syscalls.h
vendored
1
deps/libuv/src/unix/os390-syscalls.h
vendored
@ -70,5 +70,6 @@ int sem_destroy(UV_PLATFORM_SEM_T* semid);
|
||||
int sem_post(UV_PLATFORM_SEM_T* semid);
|
||||
int sem_trywait(UV_PLATFORM_SEM_T* semid);
|
||||
int sem_wait(UV_PLATFORM_SEM_T* semid);
|
||||
void uv__os390_cleanup(void);
|
||||
|
||||
#endif /* UV_OS390_SYSCALL_H_ */
|
||||
|
97
deps/libuv/src/unix/process.c
vendored
97
deps/libuv/src/unix/process.c
vendored
@ -26,6 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
@ -216,13 +217,32 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
int stdio_count,
|
||||
int (*pipes)[2],
|
||||
int error_fd) {
|
||||
sigset_t set;
|
||||
sigset_t signewset;
|
||||
int close_fd;
|
||||
int use_fd;
|
||||
int err;
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
/* Reset signal disposition first. Use a hard-coded limit because NSIG is not
|
||||
* fixed on Linux: it's either 32, 34 or 64, depending on whether RT signals
|
||||
* are enabled. We are not allowed to touch RT signal handlers, glibc uses
|
||||
* them internally.
|
||||
*/
|
||||
for (n = 1; n < 32; n += 1) {
|
||||
if (n == SIGKILL || n == SIGSTOP)
|
||||
continue; /* Can't be changed. */
|
||||
|
||||
#if defined(__HAIKU__)
|
||||
if (n == SIGKILLTHR)
|
||||
continue; /* Can't be changed. */
|
||||
#endif
|
||||
|
||||
if (SIG_ERR != signal(n, SIG_DFL))
|
||||
continue;
|
||||
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
|
||||
if (options->flags & UV_PROCESS_DETACHED)
|
||||
setsid();
|
||||
|
||||
@ -304,32 +324,10 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
environ = options->env;
|
||||
}
|
||||
|
||||
/* Reset signal disposition. Use a hard-coded limit because NSIG
|
||||
* is not fixed on Linux: it's either 32, 34 or 64, depending on
|
||||
* whether RT signals are enabled. We are not allowed to touch
|
||||
* RT signal handlers, glibc uses them internally.
|
||||
*/
|
||||
for (n = 1; n < 32; n += 1) {
|
||||
if (n == SIGKILL || n == SIGSTOP)
|
||||
continue; /* Can't be changed. */
|
||||
|
||||
#if defined(__HAIKU__)
|
||||
if (n == SIGKILLTHR)
|
||||
continue; /* Can't be changed. */
|
||||
#endif
|
||||
|
||||
if (SIG_ERR != signal(n, SIG_DFL))
|
||||
continue;
|
||||
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
|
||||
/* Reset signal mask. */
|
||||
sigemptyset(&set);
|
||||
err = pthread_sigmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
if (err != 0)
|
||||
uv__write_errno(error_fd);
|
||||
/* Reset signal mask just before exec. */
|
||||
sigemptyset(&signewset);
|
||||
if (sigprocmask(SIG_SETMASK, &signewset, NULL) != 0)
|
||||
abort();
|
||||
|
||||
#ifdef __MVS__
|
||||
execvpe(options->file, options->args, environ);
|
||||
@ -338,6 +336,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
#endif
|
||||
|
||||
uv__write_errno(error_fd);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -349,6 +348,8 @@ int uv_spawn(uv_loop_t* loop,
|
||||
/* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
|
||||
return UV_ENOSYS;
|
||||
#else
|
||||
sigset_t signewset;
|
||||
sigset_t sigoldset;
|
||||
int signal_pipe[2] = { -1, -1 };
|
||||
int pipes_storage[8][2];
|
||||
int (*pipes)[2];
|
||||
@ -423,25 +424,41 @@ int uv_spawn(uv_loop_t* loop,
|
||||
|
||||
/* Acquire write lock to prevent opening new fds in worker threads */
|
||||
uv_rwlock_wrlock(&loop->cloexec_lock);
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
err = UV__ERR(errno);
|
||||
uv_rwlock_wrunlock(&loop->cloexec_lock);
|
||||
uv__close(signal_pipe[0]);
|
||||
uv__close(signal_pipe[1]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
|
||||
/* Start the child with most signals blocked, to avoid any issues before we
|
||||
* can reset them, but allow program failures to exit (and not hang). */
|
||||
sigfillset(&signewset);
|
||||
sigdelset(&signewset, SIGKILL);
|
||||
sigdelset(&signewset, SIGSTOP);
|
||||
sigdelset(&signewset, SIGTRAP);
|
||||
sigdelset(&signewset, SIGSEGV);
|
||||
sigdelset(&signewset, SIGBUS);
|
||||
sigdelset(&signewset, SIGILL);
|
||||
sigdelset(&signewset, SIGSYS);
|
||||
sigdelset(&signewset, SIGABRT);
|
||||
if (pthread_sigmask(SIG_BLOCK, &signewset, &sigoldset) != 0)
|
||||
abort();
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
err = UV__ERR(errno);
|
||||
|
||||
if (pid == 0)
|
||||
uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
|
||||
|
||||
if (pthread_sigmask(SIG_SETMASK, &sigoldset, NULL) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Release lock in parent process */
|
||||
uv_rwlock_wrunlock(&loop->cloexec_lock);
|
||||
|
||||
uv__close(signal_pipe[1]);
|
||||
|
||||
if (pid == -1) {
|
||||
uv__close(signal_pipe[0]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
process->status = 0;
|
||||
exec_errorno = 0;
|
||||
do
|
||||
|
10
deps/libuv/src/unix/stream.c
vendored
10
deps/libuv/src/unix/stream.c
vendored
@ -1010,7 +1010,6 @@ uv_handle_type uv__handle_type(int fd) {
|
||||
static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
|
||||
stream->flags |= UV_HANDLE_READ_EOF;
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
stream->flags &= ~UV_HANDLE_READABLE;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
@ -1550,15 +1549,12 @@ int uv__read_start(uv_stream_t* stream,
|
||||
assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
|
||||
stream->type == UV_TTY);
|
||||
|
||||
/* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just
|
||||
* expresses the desired state of the user.
|
||||
*/
|
||||
/* The UV_HANDLE_READING flag is irrelevant of the state of the stream - it
|
||||
* just expresses the desired state of the user. */
|
||||
stream->flags |= UV_HANDLE_READING;
|
||||
stream->flags &= ~UV_HANDLE_READ_EOF;
|
||||
|
||||
/* TODO: try to do the read inline? */
|
||||
/* TODO: keep track of tcp state. If we've gotten a EOF then we should
|
||||
* not start the IO watcher.
|
||||
*/
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
assert(alloc_cb);
|
||||
|
||||
|
62
deps/libuv/src/unix/udp.c
vendored
62
deps/libuv/src/unix/udp.c
vendored
@ -375,8 +375,11 @@ write_queue_drain:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Safety: npkts known to be >0 below. Hence cast from ssize_t
|
||||
* to size_t safe.
|
||||
*/
|
||||
for (i = 0, q = QUEUE_HEAD(&handle->write_queue);
|
||||
i < pkts && q != &handle->write_queue;
|
||||
i < (size_t)npkts && q != &handle->write_queue;
|
||||
++i, q = QUEUE_HEAD(&handle->write_queue)) {
|
||||
assert(q != NULL);
|
||||
req = QUEUE_DATA(q, uv_udp_send_t, queue);
|
||||
@ -651,28 +654,71 @@ int uv__udp_connect(uv_udp_t* handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* From https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
|
||||
* Any of uv supported UNIXs kernel should be standardized, but the kernel
|
||||
* implementation logic not same, let's use pseudocode to explain the udp
|
||||
* disconnect behaviors:
|
||||
*
|
||||
* Predefined stubs for pseudocode:
|
||||
* 1. sodisconnect: The function to perform the real udp disconnect
|
||||
* 2. pru_connect: The function to perform the real udp connect
|
||||
* 3. so: The kernel object match with socket fd
|
||||
* 4. addr: The sockaddr parameter from user space
|
||||
*
|
||||
* BSDs:
|
||||
* if(sodisconnect(so) == 0) { // udp disconnect succeed
|
||||
* if (addr->sa_len != so->addr->sa_len) return EINVAL;
|
||||
* if (addr->sa_family != so->addr->sa_family) return EAFNOSUPPORT;
|
||||
* pru_connect(so);
|
||||
* }
|
||||
* else return EISCONN;
|
||||
*
|
||||
* z/OS (same with Windows):
|
||||
* if(addr->sa_len < so->addr->sa_len) return EINVAL;
|
||||
* if (addr->sa_family == AF_UNSPEC) sodisconnect(so);
|
||||
*
|
||||
* AIX:
|
||||
* if(addr->sa_len != sizeof(struct sockaddr)) return EINVAL; // ignore ip proto version
|
||||
* if (addr->sa_family == AF_UNSPEC) sodisconnect(so);
|
||||
*
|
||||
* Linux,Others:
|
||||
* if(addr->sa_len < sizeof(struct sockaddr)) return EINVAL;
|
||||
* if (addr->sa_family == AF_UNSPEC) sodisconnect(so);
|
||||
*/
|
||||
int uv__udp_disconnect(uv_udp_t* handle) {
|
||||
int r;
|
||||
#if defined(__MVS__)
|
||||
struct sockaddr_storage addr;
|
||||
#else
|
||||
struct sockaddr addr;
|
||||
#endif
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
|
||||
#if defined(__MVS__)
|
||||
addr.ss_family = AF_UNSPEC;
|
||||
#else
|
||||
addr.sa_family = AF_UNSPEC;
|
||||
|
||||
#endif
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
r = connect(handle->io_watcher.fd, &addr, sizeof(addr));
|
||||
r = connect(handle->io_watcher.fd, (struct sockaddr*) &addr, sizeof(addr));
|
||||
} while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r == -1 && errno != EAFNOSUPPORT)
|
||||
if (r == -1) {
|
||||
#if defined(BSD) /* The macro BSD is from sys/param.h */
|
||||
if (errno != EAFNOSUPPORT && errno != EINVAL)
|
||||
return UV__ERR(errno);
|
||||
#else
|
||||
return UV__ERR(errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
handle->flags &= ~UV_HANDLE_UDP_CONNECTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_send(uv_udp_send_t* req,
|
||||
uv_udp_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
@ -880,7 +926,7 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
|
||||
#if !defined(__OpenBSD__) && \
|
||||
!defined(__NetBSD__) && \
|
||||
!defined(__ANDROID__) && \
|
||||
!defined(__DragonFly__) & \
|
||||
!defined(__DragonFly__) && \
|
||||
!defined(__QNX__)
|
||||
static int uv__udp_set_source_membership4(uv_udp_t* handle,
|
||||
const struct sockaddr_in* multicast_addr,
|
||||
|
19
deps/libuv/src/uv-common.c
vendored
19
deps/libuv/src/uv-common.c
vendored
@ -274,6 +274,20 @@ int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
int uv_ip_name(const struct sockaddr *src, char *dst, size_t size) {
|
||||
switch (src->sa_family) {
|
||||
case AF_INET:
|
||||
return uv_inet_ntop(AF_INET, &((struct sockaddr_in *)src)->sin_addr,
|
||||
dst, size);
|
||||
case AF_INET6:
|
||||
return uv_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)src)->sin6_addr,
|
||||
dst, size);
|
||||
default:
|
||||
return UV_EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_bind(uv_tcp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int flags) {
|
||||
@ -887,7 +901,12 @@ void uv_library_shutdown(void) {
|
||||
|
||||
uv__process_title_cleanup();
|
||||
uv__signal_cleanup();
|
||||
#ifdef __MVS__
|
||||
/* TODO(itodorov) - zos: revisit when Woz compiler is available. */
|
||||
uv__os390_cleanup();
|
||||
#else
|
||||
uv__threadpool_cleanup();
|
||||
#endif
|
||||
uv__store_relaxed(&was_shutdown, 1);
|
||||
}
|
||||
|
||||
|
6
deps/libuv/src/win/fs-event.c
vendored
6
deps/libuv/src/win/fs-event.c
vendored
@ -574,10 +574,10 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
||||
handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
|
||||
}
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_CLOSING)) {
|
||||
uv_fs_event_queue_readdirchanges(loop, handle);
|
||||
} else {
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
} else if (uv__is_active(handle)) {
|
||||
uv_fs_event_queue_readdirchanges(loop, handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
18
deps/libuv/src/win/fs.c
vendored
18
deps/libuv/src/win/fs.c
vendored
@ -758,7 +758,7 @@ void fs__read_filemap(uv_fs_t* req, struct uv__fd_info_s* fd_info) {
|
||||
void* view;
|
||||
|
||||
if (rw_flags == UV_FS_O_WRONLY) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FLAGS);
|
||||
return;
|
||||
}
|
||||
if (fd_info->is_directory) {
|
||||
@ -912,6 +912,11 @@ void fs__read(uv_fs_t* req) {
|
||||
SET_REQ_RESULT(req, bytes);
|
||||
} else {
|
||||
error = GetLastError();
|
||||
|
||||
if (error == ERROR_ACCESS_DENIED) {
|
||||
error = ERROR_INVALID_FLAGS;
|
||||
}
|
||||
|
||||
if (error == ERROR_HANDLE_EOF) {
|
||||
SET_REQ_RESULT(req, bytes);
|
||||
} else {
|
||||
@ -936,7 +941,7 @@ void fs__write_filemap(uv_fs_t* req, HANDLE file,
|
||||
FILETIME ft;
|
||||
|
||||
if (rw_flags == UV_FS_O_RDONLY) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FLAGS);
|
||||
return;
|
||||
}
|
||||
if (fd_info->is_directory) {
|
||||
@ -1052,6 +1057,7 @@ void fs__write(uv_fs_t* req) {
|
||||
OVERLAPPED overlapped, *overlapped_ptr;
|
||||
LARGE_INTEGER offset_;
|
||||
DWORD bytes;
|
||||
DWORD error;
|
||||
int result;
|
||||
unsigned int index;
|
||||
LARGE_INTEGER original_position;
|
||||
@ -1111,7 +1117,13 @@ void fs__write(uv_fs_t* req) {
|
||||
if (result || bytes > 0) {
|
||||
SET_REQ_RESULT(req, bytes);
|
||||
} else {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
error = GetLastError();
|
||||
|
||||
if (error == ERROR_ACCESS_DENIED) {
|
||||
error = ERROR_INVALID_FLAGS;
|
||||
}
|
||||
|
||||
SET_REQ_WIN32_ERROR(req, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
2
deps/libuv/src/win/pipe.c
vendored
2
deps/libuv/src/win/pipe.c
vendored
@ -1252,7 +1252,6 @@ static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) {
|
||||
assert(req != NULL);
|
||||
assert(req->type == UV_WRITE);
|
||||
assert(handle->type == UV_NAMED_PIPE);
|
||||
assert(req->write_buffer.base);
|
||||
|
||||
result = WriteFile(handle->handle,
|
||||
req->write_buffer.base,
|
||||
@ -1797,7 +1796,6 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
|
||||
* it. */
|
||||
eof_timer_destroy(handle);
|
||||
|
||||
handle->flags &= ~UV_HANDLE_READABLE;
|
||||
uv_read_stop((uv_stream_t*) handle);
|
||||
|
||||
handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf);
|
||||
|
4
deps/libuv/src/win/process.c
vendored
4
deps/libuv/src/win/process.c
vendored
@ -169,7 +169,9 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
|
||||
size_t cwd_len) {
|
||||
WCHAR *result, *result_pos;
|
||||
DWORD attrs;
|
||||
if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') {
|
||||
if (dir_len > 2 &&
|
||||
((dir[0] == L'\\' || dir[0] == L'/') &&
|
||||
(dir[1] == L'\\' || dir[1] == L'/'))) {
|
||||
/* It's a UNC path so ignore cwd */
|
||||
cwd_len = 0;
|
||||
} else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
|
||||
|
5
deps/libuv/src/win/tcp.c
vendored
5
deps/libuv/src/win/tcp.c
vendored
@ -1044,7 +1044,6 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||
}
|
||||
handle->flags &= ~UV_HANDLE_READABLE;
|
||||
|
||||
buf.base = 0;
|
||||
buf.len = 0;
|
||||
@ -1081,7 +1080,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
}
|
||||
} else {
|
||||
/* Connection closed */
|
||||
handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE);
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||
|
||||
handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf);
|
||||
@ -1651,7 +1650,7 @@ int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int f
|
||||
err = WSAGetLastError();
|
||||
if (err == ERROR_IO_PENDING) {
|
||||
/* Result should complete immediately, since we already called connect,
|
||||
* but emperically, we sometimes have to poll the kernel a couple times
|
||||
* but empirically, we sometimes have to poll the kernel a couple times
|
||||
* until it notices that. */
|
||||
while (!WSAGetOverlappedResult(client1, &overlap, &bytes, FALSE, &flags)) {
|
||||
err = WSAGetLastError();
|
||||
|
15
deps/libuv/src/win/thread.c
vendored
15
deps/libuv/src/win/thread.c
vendored
@ -103,7 +103,7 @@ static UINT __stdcall uv__thread_start(void* arg) {
|
||||
uv__free(ctx_p);
|
||||
|
||||
uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
|
||||
uv_key_set(&uv__current_thread_key, (void*) ctx.self);
|
||||
uv_key_set(&uv__current_thread_key, ctx.self);
|
||||
|
||||
ctx.entry(ctx.arg);
|
||||
|
||||
@ -183,7 +183,18 @@ int uv_thread_create_ex(uv_thread_t* tid,
|
||||
|
||||
uv_thread_t uv_thread_self(void) {
|
||||
uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
|
||||
return (uv_thread_t) uv_key_get(&uv__current_thread_key);
|
||||
uv_thread_t key = uv_key_get(&uv__current_thread_key);
|
||||
if (key == NULL) {
|
||||
/* If the thread wasn't started by uv_thread_create (such as the main
|
||||
* thread), we assign an id to it now. */
|
||||
if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
|
||||
GetCurrentProcess(), &key, 0,
|
||||
FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||
uv_fatal_error(GetLastError(), "DuplicateHandle");
|
||||
}
|
||||
uv_key_set(&uv__current_thread_key, key);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
|
2
deps/libuv/src/win/udp.c
vendored
2
deps/libuv/src/win/udp.c
vendored
@ -1083,7 +1083,7 @@ int uv__udp_connect(uv_udp_t* handle,
|
||||
|
||||
int uv__udp_disconnect(uv_udp_t* handle) {
|
||||
int err;
|
||||
struct sockaddr addr;
|
||||
struct sockaddr_storage addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
|
5
deps/libuv/src/win/util.c
vendored
5
deps/libuv/src/win/util.c
vendored
@ -1674,7 +1674,10 @@ int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
|
||||
uv__once_init(); /* Initialize winsock */
|
||||
|
||||
if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
|
||||
if (pGetHostNameW == NULL)
|
||||
return UV_ENOSYS;
|
||||
|
||||
if (pGetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str);
|
||||
|
10
deps/libuv/src/win/winapi.c
vendored
10
deps/libuv/src/win/winapi.c
vendored
@ -45,12 +45,15 @@ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
/* User32.dll function pointer */
|
||||
sSetWinEventHook pSetWinEventHook;
|
||||
|
||||
/* ws2_32.dll function pointer */
|
||||
uv_sGetHostNameW pGetHostNameW;
|
||||
|
||||
void uv_winapi_init(void) {
|
||||
HMODULE ntdll_module;
|
||||
HMODULE powrprof_module;
|
||||
HMODULE user32_module;
|
||||
HMODULE kernel32_module;
|
||||
HMODULE ws2_32_module;
|
||||
|
||||
ntdll_module = GetModuleHandleA("ntdll.dll");
|
||||
if (ntdll_module == NULL) {
|
||||
@ -134,4 +137,11 @@ void uv_winapi_init(void) {
|
||||
pSetWinEventHook = (sSetWinEventHook)
|
||||
GetProcAddress(user32_module, "SetWinEventHook");
|
||||
}
|
||||
|
||||
ws2_32_module = LoadLibraryA("ws2_32.dll");
|
||||
if (ws2_32_module != NULL) {
|
||||
pGetHostNameW = (uv_sGetHostNameW) GetProcAddress(
|
||||
ws2_32_module,
|
||||
"GetHostNameW");
|
||||
}
|
||||
}
|
||||
|
7
deps/libuv/src/win/winapi.h
vendored
7
deps/libuv/src/win/winapi.h
vendored
@ -4759,4 +4759,11 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi
|
||||
/* User32.dll function pointer */
|
||||
extern sSetWinEventHook pSetWinEventHook;
|
||||
|
||||
/* ws2_32.dll function pointer */
|
||||
/* mingw doesn't have this definition, so let's declare it here locally */
|
||||
typedef int (WINAPI *uv_sGetHostNameW)
|
||||
(PWSTR,
|
||||
int);
|
||||
extern uv_sGetHostNameW pGetHostNameW;
|
||||
|
||||
#endif /* UV_WIN_WINAPI_H_ */
|
||||
|
Reference in New Issue
Block a user