deps: upgrade to libuv 1.31.0
Notable changes: - UV_FS_O_FILEMAP has been added for faster access to memory mapped files on Windows. - uv_fs_mkdir() now returns UV_EINVAL for invalid filenames on Windows. It previously returned UV_ENOENT. - The uv_fs_statfs() API has been added. - The uv_os_environ() and uv_os_free_environ() APIs have been added. Fixes: https://github.com/nodejs/node/issues/28599 Fixes: https://github.com/nodejs/node/issues/28945 Fixes: https://github.com/nodejs/node/issues/29008 PR-URL: https://github.com/nodejs/node/pull/29070 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
This commit is contained in:
parent
8ef68e66d0
commit
ce7f3ed13c
1
deps/uv/.gitignore
vendored
1
deps/uv/.gitignore
vendored
@ -51,6 +51,7 @@ Makefile.in
|
||||
/test/run-benchmarks
|
||||
/test/run-benchmarks.exe
|
||||
/test/run-benchmarks.dSYM
|
||||
test_file_*
|
||||
|
||||
*.sln
|
||||
*.sln.cache
|
||||
|
1
deps/uv/.mailmap
vendored
1
deps/uv/.mailmap
vendored
@ -38,6 +38,7 @@ Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
|
||||
San-Tai Hsu <vanilla@fatpipi.com>
|
||||
Santiago Gimeno <santiago.gimeno@quantion.es> <santiago.gimeno@gmail.com>
|
||||
Saúl Ibarra Corretgé <saghul@gmail.com>
|
||||
Saúl Ibarra Corretgé <saghul@gmail.com> <s@saghul.net>
|
||||
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
|
||||
Timothy J. Fontaine <tjfontaine@gmail.com>
|
||||
Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
||||
|
7
deps/uv/AUTHORS
vendored
7
deps/uv/AUTHORS
vendored
@ -389,3 +389,10 @@ Jenil Christo <jenilchristo5@gmail.com>
|
||||
Evgeny Ermakov <evgeny.v.ermakov@gmail.com>
|
||||
gengjiawen <technicalcute@gmail.com>
|
||||
Leo Chung <gewalalb@gmail.com>
|
||||
Javier Blazquez <jblazquez@riotgames.com>
|
||||
Mustafa M <mus-m@outlook.com>
|
||||
Zach Bjornson <zbbjornson@gmail.com>
|
||||
Nan Xiao <nan@chinadtrace.org>
|
||||
Ben Davies <kaiepi@outlook.com>
|
||||
Nhan Khong <knhana7@gmail.com>
|
||||
Crunkle <justcrunkle@hotmail.co.uk>
|
||||
|
2
deps/uv/CMakeLists.txt
vendored
2
deps/uv/CMakeLists.txt
vendored
@ -53,6 +53,8 @@ set(uv_test_sources
|
||||
test/test-fs-poll.c
|
||||
test/test-fs.c
|
||||
test/test-fs-readdir.c
|
||||
test/test-fs-fd-hash.c
|
||||
test/test-fs-open-flags.c
|
||||
test/test-get-currentexe.c
|
||||
test/test-get-loadavg.c
|
||||
test/test-get-memory.c
|
||||
|
49
deps/uv/ChangeLog
vendored
49
deps/uv/ChangeLog
vendored
@ -1,3 +1,52 @@
|
||||
2019.08.10, Version 1.31.0 (Stable), 0a6771cee4c15184c924bfe9d397bdd0c3b206ba
|
||||
|
||||
Changes since version 1.30.1:
|
||||
|
||||
* win,fs: don't modify global file translation mode (Javier Blazquez)
|
||||
|
||||
* win: fix uv_os_tmpdir when env var is 260 chars (Mustafa M)
|
||||
|
||||
* win: prevent tty event explosion machine hang (Javier Blazquez)
|
||||
|
||||
* win: add UV_FS_O_FILEMAP (João Reis)
|
||||
|
||||
* win, fs: mkdir return UV_EINVAL for invalid names (Bartosz Sosnowski)
|
||||
|
||||
* github: add root warning to template (cjihrig)
|
||||
|
||||
* win: misc fs cleanup (cjihrig)
|
||||
|
||||
* unix,win: add uv_fs_statfs() (cjihrig)
|
||||
|
||||
* test: avoid AF_LOCAL (Carlo Marcelo Arenas Belón)
|
||||
|
||||
* unix,win: add ability to retrieve all env variables (Saúl Ibarra Corretgé)
|
||||
|
||||
* Revert "darwin: speed up uv_set_process_title()" (Ben Noordhuis)
|
||||
|
||||
* doc: add %p to valgrind log-file arg (Zach Bjornson)
|
||||
|
||||
* doc: fix typo in basics.rst (Nan Xiao)
|
||||
|
||||
* ibmi: support Makefile build for IBM i (Xu Meng)
|
||||
|
||||
* OpenBSD: only get active CPU core count (Ben Davies)
|
||||
|
||||
* test: fix gcc 8 warnings for tests (Nhan Khong)
|
||||
|
||||
* ibmi: use correct header files (Xu Meng)
|
||||
|
||||
* unix: clear UV_HANDLE_READING flag before callback (zyxwvu Shi)
|
||||
|
||||
* unix: fix unused-function warning on BSD (Nhan Khong)
|
||||
|
||||
* test: fix test runner on MinGW (Crunkle)
|
||||
|
||||
* win: remove try-except outside MSVC (Crunkle)
|
||||
|
||||
* win: fix uv_spawn() ENOMEM on empty env (Ben Noordhuis)
|
||||
|
||||
|
||||
2019.07.03, Version 1.30.1 (Stable), 1551969c84c2f546a429dac169c7fdac3e38115e
|
||||
|
||||
Changes since version 1.30.0:
|
||||
|
21
deps/uv/Makefile.am
vendored
21
deps/uv/Makefile.am
vendored
@ -184,6 +184,8 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-fs-poll.c \
|
||||
test/test-fs.c \
|
||||
test/test-fs-readdir.c \
|
||||
test/test-fs-fd-hash.c \
|
||||
test/test-fs-open-flags.c \
|
||||
test/test-fork.c \
|
||||
test/test-getters-setters.c \
|
||||
test/test-get-currentexe.c \
|
||||
@ -322,6 +324,12 @@ test_run_tests_CFLAGS += -D_ALL_SOURCE \
|
||||
-D_LINUX_SOURCE_COMPAT
|
||||
endif
|
||||
|
||||
if OS400
|
||||
test_run_tests_CFLAGS += -D_ALL_SOURCE \
|
||||
-D_XOPEN_SOURCE=500 \
|
||||
-D_LINUX_SOURCE_COMPAT
|
||||
endif
|
||||
|
||||
if HAIKU
|
||||
test_run_tests_CFLAGS += -D_BSD_SOURCE
|
||||
endif
|
||||
@ -362,6 +370,19 @@ uvinclude_HEADERS += include/uv/aix.h
|
||||
libuv_la_SOURCES += src/unix/aix.c src/unix/aix-common.c
|
||||
endif
|
||||
|
||||
if OS400
|
||||
libuv_la_CFLAGS += -D_ALL_SOURCE \
|
||||
-D_XOPEN_SOURCE=500 \
|
||||
-D_LINUX_SOURCE_COMPAT \
|
||||
-D_THREAD_SAFE
|
||||
uvinclude_HEADERS += include/uv/posix.h
|
||||
libuv_la_SOURCES += src/unix/aix-common.c \
|
||||
src/unix/ibmi.c \
|
||||
src/unix/posix-poll.c \
|
||||
src/unix/no-fsevents.c \
|
||||
src/unix/no-proctitle.c
|
||||
endif
|
||||
|
||||
if ANDROID
|
||||
uvinclude_HEADERS += include/uv/android-ifaddrs.h
|
||||
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
|
||||
|
2
deps/uv/README.md
vendored
2
deps/uv/README.md
vendored
@ -387,7 +387,7 @@ $ gdb --args out/Debug/run-tests TEST_NAME
|
||||
Use the `--trace-children=yes` parameter:
|
||||
|
||||
```bash
|
||||
$ valgrind --trace-children=yes -v --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memcheck.log out/Debug/run-tests TEST_NAME
|
||||
$ valgrind --trace-children=yes -v --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memcheck-%p.log out/Debug/run-tests TEST_NAME
|
||||
```
|
||||
|
||||
### Running benchmarks
|
||||
|
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.30.1], [https://github.com/libuv/libuv/issues])
|
||||
AC_INIT([libuv], [1.31.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
m4_include([m4/as_case.m4])
|
||||
@ -63,6 +63,7 @@ AM_CONDITIONAL([MSYS], [AS_CASE([$host_os],[msys*], [true], [false])
|
||||
AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])])
|
||||
AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])])
|
||||
AM_CONDITIONAL([OS390], [AS_CASE([$host_os],[openedition*], [true], [false])])
|
||||
AM_CONDITIONAL([OS400], [AS_CASE([$host_os],[os400], [true], [false])])
|
||||
AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])])
|
||||
AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])])
|
||||
AS_CASE([$host_os],[mingw*], [
|
||||
|
47
deps/uv/docs/src/fs.rst
vendored
47
deps/uv/docs/src/fs.rst
vendored
@ -102,6 +102,24 @@ Data types
|
||||
UV_FS_CLOSEDIR
|
||||
} uv_fs_type;
|
||||
|
||||
.. c:type:: uv_statfs_t
|
||||
|
||||
Reduced cross platform equivalent of ``struct statfs``.
|
||||
Used in :c:func:`uv_fs_statfs`.
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_statfs_s {
|
||||
uint64_t f_type;
|
||||
uint64_t f_bsize;
|
||||
uint64_t f_blocks;
|
||||
uint64_t f_bfree;
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint64_t f_spare[4];
|
||||
} uv_statfs_t;
|
||||
|
||||
.. c:type:: uv_dirent_t
|
||||
|
||||
Cross platform (reduced) equivalent of ``struct dirent``.
|
||||
@ -200,6 +218,11 @@ API
|
||||
|
||||
Equivalent to :man:`preadv(2)`.
|
||||
|
||||
.. warning::
|
||||
On Windows, under non-MSVC environments (e.g. when GCC or Clang is used
|
||||
to build libuv), files opened using ``UV_FS_O_FILEMAP`` may cause a fatal
|
||||
crash if the memory mapped read operation fails.
|
||||
|
||||
.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to :man:`unlink(2)`.
|
||||
@ -208,6 +231,11 @@ API
|
||||
|
||||
Equivalent to :man:`pwritev(2)`.
|
||||
|
||||
.. warning::
|
||||
On Windows, under non-MSVC environments (e.g. when GCC or Clang is used
|
||||
to build libuv), files opened using ``UV_FS_O_FILEMAP`` may cause a fatal
|
||||
crash if the memory mapped write operation fails.
|
||||
|
||||
.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
|
||||
|
||||
Equivalent to :man:`mkdir(2)`.
|
||||
@ -290,6 +318,17 @@ API
|
||||
|
||||
Equivalent to :man:`stat(2)`, :man:`fstat(2)` and :man:`lstat(2)` respectively.
|
||||
|
||||
.. c:function:: int uv_fs_statfs(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to :man:`statfs(2)`. On success, a `uv_statfs_t` is allocated
|
||||
and returned via `req->ptr`. This memory is freed by `uv_fs_req_cleanup()`.
|
||||
|
||||
.. note::
|
||||
Any fields in the resulting `uv_statfs_t` that are not supported by the
|
||||
underlying operating system are set to zero.
|
||||
|
||||
.. versionadded:: 1.31.0
|
||||
|
||||
.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
|
||||
|
||||
Equivalent to :man:`rename(2)`.
|
||||
@ -534,6 +573,14 @@ File open constants
|
||||
|
||||
.. versionchanged:: 1.17.0 support is added for Windows.
|
||||
|
||||
.. c:macro:: UV_FS_O_FILEMAP
|
||||
|
||||
Use a memory file mapping to access the file. When using this flag, the
|
||||
file cannot be open multiple times concurrently.
|
||||
|
||||
.. note::
|
||||
`UV_FS_O_FILEMAP` is only supported on Windows.
|
||||
|
||||
.. c:macro:: UV_FS_O_NOATIME
|
||||
|
||||
Do not update the file access time when the file is read.
|
||||
|
28
deps/uv/docs/src/misc.rst
vendored
28
deps/uv/docs/src/misc.rst
vendored
@ -180,6 +180,17 @@ Data types
|
||||
char machine[256];
|
||||
} uv_utsname_t;
|
||||
|
||||
.. c:type:: uv_env_item_t
|
||||
|
||||
Data type for environment variable storage.
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_env_item_s {
|
||||
char* name;
|
||||
char* value;
|
||||
} uv_env_item_t;
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
@ -523,6 +534,23 @@ API
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
.. c:function:: int uv_os_environ(uv_env_item_t** envitems, int* count)
|
||||
|
||||
Retrieves all environment variables. This function will allocate memory
|
||||
which must be freed by calling :c:func:`uv_os_free_environ`.
|
||||
|
||||
.. warning::
|
||||
This function is not thread safe.
|
||||
|
||||
.. versionadded:: 1.31.0
|
||||
|
||||
.. c:function:: void uv_os_free_environ(uv_env_item_t* envitems, int count);
|
||||
|
||||
Frees the memory allocated for the environment variables by
|
||||
:c:func:`uv_os_environ`.
|
||||
|
||||
.. versionadded:: 1.31.0
|
||||
|
||||
.. c:function:: int uv_os_getenv(const char* name, char* buffer, size_t* size)
|
||||
|
||||
Retrieves the environment variable specified by `name`, copies its value
|
||||
|
27
deps/uv/include/uv.h
vendored
27
deps/uv/include/uv.h
vendored
@ -231,11 +231,13 @@ typedef struct uv_fs_s uv_fs_t;
|
||||
typedef struct uv_work_s uv_work_t;
|
||||
|
||||
/* None of the above. */
|
||||
typedef struct uv_env_item_s uv_env_item_t;
|
||||
typedef struct uv_cpu_info_s uv_cpu_info_t;
|
||||
typedef struct uv_interface_address_s uv_interface_address_t;
|
||||
typedef struct uv_dirent_s uv_dirent_t;
|
||||
typedef struct uv_passwd_s uv_passwd_t;
|
||||
typedef struct uv_utsname_s uv_utsname_t;
|
||||
typedef struct uv_statfs_s uv_statfs_t;
|
||||
|
||||
typedef enum {
|
||||
UV_LOOP_BLOCK_SIGNAL
|
||||
@ -1070,6 +1072,17 @@ struct uv_utsname_s {
|
||||
to as meaningless in the docs. */
|
||||
};
|
||||
|
||||
struct uv_statfs_s {
|
||||
uint64_t f_type;
|
||||
uint64_t f_bsize;
|
||||
uint64_t f_blocks;
|
||||
uint64_t f_bfree;
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint64_t f_spare[4];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
UV_DIRENT_UNKNOWN,
|
||||
UV_DIRENT_FILE,
|
||||
@ -1150,6 +1163,13 @@ UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count);
|
||||
|
||||
struct uv_env_item_s {
|
||||
char* name;
|
||||
char* value;
|
||||
};
|
||||
|
||||
UV_EXTERN int uv_os_environ(uv_env_item_t** envitems, int* count);
|
||||
UV_EXTERN void uv_os_free_environ(uv_env_item_t* envitems, int count);
|
||||
UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
|
||||
UV_EXTERN int uv_os_setenv(const char* name, const char* value);
|
||||
UV_EXTERN int uv_os_unsetenv(const char* name);
|
||||
@ -1205,7 +1225,8 @@ typedef enum {
|
||||
UV_FS_LCHOWN,
|
||||
UV_FS_OPENDIR,
|
||||
UV_FS_READDIR,
|
||||
UV_FS_CLOSEDIR
|
||||
UV_FS_CLOSEDIR,
|
||||
UV_FS_STATFS
|
||||
} uv_fs_type;
|
||||
|
||||
struct uv_dir_s {
|
||||
@ -1433,6 +1454,10 @@ UV_EXTERN int uv_fs_lchown(uv_loop_t* loop,
|
||||
uv_uid_t uid,
|
||||
uv_gid_t gid,
|
||||
uv_fs_cb cb);
|
||||
UV_EXTERN int uv_fs_statfs(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
uv_fs_cb cb);
|
||||
|
||||
|
||||
enum uv_fs_event {
|
||||
|
6
deps/uv/include/uv/unix.h
vendored
6
deps/uv/include/uv/unix.h
vendored
@ -49,6 +49,8 @@
|
||||
# include "uv/linux.h"
|
||||
#elif defined (__MVS__)
|
||||
# include "uv/os390.h"
|
||||
#elif defined(__PASE__) /* __PASE__ and _AIX are both defined on IBM i */
|
||||
# include "uv/posix.h" /* IBM i needs uv/posix.h, not uv/aix.h */
|
||||
#elif defined(_AIX)
|
||||
# include "uv/aix.h"
|
||||
#elif defined(__sun)
|
||||
@ -61,8 +63,7 @@
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# include "uv/bsd.h"
|
||||
#elif defined(__PASE__) || \
|
||||
defined(__CYGWIN__) || \
|
||||
#elif defined(__CYGWIN__) || \
|
||||
defined(__MSYS__) || \
|
||||
defined(__GNU__)
|
||||
# include "uv/posix.h"
|
||||
@ -481,6 +482,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
/* fs open() flags supported on other platforms: */
|
||||
#define UV_FS_O_FILEMAP 0
|
||||
#define UV_FS_O_RANDOM 0
|
||||
#define UV_FS_O_SHORT_LIVED 0
|
||||
#define UV_FS_O_SEQUENTIAL 0
|
||||
|
4
deps/uv/include/uv/version.h
vendored
4
deps/uv/include/uv/version.h
vendored
@ -31,8 +31,8 @@
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 30
|
||||
#define UV_VERSION_PATCH 1
|
||||
#define UV_VERSION_MINOR 31
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
|
||||
|
1
deps/uv/include/uv/win.h
vendored
1
deps/uv/include/uv/win.h
vendored
@ -668,6 +668,7 @@ typedef struct {
|
||||
#define UV_FS_O_APPEND _O_APPEND
|
||||
#define UV_FS_O_CREAT _O_CREAT
|
||||
#define UV_FS_O_EXCL _O_EXCL
|
||||
#define UV_FS_O_FILEMAP 0x20000000
|
||||
#define UV_FS_O_RANDOM _O_RANDOM
|
||||
#define UV_FS_O_RDONLY _O_RDONLY
|
||||
#define UV_FS_O_RDWR _O_RDWR
|
||||
|
60
deps/uv/src/unix/core.c
vendored
60
deps/uv/src/unix/core.c
vendored
@ -50,11 +50,15 @@
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <crt_externs.h>
|
||||
# include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||
# include <sys/filio.h>
|
||||
# if defined(O_CLOEXEC)
|
||||
# define UV__O_CLOEXEC O_CLOEXEC
|
||||
# endif
|
||||
# define environ (*_NSGetEnviron())
|
||||
#else
|
||||
extern char** environ;
|
||||
#endif
|
||||
|
||||
#if defined(__DragonFly__) || \
|
||||
@ -1284,6 +1288,62 @@ int uv_translate_sys_error(int sys_errno) {
|
||||
}
|
||||
|
||||
|
||||
int uv_os_environ(uv_env_item_t** envitems, int* count) {
|
||||
int i, j, cnt;
|
||||
uv_env_item_t* envitem;
|
||||
|
||||
*envitems = NULL;
|
||||
*count = 0;
|
||||
|
||||
for (i = 0; environ[i] != NULL; i++);
|
||||
|
||||
*envitems = uv__calloc(i, sizeof(**envitems));
|
||||
|
||||
if (envitems == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
for (j = 0, cnt = 0; j < i; j++) {
|
||||
char* buf;
|
||||
char* ptr;
|
||||
|
||||
if (environ[j] == NULL)
|
||||
break;
|
||||
|
||||
buf = uv__strdup(environ[j]);
|
||||
if (buf == NULL)
|
||||
goto fail;
|
||||
|
||||
ptr = strchr(buf, '=');
|
||||
if (ptr == NULL) {
|
||||
uv__free(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
envitem = &(*envitems)[cnt];
|
||||
envitem->name = buf;
|
||||
envitem->value = ptr + 1;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
*count = cnt;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < cnt; i++) {
|
||||
envitem = &(*envitems)[cnt];
|
||||
uv__free(envitem->name);
|
||||
}
|
||||
uv__free(*envitems);
|
||||
|
||||
*envitems = NULL;
|
||||
*count = 0;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
|
||||
char* var;
|
||||
size_t len;
|
||||
|
151
deps/uv/src/unix/darwin-proctitle.c
vendored
151
deps/uv/src/unix/darwin-proctitle.c
vendored
@ -33,56 +33,61 @@
|
||||
# include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
|
||||
|
||||
static int uv__pthread_setname_np(const char* name) {
|
||||
int (*dynamic_pthread_setname_np)(const char* name);
|
||||
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
||||
int err;
|
||||
|
||||
static int (*dynamic_pthread_setname_np)(const char* name);
|
||||
#if !TARGET_OS_IPHONE
|
||||
static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
||||
const char*,
|
||||
CFStringEncoding);
|
||||
static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
|
||||
static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
|
||||
static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
|
||||
static CFTypeRef (*pLSGetCurrentApplicationASN)(void);
|
||||
static OSStatus (*pLSSetApplicationInformationItem)(int,
|
||||
CFTypeRef,
|
||||
CFStringRef,
|
||||
CFStringRef,
|
||||
CFDictionaryRef*);
|
||||
static void* application_services_handle;
|
||||
static void* core_foundation_handle;
|
||||
static CFBundleRef launch_services_bundle;
|
||||
static CFStringRef* display_name_key;
|
||||
static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
|
||||
static CFBundleRef (*pCFBundleGetMainBundle)(void);
|
||||
static CFBundleRef hi_services_bundle;
|
||||
static OSStatus (*pSetApplicationIsDaemon)(int);
|
||||
static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
|
||||
static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
|
||||
void*);
|
||||
|
||||
|
||||
UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) {
|
||||
if (core_foundation_handle != NULL) {
|
||||
dlclose(core_foundation_handle);
|
||||
core_foundation_handle = NULL;
|
||||
}
|
||||
|
||||
if (application_services_handle != NULL) {
|
||||
dlclose(application_services_handle);
|
||||
application_services_handle = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* !TARGET_OS_IPHONE */
|
||||
|
||||
|
||||
void uv__set_process_title_platform_init(void) {
|
||||
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
||||
*(void **)(&dynamic_pthread_setname_np) =
|
||||
dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
if (dynamic_pthread_setname_np == NULL)
|
||||
return UV_ENOSYS;
|
||||
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
|
||||
err = dynamic_pthread_setname_np(namebuf);
|
||||
if (err)
|
||||
return UV__ERR(err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__set_process_title(const char* title) {
|
||||
#if TARGET_OS_IPHONE
|
||||
return uv__pthread_setname_np(title);
|
||||
#else
|
||||
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
||||
const char*,
|
||||
CFStringEncoding);
|
||||
CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
|
||||
void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
|
||||
void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
|
||||
CFTypeRef (*pLSGetCurrentApplicationASN)(void);
|
||||
OSStatus (*pLSSetApplicationInformationItem)(int,
|
||||
CFTypeRef,
|
||||
CFStringRef,
|
||||
CFStringRef,
|
||||
CFDictionaryRef*);
|
||||
void* application_services_handle;
|
||||
void* core_foundation_handle;
|
||||
CFBundleRef launch_services_bundle;
|
||||
CFStringRef* display_name_key;
|
||||
CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
|
||||
CFBundleRef (*pCFBundleGetMainBundle)(void);
|
||||
CFBundleRef hi_services_bundle;
|
||||
OSStatus (*pSetApplicationIsDaemon)(int);
|
||||
CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
|
||||
void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
|
||||
void*);
|
||||
CFTypeRef asn;
|
||||
int err;
|
||||
|
||||
err = UV_ENOENT;
|
||||
application_services_handle = dlopen("/System/Library/Frameworks/"
|
||||
"ApplicationServices.framework/"
|
||||
"Versions/A/ApplicationServices",
|
||||
@ -111,6 +116,8 @@ void uv__set_process_title_platform_init(void) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
|
||||
|
||||
launch_services_bundle =
|
||||
pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
|
||||
|
||||
@ -141,14 +148,13 @@ void uv__set_process_title_platform_init(void) {
|
||||
"CFBundleGetInfoDictionary");
|
||||
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
|
||||
"CFBundleGetMainBundle");
|
||||
|
||||
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
|
||||
goto out;
|
||||
|
||||
/* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
|
||||
hi_services_bundle =
|
||||
pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
|
||||
|
||||
err = UV_ENOENT;
|
||||
if (hi_services_bundle == NULL)
|
||||
goto out;
|
||||
|
||||
@ -162,37 +168,42 @@ void uv__set_process_title_platform_init(void) {
|
||||
pCFBundleGetFunctionPointerForName(
|
||||
launch_services_bundle,
|
||||
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
|
||||
|
||||
if (pSetApplicationIsDaemon == NULL ||
|
||||
pLSApplicationCheckIn == NULL ||
|
||||
pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
return;
|
||||
if (pSetApplicationIsDaemon(1) != noErr)
|
||||
goto out;
|
||||
|
||||
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
|
||||
|
||||
/* Check into process manager?! */
|
||||
pLSApplicationCheckIn(-2,
|
||||
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
|
||||
|
||||
asn = pLSGetCurrentApplicationASN();
|
||||
|
||||
err = UV_EINVAL;
|
||||
if (pLSSetApplicationInformationItem(-2, /* Magic value. */
|
||||
asn,
|
||||
*display_name_key,
|
||||
S(title),
|
||||
NULL) != noErr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
uv__pthread_setname_np(title); /* Don't care if it fails. */
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
uv__set_process_title_platform_fini();
|
||||
if (core_foundation_handle != NULL)
|
||||
dlclose(core_foundation_handle);
|
||||
|
||||
if (application_services_handle != NULL)
|
||||
dlclose(application_services_handle);
|
||||
|
||||
return err;
|
||||
#endif /* !TARGET_OS_IPHONE */
|
||||
}
|
||||
|
||||
|
||||
void uv__set_process_title(const char* title) {
|
||||
#if !TARGET_OS_IPHONE
|
||||
if (core_foundation_handle != NULL && pSetApplicationIsDaemon(1) != noErr) {
|
||||
CFTypeRef asn;
|
||||
pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
|
||||
pLSApplicationCheckIn(/* Magic value */ -2,
|
||||
pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
|
||||
asn = pLSGetCurrentApplicationASN();
|
||||
pLSSetApplicationInformationItem(/* Magic value */ -2, asn,
|
||||
*display_name_key, S(title), NULL);
|
||||
}
|
||||
#endif /* !TARGET_OS_IPHONE */
|
||||
|
||||
if (dynamic_pthread_setname_np != NULL) {
|
||||
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
||||
uv__strscpy(namebuf, title, sizeof(namebuf));
|
||||
dynamic_pthread_setname_np(namebuf);
|
||||
}
|
||||
}
|
||||
|
61
deps/uv/src/unix/fs.c
vendored
61
deps/uv/src/unix/fs.c
vendored
@ -70,6 +70,20 @@
|
||||
# include <utime.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || \
|
||||
defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# include <sys/param.h>
|
||||
# include <sys/mount.h>
|
||||
#elif defined(__sun) || defined(__MVS__)
|
||||
# include <sys/statvfs.h>
|
||||
#else
|
||||
# include <sys/statfs.h>
|
||||
#endif
|
||||
|
||||
#if defined(_AIX) && _XOPEN_SOURCE <= 600
|
||||
extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
|
||||
#endif
|
||||
@ -278,6 +292,7 @@ static ssize_t uv__fs_open(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
#if !HAVE_PREADV
|
||||
static ssize_t uv__fs_preadv(uv_file fd,
|
||||
uv_buf_t* bufs,
|
||||
unsigned int nbufs,
|
||||
@ -324,6 +339,7 @@ static ssize_t uv__fs_preadv(uv_file fd,
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static ssize_t uv__fs_read(uv_fs_t* req) {
|
||||
@ -519,6 +535,40 @@ static int uv__fs_closedir(uv_fs_t* req) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uv__fs_statfs(uv_fs_t* req) {
|
||||
uv_statfs_t* stat_fs;
|
||||
#if defined(__sun) || defined(__MVS__)
|
||||
struct statvfs buf;
|
||||
|
||||
if (0 != statvfs(req->path, &buf))
|
||||
#else
|
||||
struct statfs buf;
|
||||
|
||||
if (0 != statfs(req->path, &buf))
|
||||
#endif /* defined(__sun) */
|
||||
return -1;
|
||||
|
||||
stat_fs = uv__malloc(sizeof(*stat_fs));
|
||||
if (stat_fs == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(__sun) || defined(__MVS__)
|
||||
stat_fs->f_type = 0; /* f_type is not supported. */
|
||||
#else
|
||||
stat_fs->f_type = buf.f_type;
|
||||
#endif
|
||||
stat_fs->f_bsize = buf.f_bsize;
|
||||
stat_fs->f_blocks = buf.f_blocks;
|
||||
stat_fs->f_bfree = buf.f_bfree;
|
||||
stat_fs->f_bavail = buf.f_bavail;
|
||||
stat_fs->f_files = buf.f_files;
|
||||
stat_fs->f_ffree = buf.f_ffree;
|
||||
req->ptr = stat_fs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t uv__fs_pathmax_size(const char* path) {
|
||||
ssize_t pathmax;
|
||||
|
||||
@ -1386,6 +1436,7 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
X(RMDIR, rmdir(req->path));
|
||||
X(SENDFILE, uv__fs_sendfile(req));
|
||||
X(STAT, uv__fs_stat(req->path, &req->statbuf));
|
||||
X(STATFS, uv__fs_statfs(req));
|
||||
X(SYMLINK, symlink(req->path, req->new_path));
|
||||
X(UNLINK, unlink(req->path));
|
||||
X(UTIME, uv__fs_utime(req));
|
||||
@ -1858,3 +1909,13 @@ int uv_fs_copyfile(uv_loop_t* loop,
|
||||
req->flags = flags;
|
||||
POST;
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_statfs(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
uv_fs_cb cb) {
|
||||
INIT(STATFS);
|
||||
PATH;
|
||||
POST;
|
||||
}
|
||||
|
2
deps/uv/src/unix/openbsd.c
vendored
2
deps/uv/src/unix/openbsd.c
vendored
@ -193,7 +193,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
if (sysctl(which, 2, &model, &size, NULL, 0))
|
||||
return UV__ERR(errno);
|
||||
|
||||
which[1] = HW_NCPU;
|
||||
which[1] = HW_NCPUONLINE;
|
||||
size = sizeof(numcpus);
|
||||
if (sysctl(which, 2, &numcpus, &size, NULL, 0))
|
||||
return UV__ERR(errno);
|
||||
|
4
deps/uv/src/unix/proctitle.c
vendored
4
deps/uv/src/unix/proctitle.c
vendored
@ -24,7 +24,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void uv__set_process_title_platform_init(void);
|
||||
extern void uv__set_process_title(const char* title);
|
||||
|
||||
static uv_mutex_t process_title_mutex;
|
||||
@ -39,9 +38,6 @@ static struct {
|
||||
|
||||
static void init_process_title_mutex_once(void) {
|
||||
uv_mutex_init(&process_title_mutex);
|
||||
#ifdef __APPLE__
|
||||
uv__set_process_title_platform_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
2
deps/uv/src/unix/stream.c
vendored
2
deps/uv/src/unix/stream.c
vendored
@ -1000,12 +1000,12 @@ 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;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
stream->read_cb(stream, UV_EOF, buf);
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
}
|
||||
|
||||
|
||||
|
11
deps/uv/src/uv-common.c
vendored
11
deps/uv/src/uv-common.c
vendored
@ -786,3 +786,14 @@ void uv_loop_delete(uv_loop_t* loop) {
|
||||
if (loop != default_loop)
|
||||
uv__free(loop);
|
||||
}
|
||||
|
||||
|
||||
void uv_os_free_environ(uv_env_item_t* envitems, int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
uv__free(envitems[i].name);
|
||||
}
|
||||
|
||||
uv__free(envitems);
|
||||
}
|
||||
|
178
deps/uv/src/win/fs-fd-hash-inl.h
vendored
Normal file
178
deps/uv/src/win/fs-fd-hash-inl.h
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
#ifndef UV_WIN_FS_FD_HASH_INL_H_
|
||||
#define UV_WIN_FS_FD_HASH_INL_H_
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* Files are only inserted in uv__fd_hash when the UV_FS_O_FILEMAP flag is
|
||||
* specified. Thus, when uv__fd_hash_get returns true, the file mapping in the
|
||||
* info structure should be used for read/write operations.
|
||||
*
|
||||
* If the file is empty, the mapping field will be set to
|
||||
* INVALID_HANDLE_VALUE. This is not an issue since the file mapping needs to
|
||||
* be created anyway when the file size changes.
|
||||
*
|
||||
* Since file descriptors are sequential integers, the modulo operator is used
|
||||
* as hashing function. For each bucket, a single linked list of arrays is
|
||||
* kept to minimize allocations. A statically allocated memory buffer is kept
|
||||
* for the first array in each bucket. */
|
||||
|
||||
|
||||
#define UV__FD_HASH_SIZE 256
|
||||
#define UV__FD_HASH_GROUP_SIZE 16
|
||||
|
||||
struct uv__fd_info_s {
|
||||
int flags;
|
||||
BOOLEAN is_directory;
|
||||
HANDLE mapping;
|
||||
LARGE_INTEGER size;
|
||||
LARGE_INTEGER current_pos;
|
||||
};
|
||||
|
||||
struct uv__fd_hash_entry_s {
|
||||
uv_file fd;
|
||||
struct uv__fd_info_s info;
|
||||
};
|
||||
|
||||
struct uv__fd_hash_entry_group_s {
|
||||
struct uv__fd_hash_entry_s entries[UV__FD_HASH_GROUP_SIZE];
|
||||
struct uv__fd_hash_entry_group_s* next;
|
||||
};
|
||||
|
||||
struct uv__fd_hash_bucket_s {
|
||||
size_t size;
|
||||
struct uv__fd_hash_entry_group_s* data;
|
||||
};
|
||||
|
||||
|
||||
static uv_mutex_t uv__fd_hash_mutex;
|
||||
|
||||
static struct uv__fd_hash_entry_group_s
|
||||
uv__fd_hash_entry_initial[UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE];
|
||||
static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE];
|
||||
|
||||
|
||||
INLINE static void uv__fd_hash_init(void) {
|
||||
int i, err;
|
||||
|
||||
err = uv_mutex_init(&uv__fd_hash_mutex);
|
||||
if (err) {
|
||||
uv_fatal_error(err, "uv_mutex_init");
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) {
|
||||
uv__fd_hash[i].size = 0;
|
||||
uv__fd_hash[i].data =
|
||||
uv__fd_hash_entry_initial + i * UV__FD_HASH_GROUP_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
#define FIND_COMMON_VARIABLES \
|
||||
unsigned i; \
|
||||
unsigned bucket = fd % ARRAY_SIZE(uv__fd_hash); \
|
||||
struct uv__fd_hash_entry_s* entry_ptr = NULL; \
|
||||
struct uv__fd_hash_entry_group_s* group_ptr; \
|
||||
struct uv__fd_hash_bucket_s* bucket_ptr = &uv__fd_hash[bucket];
|
||||
|
||||
#define FIND_IN_GROUP_PTR(group_size) \
|
||||
do { \
|
||||
for (i = 0; i < group_size; ++i) { \
|
||||
if (group_ptr->entries[i].fd == fd) { \
|
||||
entry_ptr = &group_ptr->entries[i]; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FIND_IN_BUCKET_PTR() \
|
||||
do { \
|
||||
size_t first_group_size = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE; \
|
||||
if (bucket_ptr->size != 0 && first_group_size == 0) \
|
||||
first_group_size = UV__FD_HASH_GROUP_SIZE; \
|
||||
group_ptr = bucket_ptr->data; \
|
||||
FIND_IN_GROUP_PTR(first_group_size); \
|
||||
for (group_ptr = group_ptr->next; \
|
||||
group_ptr != NULL && entry_ptr == NULL; \
|
||||
group_ptr = group_ptr->next) \
|
||||
FIND_IN_GROUP_PTR(UV__FD_HASH_GROUP_SIZE); \
|
||||
} while (0)
|
||||
|
||||
INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
|
||||
FIND_COMMON_VARIABLES
|
||||
|
||||
uv_mutex_lock(&uv__fd_hash_mutex);
|
||||
|
||||
FIND_IN_BUCKET_PTR();
|
||||
|
||||
if (entry_ptr != NULL) {
|
||||
*info = entry_ptr->info;
|
||||
}
|
||||
|
||||
uv_mutex_unlock(&uv__fd_hash_mutex);
|
||||
return entry_ptr != NULL;
|
||||
}
|
||||
|
||||
INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
|
||||
FIND_COMMON_VARIABLES
|
||||
|
||||
uv_mutex_lock(&uv__fd_hash_mutex);
|
||||
|
||||
FIND_IN_BUCKET_PTR();
|
||||
|
||||
if (entry_ptr == NULL) {
|
||||
i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;
|
||||
|
||||
if (bucket_ptr->size != 0 && i == 0) {
|
||||
struct uv__fd_hash_entry_group_s* new_group_ptr =
|
||||
uv__malloc(sizeof(*new_group_ptr));
|
||||
if (new_group_ptr == NULL) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
new_group_ptr->next = bucket_ptr->data;
|
||||
bucket_ptr->data = new_group_ptr;
|
||||
}
|
||||
|
||||
bucket_ptr->size += 1;
|
||||
entry_ptr = &bucket_ptr->data->entries[i];
|
||||
entry_ptr->fd = fd;
|
||||
}
|
||||
|
||||
entry_ptr->info = *info;
|
||||
|
||||
uv_mutex_unlock(&uv__fd_hash_mutex);
|
||||
}
|
||||
|
||||
INLINE static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
|
||||
FIND_COMMON_VARIABLES
|
||||
|
||||
uv_mutex_lock(&uv__fd_hash_mutex);
|
||||
|
||||
FIND_IN_BUCKET_PTR();
|
||||
|
||||
if (entry_ptr != NULL) {
|
||||
*info = entry_ptr->info;
|
||||
|
||||
bucket_ptr->size -= 1;
|
||||
|
||||
i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;
|
||||
if (entry_ptr != &bucket_ptr->data->entries[i]) {
|
||||
*entry_ptr = bucket_ptr->data->entries[i];
|
||||
}
|
||||
|
||||
if (bucket_ptr->size != 0 &&
|
||||
bucket_ptr->size % UV__FD_HASH_GROUP_SIZE == 0) {
|
||||
struct uv__fd_hash_entry_group_s* old_group_ptr = bucket_ptr->data;
|
||||
bucket_ptr->data = old_group_ptr->next;
|
||||
uv__free(old_group_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
uv_mutex_unlock(&uv__fd_hash_mutex);
|
||||
return entry_ptr != NULL;
|
||||
}
|
||||
|
||||
#undef FIND_COMMON_VARIABLES
|
||||
#undef FIND_IN_GROUP_PTR
|
||||
#undef FIND_IN_BUCKET_PTR
|
||||
|
||||
#endif /* UV_WIN_FS_FD_HASH_INL_H_ */
|
458
deps/uv/src/win/fs.c
vendored
458
deps/uv/src/win/fs.c
vendored
@ -34,6 +34,7 @@
|
||||
#include "internal.h"
|
||||
#include "req-inl.h"
|
||||
#include "handle-inl.h"
|
||||
#include "fs-fd-hash-inl.h"
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
@ -126,6 +127,8 @@
|
||||
#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \
|
||||
((c) >= L'A' && (c) <= L'Z'))
|
||||
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
const WCHAR JUNCTION_PREFIX[] = L"\\??\\";
|
||||
const WCHAR JUNCTION_PREFIX_LEN = 4;
|
||||
|
||||
@ -137,8 +140,16 @@ const WCHAR UNC_PATH_PREFIX_LEN = 8;
|
||||
|
||||
static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
|
||||
|
||||
static DWORD uv__allocation_granularity;
|
||||
|
||||
|
||||
void uv_fs_init(void) {
|
||||
_fmode = _O_BINARY;
|
||||
SYSTEM_INFO system_info;
|
||||
|
||||
GetSystemInfo(&system_info);
|
||||
uv__allocation_granularity = system_info.dwAllocationGranularity;
|
||||
|
||||
uv__fd_hash_init();
|
||||
}
|
||||
|
||||
|
||||
@ -414,6 +425,27 @@ void fs__open(uv_fs_t* req) {
|
||||
HANDLE file;
|
||||
int fd, current_umask;
|
||||
int flags = req->fs.info.file_flags;
|
||||
struct uv__fd_info_s fd_info;
|
||||
|
||||
/* Adjust flags to be compatible with the memory file mapping. Save the
|
||||
* original flags to emulate the correct behavior. */
|
||||
if (flags & UV_FS_O_FILEMAP) {
|
||||
fd_info.flags = flags;
|
||||
fd_info.current_pos.QuadPart = 0;
|
||||
|
||||
if ((flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR)) ==
|
||||
UV_FS_O_WRONLY) {
|
||||
/* CreateFileMapping always needs read access */
|
||||
flags = (flags & ~UV_FS_O_WRONLY) | UV_FS_O_RDWR;
|
||||
}
|
||||
|
||||
if (flags & UV_FS_O_APPEND) {
|
||||
/* Clear the append flag and ensure RDRW mode */
|
||||
flags &= ~UV_FS_O_APPEND;
|
||||
flags &= ~(UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
|
||||
flags |= UV_FS_O_RDWR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Obtain the active umask. umask() never fails and returns the previous
|
||||
* umask. */
|
||||
@ -444,7 +476,8 @@ void fs__open(uv_fs_t* req) {
|
||||
* Here is where we deviate significantly from what CRT's _open()
|
||||
* does. We indiscriminately use all the sharing modes, to match
|
||||
* UNIX semantics. In particular, this ensures that the file can
|
||||
* be deleted even whilst it's open, fixing issue #1449.
|
||||
* be deleted even whilst it's open, fixing issue
|
||||
* https://github.com/nodejs/node-v0.x-archive/issues/1449.
|
||||
* We still support exclusive sharing mode, since it is necessary
|
||||
* for opening raw block devices, otherwise Windows will prevent
|
||||
* any attempt to write past the master boot record.
|
||||
@ -583,11 +616,55 @@ void fs__open(uv_fs_t* req) {
|
||||
else if (GetLastError() != ERROR_SUCCESS)
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
else
|
||||
SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
|
||||
SET_REQ_WIN32_ERROR(req, (DWORD) UV_UNKNOWN);
|
||||
CloseHandle(file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & UV_FS_O_FILEMAP) {
|
||||
FILE_STANDARD_INFO file_info;
|
||||
if (!GetFileInformationByHandleEx(file,
|
||||
FileStandardInfo,
|
||||
&file_info,
|
||||
sizeof file_info)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(file);
|
||||
return;
|
||||
}
|
||||
fd_info.is_directory = file_info.Directory;
|
||||
|
||||
if (fd_info.is_directory) {
|
||||
fd_info.size.QuadPart = 0;
|
||||
fd_info.mapping = INVALID_HANDLE_VALUE;
|
||||
} else {
|
||||
if (!GetFileSizeEx(file, &fd_info.size)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fd_info.size.QuadPart == 0) {
|
||||
fd_info.mapping = INVALID_HANDLE_VALUE;
|
||||
} else {
|
||||
DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY |
|
||||
UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE;
|
||||
fd_info.mapping = CreateFileMapping(file,
|
||||
NULL,
|
||||
flProtect,
|
||||
fd_info.size.HighPart,
|
||||
fd_info.size.LowPart,
|
||||
NULL);
|
||||
if (fd_info.mapping == NULL) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uv__fd_hash_add(fd, &fd_info);
|
||||
}
|
||||
|
||||
SET_REQ_RESULT(req, fd);
|
||||
return;
|
||||
|
||||
@ -598,9 +675,16 @@ void fs__open(uv_fs_t* req) {
|
||||
void fs__close(uv_fs_t* req) {
|
||||
int fd = req->file.fd;
|
||||
int result;
|
||||
struct uv__fd_info_s fd_info;
|
||||
|
||||
VERIFY_FD(fd, req);
|
||||
|
||||
if (uv__fd_hash_remove(fd, &fd_info)) {
|
||||
if (fd_info.mapping != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fd_info.mapping);
|
||||
}
|
||||
}
|
||||
|
||||
if (fd > 2)
|
||||
result = _close(fd);
|
||||
else
|
||||
@ -618,6 +702,123 @@ void fs__close(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
LONG fs__filemap_ex_filter(LONG excode, PEXCEPTION_POINTERS pep,
|
||||
int* perror) {
|
||||
if (excode != EXCEPTION_IN_PAGE_ERROR) {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
assert(perror != NULL);
|
||||
if (pep != NULL && pep->ExceptionRecord != NULL &&
|
||||
pep->ExceptionRecord->NumberParameters >= 3) {
|
||||
NTSTATUS status = (NTSTATUS)pep->ExceptionRecord->ExceptionInformation[3];
|
||||
*perror = pRtlNtStatusToDosError(status);
|
||||
if (*perror != ERROR_SUCCESS) {
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
}
|
||||
*perror = UV_UNKNOWN;
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
|
||||
void fs__read_filemap(uv_fs_t* req, struct uv__fd_info_s* fd_info) {
|
||||
int fd = req->file.fd; /* VERIFY_FD done in fs__read */
|
||||
int rw_flags = fd_info->flags &
|
||||
(UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
|
||||
size_t read_size, done_read;
|
||||
unsigned int index;
|
||||
LARGE_INTEGER pos, end_pos;
|
||||
size_t view_offset;
|
||||
LARGE_INTEGER view_base;
|
||||
void* view;
|
||||
|
||||
if (rw_flags == UV_FS_O_WRONLY) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
if (fd_info->is_directory) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->fs.info.offset == -1) {
|
||||
pos = fd_info->current_pos;
|
||||
} else {
|
||||
pos.QuadPart = req->fs.info.offset;
|
||||
}
|
||||
|
||||
/* Make sure we wont read past EOF. */
|
||||
if (pos.QuadPart >= fd_info->size.QuadPart) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
read_size = 0;
|
||||
for (index = 0; index < req->fs.info.nbufs; ++index) {
|
||||
read_size += req->fs.info.bufs[index].len;
|
||||
}
|
||||
read_size = (size_t) MIN((LONGLONG) read_size,
|
||||
fd_info->size.QuadPart - pos.QuadPart);
|
||||
if (read_size == 0) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
end_pos.QuadPart = pos.QuadPart + read_size;
|
||||
|
||||
view_offset = pos.QuadPart % uv__allocation_granularity;
|
||||
view_base.QuadPart = pos.QuadPart - view_offset;
|
||||
view = MapViewOfFile(fd_info->mapping,
|
||||
FILE_MAP_READ,
|
||||
view_base.HighPart,
|
||||
view_base.LowPart,
|
||||
view_offset + read_size);
|
||||
if (view == NULL) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
done_read = 0;
|
||||
for (index = 0;
|
||||
index < req->fs.info.nbufs && done_read < read_size;
|
||||
++index) {
|
||||
int err = 0;
|
||||
size_t this_read_size = MIN(req->fs.info.bufs[index].len,
|
||||
read_size - done_read);
|
||||
#ifdef _MSC_VER
|
||||
__try {
|
||||
#endif
|
||||
memcpy(req->fs.info.bufs[index].base,
|
||||
(char*)view + view_offset + done_read,
|
||||
this_read_size);
|
||||
#ifdef _MSC_VER
|
||||
}
|
||||
__except (fs__filemap_ex_filter(GetExceptionCode(),
|
||||
GetExceptionInformation(), &err)) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
UnmapViewOfFile(view);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
done_read += this_read_size;
|
||||
}
|
||||
assert(done_read == read_size);
|
||||
|
||||
if (!UnmapViewOfFile(view)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->fs.info.offset == -1) {
|
||||
fd_info->current_pos = end_pos;
|
||||
uv__fd_hash_add(fd, fd_info);
|
||||
}
|
||||
|
||||
SET_REQ_RESULT(req, read_size);
|
||||
return;
|
||||
}
|
||||
|
||||
void fs__read(uv_fs_t* req) {
|
||||
int fd = req->file.fd;
|
||||
int64_t offset = req->fs.info.offset;
|
||||
@ -631,9 +832,15 @@ void fs__read(uv_fs_t* req) {
|
||||
LARGE_INTEGER original_position;
|
||||
LARGE_INTEGER zero_offset;
|
||||
int restore_position;
|
||||
struct uv__fd_info_s fd_info;
|
||||
|
||||
VERIFY_FD(fd, req);
|
||||
|
||||
if (uv__fd_hash_get(fd, &fd_info)) {
|
||||
fs__read_filemap(req, &fd_info);
|
||||
return;
|
||||
}
|
||||
|
||||
zero_offset.QuadPart = 0;
|
||||
restore_position = 0;
|
||||
handle = uv__get_osfhandle(fd);
|
||||
@ -690,6 +897,131 @@ void fs__read(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
void fs__write_filemap(uv_fs_t* req, HANDLE file,
|
||||
struct uv__fd_info_s* fd_info) {
|
||||
int fd = req->file.fd; /* VERIFY_FD done in fs__write */
|
||||
int force_append = fd_info->flags & UV_FS_O_APPEND;
|
||||
int rw_flags = fd_info->flags &
|
||||
(UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
|
||||
size_t write_size, done_write;
|
||||
unsigned int index;
|
||||
LARGE_INTEGER zero, pos, end_pos;
|
||||
size_t view_offset;
|
||||
LARGE_INTEGER view_base;
|
||||
void* view;
|
||||
FILETIME ft;
|
||||
|
||||
if (rw_flags == UV_FS_O_RDONLY) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
if (fd_info->is_directory) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION);
|
||||
return;
|
||||
}
|
||||
|
||||
write_size = 0;
|
||||
for (index = 0; index < req->fs.info.nbufs; ++index) {
|
||||
write_size += req->fs.info.bufs[index].len;
|
||||
}
|
||||
|
||||
if (write_size == 0) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
zero.QuadPart = 0;
|
||||
if (force_append) {
|
||||
pos = fd_info->size;
|
||||
} else if (req->fs.info.offset == -1) {
|
||||
pos = fd_info->current_pos;
|
||||
} else {
|
||||
pos.QuadPart = req->fs.info.offset;
|
||||
}
|
||||
|
||||
end_pos.QuadPart = pos.QuadPart + write_size;
|
||||
|
||||
/* Recreate the mapping to enlarge the file if needed */
|
||||
if (end_pos.QuadPart > fd_info->size.QuadPart) {
|
||||
if (fd_info->mapping != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fd_info->mapping);
|
||||
}
|
||||
|
||||
fd_info->mapping = CreateFileMapping(file,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
end_pos.HighPart,
|
||||
end_pos.LowPart,
|
||||
NULL);
|
||||
if (fd_info->mapping == NULL) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(file);
|
||||
fd_info->mapping = INVALID_HANDLE_VALUE;
|
||||
fd_info->size.QuadPart = 0;
|
||||
fd_info->current_pos.QuadPart = 0;
|
||||
uv__fd_hash_add(fd, fd_info);
|
||||
return;
|
||||
}
|
||||
|
||||
fd_info->size = end_pos;
|
||||
uv__fd_hash_add(fd, fd_info);
|
||||
}
|
||||
|
||||
view_offset = pos.QuadPart % uv__allocation_granularity;
|
||||
view_base.QuadPart = pos.QuadPart - view_offset;
|
||||
view = MapViewOfFile(fd_info->mapping,
|
||||
FILE_MAP_WRITE,
|
||||
view_base.HighPart,
|
||||
view_base.LowPart,
|
||||
view_offset + write_size);
|
||||
if (view == NULL) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
done_write = 0;
|
||||
for (index = 0; index < req->fs.info.nbufs; ++index) {
|
||||
int err = 0;
|
||||
#ifdef _MSC_VER
|
||||
__try {
|
||||
#endif
|
||||
memcpy((char*)view + view_offset + done_write,
|
||||
req->fs.info.bufs[index].base,
|
||||
req->fs.info.bufs[index].len);
|
||||
#ifdef _MSC_VER
|
||||
}
|
||||
__except (fs__filemap_ex_filter(GetExceptionCode(),
|
||||
GetExceptionInformation(), &err)) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
UnmapViewOfFile(view);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
done_write += req->fs.info.bufs[index].len;
|
||||
}
|
||||
assert(done_write == write_size);
|
||||
|
||||
if (!FlushViewOfFile(view, 0)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
UnmapViewOfFile(view);
|
||||
return;
|
||||
}
|
||||
if (!UnmapViewOfFile(view)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->fs.info.offset == -1) {
|
||||
fd_info->current_pos = end_pos;
|
||||
uv__fd_hash_add(fd, fd_info);
|
||||
}
|
||||
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
SetFileTime(file, NULL, NULL, &ft);
|
||||
|
||||
SET_REQ_RESULT(req, done_write);
|
||||
}
|
||||
|
||||
void fs__write(uv_fs_t* req) {
|
||||
int fd = req->file.fd;
|
||||
int64_t offset = req->fs.info.offset;
|
||||
@ -702,6 +1034,7 @@ void fs__write(uv_fs_t* req) {
|
||||
LARGE_INTEGER original_position;
|
||||
LARGE_INTEGER zero_offset;
|
||||
int restore_position;
|
||||
struct uv__fd_info_s fd_info;
|
||||
|
||||
VERIFY_FD(fd, req);
|
||||
|
||||
@ -713,6 +1046,11 @@ void fs__write(uv_fs_t* req) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (uv__fd_hash_get(fd, &fd_info)) {
|
||||
fs__write_filemap(req, handle, &fd_info);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset != -1) {
|
||||
memset(&overlapped, 0, sizeof overlapped);
|
||||
overlapped_ptr = &overlapped;
|
||||
@ -850,8 +1188,13 @@ void fs__unlink(uv_fs_t* req) {
|
||||
|
||||
void fs__mkdir(uv_fs_t* req) {
|
||||
/* TODO: use req->mode. */
|
||||
int result = _wmkdir(req->file.pathw);
|
||||
SET_REQ_RESULT(req, result);
|
||||
req->result = _wmkdir(req->file.pathw);
|
||||
if (req->result == -1) {
|
||||
req->sys_errno_ = _doserrno;
|
||||
req->result = req->sys_errno_ == ERROR_INVALID_NAME
|
||||
? UV_EINVAL
|
||||
: uv_translate_sys_error(req->sys_errno_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1536,6 +1879,7 @@ static void fs__fdatasync(uv_fs_t* req) {
|
||||
static void fs__ftruncate(uv_fs_t* req) {
|
||||
int fd = req->file.fd;
|
||||
HANDLE handle;
|
||||
struct uv__fd_info_s fd_info = { 0 };
|
||||
NTSTATUS status;
|
||||
IO_STATUS_BLOCK io_status;
|
||||
FILE_END_OF_FILE_INFORMATION eof_info;
|
||||
@ -1544,6 +1888,17 @@ static void fs__ftruncate(uv_fs_t* req) {
|
||||
|
||||
handle = uv__get_osfhandle(fd);
|
||||
|
||||
if (uv__fd_hash_get(fd, &fd_info)) {
|
||||
if (fd_info.is_directory) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fd_info.mapping != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fd_info.mapping);
|
||||
}
|
||||
}
|
||||
|
||||
eof_info.EndOfFile.QuadPart = req->fs.info.offset;
|
||||
|
||||
status = pNtSetInformationFile(handle,
|
||||
@ -1556,6 +1911,43 @@ static void fs__ftruncate(uv_fs_t* req) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
} else {
|
||||
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
|
||||
|
||||
if (fd_info.flags) {
|
||||
CloseHandle(handle);
|
||||
fd_info.mapping = INVALID_HANDLE_VALUE;
|
||||
fd_info.size.QuadPart = 0;
|
||||
fd_info.current_pos.QuadPart = 0;
|
||||
uv__fd_hash_add(fd, &fd_info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd_info.flags) {
|
||||
fd_info.size = eof_info.EndOfFile;
|
||||
|
||||
if (fd_info.size.QuadPart == 0) {
|
||||
fd_info.mapping = INVALID_HANDLE_VALUE;
|
||||
} else {
|
||||
DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY |
|
||||
UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE;
|
||||
fd_info.mapping = CreateFileMapping(handle,
|
||||
NULL,
|
||||
flProtect,
|
||||
fd_info.size.HighPart,
|
||||
fd_info.size.LowPart,
|
||||
NULL);
|
||||
if (fd_info.mapping == NULL) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(handle);
|
||||
fd_info.mapping = INVALID_HANDLE_VALUE;
|
||||
fd_info.size.QuadPart = 0;
|
||||
fd_info.current_pos.QuadPart = 0;
|
||||
uv__fd_hash_add(fd, &fd_info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uv__fd_hash_add(fd, &fd_info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1563,7 +1955,6 @@ static void fs__ftruncate(uv_fs_t* req) {
|
||||
static void fs__copyfile(uv_fs_t* req) {
|
||||
int flags;
|
||||
int overwrite;
|
||||
DWORD error;
|
||||
uv_stat_t statbuf;
|
||||
uv_stat_t new_statbuf;
|
||||
|
||||
@ -2165,6 +2556,41 @@ static void fs__lchown(uv_fs_t* req) {
|
||||
req->result = 0;
|
||||
}
|
||||
|
||||
|
||||
static void fs__statfs(uv_fs_t* req) {
|
||||
uv_statfs_t* stat_fs;
|
||||
DWORD sectors_per_cluster;
|
||||
DWORD bytes_per_sector;
|
||||
DWORD free_clusters;
|
||||
DWORD total_clusters;
|
||||
|
||||
if (0 == GetDiskFreeSpaceW(req->file.pathw,
|
||||
§ors_per_cluster,
|
||||
&bytes_per_sector,
|
||||
&free_clusters,
|
||||
&total_clusters)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
stat_fs = uv__malloc(sizeof(*stat_fs));
|
||||
if (stat_fs == NULL) {
|
||||
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
stat_fs->f_type = 0;
|
||||
stat_fs->f_bsize = bytes_per_sector * sectors_per_cluster;
|
||||
stat_fs->f_blocks = total_clusters;
|
||||
stat_fs->f_bfree = free_clusters;
|
||||
stat_fs->f_bavail = free_clusters;
|
||||
stat_fs->f_files = 0;
|
||||
stat_fs->f_ffree = 0;
|
||||
req->ptr = stat_fs;
|
||||
SET_REQ_RESULT(req, 0);
|
||||
}
|
||||
|
||||
|
||||
static void uv__fs_work(struct uv__work* w) {
|
||||
uv_fs_t* req;
|
||||
|
||||
@ -2204,8 +2630,9 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
XX(READLINK, readlink)
|
||||
XX(REALPATH, realpath)
|
||||
XX(CHOWN, chown)
|
||||
XX(FCHOWN, fchown);
|
||||
XX(LCHOWN, lchown);
|
||||
XX(FCHOWN, fchown)
|
||||
XX(LCHOWN, lchown)
|
||||
XX(STATFS, statfs)
|
||||
default:
|
||||
assert(!"bad uv_fs_type");
|
||||
}
|
||||
@ -2717,3 +3144,18 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
|
||||
req->fs.time.mtime = mtime;
|
||||
POST;
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_statfs(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
const char* path,
|
||||
uv_fs_cb cb) {
|
||||
int err;
|
||||
|
||||
INIT(UV_FS_STATFS);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
POST;
|
||||
}
|
||||
|
4
deps/uv/src/win/process.c
vendored
4
deps/uv/src/win/process.c
vendored
@ -714,7 +714,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
||||
|
||||
/* second pass: copy to UTF-16 environment block */
|
||||
dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR));
|
||||
if (!dst_copy) {
|
||||
if (dst_copy == NULL && env_len > 0) {
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
env_copy = alloca(env_block_count * sizeof(WCHAR*));
|
||||
@ -739,7 +739,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
||||
}
|
||||
}
|
||||
*ptr_copy = NULL;
|
||||
assert(env_len == (size_t) (ptr - dst_copy));
|
||||
assert(env_len == 0 || env_len == (size_t) (ptr - dst_copy));
|
||||
|
||||
/* sort our (UTF-16) copy */
|
||||
qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp);
|
||||
|
21
deps/uv/src/win/tty.c
vendored
21
deps/uv/src/win/tty.c
vendored
@ -2280,6 +2280,8 @@ static void uv__determine_vterm_state(HANDLE handle) {
|
||||
|
||||
static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) {
|
||||
CONSOLE_SCREEN_BUFFER_INFO sb_info;
|
||||
NTSTATUS status;
|
||||
ULONG_PTR conhost_pid;
|
||||
MSG msg;
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info))
|
||||
@ -2288,14 +2290,29 @@ static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) {
|
||||
uv__tty_console_width = sb_info.dwSize.X;
|
||||
uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
|
||||
|
||||
if (pSetWinEventHook == NULL)
|
||||
if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL)
|
||||
return 0;
|
||||
|
||||
status = pNtQueryInformationProcess(GetCurrentProcess(),
|
||||
ProcessConsoleHostProcess,
|
||||
&conhost_pid,
|
||||
sizeof(conhost_pid),
|
||||
NULL);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
/* We couldn't retrieve our console host process, probably because this
|
||||
* is a 32-bit process running on 64-bit Windows. Fall back to receiving
|
||||
* console events from all processes. */
|
||||
conhost_pid = 0;
|
||||
|
||||
/* Ensure the PID is a multiple of 4, which is required by SetWinEventHook */
|
||||
conhost_pid &= ~(ULONG_PTR)0x3;
|
||||
|
||||
if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT,
|
||||
EVENT_CONSOLE_LAYOUT,
|
||||
NULL,
|
||||
uv__tty_console_resize_event,
|
||||
0,
|
||||
(DWORD)conhost_pid,
|
||||
0,
|
||||
WINEVENT_OUTOFCONTEXT))
|
||||
return 0;
|
||||
|
75
deps/uv/src/win/util.c
vendored
75
deps/uv/src/win/util.c
vendored
@ -1171,18 +1171,18 @@ int uv_os_homedir(char* buffer, size_t* size) {
|
||||
|
||||
|
||||
int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||
wchar_t path[MAX_PATH + 1];
|
||||
wchar_t path[MAX_PATH + 2];
|
||||
DWORD bufsize;
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
len = GetTempPathW(MAX_PATH + 1, path);
|
||||
len = GetTempPathW(ARRAY_SIZE(path), path);
|
||||
|
||||
if (len == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
} else if (len > MAX_PATH + 1) {
|
||||
} else if (len > ARRAY_SIZE(path)) {
|
||||
/* This should not be possible */
|
||||
return UV_EIO;
|
||||
}
|
||||
@ -1397,6 +1397,75 @@ int uv_os_get_passwd(uv_passwd_t* pwd) {
|
||||
}
|
||||
|
||||
|
||||
int uv_os_environ(uv_env_item_t** envitems, int* count) {
|
||||
wchar_t* env;
|
||||
wchar_t* penv;
|
||||
int i, cnt;
|
||||
uv_env_item_t* envitem;
|
||||
|
||||
*envitems = NULL;
|
||||
*count = 0;
|
||||
|
||||
env = GetEnvironmentStringsW();
|
||||
if (env == NULL)
|
||||
return 0;
|
||||
|
||||
for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);
|
||||
|
||||
*envitems = uv__calloc(i, sizeof(**envitems));
|
||||
if (envitems == NULL) {
|
||||
FreeEnvironmentStringsW(env);
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
penv = env;
|
||||
cnt = 0;
|
||||
|
||||
while (*penv != L'\0' && cnt < i) {
|
||||
char* buf;
|
||||
char* ptr;
|
||||
|
||||
if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0)
|
||||
goto fail;
|
||||
|
||||
ptr = strchr(buf, '=');
|
||||
if (ptr == NULL) {
|
||||
uv__free(buf);
|
||||
goto do_continue;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
envitem = &(*envitems)[cnt];
|
||||
envitem->name = buf;
|
||||
envitem->value = ptr + 1;
|
||||
|
||||
cnt++;
|
||||
|
||||
do_continue:
|
||||
penv += wcslen(penv) + 1;
|
||||
}
|
||||
|
||||
FreeEnvironmentStringsW(env);
|
||||
|
||||
*count = cnt;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
FreeEnvironmentStringsW(env);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
envitem = &(*envitems)[cnt];
|
||||
uv__free(envitem->name);
|
||||
}
|
||||
uv__free(*envitems);
|
||||
|
||||
*envitems = NULL;
|
||||
*count = 0;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
|
||||
wchar_t var[MAX_ENV_VAR_LENGTH];
|
||||
wchar_t* name_w;
|
||||
|
8
deps/uv/src/win/winapi.c
vendored
8
deps/uv/src/win/winapi.c
vendored
@ -34,6 +34,7 @@ sNtSetInformationFile pNtSetInformationFile;
|
||||
sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
|
||||
sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
||||
sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
|
||||
/* Kernel32 function pointers */
|
||||
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
@ -106,6 +107,13 @@ void uv_winapi_init(void) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress(
|
||||
ntdll_module,
|
||||
"NtQueryInformationProcess");
|
||||
if (pNtQueryInformationProcess == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
kernel32_module = GetModuleHandleA("kernel32.dll");
|
||||
if (kernel32_module == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetModuleHandleA");
|
||||
|
12
deps/uv/src/win/winapi.h
vendored
12
deps/uv/src/win/winapi.h
vendored
@ -4436,6 +4436,10 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
# define SystemProcessorPerformanceInformation 8
|
||||
#endif
|
||||
|
||||
#ifndef ProcessConsoleHostProcess
|
||||
# define ProcessConsoleHostProcess 49
|
||||
#endif
|
||||
|
||||
#ifndef FILE_DEVICE_FILE_SYSTEM
|
||||
# define FILE_DEVICE_FILE_SYSTEM 0x00000009
|
||||
#endif
|
||||
@ -4578,6 +4582,13 @@ typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile)
|
||||
BOOLEAN RestartScan
|
||||
);
|
||||
|
||||
typedef NTSTATUS (NTAPI *sNtQueryInformationProcess)
|
||||
(HANDLE ProcessHandle,
|
||||
UINT ProcessInformationClass,
|
||||
PVOID ProcessInformation,
|
||||
ULONG Length,
|
||||
PULONG ReturnLength);
|
||||
|
||||
/*
|
||||
* Kernel32 headers
|
||||
*/
|
||||
@ -4718,6 +4729,7 @@ extern sNtSetInformationFile pNtSetInformationFile;
|
||||
extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
|
||||
extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
||||
extern sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
extern sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
|
||||
/* Kernel32 function pointers */
|
||||
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
|
6
deps/uv/test/runner-win.c
vendored
6
deps/uv/test/runner-win.c
vendored
@ -56,6 +56,12 @@ int platform_init(int argc, char **argv) {
|
||||
_setmode(1, _O_BINARY);
|
||||
_setmode(2, _O_BINARY);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
_set_fmode(_O_BINARY);
|
||||
#else
|
||||
_fmode = _O_BINARY;
|
||||
#endif
|
||||
|
||||
/* Disable stdio output buffering. */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
|
4
deps/uv/test/task.h
vendored
4
deps/uv/test/task.h
vendored
@ -44,6 +44,10 @@
|
||||
# pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
#endif
|
||||
|
||||
#define TEST_PORT 9123
|
||||
#define TEST_PORT_2 9124
|
||||
|
||||
|
37
deps/uv/test/test-env-vars.c
vendored
37
deps/uv/test/test-env-vars.c
vendored
@ -27,9 +27,11 @@
|
||||
|
||||
TEST_IMPL(env_vars) {
|
||||
const char* name = "UV_TEST_FOO";
|
||||
const char* name2 = "UV_TEST_FOO2";
|
||||
char buf[BUF_SIZE];
|
||||
size_t size;
|
||||
int r;
|
||||
int i, r, envcount, found;
|
||||
uv_env_item_t* envitems;
|
||||
|
||||
/* Reject invalid inputs when setting an environment variable */
|
||||
r = uv_os_setenv(NULL, "foo");
|
||||
@ -86,5 +88,38 @@ TEST_IMPL(env_vars) {
|
||||
r = uv_os_unsetenv(name);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Check getting all env variables. */
|
||||
r = uv_os_setenv(name, "123456789");
|
||||
ASSERT(r == 0);
|
||||
r = uv_os_setenv(name2, "");
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_os_environ(&envitems, &envcount);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(envcount > 0);
|
||||
|
||||
found = 0;
|
||||
|
||||
for (i = 0; i < envcount; i++) {
|
||||
/* printf("Env: %s = %s\n", envitems[i].name, envitems[i].value); */
|
||||
if (strcmp(envitems[i].name, name) == 0) {
|
||||
found++;
|
||||
ASSERT(strcmp(envitems[i].value, "123456789") == 0);
|
||||
} else if (strcmp(envitems[i].name, name2) == 0) {
|
||||
found++;
|
||||
ASSERT(strlen(envitems[i].value) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(found == 2);
|
||||
|
||||
uv_os_free_environ(envitems, envcount);
|
||||
|
||||
r = uv_os_unsetenv(name);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_os_unsetenv(name2);
|
||||
ASSERT(r == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
133
deps/uv/test/test-fs-fd-hash.c
vendored
Normal file
133
deps/uv/test/test-fs-fd-hash.c
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
/* Copyright libuv project 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.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "../src/win/fs-fd-hash-inl.h"
|
||||
|
||||
|
||||
#define HASH_MAX 1000000000
|
||||
#define HASH_INC (1000 * UV__FD_HASH_SIZE + 2)
|
||||
#define BUCKET_MAX (UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE * 10)
|
||||
#define BUCKET_INC UV__FD_HASH_SIZE
|
||||
#define FD_DIFF 9
|
||||
|
||||
|
||||
void assert_nonexistent(int fd) {
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
ASSERT(!uv__fd_hash_get(fd, &info));
|
||||
ASSERT(!uv__fd_hash_remove(fd, &info));
|
||||
}
|
||||
|
||||
void assert_existent(int fd) {
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
ASSERT(uv__fd_hash_get(fd, &info));
|
||||
ASSERT(info.flags == fd + FD_DIFF);
|
||||
}
|
||||
|
||||
void assert_insertion(int fd) {
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
assert_nonexistent(fd);
|
||||
info.flags = fd + FD_DIFF;
|
||||
uv__fd_hash_add(fd, &info);
|
||||
assert_existent(fd);
|
||||
}
|
||||
|
||||
void assert_removal(int fd) {
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
assert_existent(fd);
|
||||
uv__fd_hash_remove(fd, &info);
|
||||
ASSERT(info.flags == fd + FD_DIFF);
|
||||
assert_nonexistent(fd);
|
||||
}
|
||||
|
||||
|
||||
/* Run a function for a set of values up to a very high number */
|
||||
#define RUN_HASH(function) \
|
||||
do { \
|
||||
for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \
|
||||
function(fd); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Run a function for a set of values that will cause many collisions */
|
||||
#define RUN_COLLISIONS(function) \
|
||||
do { \
|
||||
for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \
|
||||
function(fd); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
TEST_IMPL(fs_fd_hash) {
|
||||
int fd;
|
||||
|
||||
uv__fd_hash_init();
|
||||
|
||||
/* Empty table */
|
||||
RUN_HASH(assert_nonexistent);
|
||||
RUN_COLLISIONS(assert_nonexistent);
|
||||
|
||||
/* Fill up */
|
||||
RUN_HASH(assert_insertion);
|
||||
RUN_COLLISIONS(assert_insertion);
|
||||
|
||||
/* Full */
|
||||
RUN_HASH(assert_existent);
|
||||
RUN_COLLISIONS(assert_existent);
|
||||
|
||||
/* Update */
|
||||
{
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
info.flags = FD_DIFF + FD_DIFF;
|
||||
uv__fd_hash_add(0, &info);
|
||||
}
|
||||
{
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
ASSERT(uv__fd_hash_get(0, &info));
|
||||
ASSERT(info.flags == FD_DIFF + FD_DIFF);
|
||||
}
|
||||
{
|
||||
/* Leave as it was, will be again tested below */
|
||||
struct uv__fd_info_s info = { 0 };
|
||||
info.flags = FD_DIFF;
|
||||
uv__fd_hash_add(0, &info);
|
||||
}
|
||||
|
||||
/* Remove all */
|
||||
RUN_HASH(assert_removal);
|
||||
RUN_COLLISIONS(assert_removal);
|
||||
|
||||
/* Empty table */
|
||||
RUN_HASH(assert_nonexistent);
|
||||
RUN_COLLISIONS(assert_nonexistent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */
|
||||
|
||||
#endif /* ifndef _WIN32 */
|
435
deps/uv/test/test-fs-open-flags.c
vendored
Normal file
435
deps/uv/test/test-fs-open-flags.c
vendored
Normal file
@ -0,0 +1,435 @@
|
||||
/* Copyright libuv project 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.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#if defined(__unix__) || defined(__POSIX__) || \
|
||||
defined(__APPLE__) || defined(__sun) || \
|
||||
defined(_AIX) || defined(__MVS__) || \
|
||||
defined(__HAIKU__)
|
||||
# include <unistd.h> /* unlink, rmdir */
|
||||
#else
|
||||
# include <direct.h>
|
||||
# define rmdir _rmdir
|
||||
# define unlink _unlink
|
||||
#endif
|
||||
|
||||
static int flags;
|
||||
|
||||
static uv_fs_t close_req;
|
||||
static uv_fs_t mkdir_req;
|
||||
static uv_fs_t open_req;
|
||||
static uv_fs_t read_req;
|
||||
static uv_fs_t rmdir_req;
|
||||
static uv_fs_t unlink_req;
|
||||
static uv_fs_t write_req;
|
||||
|
||||
static char buf[32];
|
||||
static uv_buf_t iov;
|
||||
|
||||
/* Opening the same file multiple times quickly can cause uv_fs_open to fail
|
||||
* with EBUSY, so append an identifier to the file name for each operation */
|
||||
static int sid = 0;
|
||||
|
||||
#define FILE_NAME_SIZE 128
|
||||
static char absent_file[FILE_NAME_SIZE];
|
||||
static char empty_file[FILE_NAME_SIZE];
|
||||
static char dummy_file[FILE_NAME_SIZE];
|
||||
static char empty_dir[] = "empty_dir";
|
||||
|
||||
static void setup() {
|
||||
int r;
|
||||
|
||||
/* empty_dir */
|
||||
r = uv_fs_rmdir(NULL, &rmdir_req, empty_dir, NULL);
|
||||
ASSERT(r == 0 || r == UV_ENOENT);
|
||||
ASSERT(rmdir_req.result == 0 || rmdir_req.result == UV_ENOENT);
|
||||
uv_fs_req_cleanup(&rmdir_req);
|
||||
|
||||
r = uv_fs_mkdir(NULL, &mkdir_req, empty_dir, 0755, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(mkdir_req.result == 0);
|
||||
uv_fs_req_cleanup(&mkdir_req);
|
||||
}
|
||||
|
||||
static void refresh() {
|
||||
int r;
|
||||
|
||||
/* absent_file */
|
||||
sprintf(absent_file, "test_file_%d", sid++);
|
||||
|
||||
r = uv_fs_unlink(NULL, &unlink_req, absent_file, NULL);
|
||||
ASSERT(r == 0 || r == UV_ENOENT);
|
||||
ASSERT(unlink_req.result == 0 || unlink_req.result == UV_ENOENT);
|
||||
uv_fs_req_cleanup(&unlink_req);
|
||||
|
||||
/* empty_file */
|
||||
sprintf(empty_file, "test_file_%d", sid++);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req, empty_file,
|
||||
UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* dummy_file */
|
||||
sprintf(dummy_file, "test_file_%d", sid++);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req, dummy_file,
|
||||
UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req);
|
||||
|
||||
iov = uv_buf_init("a", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 1);
|
||||
ASSERT(write_req.result == 1);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
}
|
||||
|
||||
static void cleanup() {
|
||||
unlink(absent_file);
|
||||
unlink(empty_file);
|
||||
unlink(dummy_file);
|
||||
}
|
||||
|
||||
static void openFail(char *file, int error) {
|
||||
int r;
|
||||
|
||||
refresh();
|
||||
|
||||
r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r == error);
|
||||
ASSERT(open_req.result == error);
|
||||
uv_fs_req_cleanup(&open_req);
|
||||
|
||||
/* Ensure the first call does not create the file */
|
||||
r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r == error);
|
||||
ASSERT(open_req.result == error);
|
||||
uv_fs_req_cleanup(&open_req);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
static void refreshOpen(char *file) {
|
||||
int r;
|
||||
|
||||
refresh();
|
||||
|
||||
r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req);
|
||||
}
|
||||
|
||||
static void writeExpect(char *file, char *expected, int size) {
|
||||
int r;
|
||||
|
||||
refreshOpen(file);
|
||||
|
||||
iov = uv_buf_init("b", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 1);
|
||||
ASSERT(write_req.result == 1);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
iov = uv_buf_init("c", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 1);
|
||||
ASSERT(write_req.result == 1);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* Check contents */
|
||||
r = uv_fs_open(NULL, &open_req, file, UV_FS_O_RDONLY, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == size);
|
||||
ASSERT(read_req.result == size);
|
||||
ASSERT(strncmp(buf, expected, size) == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
static void writeFail(char *file, int error) {
|
||||
int r;
|
||||
|
||||
refreshOpen(file);
|
||||
|
||||
iov = uv_buf_init("z", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == error);
|
||||
ASSERT(write_req.result == error);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
iov = uv_buf_init("z", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == error);
|
||||
ASSERT(write_req.result == error);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
static void readExpect(char *file, char *expected, int size) {
|
||||
int r;
|
||||
|
||||
refreshOpen(file);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == size);
|
||||
ASSERT(read_req.result == size);
|
||||
ASSERT(strncmp(buf, expected, size) == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
static void readFail(char *file, int error) {
|
||||
int r;
|
||||
|
||||
refreshOpen(file);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == error);
|
||||
ASSERT(read_req.result == error);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == error);
|
||||
ASSERT(read_req.result == error);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
static void fs_open_flags(int add_flags) {
|
||||
/* Follow the order from
|
||||
* https://github.com/nodejs/node/blob/1a96abe849/lib/internal/fs/utils.js#L329-L354
|
||||
*/
|
||||
|
||||
/* r */
|
||||
flags = add_flags | UV_FS_O_RDONLY;
|
||||
openFail(absent_file, UV_ENOENT);
|
||||
writeFail(empty_file, UV_EPERM);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeFail(dummy_file, UV_EPERM);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EPERM);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* rs */
|
||||
flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC;
|
||||
openFail(absent_file, UV_ENOENT);
|
||||
writeFail(empty_file, UV_EPERM);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeFail(dummy_file, UV_EPERM);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EPERM);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* r+ */
|
||||
flags = add_flags | UV_FS_O_RDWR;
|
||||
openFail(absent_file, UV_ENOENT);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeExpect(dummy_file, "bc", 2);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* rs+ */
|
||||
flags = add_flags | UV_FS_O_RDWR | UV_FS_O_SYNC;
|
||||
openFail(absent_file, UV_ENOENT);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeExpect(dummy_file, "bc", 2);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* w */
|
||||
flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readFail(empty_file, UV_EPERM);
|
||||
writeExpect(dummy_file, "bc", 2);
|
||||
readFail(dummy_file, UV_EPERM);
|
||||
openFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* wx */
|
||||
flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY |
|
||||
UV_FS_O_EXCL;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
openFail(empty_file, UV_EEXIST);
|
||||
openFail(dummy_file, UV_EEXIST);
|
||||
openFail(empty_dir, UV_EEXIST);
|
||||
|
||||
/* w+ */
|
||||
flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readExpect(absent_file, "", 0);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeExpect(dummy_file, "bc", 2);
|
||||
readExpect(dummy_file, "", 0);
|
||||
openFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* wx+ */
|
||||
flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR |
|
||||
UV_FS_O_EXCL;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readExpect(absent_file, "", 0);
|
||||
openFail(empty_file, UV_EEXIST);
|
||||
openFail(dummy_file, UV_EEXIST);
|
||||
openFail(empty_dir, UV_EEXIST);
|
||||
|
||||
/* a */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readFail(empty_file, UV_EPERM);
|
||||
writeExpect(dummy_file, "abc", 3);
|
||||
readFail(dummy_file, UV_EPERM);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EPERM);
|
||||
|
||||
/* ax */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY |
|
||||
UV_FS_O_EXCL;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
openFail(empty_file, UV_EEXIST);
|
||||
openFail(dummy_file, UV_EEXIST);
|
||||
openFail(empty_dir, UV_EEXIST);
|
||||
|
||||
/* as */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY |
|
||||
UV_FS_O_SYNC;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readFail(empty_file, UV_EPERM);
|
||||
writeExpect(dummy_file, "abc", 3);
|
||||
readFail(dummy_file, UV_EPERM);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EPERM);
|
||||
|
||||
/* a+ */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readExpect(absent_file, "", 0);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeExpect(dummy_file, "abc", 3);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* ax+ */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR |
|
||||
UV_FS_O_EXCL;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readExpect(absent_file, "", 0);
|
||||
openFail(empty_file, UV_EEXIST);
|
||||
openFail(dummy_file, UV_EEXIST);
|
||||
openFail(empty_dir, UV_EEXIST);
|
||||
|
||||
/* as+ */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR |
|
||||
UV_FS_O_SYNC;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readExpect(absent_file, "", 0);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeExpect(dummy_file, "abc", 3);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
}
|
||||
TEST_IMPL(fs_open_flags) {
|
||||
setup();
|
||||
|
||||
fs_open_flags(0);
|
||||
fs_open_flags(UV_FS_O_FILEMAP);
|
||||
|
||||
/* Cleanup. */
|
||||
rmdir(empty_dir);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */
|
||||
|
||||
#endif /* ifndef _WIN32 */
|
332
deps/uv/test/test-fs.c
vendored
332
deps/uv/test/test-fs.c
vendored
@ -94,6 +94,7 @@ static int readlink_cb_count;
|
||||
static int realpath_cb_count;
|
||||
static int utime_cb_count;
|
||||
static int futime_cb_count;
|
||||
static int statfs_cb_count;
|
||||
|
||||
static uv_loop_t* loop;
|
||||
|
||||
@ -330,6 +331,38 @@ static void fstat_cb(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
static void statfs_cb(uv_fs_t* req) {
|
||||
uv_statfs_t* stats;
|
||||
|
||||
ASSERT(req->fs_type == UV_FS_STATFS);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(req->ptr != NULL);
|
||||
stats = req->ptr;
|
||||
|
||||
#if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__)
|
||||
ASSERT(stats->f_type == 0);
|
||||
#else
|
||||
ASSERT(stats->f_type > 0);
|
||||
#endif
|
||||
|
||||
ASSERT(stats->f_bsize > 0);
|
||||
ASSERT(stats->f_blocks > 0);
|
||||
ASSERT(stats->f_bfree <= stats->f_blocks);
|
||||
ASSERT(stats->f_bavail <= stats->f_bfree);
|
||||
|
||||
#ifdef _WIN32
|
||||
ASSERT(stats->f_files == 0);
|
||||
ASSERT(stats->f_ffree == 0);
|
||||
#else
|
||||
ASSERT(stats->f_files > 0);
|
||||
ASSERT(stats->f_ffree <= stats->f_files);
|
||||
#endif
|
||||
uv_fs_req_cleanup(req);
|
||||
ASSERT(req->ptr == NULL);
|
||||
statfs_cb_count++;
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_fs_t* req) {
|
||||
int r;
|
||||
ASSERT(req == &close_req);
|
||||
@ -847,7 +880,7 @@ TEST_IMPL(fs_file_async) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_file_sync) {
|
||||
static void fs_file_sync(int add_flags) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@ -856,8 +889,8 @@ TEST_IMPL(fs_file_sync) {
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
r = uv_fs_open(loop, &open_req1, "test_file",
|
||||
O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -873,7 +906,7 @@ TEST_IMPL(fs_file_sync) {
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR, 0, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR | add_flags, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -900,7 +933,8 @@ TEST_IMPL(fs_file_sync) {
|
||||
ASSERT(rename_req.result == 0);
|
||||
uv_fs_req_cleanup(&rename_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY, 0, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY | add_flags, 0,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -926,13 +960,17 @@ TEST_IMPL(fs_file_sync) {
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
unlink("test_file2");
|
||||
}
|
||||
TEST_IMPL(fs_file_sync) {
|
||||
fs_file_sync(0);
|
||||
fs_file_sync(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_file_write_null_buffer) {
|
||||
static void fs_file_write_null_buffer(int add_flags) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@ -940,8 +978,8 @@ TEST_IMPL(fs_file_write_null_buffer) {
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file",
|
||||
O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -958,6 +996,10 @@ TEST_IMPL(fs_file_write_null_buffer) {
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_file_write_null_buffer) {
|
||||
fs_file_write_null_buffer(0);
|
||||
fs_file_write_null_buffer(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
@ -1470,7 +1512,7 @@ TEST_IMPL(fs_chmod) {
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(fchmod_cb_count == 1);
|
||||
|
||||
close(file);
|
||||
uv_fs_close(loop, &req, file, NULL);
|
||||
|
||||
/*
|
||||
* Run the loop just to check we don't have make any extraneous uv_ref()
|
||||
@ -1513,7 +1555,7 @@ TEST_IMPL(fs_unlink_readonly) {
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
close(file);
|
||||
uv_fs_close(loop, &req, file, NULL);
|
||||
|
||||
/* Make the file read-only */
|
||||
r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL);
|
||||
@ -1572,7 +1614,7 @@ TEST_IMPL(fs_unlink_archive_readonly) {
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
close(file);
|
||||
uv_fs_close(loop, &req, file, NULL);
|
||||
|
||||
/* Make the file read-only and clear archive flag */
|
||||
r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY);
|
||||
@ -1722,7 +1764,7 @@ TEST_IMPL(fs_link) {
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
close(file);
|
||||
uv_fs_close(loop, &req, file, NULL);
|
||||
|
||||
/* sync link */
|
||||
r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL);
|
||||
@ -1764,7 +1806,7 @@ TEST_IMPL(fs_link) {
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
|
||||
close(link);
|
||||
uv_fs_close(loop, &req, link, NULL);
|
||||
|
||||
/*
|
||||
* Run the loop just to check we don't have make any extraneous uv_ref()
|
||||
@ -1871,7 +1913,7 @@ TEST_IMPL(fs_symlink) {
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
close(file);
|
||||
uv_fs_close(loop, &req, file, NULL);
|
||||
|
||||
/* sync symlink */
|
||||
r = uv_fs_symlink(NULL, &req, "test_file", "test_file_symlink", 0, NULL);
|
||||
@ -1909,7 +1951,7 @@ TEST_IMPL(fs_symlink) {
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
|
||||
close(link);
|
||||
uv_fs_close(loop, &req, link, NULL);
|
||||
|
||||
r = uv_fs_symlink(NULL,
|
||||
&req,
|
||||
@ -1971,7 +2013,7 @@ TEST_IMPL(fs_symlink) {
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
|
||||
close(link);
|
||||
uv_fs_close(loop, &req, link, NULL);
|
||||
|
||||
r = uv_fs_symlink(NULL,
|
||||
&req,
|
||||
@ -2293,7 +2335,7 @@ TEST_IMPL(fs_utime) {
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
close(r);
|
||||
uv_fs_close(loop, &req, r, NULL);
|
||||
|
||||
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
|
||||
|
||||
@ -2388,7 +2430,7 @@ TEST_IMPL(fs_futime) {
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
close(r);
|
||||
uv_fs_close(loop, &req, r, NULL);
|
||||
|
||||
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
|
||||
|
||||
@ -2583,7 +2625,7 @@ TEST_IMPL(fs_open_dir) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_file_open_append) {
|
||||
static void fs_file_open_append(int add_flags) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@ -2591,8 +2633,8 @@ TEST_IMPL(fs_file_open_append) {
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file",
|
||||
O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2608,7 +2650,8 @@ TEST_IMPL(fs_file_open_append) {
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR | O_APPEND, 0, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file",
|
||||
O_RDWR | O_APPEND | add_flags, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2624,7 +2667,8 @@ TEST_IMPL(fs_file_open_append) {
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, S_IRUSR, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags,
|
||||
S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2646,6 +2690,10 @@ TEST_IMPL(fs_file_open_append) {
|
||||
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_file_open_append) {
|
||||
fs_file_open_append(0);
|
||||
fs_file_open_append(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
@ -2721,13 +2769,13 @@ TEST_IMPL(fs_rename_to_existing_file) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_read_bufs) {
|
||||
static void fs_read_bufs(int add_flags) {
|
||||
char scratch[768];
|
||||
uv_buf_t bufs[4];
|
||||
|
||||
ASSERT(0 <= uv_fs_open(NULL, &open_req1,
|
||||
"test/fixtures/lorem_ipsum.txt",
|
||||
O_RDONLY, 0, NULL));
|
||||
O_RDONLY | add_flags, 0, NULL));
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
@ -2769,13 +2817,17 @@ TEST_IMPL(fs_read_bufs) {
|
||||
ASSERT(0 == uv_fs_close(NULL, &close_req, open_req1.result, NULL));
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
}
|
||||
TEST_IMPL(fs_read_bufs) {
|
||||
fs_read_bufs(0);
|
||||
fs_read_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_read_file_eof) {
|
||||
static void fs_read_file_eof(int add_flags) {
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__)
|
||||
RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!");
|
||||
#endif
|
||||
@ -2786,8 +2838,8 @@ TEST_IMPL(fs_read_file_eof) {
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file",
|
||||
O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2803,7 +2855,8 @@ TEST_IMPL(fs_read_file_eof) {
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, 0,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2830,13 +2883,17 @@ TEST_IMPL(fs_read_file_eof) {
|
||||
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_read_file_eof) {
|
||||
fs_read_file_eof(0);
|
||||
fs_read_file_eof(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_write_multiple_bufs) {
|
||||
static void fs_write_multiple_bufs(int add_flags) {
|
||||
uv_buf_t iovs[2];
|
||||
int r;
|
||||
|
||||
@ -2845,8 +2902,8 @@ TEST_IMPL(fs_write_multiple_bufs) {
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file",
|
||||
O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2863,7 +2920,8 @@ TEST_IMPL(fs_write_multiple_bufs) {
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL);
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, 0,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
@ -2919,13 +2977,17 @@ TEST_IMPL(fs_write_multiple_bufs) {
|
||||
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_write_multiple_bufs) {
|
||||
fs_write_multiple_bufs(0);
|
||||
fs_write_multiple_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_write_alotof_bufs) {
|
||||
static void fs_write_alotof_bufs(int add_flags) {
|
||||
size_t iovcount;
|
||||
size_t iovmax;
|
||||
uv_buf_t* iovs;
|
||||
@ -2947,7 +3009,7 @@ TEST_IMPL(fs_write_alotof_bufs) {
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req1,
|
||||
"test_file",
|
||||
O_RDWR | O_CREAT,
|
||||
O_RDWR | O_CREAT | add_flags,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
@ -2976,7 +3038,17 @@ TEST_IMPL(fs_write_alotof_bufs) {
|
||||
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
|
||||
sizeof(test_buf));
|
||||
|
||||
ASSERT(lseek(open_req1.result, 0, SEEK_SET) == 0);
|
||||
r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, 0,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, iovcount, -1, NULL);
|
||||
if (iovcount > iovmax)
|
||||
iovcount = iovmax;
|
||||
@ -3012,13 +3084,17 @@ TEST_IMPL(fs_write_alotof_bufs) {
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
free(iovs);
|
||||
}
|
||||
TEST_IMPL(fs_write_alotof_bufs) {
|
||||
fs_write_alotof_bufs(0);
|
||||
fs_write_alotof_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
static void fs_write_alotof_bufs_with_offset(int add_flags) {
|
||||
size_t iovcount;
|
||||
size_t iovmax;
|
||||
uv_buf_t* iovs;
|
||||
@ -3045,7 +3121,7 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req1,
|
||||
"test_file",
|
||||
O_RDWR | O_CREAT,
|
||||
O_RDWR | O_CREAT | add_flags,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
@ -3124,6 +3200,10 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
free(iovs);
|
||||
}
|
||||
TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
fs_write_alotof_bufs_with_offset(0);
|
||||
fs_write_alotof_bufs_with_offset(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
@ -3539,6 +3619,146 @@ TEST_IMPL(fs_file_pos_after_op_with_offset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void fs_file_pos_common() {
|
||||
int r;
|
||||
|
||||
iov = uv_buf_init("abc", 3);
|
||||
r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 3);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
/* Read with offset should not change the position */
|
||||
iov = uv_buf_init(buf, 1);
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 1, NULL);
|
||||
ASSERT(r == 1);
|
||||
ASSERT(buf[0] == 'b');
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
/* Write without offset should change the position */
|
||||
iov = uv_buf_init("d", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 1);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
}
|
||||
|
||||
static void fs_file_pos_close_check(const char *contents, int size) {
|
||||
int r;
|
||||
|
||||
/* Close */
|
||||
r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* Confirm file contents */
|
||||
r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == size);
|
||||
ASSERT(strncmp(buf, contents, size) == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
|
||||
static void fs_file_pos_write(int add_flags) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req1,
|
||||
"test_file",
|
||||
O_TRUNC | O_CREAT | O_RDWR | add_flags,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r > 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
fs_file_pos_common();
|
||||
|
||||
/* Write with offset should not change the position */
|
||||
iov = uv_buf_init("e", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 1, NULL);
|
||||
ASSERT(r == 1);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
fs_file_pos_close_check("aecd", 4);
|
||||
}
|
||||
TEST_IMPL(fs_file_pos_write) {
|
||||
fs_file_pos_write(0);
|
||||
fs_file_pos_write(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fs_file_pos_append(int add_flags) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
&open_req1,
|
||||
"test_file",
|
||||
O_APPEND | O_CREAT | O_RDWR | add_flags,
|
||||
S_IWUSR | S_IRUSR,
|
||||
NULL);
|
||||
ASSERT(r > 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
fs_file_pos_common();
|
||||
|
||||
/* Write with offset appends (ignoring offset)
|
||||
* but does not change the position */
|
||||
iov = uv_buf_init("e", 1);
|
||||
r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 1, NULL);
|
||||
ASSERT(r == 1);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 1);
|
||||
ASSERT(buf[0] == 'e');
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
fs_file_pos_close_check("abcde", 5);
|
||||
}
|
||||
TEST_IMPL(fs_file_pos_append) {
|
||||
fs_file_pos_append(0);
|
||||
fs_file_pos_append(UV_FS_O_FILEMAP);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_IMPL(fs_null_req) {
|
||||
/* Verify that all fs functions return UV_EINVAL when the request is NULL. */
|
||||
int r;
|
||||
@ -3630,6 +3850,9 @@ TEST_IMPL(fs_null_req) {
|
||||
r = uv_fs_futime(NULL, NULL, 0, 0.0, 0.0, NULL);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
|
||||
r = uv_fs_statfs(NULL, NULL, NULL, NULL);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
|
||||
/* This should be a no-op. */
|
||||
uv_fs_req_cleanup(NULL);
|
||||
|
||||
@ -3873,4 +4096,37 @@ TEST_IMPL(fs_fchmod_archive_readonly) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_invalid_mkdir_name) {
|
||||
uv_loop_t* loop;
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
|
||||
loop = uv_default_loop();
|
||||
r = uv_fs_mkdir(loop, &req, "invalid>", 0, NULL);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_IMPL(fs_statfs) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
/* Test the synchronous version. */
|
||||
r = uv_fs_statfs(NULL, &req, ".", NULL);
|
||||
ASSERT(r == 0);
|
||||
statfs_cb(&req);
|
||||
ASSERT(statfs_cb_count == 1);
|
||||
|
||||
/* Test the asynchronous version. */
|
||||
r = uv_fs_statfs(loop, &req, ".", statfs_cb);
|
||||
ASSERT(r == 0);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(statfs_cb_count == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
4
deps/uv/test/test-ipc.c
vendored
4
deps/uv/test/test-ipc.c
vendored
@ -838,10 +838,10 @@ static unsigned int write_until_data_queued() {
|
||||
closed_handle_large_write_cb);
|
||||
ASSERT(r == 0);
|
||||
i++;
|
||||
} while (((uv_stream_t*)&channel)->write_queue_size == 0 &&
|
||||
} while (channel.write_queue_size == 0 &&
|
||||
i < ARRAY_SIZE(write_reqs));
|
||||
|
||||
return ((uv_stream_t*)&channel)->write_queue_size;
|
||||
return channel.write_queue_size;
|
||||
}
|
||||
|
||||
static void send_handle_and_close() {
|
||||
|
18
deps/uv/test/test-list.h
vendored
18
deps/uv/test/test-list.h
vendored
@ -264,6 +264,7 @@ TEST_DECLARE (spawn_fails)
|
||||
#ifndef _WIN32
|
||||
TEST_DECLARE (spawn_fails_check_for_waitpid_cleanup)
|
||||
#endif
|
||||
TEST_DECLARE (spawn_empty_env)
|
||||
TEST_DECLARE (spawn_exit_code)
|
||||
TEST_DECLARE (spawn_stdout)
|
||||
TEST_DECLARE (spawn_stdin)
|
||||
@ -321,10 +322,15 @@ TEST_DECLARE (fs_symlink_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_symlink_junction)
|
||||
TEST_DECLARE (fs_non_symlink_reparse_point)
|
||||
TEST_DECLARE (fs_open_flags)
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
TEST_DECLARE (fs_fd_hash)
|
||||
#endif
|
||||
TEST_DECLARE (fs_utime)
|
||||
TEST_DECLARE (fs_futime)
|
||||
TEST_DECLARE (fs_file_open_append)
|
||||
TEST_DECLARE (fs_statfs)
|
||||
TEST_DECLARE (fs_stat_missing_path)
|
||||
TEST_DECLARE (fs_read_bufs)
|
||||
TEST_DECLARE (fs_read_file_eof)
|
||||
@ -370,10 +376,13 @@ TEST_DECLARE (fs_file_pos_after_op_with_offset)
|
||||
TEST_DECLARE (fs_null_req)
|
||||
TEST_DECLARE (fs_read_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_file_pos_write)
|
||||
TEST_DECLARE (fs_file_pos_append)
|
||||
TEST_DECLARE (fs_exclusive_sharing_mode)
|
||||
TEST_DECLARE (fs_file_flag_no_buffering)
|
||||
TEST_DECLARE (fs_open_readonly_acl)
|
||||
TEST_DECLARE (fs_fchmod_archive_readonly)
|
||||
TEST_DECLARE (fs_invalid_mkdir_name)
|
||||
#endif
|
||||
TEST_DECLARE (strscpy)
|
||||
TEST_DECLARE (threadpool_queue_work_simple)
|
||||
@ -821,6 +830,7 @@ TASK_LIST_START
|
||||
#ifndef _WIN32
|
||||
TEST_ENTRY (spawn_fails_check_for_waitpid_cleanup)
|
||||
#endif
|
||||
TEST_ENTRY (spawn_empty_env)
|
||||
TEST_ENTRY (spawn_exit_code)
|
||||
TEST_ENTRY (spawn_stdout)
|
||||
TEST_ENTRY (spawn_stdin)
|
||||
@ -912,7 +922,12 @@ TASK_LIST_START
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_symlink_junction)
|
||||
TEST_ENTRY (fs_non_symlink_reparse_point)
|
||||
TEST_ENTRY (fs_open_flags)
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
TEST_ENTRY (fs_fd_hash)
|
||||
#endif
|
||||
TEST_ENTRY (fs_statfs)
|
||||
TEST_ENTRY (fs_stat_missing_path)
|
||||
TEST_ENTRY (fs_read_bufs)
|
||||
TEST_ENTRY (fs_read_file_eof)
|
||||
@ -957,10 +972,13 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_null_req)
|
||||
TEST_ENTRY (fs_read_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_file_pos_write)
|
||||
TEST_ENTRY (fs_file_pos_append)
|
||||
TEST_ENTRY (fs_exclusive_sharing_mode)
|
||||
TEST_ENTRY (fs_file_flag_no_buffering)
|
||||
TEST_ENTRY (fs_open_readonly_acl)
|
||||
TEST_ENTRY (fs_fchmod_archive_readonly)
|
||||
TEST_ENTRY (fs_invalid_mkdir_name)
|
||||
#endif
|
||||
TEST_ENTRY (get_osfhandle_valid_handle)
|
||||
TEST_ENTRY (open_osfhandle_valid_handle)
|
||||
|
2
deps/uv/test/test-pipe-getsockname.c
vendored
2
deps/uv/test/test-pipe-getsockname.c
vendored
@ -171,7 +171,7 @@ TEST_IMPL(pipe_getsockname_abstract) {
|
||||
socklen_t sun_len;
|
||||
char abstract_pipe[] = "\0test-pipe";
|
||||
|
||||
sock = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
ASSERT(sock != -1);
|
||||
|
||||
sun_len = sizeof sun;
|
||||
|
6
deps/uv/test/test-process-title-threadsafe.c
vendored
6
deps/uv/test/test-process-title-threadsafe.c
vendored
@ -25,7 +25,11 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define NUM_ITERATIONS 50
|
||||
#ifdef __APPLE__
|
||||
# define NUM_ITERATIONS 10
|
||||
#else
|
||||
# define NUM_ITERATIONS 50
|
||||
#endif
|
||||
|
||||
static const char* titles[] = {
|
||||
"8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled",
|
||||
|
26
deps/uv/test/test-queue-foreach-delete.c
vendored
26
deps/uv/test/test-queue-foreach-delete.c
vendored
@ -65,11 +65,11 @@ static const unsigned first_handle_number_fs_event = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#define DEFINE_GLOBALS_AND_CBS(name) \
|
||||
#define DEFINE_GLOBALS_AND_CBS(name, ...) \
|
||||
static uv_##name##_t (name)[3]; \
|
||||
static unsigned name##_cb_calls[3]; \
|
||||
\
|
||||
static void name##2_cb(uv_##name##_t* handle) { \
|
||||
static void name##2_cb(__VA_ARGS__) { \
|
||||
ASSERT(handle == &(name)[2]); \
|
||||
if (first_handle_number_##name == 2) { \
|
||||
uv_close((uv_handle_t*)&(name)[2], NULL); \
|
||||
@ -78,12 +78,12 @@ static const unsigned first_handle_number_fs_event = 0;
|
||||
name##_cb_calls[2]++; \
|
||||
} \
|
||||
\
|
||||
static void name##1_cb(uv_##name##_t* handle) { \
|
||||
static void name##1_cb(__VA_ARGS__) { \
|
||||
ASSERT(handle == &(name)[1]); \
|
||||
ASSERT(0 && "Shouldn't be called" && (&name[0])); \
|
||||
} \
|
||||
\
|
||||
static void name##0_cb(uv_##name##_t* handle) { \
|
||||
static void name##0_cb(__VA_ARGS__) { \
|
||||
ASSERT(handle == &(name)[0]); \
|
||||
if (first_handle_number_##name == 0) { \
|
||||
uv_close((uv_handle_t*)&(name)[0], NULL); \
|
||||
@ -93,9 +93,9 @@ static const unsigned first_handle_number_fs_event = 0;
|
||||
} \
|
||||
\
|
||||
static const uv_##name##_cb name##_cbs[] = { \
|
||||
(uv_##name##_cb)name##0_cb, \
|
||||
(uv_##name##_cb)name##1_cb, \
|
||||
(uv_##name##_cb)name##2_cb, \
|
||||
name##0_cb, \
|
||||
name##1_cb, \
|
||||
name##2_cb, \
|
||||
};
|
||||
|
||||
#define INIT_AND_START(name, loop) \
|
||||
@ -118,12 +118,16 @@ static const unsigned first_handle_number_fs_event = 0;
|
||||
ASSERT(name##_cb_calls[2] == 1); \
|
||||
} while (0)
|
||||
|
||||
DEFINE_GLOBALS_AND_CBS(idle)
|
||||
DEFINE_GLOBALS_AND_CBS(prepare)
|
||||
DEFINE_GLOBALS_AND_CBS(check)
|
||||
DEFINE_GLOBALS_AND_CBS(idle, uv_idle_t* handle)
|
||||
DEFINE_GLOBALS_AND_CBS(prepare, uv_prepare_t* handle)
|
||||
DEFINE_GLOBALS_AND_CBS(check, uv_check_t* handle)
|
||||
|
||||
#ifdef __linux__
|
||||
DEFINE_GLOBALS_AND_CBS(fs_event)
|
||||
DEFINE_GLOBALS_AND_CBS(fs_event,
|
||||
uv_fs_event_t* handle,
|
||||
const char* filename,
|
||||
int events,
|
||||
int status)
|
||||
|
||||
static const char watched_dir[] = ".";
|
||||
static uv_timer_t timer;
|
||||
|
28
deps/uv/test/test-spawn.c
vendored
28
deps/uv/test/test-spawn.c
vendored
@ -232,6 +232,34 @@ TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) {
|
||||
#endif
|
||||
|
||||
|
||||
TEST_IMPL(spawn_empty_env) {
|
||||
char* env[1];
|
||||
|
||||
/* The autotools dynamic library build requires the presence of
|
||||
* DYLD_LIBARY_PATH (macOS) or LD_LIBRARY_PATH (other Unices)
|
||||
* in the environment, but of course that doesn't work with
|
||||
* the empty environment that we're testing here.
|
||||
*/
|
||||
if (NULL != getenv("DYLD_LIBARY_PATH") ||
|
||||
NULL != getenv("LD_LIBRARY_PATH")) {
|
||||
RETURN_SKIP("doesn't work with DYLD_LIBRARY_PATH/LD_LIBRARY_PATH");
|
||||
}
|
||||
|
||||
init_process_options("spawn_helper1", exit_cb);
|
||||
options.env = env;
|
||||
env[0] = NULL;
|
||||
|
||||
ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||
|
||||
ASSERT(exit_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(spawn_exit_code) {
|
||||
int r;
|
||||
|
||||
|
11
deps/uv/test/test-tmpdir.c
vendored
11
deps/uv/test/test-tmpdir.c
vendored
@ -67,5 +67,16 @@ TEST_IMPL(tmpdir) {
|
||||
r = uv_os_tmpdir(tmpdir, &len);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
|
||||
#ifdef _WIN32
|
||||
const char *name = "TMP";
|
||||
char tmpdir_win[] = "C:\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
r = uv_os_setenv(name, tmpdir_win);
|
||||
ASSERT(r == 0);
|
||||
char tmpdirx[PATHMAX];
|
||||
size_t lenx = sizeof tmpdirx;
|
||||
r = uv_os_tmpdir(tmpdirx, &lenx);
|
||||
ASSERT(r == 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
2
deps/uv/test/test.gyp
vendored
2
deps/uv/test/test.gyp
vendored
@ -35,6 +35,8 @@
|
||||
'test-fs-readdir.c',
|
||||
'test-fs-copyfile.c',
|
||||
'test-fs-event.c',
|
||||
'test-fs-fd-hash.c',
|
||||
'test-fs-open-flags.c',
|
||||
'test-fs-poll.c',
|
||||
'test-getters-setters.c',
|
||||
'test-get-currentexe.c',
|
||||
|
Loading…
x
Reference in New Issue
Block a user