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:
cjihrig 2019-08-09 11:03:55 -04:00
parent 8ef68e66d0
commit ce7f3ed13c
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
42 changed files with 2138 additions and 152 deletions

1
deps/uv/.gitignore vendored
View File

@ -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
View File

@ -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
View File

@ -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>

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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*], [

View File

@ -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.

View File

@ -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
View File

@ -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 {

View File

@ -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

View File

@ -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 ""

View File

@ -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

View File

@ -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;

View File

@ -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
View File

@ -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;
}

View File

@ -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);

View File

@ -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
}

View File

@ -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;
}

View File

@ -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
View 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
View File

@ -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,
&sectors_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;
}

View File

@ -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
View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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
View File

@ -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

View File

@ -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
View 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
View 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
View File

@ -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;
}

View File

@ -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() {

View File

@ -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)

View File

@ -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;

View File

@ -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",

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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',