summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibuv/src/win
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibuv/src/win')
-rw-r--r--Utilities/cmlibuv/src/win/dl.c55
-rw-r--r--Utilities/cmlibuv/src/win/error.c2
-rw-r--r--Utilities/cmlibuv/src/win/fs.c581
-rw-r--r--Utilities/cmlibuv/src/win/getaddrinfo.c71
-rw-r--r--Utilities/cmlibuv/src/win/handle.c5
-rw-r--r--Utilities/cmlibuv/src/win/internal.h1
-rw-r--r--Utilities/cmlibuv/src/win/pipe.c137
-rw-r--r--Utilities/cmlibuv/src/win/process.c31
-rw-r--r--Utilities/cmlibuv/src/win/signal.c2
-rw-r--r--Utilities/cmlibuv/src/win/stream-inl.h3
-rw-r--r--Utilities/cmlibuv/src/win/tcp.c32
-rw-r--r--Utilities/cmlibuv/src/win/thread.c6
-rw-r--r--Utilities/cmlibuv/src/win/timer.c2
-rw-r--r--Utilities/cmlibuv/src/win/tty.c121
-rw-r--r--Utilities/cmlibuv/src/win/udp.c51
-rw-r--r--Utilities/cmlibuv/src/win/util.c11
-rw-r--r--Utilities/cmlibuv/src/win/winapi.c10
-rw-r--r--Utilities/cmlibuv/src/win/winapi.h26
-rw-r--r--Utilities/cmlibuv/src/win/winsock.c28
-rw-r--r--Utilities/cmlibuv/src/win/winsock.h3
20 files changed, 747 insertions, 431 deletions
diff --git a/Utilities/cmlibuv/src/win/dl.c b/Utilities/cmlibuv/src/win/dl.c
index 39e400a..97ac1c1 100644
--- a/Utilities/cmlibuv/src/win/dl.c
+++ b/Utilities/cmlibuv/src/win/dl.c
@@ -22,7 +22,7 @@
#include "uv.h"
#include "internal.h"
-static int uv__dlerror(uv_lib_t* lib, int errorno);
+static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno);
int uv_dlopen(const char* filename, uv_lib_t* lib) {
@@ -37,12 +37,12 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
-1,
filename_w,
ARRAY_SIZE(filename_w))) {
- return uv__dlerror(lib, GetLastError());
+ return uv__dlerror(lib, filename, GetLastError());
}
lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (lib->handle == NULL) {
- return uv__dlerror(lib, GetLastError());
+ return uv__dlerror(lib, filename, GetLastError());
}
return 0;
@@ -65,7 +65,7 @@ void uv_dlclose(uv_lib_t* lib) {
int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
*ptr = (void*) GetProcAddress(lib->handle, name);
- return uv__dlerror(lib, *ptr ? 0 : GetLastError());
+ return uv__dlerror(lib, "", *ptr ? 0 : GetLastError());
}
@@ -88,31 +88,46 @@ static void uv__format_fallback_error(uv_lib_t* lib, int errorno){
-static int uv__dlerror(uv_lib_t* lib, int errorno) {
+static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno) {
+ DWORD_PTR arg;
DWORD res;
+ char* msg;
if (lib->errmsg) {
- LocalFree((void*)lib->errmsg);
+ LocalFree(lib->errmsg);
lib->errmsg = NULL;
}
- if (errorno) {
+ if (errorno == 0)
+ return 0;
+
+ res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ (LPSTR) &lib->errmsg, 0, NULL);
+
+ if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- (LPSTR) &lib->errmsg, 0, NULL);
- if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
- res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
- 0, (LPSTR) &lib->errmsg, 0, NULL);
- }
-
- if (!res) {
- uv__format_fallback_error(lib, errorno);
- }
+ 0, (LPSTR) &lib->errmsg, 0, NULL);
+ }
+
+ if (res && errorno == ERROR_BAD_EXE_FORMAT && strstr(lib->errmsg, "%1")) {
+ msg = lib->errmsg;
+ lib->errmsg = NULL;
+ arg = (DWORD_PTR) filename;
+ res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_ARGUMENT_ARRAY |
+ FORMAT_MESSAGE_FROM_STRING,
+ msg,
+ 0, 0, (LPSTR) &lib->errmsg, 0, (va_list*) &arg);
+ LocalFree(msg);
}
- return errorno ? -1 : 0;
+ if (!res)
+ uv__format_fallback_error(lib, errorno);
+
+ return -1;
}
diff --git a/Utilities/cmlibuv/src/win/error.c b/Utilities/cmlibuv/src/win/error.c
index 642d111..9b03bfe 100644
--- a/Utilities/cmlibuv/src/win/error.c
+++ b/Utilities/cmlibuv/src/win/error.c
@@ -58,7 +58,7 @@ void uv_fatal_error(const int errorno, const char* syscall) {
LocalFree(buf);
}
- *((char*)NULL) = 0xff; /* Force debug break */
+ DebugBreak();
abort();
}
diff --git a/Utilities/cmlibuv/src/win/fs.c b/Utilities/cmlibuv/src/win/fs.c
index 2d72cdc..097b00e 100644
--- a/Utilities/cmlibuv/src/win/fs.c
+++ b/Utilities/cmlibuv/src/win/fs.c
@@ -43,11 +43,26 @@
#define UV_FS_CLEANEDUP 0x0010
-#define QUEUE_FS_TP_JOB(loop, req) \
- do { \
- uv__req_register(loop, req); \
- uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
- } while (0)
+#define INIT(subtype) \
+ do { \
+ if (req == NULL) \
+ return UV_EINVAL; \
+ uv_fs_req_init(loop, req, subtype, cb); \
+ } \
+ while (0)
+
+#define POST \
+ do { \
+ if (cb != NULL) { \
+ uv__req_register(loop, req); \
+ uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
+ return 0; \
+ } else { \
+ uv__fs_work(&req->work_req); \
+ return req->result; \
+ } \
+ } \
+ while (0)
#define SET_REQ_RESULT(req, result_value) \
do { \
@@ -113,6 +128,7 @@ const WCHAR LONG_PATH_PREFIX_LEN = 4;
const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
const WCHAR UNC_PATH_PREFIX_LEN = 8;
+static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
void uv_fs_init(void) {
_fmode = _O_BINARY;
@@ -220,6 +236,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
uv_fs_type fs_type, const uv_fs_cb cb) {
+ uv__once_init();
UV_REQ_INIT(req, UV_FS);
req->loop = loop;
req->flags = 0;
@@ -398,21 +415,21 @@ void fs__open(uv_fs_t* req) {
umask(current_umask);
/* convert flags and mode to CreateFile parameters */
- switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
- case _O_RDONLY:
+ switch (flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR)) {
+ case UV_FS_O_RDONLY:
access = FILE_GENERIC_READ;
break;
- case _O_WRONLY:
+ case UV_FS_O_WRONLY:
access = FILE_GENERIC_WRITE;
break;
- case _O_RDWR:
+ case UV_FS_O_RDWR:
access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
break;
default:
goto einval;
}
- if (flags & _O_APPEND) {
+ if (flags & UV_FS_O_APPEND) {
access &= ~FILE_WRITE_DATA;
access |= FILE_APPEND_DATA;
}
@@ -422,26 +439,33 @@ void fs__open(uv_fs_t* req) {
* 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.
+ * 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.
*/
- share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ if (flags & UV_FS_O_EXLOCK) {
+ share = 0;
+ } else {
+ share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ }
- switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
+ switch (flags & (UV_FS_O_CREAT | UV_FS_O_EXCL | UV_FS_O_TRUNC)) {
case 0:
- case _O_EXCL:
+ case UV_FS_O_EXCL:
disposition = OPEN_EXISTING;
break;
- case _O_CREAT:
+ case UV_FS_O_CREAT:
disposition = OPEN_ALWAYS;
break;
- case _O_CREAT | _O_EXCL:
- case _O_CREAT | _O_TRUNC | _O_EXCL:
+ case UV_FS_O_CREAT | UV_FS_O_EXCL:
+ case UV_FS_O_CREAT | UV_FS_O_TRUNC | UV_FS_O_EXCL:
disposition = CREATE_NEW;
break;
- case _O_TRUNC:
- case _O_TRUNC | _O_EXCL:
+ case UV_FS_O_TRUNC:
+ case UV_FS_O_TRUNC | UV_FS_O_EXCL:
disposition = TRUNCATE_EXISTING;
break;
- case _O_CREAT | _O_TRUNC:
+ case UV_FS_O_CREAT | UV_FS_O_TRUNC:
disposition = CREATE_ALWAYS;
break;
default:
@@ -449,34 +473,49 @@ void fs__open(uv_fs_t* req) {
}
attributes |= FILE_ATTRIBUTE_NORMAL;
- if (flags & _O_CREAT) {
+ if (flags & UV_FS_O_CREAT) {
if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
attributes |= FILE_ATTRIBUTE_READONLY;
}
}
- if (flags & _O_TEMPORARY ) {
+ if (flags & UV_FS_O_TEMPORARY ) {
attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
access |= DELETE;
}
- if (flags & _O_SHORT_LIVED) {
+ if (flags & UV_FS_O_SHORT_LIVED) {
attributes |= FILE_ATTRIBUTE_TEMPORARY;
}
- switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) {
+ switch (flags & (UV_FS_O_SEQUENTIAL | UV_FS_O_RANDOM)) {
case 0:
break;
- case _O_SEQUENTIAL:
+ case UV_FS_O_SEQUENTIAL:
attributes |= FILE_FLAG_SEQUENTIAL_SCAN;
break;
- case _O_RANDOM:
+ case UV_FS_O_RANDOM:
attributes |= FILE_FLAG_RANDOM_ACCESS;
break;
default:
goto einval;
}
+ if (flags & UV_FS_O_DIRECT) {
+ attributes |= FILE_FLAG_NO_BUFFERING;
+ }
+
+ switch (flags & (UV_FS_O_DSYNC | UV_FS_O_SYNC)) {
+ case 0:
+ break;
+ case UV_FS_O_DSYNC:
+ case UV_FS_O_SYNC:
+ attributes |= FILE_FLAG_WRITE_THROUGH;
+ break;
+ default:
+ goto einval;
+ }
+
/* Setting this flag makes it possible to open a directory. */
attributes |= FILE_FLAG_BACKUP_SEMANTICS;
@@ -489,9 +528,9 @@ void fs__open(uv_fs_t* req) {
NULL);
if (file == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
- if (error == ERROR_FILE_EXISTS && (flags & _O_CREAT) &&
- !(flags & _O_EXCL)) {
- /* Special case: when ERROR_FILE_EXISTS happens and O_CREAT was */
+ if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) &&
+ !(flags & UV_FS_O_EXCL)) {
+ /* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was */
/* specified, it means the path referred to a directory. */
SET_REQ_UV_ERROR(req, UV_EISDIR, error);
} else {
@@ -556,9 +595,14 @@ void fs__read(uv_fs_t* req) {
DWORD error;
int result;
unsigned int index;
+ LARGE_INTEGER original_position;
+ LARGE_INTEGER zero_offset;
+ int restore_position;
VERIFY_FD(fd, req);
+ zero_offset.QuadPart = 0;
+ restore_position = 0;
handle = uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
@@ -569,6 +613,10 @@ void fs__read(uv_fs_t* req) {
if (offset != -1) {
memset(&overlapped, 0, sizeof overlapped);
overlapped_ptr = &overlapped;
+ if (SetFilePointerEx(handle, zero_offset, &original_position,
+ FILE_CURRENT)) {
+ restore_position = 1;
+ }
} else {
overlapped_ptr = NULL;
}
@@ -593,6 +641,9 @@ void fs__read(uv_fs_t* req) {
++index;
} while (result && index < req->fs.info.nbufs);
+ if (restore_position)
+ SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN);
+
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
} else {
@@ -615,9 +666,14 @@ void fs__write(uv_fs_t* req) {
DWORD bytes;
int result;
unsigned int index;
+ LARGE_INTEGER original_position;
+ LARGE_INTEGER zero_offset;
+ int restore_position;
VERIFY_FD(fd, req);
+ zero_offset.QuadPart = 0;
+ restore_position = 0;
handle = uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
@@ -627,6 +683,10 @@ void fs__write(uv_fs_t* req) {
if (offset != -1) {
memset(&overlapped, 0, sizeof overlapped);
overlapped_ptr = &overlapped;
+ if (SetFilePointerEx(handle, zero_offset, &original_position,
+ FILE_CURRENT)) {
+ restore_position = 1;
+ }
} else {
overlapped_ptr = NULL;
}
@@ -651,6 +711,9 @@ void fs__write(uv_fs_t* req) {
++index;
} while (result && index < req->fs.info.nbufs);
+ if (restore_position)
+ SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN);
+
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
} else {
@@ -1029,7 +1092,8 @@ cleanup:
}
-INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
+INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
+ int do_lstat) {
FILE_ALL_INFORMATION file_info;
FILE_FS_VOLUME_INFORMATION volume_info;
NTSTATUS nt_status;
@@ -1084,19 +1148,25 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
*/
statbuf->st_mode = 0;
- if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ /*
+ * On Windows, FILE_ATTRIBUTE_REPARSE_POINT is a general purpose mechanism
+ * by which filesystem drivers can intercept and alter file system requests.
+ *
+ * The only reparse points we care about are symlinks and mount points, both
+ * of which are treated as POSIX symlinks. Further, we only care when
+ * invoked via lstat, which seeks information about the link instead of its
+ * target. Otherwise, reparse points must be treated as regular files.
+ */
+ if (do_lstat &&
+ (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
/*
- * It is possible for a file to have FILE_ATTRIBUTE_REPARSE_POINT but not have
- * any link data. In that case DeviceIoControl() in fs__readlink_handle() sets
- * the last error to ERROR_NOT_A_REPARSE_POINT. Then the stat result mode
- * calculated below will indicate a normal directory or file, as if
- * FILE_ATTRIBUTE_REPARSE_POINT was not present.
+ * If reading the link fails, the reparse point is not a symlink and needs
+ * to be treated as a regular file. The higher level lstat function will
+ * detect this failure and retry without do_lstat if appropriate.
*/
- if (fs__readlink_handle(handle, NULL, &statbuf->st_size) == 0) {
- statbuf->st_mode |= S_IFLNK;
- } else if (GetLastError() != ERROR_NOT_A_REPARSE_POINT) {
+ if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0)
return -1;
- }
+ statbuf->st_mode |= S_IFLNK;
}
if (statbuf->st_mode == 0) {
@@ -1139,8 +1209,12 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
*
* Therefore we'll just report a sensible value that's quite commonly okay
* on modern hardware.
+ *
+ * 4096 is the minimum required to be compatible with newer Advanced Format
+ * drives (which have 4096 bytes per physical sector), and to be backwards
+ * compatible with older drives (which have 512 bytes per physical sector).
*/
- statbuf->st_blksize = 2048;
+ statbuf->st_blksize = 4096;
/* Todo: set st_flags to something meaningful. Also provide a wrapper for
* chattr(2).
@@ -1191,9 +1265,11 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
return;
}
- if (fs__stat_handle(handle, &req->statbuf) != 0) {
+ if (fs__stat_handle(handle, &req->statbuf, do_lstat) != 0) {
DWORD error = GetLastError();
- if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) {
+ if (do_lstat &&
+ (error == ERROR_SYMLINK_NOT_SUPPORTED ||
+ error == ERROR_NOT_A_REPARSE_POINT)) {
/* We opened a reparse point but it was not a symlink. Try again. */
fs__stat_impl(req, 0);
@@ -1237,7 +1313,7 @@ static void fs__fstat(uv_fs_t* req) {
return;
}
- if (fs__stat_handle(handle, &req->statbuf) != 0) {
+ if (fs__stat_handle(handle, &req->statbuf, 0) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
@@ -1309,6 +1385,22 @@ static void fs__ftruncate(uv_fs_t* req) {
}
+static void fs__copyfile(uv_fs_t* req) {
+ int flags;
+ int overwrite;
+
+ flags = req->fs.info.file_flags;
+ overwrite = flags & UV_FS_COPYFILE_EXCL;
+
+ if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ SET_REQ_RESULT(req, 0);
+}
+
+
static void fs__sendfile(uv_fs_t* req) {
int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
size_t length = req->fs.info.bufsml[0].len;
@@ -1675,25 +1767,46 @@ error:
static void fs__symlink(uv_fs_t* req) {
- WCHAR* pathw = req->file.pathw;
- WCHAR* new_pathw = req->fs.info.new_pathw;
- int flags = req->fs.info.file_flags;
- int result;
+ WCHAR* pathw;
+ WCHAR* new_pathw;
+ int flags;
+ int err;
+ pathw = req->file.pathw;
+ new_pathw = req->fs.info.new_pathw;
- if (flags & UV_FS_SYMLINK_JUNCTION) {
+ if (req->fs.info.file_flags & UV_FS_SYMLINK_JUNCTION) {
fs__create_junction(req, pathw, new_pathw);
- } else if (pCreateSymbolicLinkW) {
- result = pCreateSymbolicLinkW(new_pathw,
- pathw,
- flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
- if (result == -1) {
- SET_REQ_WIN32_ERROR(req, GetLastError());
- } else {
- SET_REQ_RESULT(req, result);
- }
- } else {
+ return;
+ }
+ if (!pCreateSymbolicLinkW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
+ return;
+ }
+
+ if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR)
+ flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag;
+ else
+ flags = uv__file_symlink_usermode_flag;
+
+ if (pCreateSymbolicLinkW(new_pathw, pathw, flags)) {
+ SET_REQ_RESULT(req, 0);
+ return;
+ }
+
+ /* Something went wrong. We will test if it is because of user-mode
+ * symlinks.
+ */
+ err = GetLastError();
+ if (err == ERROR_INVALID_PARAMETER &&
+ flags & SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) {
+ /* This system does not support user-mode symlinks. We will clear the
+ * unsupported flag and retry.
+ */
+ uv__file_symlink_usermode_flag = 0;
+ fs__symlink(req);
+ } else {
+ SET_REQ_WIN32_ERROR(req, err);
}
}
@@ -1831,6 +1944,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(CLOSE, close)
XX(READ, read)
XX(WRITE, write)
+ XX(COPYFILE, copyfile)
XX(SENDFILE, sendfile)
XX(STAT, stat)
XX(LSTAT, lstat)
@@ -1877,6 +1991,9 @@ static void uv__fs_done(struct uv__work* w, int status) {
void uv_fs_req_cleanup(uv_fs_t* req) {
+ if (req == NULL)
+ return;
+
if (req->flags & UV_FS_CLEANEDUP)
return;
@@ -1907,8 +2024,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int mode, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
-
+ INIT(UV_FS_OPEN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
@@ -1916,28 +2032,14 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
req->fs.info.file_flags = flags;
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__open(req);
- return req->result;
- }
+ POST;
}
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
+ INIT(UV_FS_CLOSE);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__close(req);
- return req->result;
- }
+ POST;
}
@@ -1948,11 +2050,11 @@ int uv_fs_read(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
+ INIT(UV_FS_READ);
+
if (bufs == NULL || nbufs == 0)
return UV_EINVAL;
- uv_fs_req_init(loop, req, UV_FS_READ, cb);
-
req->file.fd = fd;
req->fs.info.nbufs = nbufs;
@@ -1966,14 +2068,7 @@ int uv_fs_read(uv_loop_t* loop,
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
req->fs.info.offset = offset;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__read(req);
- return req->result;
- }
+ POST;
}
@@ -1984,11 +2079,11 @@ int uv_fs_write(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
+ INIT(UV_FS_WRITE);
+
if (bufs == NULL || nbufs == 0)
return UV_EINVAL;
- uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
-
req->file.fd = fd;
req->fs.info.nbufs = nbufs;
@@ -2002,14 +2097,7 @@ int uv_fs_write(uv_loop_t* loop,
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
req->fs.info.offset = offset;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__write(req);
- return req->result;
- }
+ POST;
}
@@ -2017,20 +2105,13 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
-
+ INIT(UV_FS_UNLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__unlink(req);
- return req->result;
- }
+ POST;
}
@@ -2038,22 +2119,14 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
-
+ INIT(UV_FS_MKDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__mkdir(req);
- return req->result;
- }
+ POST;
}
@@ -2061,39 +2134,25 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb);
-
+ INIT(UV_FS_MKDTEMP);
err = fs__capture_path(req, tpl, NULL, TRUE);
if (err)
return uv_translate_sys_error(err);
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__mkdtemp(req);
- return req->result;
- }
+ POST;
}
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
-
+ INIT(UV_FS_RMDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__rmdir(req);
- return req->result;
- }
+ POST;
}
@@ -2101,22 +2160,14 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb);
-
+ INIT(UV_FS_SCANDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.file_flags = flags;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__scandir(req);
- return req->result;
- }
+ POST;
}
@@ -2124,20 +2175,13 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_LINK, cb);
-
+ INIT(UV_FS_LINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__link(req);
- return req->result;
- }
+ POST;
}
@@ -2145,22 +2189,14 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, int flags, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb);
-
+ INIT(UV_FS_SYMLINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.file_flags = flags;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__symlink(req);
- return req->result;
- }
+ POST;
}
@@ -2168,20 +2204,13 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_READLINK, cb);
-
+ INIT(UV_FS_READLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__readlink(req);
- return req->result;
- }
+ POST;
}
@@ -2189,24 +2218,18 @@ int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
- if (!req || !path) {
+ INIT(UV_FS_REALPATH);
+
+ if (!path) {
return UV_EINVAL;
}
- uv_fs_req_init(loop, req, UV_FS_REALPATH, cb);
-
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__realpath(req);
- return req->result;
- }
+ POST;
}
@@ -2214,88 +2237,53 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
uv_gid_t gid, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_CHOWN, cb);
-
+ INIT(UV_FS_CHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__chown(req);
- return req->result;
- }
+ POST;
}
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid,
uv_gid_t gid, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb);
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fchown(req);
- return req->result;
- }
+ INIT(UV_FS_FCHOWN);
+ POST;
}
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_STAT, cb);
-
+ INIT(UV_FS_STAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__stat(req);
- return req->result;
- }
+ POST;
}
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
-
+ INIT(UV_FS_LSTAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__lstat(req);
- return req->result;
- }
+ POST;
}
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
+ INIT(UV_FS_FSTAT);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fstat(req);
- return req->result;
- }
+ POST;
}
@@ -2303,85 +2291,70 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
-
+ INIT(UV_FS_RENAME);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__rename(req);
- return req->result;
- }
+ POST;
}
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
+ INIT(UV_FS_FSYNC);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fsync(req);
- return req->result;
- }
+ POST;
}
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
+ INIT(UV_FS_FDATASYNC);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fdatasync(req);
- return req->result;
- }
+ POST;
}
int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd,
int64_t offset, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
-
+ INIT(UV_FS_FTRUNCATE);
req->file.fd = fd;
req->fs.info.offset = offset;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__ftruncate(req);
- return req->result;
- }
+ POST;
}
+int uv_fs_copyfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb) {
+ int err;
+
+ INIT(UV_FS_COPYFILE);
+
+ if (flags & ~UV_FS_COPYFILE_EXCL)
+ return UV_EINVAL;
+
+ err = fs__capture_path(req, path, new_path, cb != NULL);
+
+ if (err)
+ return uv_translate_sys_error(err);
+
+ req->fs.info.file_flags = flags;
+ POST;
+}
+
int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
-
+ INIT(UV_FS_SENDFILE);
req->file.fd = fd_in;
req->fs.info.fd_out = fd_out;
req->fs.info.offset = in_offset;
req->fs.info.bufsml[0].len = length;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__sendfile(req);
- return req->result;
- }
+ POST;
}
@@ -2392,21 +2365,13 @@ int uv_fs_access(uv_loop_t* loop,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_ACCESS, cb);
-
+ INIT(UV_FS_ACCESS);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err)
return uv_translate_sys_error(err);
req->fs.info.mode = flags;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- }
-
- fs__access(req);
- return req->result;
+ POST;
}
@@ -2414,39 +2379,23 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_CHMOD, cb);
-
+ INIT(UV_FS_CHMOD);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__chmod(req);
- return req->result;
- }
+ POST;
}
int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode,
uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb);
-
+ INIT(UV_FS_FCHMOD);
req->file.fd = fd;
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fchmod(req);
- return req->result;
- }
+ POST;
}
@@ -2454,8 +2403,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_UTIME, cb);
-
+ INIT(UV_FS_UTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
@@ -2463,30 +2411,15 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__utime(req);
- return req->result;
- }
+ POST;
}
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
double mtime, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FUTIME, cb);
-
+ INIT(UV_FS_FUTIME);
req->file.fd = fd;
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__futime(req);
- return req->result;
- }
+ POST;
}
diff --git a/Utilities/cmlibuv/src/win/getaddrinfo.c b/Utilities/cmlibuv/src/win/getaddrinfo.c
index baab838..282d919 100644
--- a/Utilities/cmlibuv/src/win/getaddrinfo.c
+++ b/Utilities/cmlibuv/src/win/getaddrinfo.c
@@ -28,6 +28,8 @@
/* EAI_* constants. */
#include <winsock2.h>
+/* Needed for ConvertInterfaceIndexToLuid and ConvertInterfaceLuidToNameA */
+#include <iphlpapi.h>
int uv__getaddrinfo_translate_error(int sys_err) {
switch (sys_err) {
@@ -73,6 +75,9 @@ int uv__getaddrinfo_translate_error(int sys_err) {
/* Do we need different versions of this for different architectures? */
#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2)
+#ifndef NDIS_IF_MAX_STRING_SIZE
+#define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE
+#endif
static void uv__getaddrinfo_work(struct uv__work* w) {
uv_getaddrinfo_t* req;
@@ -380,3 +385,69 @@ error:
}
return uv_translate_sys_error(err);
}
+
+int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) {
+ NET_LUID luid;
+ wchar_t wname[NDIS_IF_MAX_STRING_SIZE + 1]; /* Add one for the NUL. */
+ DWORD bufsize;
+ int r;
+
+ if (buffer == NULL || size == NULL || *size == 0)
+ return UV_EINVAL;
+
+ r = ConvertInterfaceIndexToLuid(ifindex, &luid);
+
+ if (r != 0)
+ return uv_translate_sys_error(r);
+
+ r = ConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname));
+
+ if (r != 0)
+ return uv_translate_sys_error(r);
+
+ /* Check how much space we need */
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL);
+
+ if (bufsize == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (bufsize > *size) {
+ *size = bufsize;
+ return UV_ENOBUFS;
+ }
+
+ /* Convert to UTF-8 */
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ wname,
+ -1,
+ buffer,
+ *size,
+ NULL,
+ NULL);
+
+ if (bufsize == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ *size = bufsize - 1;
+ return 0;
+}
+
+int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) {
+ int r;
+
+ if (buffer == NULL || size == NULL || *size == 0)
+ return UV_EINVAL;
+
+ r = snprintf(buffer, *size, "%d", ifindex);
+
+ if (r < 0)
+ return uv_translate_sys_error(r);
+
+ if (r >= (int) *size) {
+ *size = r + 1;
+ return UV_ENOBUFS;
+ }
+
+ *size = r;
+ return 0;
+}
diff --git a/Utilities/cmlibuv/src/win/handle.c b/Utilities/cmlibuv/src/win/handle.c
index 72b49d9..3915070 100644
--- a/Utilities/cmlibuv/src/win/handle.c
+++ b/Utilities/cmlibuv/src/win/handle.c
@@ -152,3 +152,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
int uv_is_closing(const uv_handle_t* handle) {
return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED));
}
+
+
+uv_os_fd_t uv_get_osfhandle(int fd) {
+ return uv__get_osfhandle(fd);
+}
diff --git a/Utilities/cmlibuv/src/win/internal.h b/Utilities/cmlibuv/src/win/internal.h
index 83601d5..9f28f77 100644
--- a/Utilities/cmlibuv/src/win/internal.h
+++ b/Utilities/cmlibuv/src/win/internal.h
@@ -330,7 +330,6 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
void uv__util_init(void);
uint64_t uv__hrtime(double scale);
-int uv_parent_pid(void);
int uv_current_pid(void);
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
int uv__getpwuid_r(uv_passwd_t* pwd);
diff --git a/Utilities/cmlibuv/src/win/pipe.c b/Utilities/cmlibuv/src/win/pipe.c
index edf3002..1a7c4dc 100644
--- a/Utilities/cmlibuv/src/win/pipe.c
+++ b/Utilities/cmlibuv/src/win/pipe.c
@@ -31,6 +31,9 @@
#include "stream-inl.h"
#include "req-inl.h"
+#include <aclapi.h>
+#include <accctrl.h>
+
typedef struct uv__ipc_queue_item_s uv__ipc_queue_item_t;
struct uv__ipc_queue_item_s {
@@ -202,7 +205,7 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
uv_unique_pipe_name(ptr, name, nameSize);
pipeHandle = CreateNamedPipeA(name,
- access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
+ access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
NULL);
@@ -534,7 +537,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
*/
handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
- FILE_FLAG_FIRST_PIPE_INSTANCE,
+ FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
@@ -803,7 +806,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
assert(req->pipeHandle == INVALID_HANDLE_VALUE);
req->pipeHandle = CreateNamedPipeW(handle->name,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
@@ -968,27 +971,31 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
uv_mutex_unlock(m);
}
restart_readfile:
- result = ReadFile(handle->handle,
- &uv_zero_,
- 0,
- &bytes,
- NULL);
- if (!result) {
- err = GetLastError();
- if (err == ERROR_OPERATION_ABORTED &&
- handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
- if (handle->flags & UV_HANDLE_READING) {
- /* just a brief break to do something else */
- handle->pipe.conn.readfile_thread = NULL;
- /* resume after it is finished */
- uv_mutex_lock(m);
- handle->pipe.conn.readfile_thread = hThread;
- uv_mutex_unlock(m);
- goto restart_readfile;
- } else {
- result = 1; /* successfully stopped reading */
+ if (handle->flags & UV_HANDLE_READING) {
+ result = ReadFile(handle->handle,
+ &uv_zero_,
+ 0,
+ &bytes,
+ NULL);
+ if (!result) {
+ err = GetLastError();
+ if (err == ERROR_OPERATION_ABORTED &&
+ handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+ if (handle->flags & UV_HANDLE_READING) {
+ /* just a brief break to do something else */
+ handle->pipe.conn.readfile_thread = NULL;
+ /* resume after it is finished */
+ uv_mutex_lock(m);
+ handle->pipe.conn.readfile_thread = hThread;
+ uv_mutex_unlock(m);
+ goto restart_readfile;
+ } else {
+ result = 1; /* successfully stopped reading */
+ }
}
}
+ } else {
+ result = 1; /* successfully aborted read before it even started */
}
if (hThread) {
assert(hThread == handle->pipe.conn.readfile_thread);
@@ -1515,7 +1522,10 @@ static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
int error, uv_buf_t buf) {
- if (error == ERROR_BROKEN_PIPE) {
+ if (error == ERROR_OPERATION_ABORTED) {
+ /* do nothing (equivalent to EINTR) */
+ }
+ else if (error == ERROR_BROKEN_PIPE) {
uv_pipe_read_eof(loop, handle, buf);
} else {
uv_pipe_read_error(loop, handle, error, buf);
@@ -1906,6 +1916,7 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (os_handle == INVALID_HANDLE_VALUE)
return UV_EBADF;
+ uv__once_init();
/* In order to avoid closing a stdio file descriptor 0-2, duplicate the
* underlying OS handle and forget about the original fd.
* We could also opt to use the original OS handle and just never close it,
@@ -1961,7 +1972,7 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
- pipe->pipe.conn.ipc_pid = uv_parent_pid();
+ pipe->pipe.conn.ipc_pid = uv_os_getppid();
assert(pipe->pipe.conn.ipc_pid != -1);
}
return 0;
@@ -1979,6 +1990,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
unsigned int name_len;
int err;
+ uv__once_init();
name_info = NULL;
if (handle->handle == INVALID_HANDLE_VALUE) {
@@ -2123,3 +2135,80 @@ uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
else
return UV_TCP;
}
+
+int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
+ SID_IDENTIFIER_AUTHORITY sid_world = SECURITY_WORLD_SID_AUTHORITY;
+ PACL old_dacl, new_dacl;
+ PSECURITY_DESCRIPTOR sd;
+ EXPLICIT_ACCESS ea;
+ PSID everyone;
+ int error;
+
+ if (handle == NULL || handle->handle == INVALID_HANDLE_VALUE)
+ return UV_EBADF;
+
+ if (mode != UV_READABLE &&
+ mode != UV_WRITABLE &&
+ mode != (UV_WRITABLE | UV_READABLE))
+ return UV_EINVAL;
+
+ if (!AllocateAndInitializeSid(&sid_world,
+ 1,
+ SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &everyone)) {
+ error = GetLastError();
+ goto done;
+ }
+
+ if (GetSecurityInfo(handle->handle,
+ SE_KERNEL_OBJECT,
+ DACL_SECURITY_INFORMATION,
+ NULL,
+ NULL,
+ &old_dacl,
+ NULL,
+ &sd)) {
+ error = GetLastError();
+ goto clean_sid;
+ }
+
+ memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
+ if (mode & UV_READABLE)
+ ea.grfAccessPermissions |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
+ if (mode & UV_WRITABLE)
+ ea.grfAccessPermissions |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
+ ea.grfAccessPermissions |= SYNCHRONIZE;
+ ea.grfAccessMode = SET_ACCESS;
+ ea.grfInheritance = NO_INHERITANCE;
+ ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ea.Trustee.ptstrName = (LPTSTR)everyone;
+
+ if (SetEntriesInAcl(1, &ea, old_dacl, &new_dacl)) {
+ error = GetLastError();
+ goto clean_sd;
+ }
+
+ if (SetSecurityInfo(handle->handle,
+ SE_KERNEL_OBJECT,
+ DACL_SECURITY_INFORMATION,
+ NULL,
+ NULL,
+ new_dacl,
+ NULL)) {
+ error = GetLastError();
+ goto clean_dacl;
+ }
+
+ error = 0;
+
+clean_dacl:
+ LocalFree((HLOCAL) new_dacl);
+clean_sd:
+ LocalFree((HLOCAL) sd);
+clean_sid:
+ FreeSid(everyone);
+done:
+ return uv_translate_sys_error(error);
+}
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c
index d141601..cc06d9e 100644
--- a/Utilities/cmlibuv/src/win/process.c
+++ b/Utilities/cmlibuv/src/win/process.c
@@ -405,8 +405,15 @@ static WCHAR* search_path(const WCHAR *file,
/* Next slice starts just after where the previous one ended */
dir_start = dir_end;
+ /* If path is quoted, find quote end */
+ if (*dir_start == L'"' || *dir_start == L'\'') {
+ dir_end = wcschr(dir_start + 1, *dir_start);
+ if (dir_end == NULL) {
+ dir_end = wcschr(dir_start, L'\0');
+ }
+ }
/* Slice until the next ; or \0 is found */
- dir_end = wcschr(dir_start, L';');
+ dir_end = wcschr(dir_end, L';');
if (dir_end == NULL) {
dir_end = wcschr(dir_start, L'\0');
}
@@ -1051,15 +1058,18 @@ int uv_spawn(uv_loop_t* loop,
startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);
+ process_flags = CREATE_UNICODE_ENVIRONMENT;
+
if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
/* Use SW_HIDE to avoid any potential process window. */
startup.wShowWindow = SW_HIDE;
+
+ /* Hide console windows. */
+ process_flags |= CREATE_NO_WINDOW;
} else {
startup.wShowWindow = SW_SHOWDEFAULT;
}
- process_flags = CREATE_UNICODE_ENVIRONMENT;
-
if (options->flags & UV_PROCESS_DETACHED) {
/* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That
* means that libuv might not let you create a fully daemonized process
@@ -1163,6 +1173,10 @@ int uv_spawn(uv_loop_t* loop,
static int uv__kill(HANDLE process_handle, int signum) {
+ if (signum < 0 || signum >= NSIG) {
+ return UV_EINVAL;
+ }
+
switch (signum) {
case SIGTERM:
case SIGKILL:
@@ -1227,8 +1241,15 @@ int uv_process_kill(uv_process_t* process, int signum) {
int uv_kill(int pid, int signum) {
int err;
- HANDLE process_handle = OpenProcess(PROCESS_TERMINATE |
- PROCESS_QUERY_INFORMATION, FALSE, pid);
+ HANDLE process_handle;
+
+ if (pid == 0) {
+ process_handle = GetCurrentProcess();
+ } else {
+ process_handle = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION,
+ FALSE,
+ pid);
+ }
if (process_handle == NULL) {
err = GetLastError();
diff --git a/Utilities/cmlibuv/src/win/signal.c b/Utilities/cmlibuv/src/win/signal.c
index 7b42dd9..a174da1 100644
--- a/Utilities/cmlibuv/src/win/signal.c
+++ b/Utilities/cmlibuv/src/win/signal.c
@@ -64,7 +64,7 @@ static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
}
-RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare);
+RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare)
/*
diff --git a/Utilities/cmlibuv/src/win/stream-inl.h b/Utilities/cmlibuv/src/win/stream-inl.h
index bf12148..dba0374 100644
--- a/Utilities/cmlibuv/src/win/stream-inl.h
+++ b/Utilities/cmlibuv/src/win/stream-inl.h
@@ -36,6 +36,7 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
uv__handle_init(loop, (uv_handle_t*) handle, type);
handle->write_queue_size = 0;
handle->activecnt = 0;
+ handle->stream.conn.shutdown_req = NULL;
}
@@ -47,8 +48,6 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->read_req.event_handle = NULL;
handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
handle->read_req.data = handle;
-
- handle->stream.conn.shutdown_req = NULL;
}
diff --git a/Utilities/cmlibuv/src/win/tcp.c b/Utilities/cmlibuv/src/win/tcp.c
index 972539f..fd6efba 100644
--- a/Utilities/cmlibuv/src/win/tcp.c
+++ b/Utilities/cmlibuv/src/win/tcp.c
@@ -747,10 +747,15 @@ static int uv_tcp_try_connect(uv_connect_t* req,
uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
const struct sockaddr* bind_addr;
+ struct sockaddr_storage converted;
BOOL success;
DWORD bytes;
int err;
+ err = uv__convert_to_localhost_if_unspecified(addr, &converted);
+ if (err)
+ return err;
+
if (handle->delayed_error) {
return handle->delayed_error;
}
@@ -782,12 +787,12 @@ static int uv_tcp_try_connect(uv_connect_t* req,
memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
success = handle->tcp.conn.func_connectex(handle->socket,
- addr,
- addrlen,
- NULL,
- 0,
- &bytes,
- &req->u.io.overlapped);
+ (const struct sockaddr*) &converted,
+ addrlen,
+ NULL,
+ 0,
+ &bytes,
+ &req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */
@@ -1446,6 +1451,8 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
WSAPROTOCOL_INFOW protocol_info;
int opt_len;
int err;
+ struct sockaddr_storage saddr;
+ int saddr_len;
/* Detect the address family of the socket. */
opt_len = (int) sizeof protocol_info;
@@ -1466,6 +1473,19 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
return uv_translate_sys_error(err);
}
+ /* Support already active socket. */
+ saddr_len = sizeof(saddr);
+ if (!uv_tcp_getsockname(handle, (struct sockaddr*) &saddr, &saddr_len)) {
+ /* Socket is already bound. */
+ handle->flags |= UV_HANDLE_BOUND;
+ saddr_len = sizeof(saddr);
+ if (!uv_tcp_getpeername(handle, (struct sockaddr*) &saddr, &saddr_len)) {
+ /* Socket is already connected. */
+ uv_connection_init((uv_stream_t*) handle);
+ handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+ }
+ }
+
return 0;
}
diff --git a/Utilities/cmlibuv/src/win/thread.c b/Utilities/cmlibuv/src/win/thread.c
index 91684e9..9eaad77 100644
--- a/Utilities/cmlibuv/src/win/thread.c
+++ b/Utilities/cmlibuv/src/win/thread.c
@@ -182,6 +182,7 @@ int uv_thread_join(uv_thread_t *tid) {
else {
CloseHandle(*tid);
*tid = 0;
+ MemoryBarrier(); /* For feature parity with pthread_join(). */
return 0;
}
}
@@ -198,6 +199,11 @@ int uv_mutex_init(uv_mutex_t* mutex) {
}
+int uv_mutex_init_recursive(uv_mutex_t* mutex) {
+ return uv_mutex_init(mutex);
+}
+
+
void uv_mutex_destroy(uv_mutex_t* mutex) {
DeleteCriticalSection(mutex);
}
diff --git a/Utilities/cmlibuv/src/win/timer.c b/Utilities/cmlibuv/src/win/timer.c
index 27ca771..7e006fe 100644
--- a/Utilities/cmlibuv/src/win/timer.c
+++ b/Utilities/cmlibuv/src/win/timer.c
@@ -56,7 +56,7 @@ static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
}
-RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare);
+RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare)
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
diff --git a/Utilities/cmlibuv/src/win/tty.c b/Utilities/cmlibuv/src/win/tty.c
index a6f5839..05a11e8 100644
--- a/Utilities/cmlibuv/src/win/tty.c
+++ b/Utilities/cmlibuv/src/win/tty.c
@@ -112,14 +112,30 @@ static int uv_tty_virtual_offset = -1;
static int uv_tty_virtual_height = -1;
static int uv_tty_virtual_width = -1;
+/* The console window size
+ * We keep this separate from uv_tty_virtual_*. We use those values to only
+ * handle signalling SIGWINCH
+ */
+
+static HANDLE uv__tty_console_handle = INVALID_HANDLE_VALUE;
+static int uv__tty_console_height = -1;
+static int uv__tty_console_width = -1;
+
+static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param);
+static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
+ DWORD event,
+ HWND hwnd,
+ LONG idObject,
+ LONG idChild,
+ DWORD dwEventThread,
+ DWORD dwmsEventTime);
+
/* We use a semaphore rather than a mutex or critical section because in some
cases (uv__cancel_read_console) we need take the lock in the main thread and
release it in another thread. Using a semaphore ensures that in such
scenario the main thread will still block when trying to acquire the lock. */
static uv_sem_t uv_tty_output_lock;
-static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
-
static WORD uv_tty_default_text_attributes =
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
@@ -141,6 +157,18 @@ static void uv__determine_vterm_state(HANDLE handle);
void uv_console_init(void) {
if (uv_sem_init(&uv_tty_output_lock, 1))
abort();
+ uv__tty_console_handle = CreateFileW(L"CONOUT$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ 0,
+ 0);
+ if (uv__tty_console_handle != NULL) {
+ QueueUserWorkItem(uv__tty_console_resize_message_loop_thread,
+ NULL,
+ WT_EXECUTELONGFUNCTION);
+ }
}
@@ -148,6 +176,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
HANDLE handle;
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+ uv__once_init();
handle = (HANDLE) uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE)
return UV_EBADF;
@@ -183,11 +212,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
if (uv__vterm_state == UV_UNCHECKED)
uv__determine_vterm_state(handle);
- /* Store the global tty output handle. This handle is used by TTY read */
- /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */
- /* is received. */
- uv_tty_output_handle = handle;
-
/* Remember the original console text attributes. */
uv_tty_capture_initial_style(&screen_buffer_info);
@@ -704,25 +728,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
}
records_left--;
- /* If the window was resized, recompute the virtual window size. This */
- /* will trigger a SIGWINCH signal if the window size changed in an */
- /* way that matters to libuv. */
- if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
- CONSOLE_SCREEN_BUFFER_INFO info;
-
- uv_sem_wait(&uv_tty_output_lock);
-
- if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
- GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
- uv_tty_update_virtual_window(&info);
- }
-
- uv_sem_post(&uv_tty_output_lock);
-
- continue;
- }
-
- /* Ignore other events that are not key or resize events. */
+ /* Ignore other events that are not key events. */
if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
continue;
}
@@ -1102,9 +1108,6 @@ static int uv__cancel_read_console(uv_tty_t* handle) {
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
- int old_virtual_width = uv_tty_virtual_width;
- int old_virtual_height = uv_tty_virtual_height;
-
uv_tty_virtual_width = info->dwSize.X;
uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;
@@ -1124,14 +1127,6 @@ static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
if (uv_tty_virtual_offset < 0) {
uv_tty_virtual_offset = 0;
}
-
- /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */
- /* if this was the first time the virtual window size was computed. */
- if (old_virtual_width != -1 && old_virtual_height != -1 &&
- (uv_tty_virtual_width != old_virtual_width ||
- uv_tty_virtual_height != old_virtual_height)) {
- uv__signal_dispatch(SIGWINCH);
- }
}
@@ -2279,3 +2274,55 @@ static void uv__determine_vterm_state(HANDLE handle) {
uv__vterm_state = UV_SUPPORTED;
}
+
+static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) {
+ CONSOLE_SCREEN_BUFFER_INFO sb_info;
+ MSG msg;
+
+ if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info))
+ return 0;
+
+ uv__tty_console_width = sb_info.dwSize.X;
+ uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
+
+ if (pSetWinEventHook == NULL)
+ return 0;
+
+ if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT,
+ EVENT_CONSOLE_LAYOUT,
+ NULL,
+ uv__tty_console_resize_event,
+ 0,
+ 0,
+ WINEVENT_OUTOFCONTEXT))
+ return 0;
+
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ return 0;
+}
+
+static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
+ DWORD event,
+ HWND hwnd,
+ LONG idObject,
+ LONG idChild,
+ DWORD dwEventThread,
+ DWORD dwmsEventTime) {
+ CONSOLE_SCREEN_BUFFER_INFO sb_info;
+ int width, height;
+
+ if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info))
+ return;
+
+ width = sb_info.dwSize.X;
+ height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
+
+ if (width != uv__tty_console_width || height != uv__tty_console_height) {
+ uv__tty_console_width = width;
+ uv__tty_console_height = height;
+ uv__signal_dispatch(SIGWINCH);
+ }
+}
diff --git a/Utilities/cmlibuv/src/win/udp.c b/Utilities/cmlibuv/src/win/udp.c
index 2fd15cf..cd1d0e0 100644
--- a/Utilities/cmlibuv/src/win/udp.c
+++ b/Utilities/cmlibuv/src/win/udp.c
@@ -897,13 +897,12 @@ int uv__udp_send(uv_udp_send_t* req,
int err;
if (!(handle->flags & UV_HANDLE_BOUND)) {
- if (addrlen == sizeof(uv_addr_ip4_any_)) {
+ if (addrlen == sizeof(uv_addr_ip4_any_))
bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
- } else if (addrlen == sizeof(uv_addr_ip6_any_)) {
+ else if (addrlen == sizeof(uv_addr_ip6_any_))
bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
- } else {
- abort();
- }
+ else
+ return UV_EINVAL;
err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0);
if (err)
return uv_translate_sys_error(err);
@@ -922,5 +921,45 @@ int uv__udp_try_send(uv_udp_t* handle,
unsigned int nbufs,
const struct sockaddr* addr,
unsigned int addrlen) {
- return UV_ENOSYS;
+ DWORD bytes;
+ const struct sockaddr* bind_addr;
+ struct sockaddr_storage converted;
+ int err;
+
+ assert(nbufs > 0);
+
+ err = uv__convert_to_localhost_if_unspecified(addr, &converted);
+ if (err)
+ return err;
+
+ /* Already sending a message.*/
+ if (handle->send_queue_count != 0)
+ return UV_EAGAIN;
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ if (addrlen == sizeof(uv_addr_ip4_any_))
+ bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
+ else if (addrlen == sizeof(uv_addr_ip6_any_))
+ bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
+ else
+ return UV_EINVAL;
+ err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0);
+ if (err)
+ return uv_translate_sys_error(err);
+ }
+
+ err = WSASendTo(handle->socket,
+ (WSABUF*)bufs,
+ nbufs,
+ &bytes,
+ 0,
+ (const struct sockaddr*) &converted,
+ addrlen,
+ NULL,
+ NULL);
+
+ if (err)
+ return uv_translate_sys_error(WSAGetLastError());
+
+ return bytes;
}
diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c
index d2e7f77..3100bc2 100644
--- a/Utilities/cmlibuv/src/win/util.c
+++ b/Utilities/cmlibuv/src/win/util.c
@@ -331,7 +331,12 @@ uint64_t uv_get_total_memory(void) {
}
-int uv_parent_pid(void) {
+uv_pid_t uv_os_getpid(void) {
+ return GetCurrentProcessId();
+}
+
+
+uv_pid_t uv_os_getppid(void) {
int parent_pid = -1;
HANDLE handle;
PROCESSENTRY32 pe;
@@ -1388,7 +1393,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
return uv_translate_sys_error(GetLastError());
- bufsize = sizeof(path);
+ bufsize = ARRAY_SIZE(path);
if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
r = GetLastError();
CloseHandle(token);
@@ -1403,7 +1408,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
CloseHandle(token);
/* Get the username using GetUserNameW() */
- bufsize = sizeof(username);
+ bufsize = ARRAY_SIZE(username);
if (!GetUserNameW(username, &bufsize)) {
r = GetLastError();
diff --git a/Utilities/cmlibuv/src/win/winapi.c b/Utilities/cmlibuv/src/win/winapi.c
index aa5d719..4ccdf0a 100644
--- a/Utilities/cmlibuv/src/win/winapi.c
+++ b/Utilities/cmlibuv/src/win/winapi.c
@@ -52,11 +52,15 @@ sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
/* Powrprof.dll function pointer */
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+/* User32.dll function pointer */
+sSetWinEventHook pSetWinEventHook;
+
void uv_winapi_init(void) {
HMODULE ntdll_module;
HMODULE kernel32_module;
HMODULE powrprof_module;
+ HMODULE user32_module;
ntdll_module = GetModuleHandleA("ntdll.dll");
if (ntdll_module == NULL) {
@@ -156,4 +160,10 @@ void uv_winapi_init(void) {
GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification");
}
+ user32_module = LoadLibraryA("user32.dll");
+ if (user32_module != NULL) {
+ pSetWinEventHook = (sSetWinEventHook)
+ GetProcAddress(user32_module, "SetWinEventHook");
+ }
+
}
diff --git a/Utilities/cmlibuv/src/win/winapi.h b/Utilities/cmlibuv/src/win/winapi.h
index 4b0eeca..8993c65 100644
--- a/Utilities/cmlibuv/src/win/winapi.h
+++ b/Utilities/cmlibuv/src/win/winapi.h
@@ -4104,6 +4104,10 @@
# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
#endif
+#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x00000002
+#endif
+
/* from winternl.h */
typedef struct _UNICODE_STRING {
USHORT Length;
@@ -4730,6 +4734,25 @@ typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification)
HANDLE Recipient,
_PHPOWERNOTIFY RegistrationHandle);
+/* from Winuser.h */
+typedef VOID (CALLBACK* WINEVENTPROC)
+ (HWINEVENTHOOK hWinEventHook,
+ DWORD event,
+ HWND hwnd,
+ LONG idObject,
+ LONG idChild,
+ DWORD idEventThread,
+ DWORD dwmsEventTime);
+
+typedef HWINEVENTHOOK (WINAPI *sSetWinEventHook)
+ (UINT eventMin,
+ UINT eventMax,
+ HMODULE hmodWinEventProc,
+ WINEVENTPROC lpfnWinEventProc,
+ DWORD idProcess,
+ DWORD idThread,
+ UINT dwflags);
+
/* Ntdll function pointers */
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
@@ -4758,4 +4781,7 @@ extern sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
/* Powrprof.dll function pointer */
extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+/* User32.dll function pointer */
+extern sSetWinEventHook pSetWinEventHook;
+
#endif /* UV_WIN_WINAPI_H_ */
diff --git a/Utilities/cmlibuv/src/win/winsock.c b/Utilities/cmlibuv/src/win/winsock.c
index e86d76b..7cfa90f 100644
--- a/Utilities/cmlibuv/src/win/winsock.c
+++ b/Utilities/cmlibuv/src/win/winsock.c
@@ -559,3 +559,31 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
return SOCKET_ERROR;
}
}
+
+int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr,
+ struct sockaddr_storage* storage) {
+ struct sockaddr_in* dest4;
+ struct sockaddr_in6* dest6;
+
+ if (addr == NULL)
+ return UV_EINVAL;
+
+ switch (addr->sa_family) {
+ case AF_INET:
+ dest4 = (struct sockaddr_in*) storage;
+ memcpy(dest4, addr, sizeof(*dest4));
+ if (dest4->sin_addr.s_addr == 0)
+ dest4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ return 0;
+ case AF_INET6:
+ dest6 = (struct sockaddr_in6*) storage;
+ memcpy(dest6, addr, sizeof(*dest6));
+ if (memcmp(&dest6->sin6_addr,
+ &uv_addr_ip6_any_.sin6_addr,
+ sizeof(uv_addr_ip6_any_.sin6_addr)) == 0)
+ dest6->sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
+ return 0;
+ default:
+ return UV_EINVAL;
+ }
+}
diff --git a/Utilities/cmlibuv/src/win/winsock.h b/Utilities/cmlibuv/src/win/winsock.h
index 3115fe3..e8b274e 100644
--- a/Utilities/cmlibuv/src/win/winsock.h
+++ b/Utilities/cmlibuv/src/win/winsock.h
@@ -188,4 +188,7 @@ typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH {
#endif
+int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr,
+ struct sockaddr_storage* storage);
+
#endif /* UV_WIN_WINSOCK_H_ */