uv__fs_buf_iter currently sets req->bufs to NULL after it is done, but
if the operation fails with EINTR then it will be retried, at which
point it expects the bufs to not be NULL, causing a seg fault as in
https://github.com/nodejs/node/issues/4291.
uv__fs_buf_iter should not set req->bufs to NULL if the operation
fails with EINTR.
Also, when it sets req->bufs to NULL, it should set req->nbufs to 0 as
well, so we don't have the messy situation of a positive nbufs with no
actual bufs.
PR-URL: https://github.com/libuv/libuv/pull/661
Reviewed-By: Fedor Indutny <fedor@indutny.com>
uClibc-ng is currently at v1.0.9. The patch corrects the uClibc
version test so that HAVE_IFADDRS_H is defined for uClibc versions
after v0.9.32.
Signed-off-by: Martin Bark <martin@barkynet.com>
PR-URL: https://github.com/libuv/libuv/pull/653
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
The following changeset
442b8a5a84 "unix: use QUEUE_MOVE when iterating over lists"
introduced a new assert failure:
`queue_foreach_delete` failed: exit code 6
Output from process `queue_foreach_delete`:
run-tests: src/unix/linux-inotify.c:244: uv_fs_event_stop: Assertion `w != ((void *)0)' failed.
Simplest test case for this:
1. create and start two uv_fs_event_t for the same path;
2. in the callback for the first one, call uv_close() on it;
3. assert/segfault while accessing the second uv_fs_event_t from uv__inotify_read().
PR-URL: https://github.com/libuv/libuv/pull/621
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
On Windows the pipe implementation could read more from a stream than
was available and it would create an assertion failure. This change
will make it so we read the minimum of the available data or the length
of the data.
To test this, I took the existing ipc_send_recv_tcp test and updated it
to do two writes and two read on each side of the pipe since that was the
reproduction recipe used by the reporter. This approach reproduced the
issue on Windows and the committed fix resolved the issue.
Fixes: https://github.com/libuv/libuv/issues/505
PR-URL: https://github.com/libuv/libuv/pull/549
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Previous behavior on Windows was to set the path to NULL for removed
and renamed fs events. This was because the path provided by
ReadDirectoryChangesW might (in rare cases) be an 8.3 short name which
could then no longer be converted to a long name after the path had
been removed or renamed. This meant that the user had to detect which
path was actually deleted or renamed and required the user to rescan
the entire watched subtree, taking several seconds or more for large
subtrees.
However, ReadDirectoryChangesW is publicly documented to emit 8.3
short names if the original handle for the changed path was opened
using an 8.3 short name, and libuv may already emit 8.3 short names for
other events if the path cannot be explicitly resolved to a long name.
This commit fixes the path for removed and renamed fs events, and does
not set the path to NULL, even if the path might be an 8.3 short name.
This makes it possible for the user to do a partial scan of the
subtree, restricting the scan to paths which match the long form or 8.3
short name (even if some of these are false positive matches). This
means that deletes and renames can now be detected accurately on
Windows within a few milliseconds.
Fixes: https://github.com/libuv/libuv/issues/634
Refs: https://github.com/libuv/libuv/pull/199
PR-URL: https://github.com/libuv/libuv/pull/639
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Equivalent to realpath(3), returns the full resolved absolute path of a
file or directory.
PR-URL: https://github.com/libuv/libuv/pull/531
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
When `uv_fsevents_t` handle is closed immediately after initializing,
there is a possibility that the `CFRunLoop`'s thread will process both
of these events at the same time. `uv__is_active(handle)` will return
`0`, and the `uv_close()` semaphore will be unblocked, leading
to the use after free in node.js.
See: https://github.com/nodejs/node/issues/4091
PR-URL: https://github.com/libuv/libuv/pull/637
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Remove restriction to Android API level >= 21, now libuv can be used with
Android API level at least 14.
Direct use of getpwuid_r function resulted in linker errors in applications
were built against API level below 21. That function was 'officially'
introduced in Android API level 21, but it exists in libc beginning from API
level at least 14.
So try to get a pointer to getpwuid_r at runtime using dlsym when building
libuv with API level < 21.
PR-URL: https://github.com/libuv/libuv/pull/633
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Like the previous commit, but this time for UNIX platforms other than
Linux.
As far as I have been able to establish, dup2 and dup3 never return
EINTR on OS X and FreeBSD. Even if other platforms do return EINTR,
it's probably still better not to retry because it's unspecified
whether the file descriptor has been closed.
Fixes: https://github.com/libuv/libuv/issues/462
PR-URL: https://github.com/libuv/libuv/pull/608
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Retrying seems like a bad idea in a multi-threaded program because the
man page leaves it unspecified whether the file descriptor is closed
after EINTR.
It's probably an academic issue because as far as I have been able to
establish by checking the kernel sources, dup2 and dup3 never actually
return EINTR. For dup3, this appears to have been the case since its
introduction in v2.6.27; for dup2, it goes back to at least v2.6.18.
Fixes: https://github.com/libuv/libuv/issues/462
PR-URL: https://github.com/libuv/libuv/pull/608
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Previously, libuv didn't return the correct error code when attempting
to close an invalid file descriptor with `uv_fs_close()`.
PR-URL: https://github.com/libuv/libuv/pull/613
Reviewed-by: Bert Belder <bertbelder@gmail.com>
When duplicating the socket handle being sent the target process
id is defaulted to the current process id. This enables uv_write2
to be used for thread-clustering in addition to process-clustering on
multi-threaded programming languages.
The ipc tests are updated to run in two modes. In the _inproc mode
the echo work is done on a second thread instead of in a second
process.
An internal function int uv_current_pid() is added to the windows
specific code which caches the value of GetCurrentProcessId(). This
means uv_write2 does not call GetCurrentProcessId() every inprocess
send.
Refs: https://github.com/joyent/libuv/issues/926
PR-URL: https://github.com/libuv/libuv/pull/540
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
The pthread_mutex_lock() and pthread_mutex_unlock() calls logically
cannot fail in uv__fs_write() but let's check the return value anyway:
cosmic rays and memory corruption do happen.
PR-URL: https://github.com/libuv/libuv/pull/603
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
fork and the exec functions are marked prohibited on tvOS and watchOS,
so referencing them causes compile errors.
This adds preprocessor conditionals to avoid calling them for those
targets.
PR-URL: https://github.com/libuv/libuv/pull/580
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
The atomics that are in place of a lack of x86 cmpxchg are a GCC
specific intrinsic. When compiling for Solaris on a SPARC platform
with a non-gcc compiler, this prevents a successful build. This commit
will rely on a Solaris Studio specific preprocessor macro to redefine
the GCC intrinsic name to be the Solaris Studio one instead.
PR-URL: https://github.com/libuv/libuv/pull/569
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
On some embedded devices (arm-linux-uclibc based ip camera),
sysconf(_SC_IOV_MAX) can not get the correct value. The return
value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
PR-URL: https://github.com/libuv/libuv/pull/573
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Commit 0199955 ("fs: undo uv__req_init when uv__malloc failed")
mistakingly unregisters the requests unconditionally in a few places,
resulting in memory corruption when it hasn't been registered first.
Fixes: https://github.com/libuv/libuv/pull/543
PR-URL: https://github.com/libuv/libuv/pull/567
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Valgrind complains that the msg_control pointer points to uninitialized
memory. While the memory is only used for writing data to, not for
reading data from, and the warning is therefore bogus, it's still
annoying enough that I decided to squelch it by zeroing the memory.
The performance implications should be minimal because this code path
is only used when sending over a handle to another process.
The warning:
==14859== Syscall param sendmsg(msg.msg_control) points to
uninitialised byte(s)
==14859== at 0x5AF1A80: __sendmsg_nocancel (in
/usr/lib64/libpthread-2.21.so)
==14859== by 0x46350E: uv__write (stream.c:810)
==14859== by 0x464B24: uv_write2 (stream.c:1398)
==14859== by 0x421ACE: run_test (test-ipc-send-recv.c:104)
==14859== by 0x421DD1: run_test_ipc_send_recv_tcp
(test-ipc-send-recv.c:156)
==14859== by 0x406D2F: run_test_part (runner.c:404)
==14859== by 0x4058CD: main (run-tests.c:58)
==14859== Address 0xffefff934 is on thread 1's stack
==14859== in frame #1, created by uv__write (stream.c:742)
PR-URL: https://github.com/libuv/libuv/pull/565
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Replace uses of QUEUE_FOREACH when the list can get modified while
iterating over it, in particular when a callback is made into the
user's code. This should fix a number of spurious failures that
people have been reporting.
PR-URL: https://github.com/libuv/libuv/pull/565
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
All uses of QUEUE_SPLIT in libuv split the list at the head so introduce
a QUEUE_MOVE macro that automates that.
PR-URL: https://github.com/libuv/libuv/pull/565
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
On AIX, the getsockname API does not operate on the UNIX domain sockets
Please see: https://www-01.ibm.com/support/knowledgecenter/ssw_aix_61/
com.ibm.aix.commtrf2/getsockname.htm
This means that the internal helper routine uv_guess_handle in tty.c
fails in AIX, for common use cases.
There is no direct API support which helps identifying a UNIX domain
socket in AIX. getpeername() retrieves the information pertinent to
connected UNIX domain socket pairs, and using getpeername where
getsockname fails was a good workaround. However, there are edge cases
where one end of a socketpair comes for introspection while the other
end has been closed, which causes getpeername to fail.
A better solution is derived based on these facts:
1.getsockname() on a broken / un-broken socketpair does not actually
fail with -1, instead it returns 0. However, the API does not modify
the socketaddr structure passed to it, with the socket information.
2.This behavior of getsockname is observed only for UNIX domain socket,
among all possible types of sockets which I tested - ~30 of them.
So a practical and stable workaround for AIX is to return
UV_UNKNOWN_HANDLE if getsockname fails. If it passes and the length
of the structure returned is 0 then we know that the type is AF_UNIX
and return UV_NAMED_PIPE , otherwise we inspect in the same way as for
other platforms to derive the type.
PR-URL: https://github.com/libuv/libuv/pull/539
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
They're no longer needed, since the Windows-native SRWLock functions are
no longer used.
PR-URL: https://github.com/libuv/libuv/pull/525
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Previously, on Windows Vista and later, we'd use the Windows native
SRWLock APIs. However they turned out to be semantically incompatible
with pthread read-write locks and/or plain buggy. This patch makes sure
that the custom implementation that was previously only used on old
Windows versions is now used everywhere.
This patch fixes a number of issues with the old fallback
implementation. Specifically:
* The reader count would not be incremented when a thread successfully
acquired a read lock while another thread *also* held a read lock.
* `uv_rwlock_tryrdlock()` and `uv_rwlock_trywrlock()` now
consistently return UV_EBUSY when a lock couldn't be acquired.
* Any unexpected errors now cause libuv to abort, with the exception of
`uv_rwlock_init()`.
See also https://github.com/libuv/libuv/issues/515.
PR-URL: https://github.com/libuv/libuv/pull/525
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Fold EAGAIN into EBUSY, and make it the only acceptable error.
PR-URL: https://github.com/libuv/libuv/pull/535
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
On AIX with the native xlC compiler, the compiler supports sync
compare swap and compare in two flavors:
1 __compare_and_swap
2 __compare_and_swaplp
This differs from the gcc version of this function in name. The
second version of this function supports 8-byte boundary for
a doubleword. Therefore, the macro logic checks:
if (AIX OS AND using xlC compiler)
if (64bit)
__compare_and_swaplp /* 64 bit version */
else
__compare_and_swap
endif
endif
Signed-off-by: Neil Mushell <nmushell@bloomberg.net>
PR-URL: https://github.com/libuv/libuv/pull/521
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Before this patch an uv_mutex_t (backed by a critical section) could be
released by a tread different from the thread that acquired it, which is
not allowed. This is fixed by using a semaphore instead.
Note that the affected code paths were used on Windows XP and Windows
Server 2003 only.
Fixes: https://github.com/libuv/libuv/issues/515
PR-URL: https://github.com/libuv/libuv/pull/516
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
uv__close() does not set errno, it returns the error. It also never
returns EINTR, it always maps it to EINPROGRESS.
PR-URL: https://github.com/libuv/libuv/pull/512
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
The code made an implicit assumption that the 'len` variable passed
to the sendfile(2) syscall is not modified by the operating system
in case of an error other than EAGAIN or EINTR.
The man page leaves this unspecified on FreeBSD, DragonFly and
Darwin, so better check the error code which returns a valid
value in `len` explicitly (only EAGAIN and EINTR).
This fixes the test case for sendfile on DragonFly.
PR-URL: https://github.com/libuv/libuv/pull/466
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
\r is a single carriage return without line feed on all platforms,
including Windows.
PR-URL: https://github.com/libuv/libuv/pull/472
Reviewed-By: Bert Belder <bertbelder@gmail.com>
Commit 0f1bdb6 ("threadpool: send signal only when queue is empty")
introduces a regression where work is not evenly distributed across
the thread pool because the work queue's condition variable is only
signalled when the queue is empty, even when there are waiting workers.
It doesn't turn into outright deadlock because there is always
at least one thread making forward progress but it does degrade
throughput, sometimes massively so.
Signalling whenever there are waiting workers fixes the throughput
issue while still keeping the number of uv_cond_signal() calls low,
which was the motivation for commit 0f1bdb6.
Fixes: https://github.com/libuv/libuv/pull/490
Fixes: https://github.com/libuv/libuv/issues/492
PR-URL: https://github.com/libuv/libuv/pull/493
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
It's an error to do so, so just ignore it. The test would cause an
invalid memory access if the fix is undone.
PR-URL: https://github.com/libuv/libuv/pull/488
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
On Windows we create multiple pipe handles (system handles) which are
attached to pending accept requests. Each of these will take turns in
replacing the reference in handle->handle, so make sure we allow for
that **only** for pipe servers.
PR-URL: https://github.com/libuv/libuv/pull/488
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
On pipe servers handle->handle takes turns between the different server
handles, so after closing all of them just reset the dandling reference.
PR-URL: https://github.com/libuv/libuv/pull/488
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>