mirror of
https://github.com/nodejs/node.git
synced 2025-05-13 10:54:13 +00:00
deps: update uv to v1.0.0-rc2
PR-URL: https://github.com/joyent/node/pull/8566 Reviewed-by: Fedor Indutny <fedor@indutny.com> Reviewed-by: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
28ae70ebad
commit
ce112c27c6
9
deps/uv/AUTHORS
vendored
9
deps/uv/AUTHORS
vendored
@ -157,3 +157,12 @@ John Firebaugh <john.firebaugh@gmail.com>
|
||||
lilohuang <lilohuang@hotmail.com>
|
||||
Paul Goldsmith <paul.goldsmith@aplink.net>
|
||||
Julien Gilli <julien.gilli@joyent.com>
|
||||
Michael Hudson-Doyle <michael.hudson@linaro.org>
|
||||
Recep ASLANTAS <m@recp.me>
|
||||
Rob Adams <readams@readams.net>
|
||||
Zachary Newman <znewman01@gmail.com>
|
||||
Robin Hahling <robin.hahling@gw-computing.net>
|
||||
Jeff Widman <jeff@jeffwidman.com>
|
||||
cjihrig <cjihrig@gmail.com>
|
||||
Tomasz Kołodziejski <tkolodziejski@mozilla.com>
|
||||
Unknown W. Brackets <checkins@unknownbrackets.org>
|
||||
|
6
deps/uv/CONTRIBUTING.md
vendored
6
deps/uv/CONTRIBUTING.md
vendored
@ -37,10 +37,10 @@ Okay, so you have decided on the proper branch. Create a feature branch
|
||||
and start hacking:
|
||||
|
||||
```
|
||||
$ git checkout -b my-feature-branch -t origin/v0.10
|
||||
$ git checkout -b my-feature-branch -t origin/v1.x
|
||||
```
|
||||
|
||||
(Where v0.10 is the latest stable branch as of this writing.)
|
||||
(Where v1.x is the latest stable branch as of this writing.)
|
||||
|
||||
### CODE
|
||||
|
||||
@ -131,7 +131,7 @@ Use `git rebase` (not `git merge`) to sync your work from time to time.
|
||||
|
||||
```
|
||||
$ git fetch upstream
|
||||
$ git rebase upstream/v0.10 # or upstream/master
|
||||
$ git rebase upstream/v1.x # or upstream/master
|
||||
```
|
||||
|
||||
|
||||
|
42
deps/uv/ChangeLog
vendored
42
deps/uv/ChangeLog
vendored
@ -1,5 +1,47 @@
|
||||
2014.10.21, Version 1.0.0-rc2 (Pre-release)
|
||||
|
||||
Changes since version 1.0.0-rc1:
|
||||
|
||||
* build: add missing fixtures to distribution tarball (Rob Adams)
|
||||
|
||||
* doc: update references to current stable branch (Zachary Newman)
|
||||
|
||||
* fs: fix readdir on empty directory (Fedor Indutny)
|
||||
|
||||
* fs: rename uv_fs_readdir to uv_fs_scandir (Saúl Ibarra Corretgé)
|
||||
|
||||
* doc: document uv_alloc_cb (Saúl Ibarra Corretgé)
|
||||
|
||||
* doc: add migration guide from version 0.10 (Saúl Ibarra Corretgé)
|
||||
|
||||
* build: add DragonFly BSD support in autotools (Robin Hahling)
|
||||
|
||||
* doc: document missing stream related structures (Saúl Ibarra Corretgé)
|
||||
|
||||
* doc: clarify uv_loop_t.data field lifetime (Saúl Ibarra Corretgé)
|
||||
|
||||
* doc: add documentation for missing functions and structures (Saúl Ibarra
|
||||
Corretgé)
|
||||
|
||||
* doc: fix punctuation and grammar in README (Jeff Widman)
|
||||
|
||||
* windows: return libuv error codes in uv_poll_init() (cjihrig)
|
||||
|
||||
* unix, windows: add uv_fs_access() (cjihrig)
|
||||
|
||||
* windows: fix netmask detection (Alexis Campailla)
|
||||
|
||||
* unix, windows: don't include null byte in uv_cwd size (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add uv_thread_equal (Tomasz Kołodziejski)
|
||||
|
||||
* windows: fix fs_write with nbufs > 1 and offset (Unknown W. Brackets)
|
||||
|
||||
|
||||
2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49
|
||||
|
||||
Changes since version 0.11.29:
|
||||
|
||||
* windows: improve timer precision (Alexis Campailla)
|
||||
|
||||
* build, gyp: set xcode flags (Recep ASLANTAS)
|
||||
|
9
deps/uv/Makefile.am
vendored
9
deps/uv/Makefile.am
vendored
@ -106,6 +106,9 @@ libuv_la_SOURCES += src/unix/async.c \
|
||||
|
||||
endif # WINNT
|
||||
|
||||
EXTRA_DIST = test/fixtures/empty_file \
|
||||
test/fixtures/load_error.node
|
||||
|
||||
TESTS = test/run-tests
|
||||
check_PROGRAMS = test/run-tests
|
||||
test_run_tests_CFLAGS =
|
||||
@ -203,6 +206,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-tcp-writealot.c \
|
||||
test/test-tcp-try-write.c \
|
||||
test/test-tcp-write-queue-order.c \
|
||||
test/test-thread-equal.c \
|
||||
test/test-thread.c \
|
||||
test/test-threadpool-cancel.c \
|
||||
test/test-threadpool.c \
|
||||
@ -268,6 +272,11 @@ libuv_la_SOURCES += src/unix/darwin.c \
|
||||
src/unix/proctitle.c
|
||||
endif
|
||||
|
||||
if DRAGONFLY
|
||||
include_HEADERS += include/uv-bsd.h
|
||||
libuv_la_SOURCES += src/unix/kqueue.c src/unix/freebsd.c
|
||||
endif
|
||||
|
||||
if FREEBSD
|
||||
include_HEADERS += include/uv-bsd.h
|
||||
libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c
|
||||
|
4
deps/uv/README.md
vendored
4
deps/uv/README.md
vendored
@ -85,7 +85,7 @@ Documentation can be browsed online [here](http://docs.libuv.org).
|
||||
|
||||
## Build Instructions
|
||||
|
||||
For GCC there are two methods building: via autotools or via [GYP][].
|
||||
For GCC there are two build methods: via autotools or via [GYP][].
|
||||
GYP is a meta-build system which can generate MSVS, Makefile, and XCode
|
||||
backends. It is best used for integration into other projects.
|
||||
|
||||
@ -100,7 +100,7 @@ To build with autotools:
|
||||
### Windows
|
||||
|
||||
First, [Python][] 2.6 or 2.7 must be installed as it is required by [GYP][].
|
||||
If python is not in your path set the environment variable `PYTHON` to its
|
||||
If python is not in your path, set the environment variable `PYTHON` to its
|
||||
location. For example: `set PYTHON=C:\Python27\python.exe`
|
||||
|
||||
To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell)
|
||||
|
3
deps/uv/configure.ac
vendored
3
deps/uv/configure.ac
vendored
@ -13,7 +13,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [1.0.0], [https://github.com/joyent/libuv/issues])
|
||||
AC_INIT([libuv], [1.0.0-rc2], [https://github.com/joyent/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
m4_include([m4/as_case.m4])
|
||||
@ -43,6 +43,7 @@ AC_SYS_LARGEFILE
|
||||
AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])])
|
||||
AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])])
|
||||
AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
|
||||
AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])])
|
||||
AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[freebsd*], [true], [false])])
|
||||
AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
|
||||
AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])])
|
||||
|
30
deps/uv/docs/src/fs.rst
vendored
30
deps/uv/docs/src/fs.rst
vendored
@ -20,9 +20,20 @@ Data types
|
||||
|
||||
Filesystem request type.
|
||||
|
||||
.. c:type:: uv_timespec_t
|
||||
|
||||
Portable equivalent of ``struct timespec``.
|
||||
|
||||
::
|
||||
|
||||
typedef struct {
|
||||
long tv_sec;
|
||||
long tv_nsec;
|
||||
} uv_timespec_t;
|
||||
|
||||
.. c:type:: uv_stat_t
|
||||
|
||||
Portable equivalent of `struct stat`.
|
||||
Portable equivalent of ``struct stat``.
|
||||
|
||||
::
|
||||
|
||||
@ -65,6 +76,7 @@ Data types
|
||||
UV_FS_FTRUNCATE,
|
||||
UV_FS_UTIME,
|
||||
UV_FS_FUTIME,
|
||||
UV_FS_ACCESS,
|
||||
UV_FS_CHMOD,
|
||||
UV_FS_FCHMOD,
|
||||
UV_FS_FSYNC,
|
||||
@ -74,7 +86,7 @@ Data types
|
||||
UV_FS_MKDIR,
|
||||
UV_FS_MKDTEMP,
|
||||
UV_FS_RENAME,
|
||||
UV_FS_READDIR,
|
||||
UV_FS_SCANDIR,
|
||||
UV_FS_LINK,
|
||||
UV_FS_SYMLINK,
|
||||
UV_FS_READLINK,
|
||||
@ -85,7 +97,7 @@ Data types
|
||||
.. c:type:: uv_dirent_t
|
||||
|
||||
Cross platform (reduced) equivalent of ``struct dirent``.
|
||||
Used in :c:func:`uv_fs_readdir_next`.
|
||||
Used in :c:func:`uv_fs_scandir_next`.
|
||||
|
||||
::
|
||||
|
||||
@ -183,11 +195,11 @@ API
|
||||
|
||||
Equivalent to ``rmdir(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent)
|
||||
.. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent)
|
||||
|
||||
Equivalent to ``readdir(2)``, with a slightly different API. Once the callback
|
||||
for the request is called, the user can use :c:func:`uv_fs_readdir_next` to
|
||||
Equivalent to ``scandir(3)``, with a slightly different API. Once the callback
|
||||
for the request is called, the user can use :c:func:`uv_fs_scandir_next` to
|
||||
get `ent` populated with the next directory entry data. When there are no
|
||||
more entries ``UV_EOF`` will be returned.
|
||||
|
||||
@ -217,6 +229,10 @@ API
|
||||
|
||||
Limited equivalent to ``sendfile(2)``.
|
||||
|
||||
.. c:function:: int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
|
||||
|
||||
Equivalent to ``access(2)`` on Unix. Windows uses ``GetFileAttributesW()``.
|
||||
|
||||
.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
|
||||
.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb)
|
||||
|
||||
|
4
deps/uv/docs/src/fs_poll.rst
vendored
4
deps/uv/docs/src/fs_poll.rst
vendored
@ -42,6 +42,10 @@ N/A
|
||||
API
|
||||
---
|
||||
|
||||
.. c:function:: int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle)
|
||||
|
||||
Initialize the handle.
|
||||
|
||||
.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval)
|
||||
|
||||
Check the file at `path` for changes every `interval` milliseconds.
|
||||
|
9
deps/uv/docs/src/handle.rst
vendored
9
deps/uv/docs/src/handle.rst
vendored
@ -21,6 +21,15 @@ Data types
|
||||
|
||||
Union of all handle types.
|
||||
|
||||
.. c:type:: void (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_read_start` and
|
||||
:c:func:`uv_udp_recv_start`. The user must fill the supplied :c:type:`uv_buf_t`
|
||||
structure with whatever size, as long as it's > 0. A suggested size (65536 at the moment)
|
||||
is provided, but it doesn't need to be honored. Setting the buffer's length to 0
|
||||
will trigger a ``UV_ENOBUFS`` error in the :c:type:`uv_udp_recv_cb` or
|
||||
:c:type:`uv_read_cb` callback.
|
||||
|
||||
.. c:type:: void (*uv_close_cb)(uv_handle_t* handle)
|
||||
|
||||
Type definition for callback passed to :c:func:`uv_close`.
|
||||
|
11
deps/uv/docs/src/index.rst
vendored
11
deps/uv/docs/src/index.rst
vendored
@ -50,6 +50,17 @@ Installation
|
||||
Installation instructions can be found on `the README <https://github.com/joyent/libuv/blob/master/README.md>`_.
|
||||
|
||||
|
||||
Upgrading
|
||||
---------
|
||||
|
||||
Migration guides for different libuv versions, starting with 1.0.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
migration_010_100
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
|
4
deps/uv/docs/src/loop.rst
vendored
4
deps/uv/docs/src/loop.rst
vendored
@ -38,7 +38,9 @@ Public members
|
||||
|
||||
.. c:member:: void* uv_loop_t.data
|
||||
|
||||
Space for user-defined arbitrary data. libuv does not use this field.
|
||||
Space for user-defined arbitrary data. libuv does not use this field. libuv does, however,
|
||||
initialize it to NULL in :c:func:`uv_loop_init`, and it poisons the value (on debug builds)
|
||||
on :c:func:`uv_loop_close`.
|
||||
|
||||
|
||||
API
|
||||
|
244
deps/uv/docs/src/migration_010_100.rst
vendored
Normal file
244
deps/uv/docs/src/migration_010_100.rst
vendored
Normal file
@ -0,0 +1,244 @@
|
||||
|
||||
.. _migration_010_100:
|
||||
|
||||
libuv 0.10 -> 1.0.0 migration guide
|
||||
===================================
|
||||
|
||||
Some APIs changed quite a bit throughout the 1.0.0 development process. Here
|
||||
is a migration guide for the most significant changes that happened after 0.10
|
||||
was released.
|
||||
|
||||
|
||||
Loop initialization and closing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In libuv 0.10 (and previous versions), loops were created with `uv_loop_new`, which
|
||||
allocated memory for a new loop and initialized it; and destroyed with `uv_loop_delete`,
|
||||
which destroyed the loop and freed the memory. Starting with 1.0, those are deprecated
|
||||
and the user is responsible for allocating the memory and then initializing the loop.
|
||||
|
||||
libuv 0.10
|
||||
|
||||
::
|
||||
|
||||
uv_loop_t* loop = uv_loop_new();
|
||||
...
|
||||
uv_loop_delete(loop);
|
||||
|
||||
libuv 1.0
|
||||
|
||||
::
|
||||
|
||||
uv_loop_t* loop = malloc(sizeof *loop);
|
||||
uv_loop_init(loop);
|
||||
...
|
||||
uv_loop_close(loop);
|
||||
free(loop);
|
||||
|
||||
.. note::
|
||||
Error handling was omitted for brevity. Check the documentation for :c:func:`uv_loop_init`
|
||||
and :c:func:`uv_loop_close`.
|
||||
|
||||
|
||||
Error handling
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Error handling had a major overhaul in libuv 1.0. In general, functions and status parameters
|
||||
would get 0 for success and -1 for failure on libuv 0.10, and the user had to use `uv_last_error`
|
||||
to fetch the error code, which was a positive number.
|
||||
|
||||
In 1.0, functions and status parameters contain the actual error code, which is 0 for success, or
|
||||
a negative number in case of error.
|
||||
|
||||
libuv 0.10
|
||||
|
||||
::
|
||||
|
||||
... assume 'server' is a TCP server which is already listening
|
||||
r = uv_listen((uv_stream_t*) server, 511, NULL);
|
||||
if (r == -1) {
|
||||
uv_err_t err = uv_last_error(uv_default_loop());
|
||||
/* err.code contains UV_EADDRINUSE */
|
||||
}
|
||||
|
||||
libuv 1.0
|
||||
|
||||
::
|
||||
|
||||
... assume 'server' is a TCP server which is already listening
|
||||
r = uv_listen((uv_stream_t*) server, 511, NULL);
|
||||
if (r < 0) {
|
||||
/* r contains UV_EADDRINUSE */
|
||||
}
|
||||
|
||||
|
||||
Threadpool changes
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In libuv 0.10 Unix used a threadpool which defaulted to 4 threads, while Windows used the
|
||||
`QueueUserWorkItem` API, which uses a Windows internal threadpool, which defaults to 512
|
||||
threads per process.
|
||||
|
||||
In 1.0, we unified both implementations, so Windows now uses the same implementation Unix
|
||||
does. The threadppol size can be set by exporting the ``UV_THREADPOOL_SIZE`` environment
|
||||
variable. See :c:ref:`threadpool`.
|
||||
|
||||
|
||||
Allocation callback API change
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In libuv 0.10 the callback had to return a filled :c:type:`uv_buf_t` by value:
|
||||
|
||||
::
|
||||
|
||||
uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
|
||||
return uv_buf_init(malloc(size), size);
|
||||
}
|
||||
|
||||
In libuv 1.0 a pointer to a buffer is passed to the callbck, which the user
|
||||
needs to fill:
|
||||
|
||||
::
|
||||
|
||||
void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
|
||||
buf->base = malloc(size);
|
||||
buf->len = size;
|
||||
}
|
||||
|
||||
|
||||
Unification of IPv4 / IPv6 APIs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
libuv 1.0 unified the IPv4 and IPv6 APIS. There is no longer a `uv_tcp_bind` and `uv_tcp_bind6`
|
||||
duality, there is only :c:func:`uv_tcp_bind` now.
|
||||
|
||||
IPv4 functions took ``struct sockaddr_in`` structures by value, and IPv6 functions took
|
||||
``struct sockaddr_in6``. Now functions take a ``struct sockaddr*`` (note it's a pointer).
|
||||
It can be stack allocated.
|
||||
|
||||
libuv 0.10
|
||||
|
||||
::
|
||||
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", 1234);
|
||||
...
|
||||
uv_tcp_bind(&server, addr)
|
||||
|
||||
libuv 1.0
|
||||
|
||||
::
|
||||
|
||||
struct sockaddr_in addr;
|
||||
uv_ip4_addr("0.0.0.0", 1234, &addr)
|
||||
...
|
||||
uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
|
||||
|
||||
The IPv4 and IPv6 struct creating functions (:c:func:`uv_ip4_addr` and :c:func:`uv_ip6_addr`)
|
||||
have also changed, make sure you check the documentation.
|
||||
|
||||
..note::
|
||||
This change applies to all functions that made a distinction between IPv4 and IPv6
|
||||
addresses.
|
||||
|
||||
|
||||
Streams / UDP data receive callback API change
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The streams and UDP data receive callbacks now get a pointer to a :c:type:`uv_buf_t` buffer,
|
||||
not a structure by value.
|
||||
|
||||
libuv 0.10
|
||||
|
||||
::
|
||||
|
||||
void on_read(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
uv_buf_t buf) {
|
||||
...
|
||||
}
|
||||
|
||||
void recv_cb(uv_udp_t* handle,
|
||||
ssize_t nread,
|
||||
uv_buf_t buf,
|
||||
struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
...
|
||||
}
|
||||
|
||||
libuv 1.0
|
||||
|
||||
::
|
||||
|
||||
void on_read(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf) {
|
||||
...
|
||||
}
|
||||
|
||||
void recv_cb(uv_udp_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf,
|
||||
const struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
Receiving handles over pipes API change
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In libuv 0.10 (and earlier versions) the `uv_read2_start` function was used to start reading
|
||||
data on a pipe, which could also result in the reception of handles over it. The callback
|
||||
for such function looked like this:
|
||||
|
||||
::
|
||||
|
||||
void on_read(uv_pipe_t* pipe,
|
||||
ssize_t nread,
|
||||
uv_buf_t buf,
|
||||
uv_handle_type pending) {
|
||||
...
|
||||
}
|
||||
|
||||
In libuv 1.0, `uv_read2_start` was removed, and the user needs to check if there are penging
|
||||
handles using :c:func:`uv_pipe_pending_count` and :c:func:`uv_pipe_pending_type` while in
|
||||
the read callback:
|
||||
|
||||
::
|
||||
|
||||
void on_read(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf) {
|
||||
...
|
||||
while (uv_pipe_pending_count((uv_pipe_t*) handle) != 0) {
|
||||
pending = uv_pipe_pending_type((uv_pipe_t*) handle);
|
||||
...
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
Extracting the file descriptor out of a handle
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
While it wasn't supported by the API, users often accessed the libuv internals in
|
||||
order to get access to the file descript of a TCP handle, for example.
|
||||
|
||||
::
|
||||
|
||||
fd = handle->io_watcher.fd;
|
||||
|
||||
This is now properly exposed through the :c:func:`uv_fileno` function.
|
||||
|
||||
|
||||
uv_fs_readdir rename and API change
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`uv_fs_readdir` returned a list of strings in the `req->ptr` field upon completion in
|
||||
libuv 0.10. In 1.0, this function got renamed to :c:func:`uv_fs_scandir`, since it's
|
||||
actually implemented using ``scandir(3)``.
|
||||
|
||||
In addition, instead of allocating a full list strings, the user is able to get one
|
||||
result at a time by using the :c:func:`uv_fs_scandir_next` function. This function
|
||||
does not need to make a roundtrip to the threadpool, because libuv will keep the
|
||||
list of *dents* returned by ``scandir(3)`` around.
|
10
deps/uv/docs/src/process.rst
vendored
10
deps/uv/docs/src/process.rst
vendored
@ -212,4 +212,14 @@ API
|
||||
setgid specified, or not having enough memory to allocate for the new
|
||||
process.
|
||||
|
||||
.. c:function:: int uv_process_kill(uv_process_t* handle, int signum)
|
||||
|
||||
Sends the specified signal to the given process handle. Check the documentation
|
||||
on :c:ref:`signal` for signal support, specially on Windows.
|
||||
|
||||
.. c:function:: int uv_kill(int pid, int signum)
|
||||
|
||||
Sends the specified signal to the given PID. Check the documentation
|
||||
on :c:ref:`signal` for signal support, specially on Windows.
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
||||
|
28
deps/uv/docs/src/stream.rst
vendored
28
deps/uv/docs/src/stream.rst
vendored
@ -16,6 +16,18 @@ Data types
|
||||
|
||||
Stream handle type.
|
||||
|
||||
.. c:type:: uv_connect_t
|
||||
|
||||
Connect request type.
|
||||
|
||||
.. c:type:: uv_shutdown_t
|
||||
|
||||
Shutdown request type.
|
||||
|
||||
.. c:type:: uv_write_t
|
||||
|
||||
Write request type.
|
||||
|
||||
.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||
|
||||
Callback called when data was read on a stream.
|
||||
@ -60,6 +72,22 @@ Public members
|
||||
|
||||
Contains the amount of queued bytes waiting to be sent. Readonly.
|
||||
|
||||
.. c:member:: uv_stream_t* uv_connect_t.handle
|
||||
|
||||
Pointer to the stream where this connection request is running.
|
||||
|
||||
.. c:member:: uv_stream_t* uv_shutdown_t.handle
|
||||
|
||||
Pointer to the stream where this shutdown request is running.
|
||||
|
||||
.. c:member:: uv_stream_t* uv_write_t.handle
|
||||
|
||||
Pointer to the stream where this write request is running.
|
||||
|
||||
.. c:member:: uv_stream_t* uv_write_t.send_handle
|
||||
|
||||
Pointer to the stream being sent using this write request..
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||
|
||||
|
||||
|
1
deps/uv/docs/src/threading.rst
vendored
1
deps/uv/docs/src/threading.rst
vendored
@ -58,6 +58,7 @@ Threads
|
||||
.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
|
||||
.. c:function:: unsigned long uv_thread_self(void)
|
||||
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
||||
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
|
||||
|
||||
Thread-local storage
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
2
deps/uv/include/uv-version.h
vendored
2
deps/uv/include/uv-version.h
vendored
@ -34,6 +34,6 @@
|
||||
#define UV_VERSION_MINOR 0
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX "rc1"
|
||||
#define UV_VERSION_SUFFIX "rc2"
|
||||
|
||||
#endif /* UV_VERSION_H */
|
||||
|
12
deps/uv/include/uv-win.h
vendored
12
deps/uv/include/uv-win.h
vendored
@ -639,3 +639,15 @@ int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
|
||||
int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
|
||||
size_t utf16Size);
|
||||
|
||||
#ifndef F_OK
|
||||
#define F_OK 0
|
||||
#endif
|
||||
#ifndef R_OK
|
||||
#define R_OK 4
|
||||
#endif
|
||||
#ifndef W_OK
|
||||
#define W_OK 2
|
||||
#endif
|
||||
#ifndef X_OK
|
||||
#define X_OK 1
|
||||
#endif
|
||||
|
15
deps/uv/include/uv.h
vendored
15
deps/uv/include/uv.h
vendored
@ -1022,6 +1022,7 @@ typedef enum {
|
||||
UV_FS_FTRUNCATE,
|
||||
UV_FS_UTIME,
|
||||
UV_FS_FUTIME,
|
||||
UV_FS_ACCESS,
|
||||
UV_FS_CHMOD,
|
||||
UV_FS_FCHMOD,
|
||||
UV_FS_FSYNC,
|
||||
@ -1031,7 +1032,7 @@ typedef enum {
|
||||
UV_FS_MKDIR,
|
||||
UV_FS_MKDTEMP,
|
||||
UV_FS_RENAME,
|
||||
UV_FS_READDIR,
|
||||
UV_FS_SCANDIR,
|
||||
UV_FS_LINK,
|
||||
UV_FS_SYMLINK,
|
||||
UV_FS_READLINK,
|
||||
@ -1094,12 +1095,12 @@ UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
uv_fs_cb cb);
|
||||
UV_EXTERN int uv_fs_readdir(uv_loop_t* loop,
|
||||
UV_EXTERN int uv_fs_scandir(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
int flags,
|
||||
uv_fs_cb cb);
|
||||
UV_EXTERN int uv_fs_readdir_next(uv_fs_t* req,
|
||||
UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req,
|
||||
uv_dirent_t* ent);
|
||||
UV_EXTERN int uv_fs_stat(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
@ -1134,6 +1135,11 @@ UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop,
|
||||
int64_t in_offset,
|
||||
size_t length,
|
||||
uv_fs_cb cb);
|
||||
UV_EXTERN int uv_fs_access(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
int flags,
|
||||
uv_fs_cb cb);
|
||||
UV_EXTERN int uv_fs_chmod(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
@ -1363,8 +1369,9 @@ UV_EXTERN void uv_key_set(uv_key_t* key, void* value);
|
||||
typedef void (*uv_thread_cb)(void* arg);
|
||||
|
||||
UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
|
||||
UV_EXTERN unsigned long uv_thread_self(void);
|
||||
UV_EXTERN uv_thread_t uv_thread_self(void);
|
||||
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
|
||||
UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
|
||||
|
||||
/* The presence of these unions force similar struct layout. */
|
||||
#define XX(_, name) uv_ ## name ## _t name;
|
||||
|
2
deps/uv/src/unix/core.c
vendored
2
deps/uv/src/unix/core.c
vendored
@ -637,7 +637,7 @@ int uv_cwd(char* buffer, size_t* size) {
|
||||
if (getcwd(buffer, *size) == NULL)
|
||||
return -errno;
|
||||
|
||||
*size = strlen(buffer) + 1;
|
||||
*size = strlen(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
32
deps/uv/src/unix/fs.c
vendored
32
deps/uv/src/unix/fs.c
vendored
@ -295,22 +295,21 @@ done:
|
||||
|
||||
|
||||
#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
|
||||
static int uv__fs_readdir_filter(uv__dirent_t* dent) {
|
||||
static int uv__fs_scandir_filter(uv__dirent_t* dent) {
|
||||
#else
|
||||
static int uv__fs_readdir_filter(const uv__dirent_t* dent) {
|
||||
static int uv__fs_scandir_filter(const uv__dirent_t* dent) {
|
||||
#endif
|
||||
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
|
||||
}
|
||||
|
||||
|
||||
/* This should have been called uv__fs_scandir(). */
|
||||
static ssize_t uv__fs_readdir(uv_fs_t* req) {
|
||||
static ssize_t uv__fs_scandir(uv_fs_t* req) {
|
||||
uv__dirent_t **dents;
|
||||
int saved_errno;
|
||||
int n;
|
||||
|
||||
dents = NULL;
|
||||
n = scandir(req->path, &dents, uv__fs_readdir_filter, alphasort);
|
||||
n = scandir(req->path, &dents, uv__fs_scandir_filter, alphasort);
|
||||
|
||||
/* NOTE: We will use nbufs as an index field */
|
||||
req->nbufs = 0;
|
||||
@ -764,6 +763,7 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
break;
|
||||
|
||||
switch (req->fs_type) {
|
||||
X(ACCESS, access(req->path, req->flags));
|
||||
X(CHMOD, chmod(req->path, req->mode));
|
||||
X(CHOWN, chown(req->path, req->uid, req->gid));
|
||||
X(CLOSE, close(req->file));
|
||||
@ -779,7 +779,7 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
X(MKDIR, mkdir(req->path, req->mode));
|
||||
X(MKDTEMP, uv__fs_mkdtemp(req));
|
||||
X(READ, uv__fs_read(req));
|
||||
X(READDIR, uv__fs_readdir(req));
|
||||
X(SCANDIR, uv__fs_scandir(req));
|
||||
X(READLINK, uv__fs_readlink(req));
|
||||
X(RENAME, rename(req->path, req->new_path));
|
||||
X(RMDIR, rmdir(req->path));
|
||||
@ -854,6 +854,18 @@ static void uv__fs_done(struct uv__work* w, int status) {
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_access(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
int flags,
|
||||
uv_fs_cb cb) {
|
||||
INIT(ACCESS);
|
||||
PATH;
|
||||
req->flags = flags;
|
||||
POST;
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_chmod(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
@ -1040,12 +1052,12 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_readdir(uv_loop_t* loop,
|
||||
int uv_fs_scandir(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
int flags,
|
||||
uv_fs_cb cb) {
|
||||
INIT(READDIR);
|
||||
INIT(SCANDIR);
|
||||
PATH;
|
||||
req->flags = flags;
|
||||
POST;
|
||||
@ -1167,8 +1179,8 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
||||
req->path = NULL;
|
||||
req->new_path = NULL;
|
||||
|
||||
if (req->fs_type == UV_FS_READDIR && req->ptr != NULL)
|
||||
uv__fs_readdir_cleanup(req);
|
||||
if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
|
||||
uv__fs_scandir_cleanup(req);
|
||||
|
||||
if (req->ptr != &req->statbuf)
|
||||
free(req->ptr);
|
||||
|
5
deps/uv/src/unix/thread.c
vendored
5
deps/uv/src/unix/thread.c
vendored
@ -36,6 +36,11 @@ int uv_thread_join(uv_thread_t *tid) {
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
|
||||
return pthread_equal(*t1, *t2);
|
||||
}
|
||||
|
||||
|
||||
int uv_mutex_init(uv_mutex_t* mutex) {
|
||||
#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
return -pthread_mutex_init(mutex, NULL);
|
||||
|
10
deps/uv/src/uv-common.c
vendored
10
deps/uv/src/uv-common.c
vendored
@ -306,11 +306,11 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
|
||||
}
|
||||
|
||||
|
||||
unsigned long uv_thread_self(void) {
|
||||
uv_thread_t uv_thread_self(void) {
|
||||
#ifdef _WIN32
|
||||
return (unsigned long) GetCurrentThreadId();
|
||||
return GetCurrentThreadId();
|
||||
#else
|
||||
return (unsigned long) pthread_self();
|
||||
return pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
||||
}
|
||||
|
||||
|
||||
void uv__fs_readdir_cleanup(uv_fs_t* req) {
|
||||
void uv__fs_scandir_cleanup(uv_fs_t* req) {
|
||||
uv__dirent_t** dents;
|
||||
|
||||
dents = req->ptr;
|
||||
@ -448,7 +448,7 @@ void uv__fs_readdir_cleanup(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent) {
|
||||
int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
|
||||
uv__dirent_t** dents;
|
||||
uv__dirent_t* dent;
|
||||
|
||||
|
2
deps/uv/src/uv-common.h
vendored
2
deps/uv/src/uv-common.h
vendored
@ -109,7 +109,7 @@ size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
|
||||
|
||||
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
|
||||
|
||||
void uv__fs_readdir_cleanup(uv_fs_t* req);
|
||||
void uv__fs_scandir_cleanup(uv_fs_t* req);
|
||||
|
||||
#define uv__has_active_reqs(loop) \
|
||||
(QUEUE_EMPTY(&(loop)->active_reqs) == 0)
|
||||
|
68
deps/uv/src/win/fs.c
vendored
68
deps/uv/src/win/fs.c
vendored
@ -613,11 +613,6 @@ void fs__write(uv_fs_t* req) {
|
||||
|
||||
if (offset != -1) {
|
||||
memset(&overlapped, 0, sizeof overlapped);
|
||||
|
||||
offset_.QuadPart = offset;
|
||||
overlapped.Offset = offset_.LowPart;
|
||||
overlapped.OffsetHigh = offset_.HighPart;
|
||||
|
||||
overlapped_ptr = &overlapped;
|
||||
} else {
|
||||
overlapped_ptr = NULL;
|
||||
@ -627,6 +622,14 @@ void fs__write(uv_fs_t* req) {
|
||||
bytes = 0;
|
||||
do {
|
||||
DWORD incremental_bytes;
|
||||
|
||||
/* WriteFile() does not advance overlapped as ReadFile() does. */
|
||||
if (offset != -1) {
|
||||
offset_.QuadPart = offset + bytes;
|
||||
overlapped.Offset = offset_.LowPart;
|
||||
overlapped.OffsetHigh = offset_.HighPart;
|
||||
}
|
||||
|
||||
result = WriteFile(handle,
|
||||
req->bufs[index].base,
|
||||
req->bufs[index].len,
|
||||
@ -783,7 +786,7 @@ void fs__mkdtemp(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
void fs__readdir(uv_fs_t* req) {
|
||||
void fs__scandir(uv_fs_t* req) {
|
||||
WCHAR* pathw = req->pathw;
|
||||
size_t len = wcslen(pathw);
|
||||
int result;
|
||||
@ -1220,6 +1223,25 @@ static void fs__sendfile(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
static void fs__access(uv_fs_t* req) {
|
||||
DWORD attr = GetFileAttributesW(req->pathw);
|
||||
|
||||
if (attr == INVALID_FILE_ATTRIBUTES) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((req->flags & W_OK) &&
|
||||
((attr & FILE_ATTRIBUTE_READONLY) ||
|
||||
(attr & FILE_ATTRIBUTE_DIRECTORY))) {
|
||||
SET_REQ_WIN32_ERROR(req, UV_EPERM);
|
||||
return;
|
||||
}
|
||||
|
||||
SET_REQ_RESULT(req, 0);
|
||||
}
|
||||
|
||||
|
||||
static void fs__chmod(uv_fs_t* req) {
|
||||
int result = _wchmod(req->pathw, req->mode);
|
||||
SET_REQ_RESULT(req, result);
|
||||
@ -1595,6 +1617,7 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
XX(FTRUNCATE, ftruncate)
|
||||
XX(UTIME, utime)
|
||||
XX(FUTIME, futime)
|
||||
XX(ACCESS, access)
|
||||
XX(CHMOD, chmod)
|
||||
XX(FCHMOD, fchmod)
|
||||
XX(FSYNC, fsync)
|
||||
@ -1604,7 +1627,7 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
XX(MKDIR, mkdir)
|
||||
XX(MKDTEMP, mkdtemp)
|
||||
XX(RENAME, rename)
|
||||
XX(READDIR, readdir)
|
||||
XX(SCANDIR, scandir)
|
||||
XX(LINK, link)
|
||||
XX(SYMLINK, symlink)
|
||||
XX(READLINK, readlink)
|
||||
@ -1839,11 +1862,11 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
||||
int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
||||
uv_fs_cb cb) {
|
||||
int err;
|
||||
|
||||
uv_fs_req_init(loop, req, UV_FS_READDIR, cb);
|
||||
uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb);
|
||||
|
||||
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
@ -1856,7 +1879,7 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
||||
QUEUE_FS_TP_JOB(loop, req);
|
||||
return 0;
|
||||
} else {
|
||||
fs__readdir(req);
|
||||
fs__scandir(req);
|
||||
return req->result;
|
||||
}
|
||||
}
|
||||
@ -2102,6 +2125,31 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_access(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
int flags,
|
||||
uv_fs_cb cb) {
|
||||
int err;
|
||||
|
||||
uv_fs_req_init(loop, req, UV_FS_ACCESS, cb);
|
||||
|
||||
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
req->flags = flags;
|
||||
|
||||
if (cb) {
|
||||
QUEUE_FS_TP_JOB(loop, req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs__access(req);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
||||
uv_fs_cb cb) {
|
||||
int err;
|
||||
|
2
deps/uv/src/win/poll.c
vendored
2
deps/uv/src/win/poll.c
vendored
@ -530,7 +530,7 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
||||
SO_PROTOCOL_INFOW,
|
||||
(char*) &protocol_info,
|
||||
&len) != 0) {
|
||||
return WSAGetLastError();
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
}
|
||||
|
||||
/* Get the peer socket that is needed to enable fast poll. If the returned */
|
||||
|
5
deps/uv/src/win/thread.c
vendored
5
deps/uv/src/win/thread.c
vendored
@ -129,6 +129,11 @@ int uv_thread_join(uv_thread_t *tid) {
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
|
||||
return *t1 == *t2;
|
||||
}
|
||||
|
||||
|
||||
int uv_mutex_init(uv_mutex_t* mutex) {
|
||||
InitializeCriticalSection(mutex);
|
||||
return 0;
|
||||
|
179
deps/uv/src/win/util.c
vendored
179
deps/uv/src/win/util.c
vendored
@ -206,7 +206,7 @@ int uv_cwd(char* buffer, size_t* size) {
|
||||
if (r == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
} else if (r > (int) *size) {
|
||||
*size = r;
|
||||
*size = r -1;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ int uv_cwd(char* buffer, size_t* size) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
*size = r;
|
||||
*size = r - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -778,11 +778,76 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
}
|
||||
|
||||
|
||||
static int is_windows_version_or_greater(DWORD os_major,
|
||||
DWORD os_minor,
|
||||
WORD service_pack_major,
|
||||
WORD service_pack_minor) {
|
||||
OSVERSIONINFOEX osvi;
|
||||
DWORDLONG condition_mask = 0;
|
||||
int op = VER_GREATER_EQUAL;
|
||||
|
||||
/* Initialize the OSVERSIONINFOEX structure. */
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
osvi.dwMajorVersion = os_major;
|
||||
osvi.dwMinorVersion = os_minor;
|
||||
osvi.wServicePackMajor = service_pack_major;
|
||||
osvi.wServicePackMinor = service_pack_minor;
|
||||
|
||||
/* Initialize the condition mask. */
|
||||
VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op);
|
||||
VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op);
|
||||
VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op);
|
||||
VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op);
|
||||
|
||||
/* Perform the test. */
|
||||
return (int) VerifyVersionInfo(
|
||||
&osvi,
|
||||
VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
|
||||
condition_mask);
|
||||
}
|
||||
|
||||
|
||||
static int address_prefix_match(int family,
|
||||
struct sockaddr* address,
|
||||
struct sockaddr* prefix_address,
|
||||
int prefix_len) {
|
||||
uint8_t* address_data;
|
||||
uint8_t* prefix_address_data;
|
||||
int i;
|
||||
|
||||
assert(address->sa_family == family);
|
||||
assert(prefix_address->sa_family == family);
|
||||
|
||||
if (family == AF_INET6) {
|
||||
address_data = (uint8_t*) &(((struct sockaddr_in6 *) address)->sin6_addr);
|
||||
prefix_address_data =
|
||||
(uint8_t*) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr);
|
||||
} else {
|
||||
address_data = (uint8_t*) &(((struct sockaddr_in *) address)->sin_addr);
|
||||
prefix_address_data =
|
||||
(uint8_t*) &(((struct sockaddr_in *) prefix_address)->sin_addr);
|
||||
}
|
||||
|
||||
for (i = 0; i < prefix_len >> 3; i++) {
|
||||
if (address_data[i] != prefix_address_data[i])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (prefix_len % 8)
|
||||
return prefix_address_data[i] ==
|
||||
(address_data[i] & (0xff << (8 - prefix_len % 8)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
int* count_ptr) {
|
||||
IP_ADAPTER_ADDRESSES* win_address_buf;
|
||||
ULONG win_address_buf_size;
|
||||
IP_ADAPTER_ADDRESSES* win_address;
|
||||
IP_ADAPTER_ADDRESSES* adapter;
|
||||
|
||||
uv_interface_address_t* uv_address_buf;
|
||||
char* name_buf;
|
||||
@ -791,6 +856,23 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
|
||||
int count;
|
||||
|
||||
int is_vista_or_greater;
|
||||
ULONG flags;
|
||||
|
||||
is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0);
|
||||
if (is_vista_or_greater) {
|
||||
flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER;
|
||||
} else {
|
||||
/* We need at least XP SP1. */
|
||||
if (!is_windows_version_or_greater(5, 1, 1, 0))
|
||||
return UV_ENOTSUP;
|
||||
|
||||
flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX;
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the size of the adapters reported by windows, and then get the */
|
||||
/* list itself. */
|
||||
win_address_buf_size = 0;
|
||||
@ -803,7 +885,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
/* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */
|
||||
/* win_address_buf_size. */
|
||||
r = GetAdaptersAddresses(AF_UNSPEC,
|
||||
GAA_FLAG_INCLUDE_PREFIX,
|
||||
flags,
|
||||
NULL,
|
||||
win_address_buf,
|
||||
&win_address_buf_size);
|
||||
@ -862,25 +944,23 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
count = 0;
|
||||
uv_address_buf_size = 0;
|
||||
|
||||
for (win_address = win_address_buf;
|
||||
win_address != NULL;
|
||||
win_address = win_address->Next) {
|
||||
/* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */
|
||||
/* with Windows XP */
|
||||
IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
|
||||
for (adapter = win_address_buf;
|
||||
adapter != NULL;
|
||||
adapter = adapter->Next) {
|
||||
IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
|
||||
int name_size;
|
||||
|
||||
/* Interfaces that are not 'up' should not be reported. Also skip */
|
||||
/* interfaces that have no associated unicast address, as to avoid */
|
||||
/* allocating space for the name for this interface. */
|
||||
if (win_address->OperStatus != IfOperStatusUp ||
|
||||
win_address->FirstUnicastAddress == NULL)
|
||||
if (adapter->OperStatus != IfOperStatusUp ||
|
||||
adapter->FirstUnicastAddress == NULL)
|
||||
continue;
|
||||
|
||||
/* Compute the size of the interface name. */
|
||||
name_size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
win_address->FriendlyName,
|
||||
adapter->FriendlyName,
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
@ -894,8 +974,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
|
||||
/* Count the number of addresses associated with this interface, and */
|
||||
/* compute the size. */
|
||||
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
|
||||
win_address->FirstUnicastAddress;
|
||||
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
|
||||
adapter->FirstUnicastAddress;
|
||||
unicast_address != NULL;
|
||||
unicast_address = unicast_address->Next) {
|
||||
count++;
|
||||
@ -916,16 +996,15 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
name_buf = (char*) (uv_address_buf + count);
|
||||
|
||||
/* Fill out the output buffer. */
|
||||
for (win_address = win_address_buf;
|
||||
win_address != NULL;
|
||||
win_address = win_address->Next) {
|
||||
IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
|
||||
IP_ADAPTER_PREFIX* prefix;
|
||||
for (adapter = win_address_buf;
|
||||
adapter != NULL;
|
||||
adapter = adapter->Next) {
|
||||
IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
|
||||
int name_size;
|
||||
size_t max_name_size;
|
||||
|
||||
if (win_address->OperStatus != IfOperStatusUp ||
|
||||
win_address->FirstUnicastAddress == NULL)
|
||||
if (adapter->OperStatus != IfOperStatusUp ||
|
||||
adapter->FirstUnicastAddress == NULL)
|
||||
continue;
|
||||
|
||||
/* Convert the interface name to UTF8. */
|
||||
@ -934,7 +1013,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
max_name_size = INT_MAX;
|
||||
name_size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
win_address->FriendlyName,
|
||||
adapter->FriendlyName,
|
||||
-1,
|
||||
name_buf,
|
||||
(int) max_name_size,
|
||||
@ -946,47 +1025,77 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
prefix = win_address->FirstPrefix;
|
||||
|
||||
/* Add an uv_interface_address_t element for every unicast address. */
|
||||
/* Walk the prefix list in tandem with the address list. */
|
||||
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
|
||||
win_address->FirstUnicastAddress;
|
||||
unicast_address != NULL && prefix != NULL;
|
||||
unicast_address = unicast_address->Next, prefix = prefix->Next) {
|
||||
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
|
||||
adapter->FirstUnicastAddress;
|
||||
unicast_address != NULL;
|
||||
unicast_address = unicast_address->Next) {
|
||||
struct sockaddr* sa;
|
||||
ULONG prefix_len;
|
||||
|
||||
sa = unicast_address->Address.lpSockaddr;
|
||||
|
||||
/* XP has no OnLinkPrefixLength field. */
|
||||
if (is_vista_or_greater) {
|
||||
prefix_len = unicast_address->OnLinkPrefixLength;
|
||||
} else {
|
||||
/* Prior to Windows Vista the FirstPrefix pointed to the list with
|
||||
* single prefix for each IP address assigned to the adapter.
|
||||
* Order of FirstPrefix does not match order of FirstUnicastAddress,
|
||||
* so we need to find corresponding prefix.
|
||||
*/
|
||||
IP_ADAPTER_PREFIX* prefix;
|
||||
prefix_len = 0;
|
||||
|
||||
for (prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) {
|
||||
/* We want the longest matching prefix. */
|
||||
if (prefix->Address.lpSockaddr->sa_family != sa->sa_family ||
|
||||
prefix->PrefixLength <= prefix_len)
|
||||
continue;
|
||||
|
||||
if (address_prefix_match(sa->sa_family, sa,
|
||||
prefix->Address.lpSockaddr, prefix->PrefixLength)) {
|
||||
prefix_len = prefix->PrefixLength;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no matching prefix information, return a single-host
|
||||
* subnet mask (e.g. 255.255.255.255 for IPv4).
|
||||
*/
|
||||
if (!prefix_len)
|
||||
prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32;
|
||||
}
|
||||
|
||||
memset(uv_address, 0, sizeof *uv_address);
|
||||
|
||||
uv_address->name = name_buf;
|
||||
|
||||
if (win_address->PhysicalAddressLength == sizeof(uv_address->phys_addr)) {
|
||||
if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) {
|
||||
memcpy(uv_address->phys_addr,
|
||||
win_address->PhysicalAddress,
|
||||
adapter->PhysicalAddress,
|
||||
sizeof(uv_address->phys_addr));
|
||||
}
|
||||
|
||||
uv_address->is_internal =
|
||||
(win_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
|
||||
(adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
|
||||
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
uv_address->address.address6 = *((struct sockaddr_in6 *) sa);
|
||||
|
||||
uv_address->netmask.netmask6.sin6_family = AF_INET6;
|
||||
memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3);
|
||||
/* This check ensures that we don't write past the size of the data. */
|
||||
if (prefix_len % 8) {
|
||||
uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] =
|
||||
0xff << (8 - prefix_len % 8);
|
||||
}
|
||||
|
||||
} else {
|
||||
uv_address->address.address4 = *((struct sockaddr_in *) sa);
|
||||
|
||||
uv_address->netmask.netmask4.sin_family = AF_INET;
|
||||
uv_address->netmask.netmask4.sin_addr.s_addr =
|
||||
htonl(0xffffffff << (32 - prefix_len));
|
||||
uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ?
|
||||
htonl(0xffffffff << (32 - prefix_len)) : 0;
|
||||
}
|
||||
|
||||
uv_address++;
|
||||
|
237
deps/uv/test/test-fs.c
vendored
237
deps/uv/test/test-fs.c
vendored
@ -67,7 +67,7 @@ static int unlink_cb_count;
|
||||
static int mkdir_cb_count;
|
||||
static int mkdtemp_cb_count;
|
||||
static int rmdir_cb_count;
|
||||
static int readdir_cb_count;
|
||||
static int scandir_cb_count;
|
||||
static int stat_cb_count;
|
||||
static int rename_cb_count;
|
||||
static int fsync_cb_count;
|
||||
@ -75,6 +75,7 @@ static int fdatasync_cb_count;
|
||||
static int ftruncate_cb_count;
|
||||
static int sendfile_cb_count;
|
||||
static int fstat_cb_count;
|
||||
static int access_cb_count;
|
||||
static int chmod_cb_count;
|
||||
static int fchmod_cb_count;
|
||||
static int chown_cb_count;
|
||||
@ -97,7 +98,7 @@ static uv_fs_t mkdir_req;
|
||||
static uv_fs_t mkdtemp_req1;
|
||||
static uv_fs_t mkdtemp_req2;
|
||||
static uv_fs_t rmdir_req;
|
||||
static uv_fs_t readdir_req;
|
||||
static uv_fs_t scandir_req;
|
||||
static uv_fs_t stat_req;
|
||||
static uv_fs_t rename_req;
|
||||
static uv_fs_t fsync_req;
|
||||
@ -109,6 +110,7 @@ static uv_fs_t futime_req;
|
||||
|
||||
static char buf[32];
|
||||
static char test_buf[] = "test-buffer\n";
|
||||
static char test_buf2[] = "second-buffer\n";
|
||||
static uv_buf_t iov;
|
||||
|
||||
static void check_permission(const char* filename, unsigned int mode) {
|
||||
@ -164,6 +166,14 @@ static void readlink_cb(uv_fs_t* req) {
|
||||
uv_fs_req_cleanup(req);
|
||||
}
|
||||
|
||||
|
||||
static void access_cb(uv_fs_t* req) {
|
||||
ASSERT(req->fs_type == UV_FS_ACCESS);
|
||||
access_cb_count++;
|
||||
uv_fs_req_cleanup(req);
|
||||
}
|
||||
|
||||
|
||||
static void fchmod_cb(uv_fs_t* req) {
|
||||
ASSERT(req->fs_type == UV_FS_FCHMOD);
|
||||
ASSERT(req->result == 0);
|
||||
@ -416,18 +426,18 @@ static void rmdir_cb(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
static void readdir_cb(uv_fs_t* req) {
|
||||
static void scandir_cb(uv_fs_t* req) {
|
||||
uv_dirent_t dent;
|
||||
ASSERT(req == &readdir_req);
|
||||
ASSERT(req->fs_type == UV_FS_READDIR);
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == 2);
|
||||
ASSERT(req->ptr);
|
||||
|
||||
while (UV_EOF != uv_fs_readdir_next(req, &dent)) {
|
||||
while (UV_EOF != uv_fs_scandir_next(req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
readdir_cb_count++;
|
||||
scandir_cb_count++;
|
||||
ASSERT(req->path);
|
||||
ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
|
||||
uv_fs_req_cleanup(req);
|
||||
@ -435,26 +445,26 @@ static void readdir_cb(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
static void empty_readdir_cb(uv_fs_t* req) {
|
||||
static void empty_scandir_cb(uv_fs_t* req) {
|
||||
uv_dirent_t dent;
|
||||
|
||||
ASSERT(req == &readdir_req);
|
||||
ASSERT(req->fs_type == UV_FS_READDIR);
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT(UV_EOF == uv_fs_readdir_next(req, &dent));
|
||||
ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent));
|
||||
uv_fs_req_cleanup(req);
|
||||
readdir_cb_count++;
|
||||
scandir_cb_count++;
|
||||
}
|
||||
|
||||
|
||||
static void file_readdir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &readdir_req);
|
||||
ASSERT(req->fs_type == UV_FS_READDIR);
|
||||
static void file_scandir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == UV_ENOTDIR);
|
||||
ASSERT(req->ptr == NULL);
|
||||
uv_fs_req_cleanup(req);
|
||||
readdir_cb_count++;
|
||||
scandir_cb_count++;
|
||||
}
|
||||
|
||||
|
||||
@ -841,23 +851,23 @@ TEST_IMPL(fs_async_dir) {
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, readdir_cb);
|
||||
r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, scandir_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(readdir_cb_count == 1);
|
||||
ASSERT(scandir_cb_count == 1);
|
||||
|
||||
/* sync uv_fs_readdir */
|
||||
r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
|
||||
/* sync uv_fs_scandir */
|
||||
r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, NULL);
|
||||
ASSERT(r == 2);
|
||||
ASSERT(readdir_req.result == 2);
|
||||
ASSERT(readdir_req.ptr);
|
||||
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||
ASSERT(scandir_req.result == 2);
|
||||
ASSERT(scandir_req.ptr);
|
||||
while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
ASSERT(!readdir_req.ptr);
|
||||
uv_fs_req_cleanup(&scandir_req);
|
||||
ASSERT(!scandir_req.ptr);
|
||||
|
||||
r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
|
||||
ASSERT(r == 0);
|
||||
@ -1119,6 +1129,70 @@ TEST_IMPL(fs_fstat) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_access) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
/* File should not exist */
|
||||
r = uv_fs_access(loop, &req, "test_file", F_OK, NULL);
|
||||
ASSERT(r < 0);
|
||||
ASSERT(req.result < 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* File should not exist */
|
||||
r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb);
|
||||
ASSERT(r == 0);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(access_cb_count == 1);
|
||||
access_cb_count = 0; /* reset for the next test */
|
||||
|
||||
/* Create file */
|
||||
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
file = req.result;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* File should exist */
|
||||
r = uv_fs_access(loop, &req, "test_file", F_OK, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* File should exist */
|
||||
r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb);
|
||||
ASSERT(r == 0);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(access_cb_count == 1);
|
||||
access_cb_count = 0; /* reset for the next test */
|
||||
|
||||
/* Close file */
|
||||
r = uv_fs_close(loop, &req, file, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/*
|
||||
* Run the loop just to check we don't have make any extraneous uv_ref()
|
||||
* calls. This should drop out immediately.
|
||||
*/
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
/* Cleanup. */
|
||||
unlink("test_file");
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_chmod) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
@ -1604,36 +1678,36 @@ TEST_IMPL(fs_symlink_dir) {
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, "test_dir_symlink", 0, NULL);
|
||||
r = uv_fs_scandir(loop, &scandir_req, "test_dir_symlink", 0, NULL);
|
||||
ASSERT(r == 2);
|
||||
ASSERT(readdir_req.result == 2);
|
||||
ASSERT(readdir_req.ptr);
|
||||
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||
ASSERT(scandir_req.result == 2);
|
||||
ASSERT(scandir_req.ptr);
|
||||
while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
ASSERT(!readdir_req.ptr);
|
||||
uv_fs_req_cleanup(&scandir_req);
|
||||
ASSERT(!scandir_req.ptr);
|
||||
|
||||
/* unlink will remove the directory symlink */
|
||||
r = uv_fs_unlink(loop, &req, "test_dir_symlink", NULL);
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, "test_dir_symlink", 0, NULL);
|
||||
r = uv_fs_scandir(loop, &scandir_req, "test_dir_symlink", 0, NULL);
|
||||
ASSERT(r == UV_ENOENT);
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
uv_fs_req_cleanup(&scandir_req);
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
|
||||
r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, NULL);
|
||||
ASSERT(r == 2);
|
||||
ASSERT(readdir_req.result == 2);
|
||||
ASSERT(readdir_req.ptr);
|
||||
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||
ASSERT(scandir_req.result == 2);
|
||||
ASSERT(scandir_req.ptr);
|
||||
while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
||||
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||
}
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
ASSERT(!readdir_req.ptr);
|
||||
uv_fs_req_cleanup(&scandir_req);
|
||||
ASSERT(!scandir_req.ptr);
|
||||
|
||||
/* clean-up */
|
||||
unlink("test_dir/file1");
|
||||
@ -1805,7 +1879,7 @@ TEST_IMPL(fs_stat_missing_path) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_readdir_empty_dir) {
|
||||
TEST_IMPL(fs_scandir_empty_dir) {
|
||||
const char* path;
|
||||
uv_fs_t req;
|
||||
uv_dirent_t dent;
|
||||
@ -1820,19 +1894,19 @@ TEST_IMPL(fs_readdir_empty_dir) {
|
||||
/* Fill the req to ensure that required fields are cleaned up */
|
||||
memset(&req, 0xdb, sizeof(req));
|
||||
|
||||
r = uv_fs_readdir(loop, &req, path, 0, NULL);
|
||||
r = uv_fs_scandir(loop, &req, path, 0, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == 0);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT(UV_EOF == uv_fs_readdir_next(&req, &dent));
|
||||
ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, path, 0, empty_readdir_cb);
|
||||
r = uv_fs_scandir(loop, &scandir_req, path, 0, empty_scandir_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(readdir_cb_count == 0);
|
||||
ASSERT(scandir_cb_count == 0);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(readdir_cb_count == 1);
|
||||
ASSERT(scandir_cb_count == 1);
|
||||
|
||||
uv_fs_rmdir(loop, &req, path, NULL);
|
||||
uv_fs_req_cleanup(&req);
|
||||
@ -1842,23 +1916,23 @@ TEST_IMPL(fs_readdir_empty_dir) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_readdir_file) {
|
||||
TEST_IMPL(fs_scandir_file) {
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
path = "test/fixtures/empty_file";
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, path, 0, NULL);
|
||||
r = uv_fs_scandir(loop, &scandir_req, path, 0, NULL);
|
||||
ASSERT(r == UV_ENOTDIR);
|
||||
uv_fs_req_cleanup(&readdir_req);
|
||||
uv_fs_req_cleanup(&scandir_req);
|
||||
|
||||
r = uv_fs_readdir(loop, &readdir_req, path, 0, file_readdir_cb);
|
||||
r = uv_fs_scandir(loop, &scandir_req, path, 0, file_scandir_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(readdir_cb_count == 0);
|
||||
ASSERT(scandir_cb_count == 0);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(readdir_cb_count == 1);
|
||||
ASSERT(scandir_cb_count == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
@ -2091,3 +2165,64 @@ TEST_IMPL(fs_read_file_eof) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_write_multiple_bufs) {
|
||||
uv_buf_t iovs[2];
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
iovs[0] = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
iovs[1] = uv_buf_init(test_buf2, sizeof(test_buf2));
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, iovs, 2, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(write_req.result >= 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(read_req.result >= 0);
|
||||
ASSERT(memcmp(buf, test_buf, sizeof(test_buf)) == 0);
|
||||
ASSERT(strcmp(buf + sizeof(test_buf), test_buf2) == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1,
|
||||
read_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(read_req.result == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
14
deps/uv/test/test-list.h
vendored
14
deps/uv/test/test-list.h
vendored
@ -218,6 +218,7 @@ TEST_DECLARE (fs_async_dir)
|
||||
TEST_DECLARE (fs_async_sendfile)
|
||||
TEST_DECLARE (fs_mkdtemp)
|
||||
TEST_DECLARE (fs_fstat)
|
||||
TEST_DECLARE (fs_access)
|
||||
TEST_DECLARE (fs_chmod)
|
||||
TEST_DECLARE (fs_chown)
|
||||
TEST_DECLARE (fs_link)
|
||||
@ -241,10 +242,11 @@ TEST_DECLARE (fs_event_close_in_callback)
|
||||
TEST_DECLARE (fs_event_start_and_close)
|
||||
TEST_DECLARE (fs_event_error_reporting)
|
||||
TEST_DECLARE (fs_event_getpath)
|
||||
TEST_DECLARE (fs_readdir_empty_dir)
|
||||
TEST_DECLARE (fs_readdir_file)
|
||||
TEST_DECLARE (fs_scandir_empty_dir)
|
||||
TEST_DECLARE (fs_scandir_file)
|
||||
TEST_DECLARE (fs_open_dir)
|
||||
TEST_DECLARE (fs_rename_to_existing_file)
|
||||
TEST_DECLARE (fs_write_multiple_bufs)
|
||||
TEST_DECLARE (threadpool_queue_work_simple)
|
||||
TEST_DECLARE (threadpool_queue_work_einval)
|
||||
TEST_DECLARE (threadpool_multiple_event_loops)
|
||||
@ -257,6 +259,7 @@ TEST_DECLARE (thread_local_storage)
|
||||
TEST_DECLARE (thread_mutex)
|
||||
TEST_DECLARE (thread_rwlock)
|
||||
TEST_DECLARE (thread_create)
|
||||
TEST_DECLARE (thread_equal)
|
||||
TEST_DECLARE (dlerror)
|
||||
TEST_DECLARE (poll_duplex)
|
||||
TEST_DECLARE (poll_unidirectional)
|
||||
@ -590,6 +593,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_async_sendfile)
|
||||
TEST_ENTRY (fs_mkdtemp)
|
||||
TEST_ENTRY (fs_fstat)
|
||||
TEST_ENTRY (fs_access)
|
||||
TEST_ENTRY (fs_chmod)
|
||||
TEST_ENTRY (fs_chown)
|
||||
TEST_ENTRY (fs_utime)
|
||||
@ -612,10 +616,11 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_event_start_and_close)
|
||||
TEST_ENTRY (fs_event_error_reporting)
|
||||
TEST_ENTRY (fs_event_getpath)
|
||||
TEST_ENTRY (fs_readdir_empty_dir)
|
||||
TEST_ENTRY (fs_readdir_file)
|
||||
TEST_ENTRY (fs_scandir_empty_dir)
|
||||
TEST_ENTRY (fs_scandir_file)
|
||||
TEST_ENTRY (fs_open_dir)
|
||||
TEST_ENTRY (fs_rename_to_existing_file)
|
||||
TEST_ENTRY (fs_write_multiple_bufs)
|
||||
TEST_ENTRY (threadpool_queue_work_simple)
|
||||
TEST_ENTRY (threadpool_queue_work_einval)
|
||||
TEST_ENTRY (threadpool_multiple_event_loops)
|
||||
@ -628,6 +633,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (thread_mutex)
|
||||
TEST_ENTRY (thread_rwlock)
|
||||
TEST_ENTRY (thread_create)
|
||||
TEST_ENTRY (thread_equal)
|
||||
TEST_ENTRY (dlerror)
|
||||
TEST_ENTRY (ip4_addr)
|
||||
TEST_ENTRY (ip6_addr_link_local)
|
||||
|
45
deps/uv/test/test-thread-equal.c
vendored
Normal file
45
deps/uv/test/test-thread-equal.c
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
uv_thread_t main_thread_id;
|
||||
uv_thread_t subthreads[2];
|
||||
|
||||
static void check_thread(void* arg) {
|
||||
uv_thread_t *thread_id = arg;
|
||||
uv_thread_t self_id = uv_thread_self();
|
||||
ASSERT(uv_thread_equal(&main_thread_id, &self_id) == 0);
|
||||
*thread_id = uv_thread_self();
|
||||
}
|
||||
|
||||
TEST_IMPL(thread_equal) {
|
||||
uv_thread_t threads[2];
|
||||
main_thread_id = uv_thread_self();
|
||||
ASSERT(0 != uv_thread_equal(&main_thread_id, &main_thread_id));
|
||||
ASSERT(0 == uv_thread_create(threads + 0, check_thread, subthreads + 0));
|
||||
ASSERT(0 == uv_thread_create(threads + 1, check_thread, subthreads + 1));
|
||||
ASSERT(0 == uv_thread_join(threads + 0));
|
||||
ASSERT(0 == uv_thread_join(threads + 1));
|
||||
ASSERT(0 == uv_thread_equal(subthreads + 0, subthreads + 1));
|
||||
return 0;
|
||||
}
|
2
deps/uv/test/test-threadpool-cancel.c
vendored
2
deps/uv/test/test-threadpool-cancel.c
vendored
@ -301,7 +301,7 @@ TEST_IMPL(threadpool_cancel_fs) {
|
||||
ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
|
||||
ASSERT(0 == uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb));
|
||||
ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
|
||||
ASSERT(0 == uv_fs_readdir(loop, reqs + n++, "/", 0, fs_cb));
|
||||
ASSERT(0 == uv_fs_scandir(loop, reqs + n++, "/", 0, fs_cb));
|
||||
ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb));
|
||||
ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb));
|
||||
ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
|
||||
|
1
deps/uv/uv.gyp
vendored
1
deps/uv/uv.gyp
vendored
@ -410,6 +410,7 @@
|
||||
'test/test-tcp-write-queue-order.c',
|
||||
'test/test-threadpool.c',
|
||||
'test/test-threadpool-cancel.c',
|
||||
'test/test-thread-equal.c',
|
||||
'test/test-mutexes.c',
|
||||
'test/test-thread.c',
|
||||
'test/test-barrier.c',
|
||||
|
Loading…
Reference in New Issue
Block a user