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:
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,
|
||||
|
Reference in New Issue
Block a user