forked from cory/tildefriends
libuv 1.47.0.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4615 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
15
deps/libuv/src/win/dl.c
vendored
15
deps/libuv/src/win/dl.c
vendored
@ -27,18 +27,17 @@ static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno);
|
||||
|
||||
int uv_dlopen(const char* filename, uv_lib_t* lib) {
|
||||
WCHAR filename_w[32768];
|
||||
ssize_t r;
|
||||
|
||||
lib->handle = NULL;
|
||||
lib->errmsg = NULL;
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
filename,
|
||||
-1,
|
||||
filename_w,
|
||||
ARRAY_SIZE(filename_w))) {
|
||||
return uv__dlerror(lib, filename, GetLastError());
|
||||
}
|
||||
r = uv_wtf8_length_as_utf16(filename);
|
||||
if (r < 0)
|
||||
return uv__dlerror(lib, filename, ERROR_NO_UNICODE_TRANSLATION);
|
||||
if ((size_t) r > ARRAY_SIZE(filename_w))
|
||||
return uv__dlerror(lib, filename, ERROR_INSUFFICIENT_BUFFER);
|
||||
uv_wtf8_to_utf16(filename, filename_w, r);
|
||||
|
||||
lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
if (lib->handle == NULL) {
|
||||
|
28
deps/libuv/src/win/fs-event.c
vendored
28
deps/libuv/src/win/fs-event.c
vendored
@ -157,7 +157,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
uv_fs_event_cb cb,
|
||||
const char* path,
|
||||
unsigned int flags) {
|
||||
int name_size, is_path_dir, size;
|
||||
int is_path_dir;
|
||||
size_t size;
|
||||
DWORD attr, last_error;
|
||||
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
|
||||
DWORD short_path_buffer_len;
|
||||
@ -176,23 +177,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
|
||||
name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) *
|
||||
sizeof(WCHAR);
|
||||
pathw = (WCHAR*)uv__malloc(name_size);
|
||||
if (!pathw) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
path,
|
||||
-1,
|
||||
pathw,
|
||||
name_size / sizeof(WCHAR))) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
last_error = uv__convert_utf8_to_utf16(path, &pathw);
|
||||
if (last_error)
|
||||
goto error_uv;
|
||||
|
||||
/* Determine whether path is a file or a directory. */
|
||||
attr = GetFileAttributesW(pathw);
|
||||
@ -333,6 +320,9 @@ short_path_done:
|
||||
return 0;
|
||||
|
||||
error:
|
||||
last_error = uv_translate_sys_error(last_error);
|
||||
|
||||
error_uv:
|
||||
if (handle->path) {
|
||||
uv__free(handle->path);
|
||||
handle->path = NULL;
|
||||
@ -365,7 +355,7 @@ error:
|
||||
|
||||
uv__free(short_path);
|
||||
|
||||
return uv_translate_sys_error(last_error);
|
||||
return last_error;
|
||||
}
|
||||
|
||||
|
||||
|
381
deps/libuv/src/win/fs.c
vendored
381
deps/libuv/src/win/fs.c
vendored
@ -31,13 +31,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "uv.h"
|
||||
|
||||
/* <winioctl.h> requires <windows.h>, included via "uv.h" above, but needs to
|
||||
be included before our "winapi.h", included via "internal.h" below. */
|
||||
#include <winioctl.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "req-inl.h"
|
||||
#include "handle-inl.h"
|
||||
#include "fs-fd-hash-inl.h"
|
||||
|
||||
#include <winioctl.h>
|
||||
|
||||
|
||||
#define UV_FS_FREE_PATHS 0x0002
|
||||
#define UV_FS_FREE_PTR 0x0008
|
||||
@ -144,279 +147,6 @@ void uv__fs_init(void) {
|
||||
}
|
||||
|
||||
|
||||
static int32_t fs__decode_wtf8_char(const char** input) {
|
||||
uint32_t code_point;
|
||||
uint8_t b1;
|
||||
uint8_t b2;
|
||||
uint8_t b3;
|
||||
uint8_t b4;
|
||||
|
||||
b1 = **input;
|
||||
if (b1 <= 0x7F)
|
||||
return b1; /* ASCII code point */
|
||||
if (b1 < 0xC2)
|
||||
return -1; /* invalid: continuation byte */
|
||||
code_point = b1;
|
||||
|
||||
b2 = *++*input;
|
||||
if ((b2 & 0xC0) != 0x80)
|
||||
return -1; /* invalid: not a continuation byte */
|
||||
code_point = (code_point << 6) | (b2 & 0x3F);
|
||||
if (b1 <= 0xDF)
|
||||
return 0x7FF & code_point; /* two-byte character */
|
||||
|
||||
b3 = *++*input;
|
||||
if ((b3 & 0xC0) != 0x80)
|
||||
return -1; /* invalid: not a continuation byte */
|
||||
code_point = (code_point << 6) | (b3 & 0x3F);
|
||||
if (b1 <= 0xEF)
|
||||
return 0xFFFF & code_point; /* three-byte character */
|
||||
|
||||
b4 = *++*input;
|
||||
if ((b4 & 0xC0) != 0x80)
|
||||
return -1; /* invalid: not a continuation byte */
|
||||
code_point = (code_point << 6) | (b4 & 0x3F);
|
||||
if (b1 <= 0xF4)
|
||||
if (code_point <= 0x10FFFF)
|
||||
return code_point; /* four-byte character */
|
||||
|
||||
/* code point too large */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t fs__get_length_wtf8(const char* source_ptr) {
|
||||
size_t w_target_len = 0;
|
||||
int32_t code_point;
|
||||
|
||||
do {
|
||||
code_point = fs__decode_wtf8_char(&source_ptr);
|
||||
if (code_point < 0)
|
||||
return -1;
|
||||
if (code_point > 0xFFFF)
|
||||
w_target_len++;
|
||||
w_target_len++;
|
||||
} while (*source_ptr++);
|
||||
return w_target_len;
|
||||
}
|
||||
|
||||
|
||||
static void fs__wtf8_to_wide(const char* source_ptr, WCHAR* w_target) {
|
||||
int32_t code_point;
|
||||
|
||||
do {
|
||||
code_point = fs__decode_wtf8_char(&source_ptr);
|
||||
/* fs__get_length_wtf8 should have been called and checked first. */
|
||||
assert(code_point >= 0);
|
||||
if (code_point > 0x10000) {
|
||||
assert(code_point < 0x10FFFF);
|
||||
*w_target++ = (((code_point - 0x10000) >> 10) + 0xD800);
|
||||
*w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00;
|
||||
} else {
|
||||
*w_target++ = code_point;
|
||||
}
|
||||
} while (*source_ptr++);
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
|
||||
const char* new_path, const int copy_path) {
|
||||
WCHAR* buf;
|
||||
WCHAR* pos;
|
||||
size_t buf_sz = 0;
|
||||
size_t path_len = 0;
|
||||
ssize_t pathw_len = 0;
|
||||
ssize_t new_pathw_len = 0;
|
||||
|
||||
/* new_path can only be set if path is also set. */
|
||||
assert(new_path == NULL || path != NULL);
|
||||
|
||||
if (path != NULL) {
|
||||
pathw_len = fs__get_length_wtf8(path);
|
||||
if (pathw_len < 0)
|
||||
return ERROR_INVALID_NAME;
|
||||
buf_sz += pathw_len * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
if (path != NULL && copy_path) {
|
||||
path_len = 1 + strlen(path);
|
||||
buf_sz += path_len;
|
||||
}
|
||||
|
||||
if (new_path != NULL) {
|
||||
new_pathw_len = fs__get_length_wtf8(new_path);
|
||||
if (new_pathw_len < 0)
|
||||
return ERROR_INVALID_NAME;
|
||||
buf_sz += new_pathw_len * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
|
||||
if (buf_sz == 0) {
|
||||
req->file.pathw = NULL;
|
||||
req->fs.info.new_pathw = NULL;
|
||||
req->path = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = uv__malloc(buf_sz);
|
||||
if (buf == NULL) {
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
pos = buf;
|
||||
|
||||
if (path != NULL) {
|
||||
fs__wtf8_to_wide(path, pos);
|
||||
req->file.pathw = pos;
|
||||
pos += pathw_len;
|
||||
} else {
|
||||
req->file.pathw = NULL;
|
||||
}
|
||||
|
||||
if (new_path != NULL) {
|
||||
fs__wtf8_to_wide(new_path, pos);
|
||||
req->fs.info.new_pathw = pos;
|
||||
pos += new_pathw_len;
|
||||
} else {
|
||||
req->fs.info.new_pathw = NULL;
|
||||
}
|
||||
|
||||
req->path = path;
|
||||
if (path != NULL && copy_path) {
|
||||
memcpy(pos, path, path_len);
|
||||
assert(path_len == buf_sz - (pos - buf) * sizeof(WCHAR));
|
||||
req->path = (char*) pos;
|
||||
}
|
||||
|
||||
req->flags |= UV_FS_FREE_PATHS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
req->fs_type = fs_type;
|
||||
req->sys_errno_ = 0;
|
||||
req->result = 0;
|
||||
req->ptr = NULL;
|
||||
req->path = NULL;
|
||||
req->cb = cb;
|
||||
memset(&req->fs, 0, sizeof(req->fs));
|
||||
}
|
||||
|
||||
|
||||
static int32_t fs__get_surrogate_value(const WCHAR* w_source_ptr,
|
||||
size_t w_source_len) {
|
||||
WCHAR u;
|
||||
WCHAR next;
|
||||
|
||||
u = w_source_ptr[0];
|
||||
if (u >= 0xD800 && u <= 0xDBFF && w_source_len > 1) {
|
||||
next = w_source_ptr[1];
|
||||
if (next >= 0xDC00 && next <= 0xDFFF)
|
||||
return 0x10000 + ((u - 0xD800) << 10) + (next - 0xDC00);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
static size_t fs__get_length_wide(const WCHAR* w_source_ptr,
|
||||
size_t w_source_len) {
|
||||
size_t target_len;
|
||||
int32_t code_point;
|
||||
|
||||
target_len = 0;
|
||||
for (; w_source_len; w_source_len--, w_source_ptr++) {
|
||||
code_point = fs__get_surrogate_value(w_source_ptr, w_source_len);
|
||||
/* Can be invalid UTF-8 but must be valid WTF-8. */
|
||||
assert(code_point >= 0);
|
||||
if (code_point < 0x80)
|
||||
target_len += 1;
|
||||
else if (code_point < 0x800)
|
||||
target_len += 2;
|
||||
else if (code_point < 0x10000)
|
||||
target_len += 3;
|
||||
else {
|
||||
target_len += 4;
|
||||
w_source_ptr++;
|
||||
w_source_len--;
|
||||
}
|
||||
}
|
||||
return target_len;
|
||||
}
|
||||
|
||||
|
||||
static int fs__wide_to_wtf8(WCHAR* w_source_ptr,
|
||||
size_t w_source_len,
|
||||
char** target_ptr,
|
||||
size_t* target_len_ptr) {
|
||||
size_t target_len;
|
||||
char* target;
|
||||
int32_t code_point;
|
||||
|
||||
/* If *target_ptr is provided, then *target_len_ptr must be its length
|
||||
* (excluding space for null), otherwise we will compute the target_len_ptr
|
||||
* length and may return a new allocation in *target_ptr if target_ptr is
|
||||
* provided. */
|
||||
if (target_ptr == NULL || *target_ptr == NULL) {
|
||||
target_len = fs__get_length_wide(w_source_ptr, w_source_len);
|
||||
if (target_len_ptr != NULL)
|
||||
*target_len_ptr = target_len;
|
||||
} else {
|
||||
target_len = *target_len_ptr;
|
||||
}
|
||||
|
||||
if (target_ptr == NULL)
|
||||
return 0;
|
||||
|
||||
if (*target_ptr == NULL) {
|
||||
target = uv__malloc(target_len + 1);
|
||||
if (target == NULL) {
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return -1;
|
||||
}
|
||||
*target_ptr = target;
|
||||
} else {
|
||||
target = *target_ptr;
|
||||
}
|
||||
|
||||
for (; w_source_len; w_source_len--, w_source_ptr++) {
|
||||
code_point = fs__get_surrogate_value(w_source_ptr, w_source_len);
|
||||
/* Can be invalid UTF-8 but must be valid WTF-8. */
|
||||
assert(code_point >= 0);
|
||||
|
||||
if (code_point < 0x80) {
|
||||
*target++ = code_point;
|
||||
} else if (code_point < 0x800) {
|
||||
*target++ = 0xC0 | (code_point >> 6);
|
||||
*target++ = 0x80 | (code_point & 0x3F);
|
||||
} else if (code_point < 0x10000) {
|
||||
*target++ = 0xE0 | (code_point >> 12);
|
||||
*target++ = 0x80 | ((code_point >> 6) & 0x3F);
|
||||
*target++ = 0x80 | (code_point & 0x3F);
|
||||
} else {
|
||||
*target++ = 0xF0 | (code_point >> 18);
|
||||
*target++ = 0x80 | ((code_point >> 12) & 0x3F);
|
||||
*target++ = 0x80 | ((code_point >> 6) & 0x3F);
|
||||
*target++ = 0x80 | (code_point & 0x3F);
|
||||
w_source_ptr++;
|
||||
w_source_len--;
|
||||
}
|
||||
}
|
||||
assert((size_t) (target - *target_ptr) == target_len);
|
||||
|
||||
*target++ = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__readlink_handle(HANDLE handle,
|
||||
char** target_ptr,
|
||||
size_t* target_len_ptr) {
|
||||
@ -550,7 +280,98 @@ INLINE static int fs__readlink_handle(HANDLE handle,
|
||||
}
|
||||
|
||||
assert(target_ptr == NULL || *target_ptr == NULL);
|
||||
return fs__wide_to_wtf8(w_target, w_target_len, target_ptr, target_len_ptr);
|
||||
return uv_utf16_to_wtf8(w_target, w_target_len, target_ptr, target_len_ptr);
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
|
||||
const char* new_path, const int copy_path) {
|
||||
WCHAR* buf;
|
||||
WCHAR* pos;
|
||||
size_t buf_sz = 0;
|
||||
size_t path_len = 0;
|
||||
ssize_t pathw_len = 0;
|
||||
ssize_t new_pathw_len = 0;
|
||||
|
||||
/* new_path can only be set if path is also set. */
|
||||
assert(new_path == NULL || path != NULL);
|
||||
|
||||
if (path != NULL) {
|
||||
pathw_len = uv_wtf8_length_as_utf16(path);
|
||||
if (pathw_len < 0)
|
||||
return ERROR_INVALID_NAME;
|
||||
buf_sz += pathw_len * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
if (path != NULL && copy_path) {
|
||||
path_len = 1 + strlen(path);
|
||||
buf_sz += path_len;
|
||||
}
|
||||
|
||||
if (new_path != NULL) {
|
||||
new_pathw_len = uv_wtf8_length_as_utf16(new_path);
|
||||
if (new_pathw_len < 0)
|
||||
return ERROR_INVALID_NAME;
|
||||
buf_sz += new_pathw_len * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
|
||||
if (buf_sz == 0) {
|
||||
req->file.pathw = NULL;
|
||||
req->fs.info.new_pathw = NULL;
|
||||
req->path = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = uv__malloc(buf_sz);
|
||||
if (buf == NULL) {
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
pos = buf;
|
||||
|
||||
if (path != NULL) {
|
||||
uv_wtf8_to_utf16(path, pos, pathw_len);
|
||||
req->file.pathw = pos;
|
||||
pos += pathw_len;
|
||||
} else {
|
||||
req->file.pathw = NULL;
|
||||
}
|
||||
|
||||
if (new_path != NULL) {
|
||||
uv_wtf8_to_utf16(new_path, pos, new_pathw_len);
|
||||
req->fs.info.new_pathw = pos;
|
||||
pos += new_pathw_len;
|
||||
} else {
|
||||
req->fs.info.new_pathw = NULL;
|
||||
}
|
||||
|
||||
req->path = path;
|
||||
if (path != NULL && copy_path) {
|
||||
memcpy(pos, path, path_len);
|
||||
assert(path_len == buf_sz - (pos - buf) * sizeof(WCHAR));
|
||||
req->path = (char*) pos;
|
||||
}
|
||||
|
||||
req->flags |= UV_FS_FREE_PATHS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
req->fs_type = fs_type;
|
||||
req->sys_errno_ = 0;
|
||||
req->result = 0;
|
||||
req->ptr = NULL;
|
||||
req->path = NULL;
|
||||
req->cb = cb;
|
||||
memset(&req->fs, 0, sizeof(req->fs));
|
||||
}
|
||||
|
||||
|
||||
@ -1569,7 +1390,7 @@ void fs__scandir(uv_fs_t* req) {
|
||||
continue;
|
||||
|
||||
/* Compute the space required to store the filename as WTF-8. */
|
||||
wtf8_len = fs__get_length_wide(&info->FileName[0], wchar_len);
|
||||
wtf8_len = uv_utf16_length_as_wtf8(&info->FileName[0], wchar_len);
|
||||
|
||||
/* Resize the dirent array if needed. */
|
||||
if (dirents_used >= dirents_size) {
|
||||
@ -1597,8 +1418,8 @@ void fs__scandir(uv_fs_t* req) {
|
||||
|
||||
/* Convert file name to UTF-8. */
|
||||
wtf8 = &dirent->d_name[0];
|
||||
if (fs__wide_to_wtf8(&info->FileName[0], wchar_len, &wtf8, &wtf8_len) == -1)
|
||||
goto win32_error;
|
||||
if (uv_utf16_to_wtf8(&info->FileName[0], wchar_len, &wtf8, &wtf8_len) != 0)
|
||||
goto out_of_memory_error;
|
||||
|
||||
/* Fill out the type field. */
|
||||
if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE)
|
||||
@ -2824,7 +2645,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
|
||||
}
|
||||
|
||||
assert(*realpath_ptr == NULL);
|
||||
r = fs__wide_to_wtf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL);
|
||||
r = uv_utf16_to_wtf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL);
|
||||
uv__free(w_realpath_buf);
|
||||
return r;
|
||||
}
|
||||
|
156
deps/libuv/src/win/getaddrinfo.c
vendored
156
deps/libuv/src/win/getaddrinfo.c
vendored
@ -104,13 +104,14 @@ static void uv__getaddrinfo_work(struct uv__work* w) {
|
||||
*/
|
||||
static void uv__getaddrinfo_done(struct uv__work* w, int status) {
|
||||
uv_getaddrinfo_t* req;
|
||||
int addrinfo_len = 0;
|
||||
int name_len = 0;
|
||||
size_t addrinfo_len = 0;
|
||||
ssize_t name_len = 0;
|
||||
size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
|
||||
struct addrinfoW* addrinfow_ptr;
|
||||
struct addrinfo* addrinfo_ptr;
|
||||
char* alloc_ptr = NULL;
|
||||
char* cur_ptr = NULL;
|
||||
int r;
|
||||
|
||||
req = container_of(w, uv_getaddrinfo_t, work_req);
|
||||
|
||||
@ -131,19 +132,12 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
|
||||
addrinfo_len += addrinfo_struct_len +
|
||||
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
|
||||
if (addrinfow_ptr->ai_canonname != NULL) {
|
||||
name_len = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
addrinfow_ptr->ai_canonname,
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (name_len == 0) {
|
||||
req->retcode = uv_translate_sys_error(GetLastError());
|
||||
name_len = uv_utf16_length_as_wtf8(addrinfow_ptr->ai_canonname, -1);
|
||||
if (name_len < 0) {
|
||||
req->retcode = name_len;
|
||||
goto complete;
|
||||
}
|
||||
addrinfo_len += ALIGNED_SIZE(name_len);
|
||||
addrinfo_len += ALIGNED_SIZE(name_len + 1);
|
||||
}
|
||||
addrinfow_ptr = addrinfow_ptr->ai_next;
|
||||
}
|
||||
@ -182,27 +176,14 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
|
||||
|
||||
/* convert canonical name to UTF-8 */
|
||||
if (addrinfow_ptr->ai_canonname != NULL) {
|
||||
name_len = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
addrinfow_ptr->ai_canonname,
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
assert(name_len > 0);
|
||||
assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
|
||||
name_len = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
addrinfow_ptr->ai_canonname,
|
||||
-1,
|
||||
cur_ptr,
|
||||
name_len,
|
||||
NULL,
|
||||
NULL);
|
||||
assert(name_len > 0);
|
||||
name_len = alloc_ptr + addrinfo_len - cur_ptr;
|
||||
r = uv__copy_utf16_to_utf8(addrinfow_ptr->ai_canonname,
|
||||
-1,
|
||||
cur_ptr,
|
||||
(size_t*)&name_len);
|
||||
assert(r == 0);
|
||||
addrinfo_ptr->ai_canonname = cur_ptr;
|
||||
cur_ptr += ALIGNED_SIZE(name_len);
|
||||
cur_ptr += ALIGNED_SIZE(name_len + 1);
|
||||
}
|
||||
assert(cur_ptr <= alloc_ptr + addrinfo_len);
|
||||
|
||||
@ -261,12 +242,11 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
const char* service,
|
||||
const struct addrinfo* hints) {
|
||||
char hostname_ascii[256];
|
||||
int nodesize = 0;
|
||||
int servicesize = 0;
|
||||
int hintssize = 0;
|
||||
size_t nodesize = 0;
|
||||
size_t servicesize = 0;
|
||||
size_t hintssize = 0;
|
||||
char* alloc_ptr = NULL;
|
||||
int err;
|
||||
long rc;
|
||||
ssize_t rc;
|
||||
|
||||
if (req == NULL || (node == NULL && service == NULL)) {
|
||||
return UV_EINVAL;
|
||||
@ -286,56 +266,36 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
hostname_ascii + sizeof(hostname_ascii));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, hostname_ascii,
|
||||
-1, NULL, 0) * sizeof(WCHAR));
|
||||
if (nodesize == 0) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
nodesize = strlen(hostname_ascii) + 1;
|
||||
node = hostname_ascii;
|
||||
}
|
||||
|
||||
if (service != NULL) {
|
||||
servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
service,
|
||||
-1,
|
||||
NULL,
|
||||
0) *
|
||||
sizeof(WCHAR));
|
||||
if (servicesize == 0) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
rc = uv_wtf8_length_as_utf16(service);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
servicesize = rc;
|
||||
}
|
||||
if (hints != NULL) {
|
||||
hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW));
|
||||
}
|
||||
|
||||
/* allocate memory for inputs, and partition it as needed */
|
||||
alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize);
|
||||
if (!alloc_ptr) {
|
||||
err = WSAENOBUFS;
|
||||
goto error;
|
||||
}
|
||||
alloc_ptr = uv__malloc(ALIGNED_SIZE(nodesize * sizeof(WCHAR)) +
|
||||
ALIGNED_SIZE(servicesize * sizeof(WCHAR)) +
|
||||
hintssize);
|
||||
if (!alloc_ptr)
|
||||
return UV_ENOMEM;
|
||||
|
||||
/* save alloc_ptr now so we can free if error */
|
||||
req->alloc = (void*)alloc_ptr;
|
||||
req->alloc = (void*) alloc_ptr;
|
||||
|
||||
/* Convert node string to UTF16 into allocated memory and save pointer in the
|
||||
* request. */
|
||||
* request. The node here has been converted to ascii. */
|
||||
if (node != NULL) {
|
||||
req->node = (WCHAR*)alloc_ptr;
|
||||
if (MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
node,
|
||||
-1,
|
||||
(WCHAR*) alloc_ptr,
|
||||
nodesize / sizeof(WCHAR)) == 0) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
alloc_ptr += nodesize;
|
||||
req->node = (WCHAR*) alloc_ptr;
|
||||
uv_wtf8_to_utf16(node, (WCHAR*) alloc_ptr, nodesize);
|
||||
alloc_ptr += ALIGNED_SIZE(nodesize * sizeof(WCHAR));
|
||||
} else {
|
||||
req->node = NULL;
|
||||
}
|
||||
@ -343,24 +303,16 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
/* Convert service string to UTF16 into allocated memory and save pointer in
|
||||
* the req. */
|
||||
if (service != NULL) {
|
||||
req->service = (WCHAR*)alloc_ptr;
|
||||
if (MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
service,
|
||||
-1,
|
||||
(WCHAR*) alloc_ptr,
|
||||
servicesize / sizeof(WCHAR)) == 0) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
alloc_ptr += servicesize;
|
||||
req->service = (WCHAR*) alloc_ptr;
|
||||
uv_wtf8_to_utf16(service, (WCHAR*) alloc_ptr, servicesize);
|
||||
alloc_ptr += ALIGNED_SIZE(servicesize * sizeof(WCHAR));
|
||||
} else {
|
||||
req->service = NULL;
|
||||
}
|
||||
|
||||
/* copy hints to allocated memory and save pointer in req */
|
||||
if (hints != NULL) {
|
||||
req->addrinfow = (struct addrinfoW*)alloc_ptr;
|
||||
req->addrinfow = (struct addrinfoW*) alloc_ptr;
|
||||
req->addrinfow->ai_family = hints->ai_family;
|
||||
req->addrinfow->ai_socktype = hints->ai_socktype;
|
||||
req->addrinfow->ai_protocol = hints->ai_protocol;
|
||||
@ -387,19 +339,11 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
uv__getaddrinfo_done(&req->work_req, 0);
|
||||
return req->retcode;
|
||||
}
|
||||
|
||||
error:
|
||||
if (req != NULL) {
|
||||
uv__free(req->alloc);
|
||||
req->alloc = NULL;
|
||||
}
|
||||
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)
|
||||
@ -415,31 +359,7 @@ int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) {
|
||||
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;
|
||||
return uv__copy_utf16_to_utf8(wname, -1, buffer, size);
|
||||
}
|
||||
|
||||
int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) {
|
||||
|
29
deps/libuv/src/win/getnameinfo.c
vendored
29
deps/libuv/src/win/getnameinfo.c
vendored
@ -42,6 +42,7 @@ static void uv__getnameinfo_work(struct uv__work* w) {
|
||||
uv_getnameinfo_t* req;
|
||||
WCHAR host[NI_MAXHOST];
|
||||
WCHAR service[NI_MAXSERV];
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
req = container_of(w, uv_getnameinfo_t, work_req);
|
||||
@ -57,29 +58,17 @@ static void uv__getnameinfo_work(struct uv__work* w) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
host,
|
||||
-1,
|
||||
req->host,
|
||||
sizeof(req->host),
|
||||
NULL,
|
||||
NULL);
|
||||
if (ret == 0) {
|
||||
req->retcode = uv_translate_sys_error(GetLastError());
|
||||
size = sizeof(req->host);
|
||||
ret = uv__copy_utf16_to_utf8(host, -1, req->host, &size);
|
||||
if (ret < 0) {
|
||||
req->retcode = ret;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
service,
|
||||
-1,
|
||||
req->service,
|
||||
sizeof(req->service),
|
||||
NULL,
|
||||
NULL);
|
||||
if (ret == 0) {
|
||||
req->retcode = uv_translate_sys_error(GetLastError());
|
||||
size = sizeof(req->service);
|
||||
ret = uv__copy_utf16_to_utf8(service, -1, req->service, &size);
|
||||
if (ret < 0) {
|
||||
req->retcode = ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
5
deps/libuv/src/win/internal.h
vendored
5
deps/libuv/src/win/internal.h
vendored
@ -257,8 +257,9 @@ void uv__util_init(void);
|
||||
|
||||
uint64_t uv__hrtime(unsigned int scale);
|
||||
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
|
||||
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16);
|
||||
int uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8);
|
||||
int uv__copy_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char* utf8, size_t *size);
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16);
|
||||
|
||||
typedef int (WINAPI *uv__peersockfunc)(SOCKET, struct sockaddr*, int*);
|
||||
|
||||
|
146
deps/libuv/src/win/pipe.c
vendored
146
deps/libuv/src/win/pipe.c
vendored
@ -49,7 +49,7 @@ static const int default_pending_pipe_instances = 4;
|
||||
|
||||
/* Pipe prefix */
|
||||
static char pipe_prefix[] = "\\\\?\\pipe";
|
||||
static const int pipe_prefix_len = sizeof(pipe_prefix) - 1;
|
||||
static const size_t pipe_prefix_len = sizeof(pipe_prefix) - 1;
|
||||
|
||||
/* IPC incoming xfer queue item. */
|
||||
typedef struct {
|
||||
@ -703,7 +703,7 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
size_t namelen,
|
||||
unsigned int flags) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
int i, err, nameSize;
|
||||
int i, err;
|
||||
uv_pipe_accept_t* req;
|
||||
|
||||
if (flags & ~UV_PIPE_NO_TRUNCATE) {
|
||||
@ -742,9 +742,8 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
|
||||
handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
|
||||
uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
|
||||
if (!handle->pipe.serv.accept_reqs) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
if (!handle->pipe.serv.accept_reqs)
|
||||
return UV_ENOMEM;
|
||||
|
||||
for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
|
||||
req = &handle->pipe.serv.accept_reqs[i];
|
||||
@ -754,22 +753,9 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
req->next_pending = NULL;
|
||||
}
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
|
||||
handle->name = uv__malloc(nameSize);
|
||||
if (!handle->name) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
name,
|
||||
-1,
|
||||
handle->name,
|
||||
nameSize / sizeof(WCHAR))) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
err = uv__convert_utf8_to_utf16(name, &handle->name);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
|
||||
@ -795,10 +781,8 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (handle->name) {
|
||||
uv__free(handle->name);
|
||||
handle->name = NULL;
|
||||
}
|
||||
uv__free(handle->name);
|
||||
handle->name = NULL;
|
||||
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
@ -861,7 +845,8 @@ int uv_pipe_connect2(uv_connect_t* req,
|
||||
unsigned int flags,
|
||||
uv_connect_cb cb) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
int err, nameSize;
|
||||
int err;
|
||||
size_t nameSize;
|
||||
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
|
||||
DWORD duplex_flags;
|
||||
|
||||
@ -904,26 +889,16 @@ int uv_pipe_connect2(uv_connect_t* req,
|
||||
}
|
||||
uv__pipe_connection_init(handle);
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
|
||||
handle->name = uv__malloc(nameSize);
|
||||
if (!handle->name) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
name,
|
||||
-1,
|
||||
handle->name,
|
||||
nameSize / sizeof(WCHAR))) {
|
||||
err = GetLastError();
|
||||
err = uv__convert_utf8_to_utf16(name, &handle->name);
|
||||
if (err) {
|
||||
err = ERROR_NO_UNICODE_TRANSLATION;
|
||||
goto error;
|
||||
}
|
||||
|
||||
pipeHandle = open_named_pipe(handle->name, &duplex_flags);
|
||||
if (pipeHandle == INVALID_HANDLE_VALUE) {
|
||||
if (GetLastError() == ERROR_PIPE_BUSY) {
|
||||
nameSize = (wcslen(handle->name) + 1) * sizeof(WCHAR);
|
||||
req->u.connect.name = uv__malloc(nameSize);
|
||||
if (!req->u.connect.name) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
@ -2439,7 +2414,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||
FILE_NAME_INFORMATION tmp_name_info;
|
||||
FILE_NAME_INFORMATION* name_info;
|
||||
WCHAR* name_buf;
|
||||
unsigned int addrlen;
|
||||
unsigned int name_size;
|
||||
unsigned int name_len;
|
||||
int err;
|
||||
@ -2450,46 +2424,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||
if (handle->name != NULL) {
|
||||
/* The user might try to query the name before we are connected,
|
||||
* and this is just easier to return the cached value if we have it. */
|
||||
name_buf = handle->name;
|
||||
name_len = wcslen(name_buf);
|
||||
|
||||
/* check how much space we need */
|
||||
addrlen = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
name_buf,
|
||||
name_len,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!addrlen) {
|
||||
*size = 0;
|
||||
err = uv_translate_sys_error(GetLastError());
|
||||
return err;
|
||||
} else if (addrlen >= *size) {
|
||||
*size = addrlen + 1;
|
||||
err = UV_ENOBUFS;
|
||||
goto error;
|
||||
}
|
||||
|
||||
addrlen = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
name_buf,
|
||||
name_len,
|
||||
buffer,
|
||||
addrlen,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!addrlen) {
|
||||
*size = 0;
|
||||
err = uv_translate_sys_error(GetLastError());
|
||||
return err;
|
||||
}
|
||||
|
||||
*size = addrlen;
|
||||
buffer[addrlen] = '\0';
|
||||
|
||||
return 0;
|
||||
return uv__copy_utf16_to_utf8(handle->name, -1, buffer, size);
|
||||
}
|
||||
|
||||
if (handle->handle == INVALID_HANDLE_VALUE) {
|
||||
@ -2517,8 +2452,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||
name_info = uv__malloc(name_size);
|
||||
if (!name_info) {
|
||||
*size = 0;
|
||||
err = UV_ENOMEM;
|
||||
goto cleanup;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
nt_status = pNtQueryInformationFile(handle->handle,
|
||||
@ -2551,51 +2485,19 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||
|
||||
name_len /= sizeof(WCHAR);
|
||||
|
||||
/* check how much space we need */
|
||||
addrlen = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
name_buf,
|
||||
name_len,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!addrlen) {
|
||||
/* "\\\\.\\pipe" + name */
|
||||
if (*size < pipe_prefix_len) {
|
||||
*size = 0;
|
||||
err = uv_translate_sys_error(GetLastError());
|
||||
goto error;
|
||||
} else if (pipe_prefix_len + addrlen >= *size) {
|
||||
/* "\\\\.\\pipe" + name */
|
||||
*size = pipe_prefix_len + addrlen + 1;
|
||||
err = UV_ENOBUFS;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(buffer, pipe_prefix, pipe_prefix_len);
|
||||
addrlen = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
name_buf,
|
||||
name_len,
|
||||
buffer+pipe_prefix_len,
|
||||
*size-pipe_prefix_len,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!addrlen) {
|
||||
*size = 0;
|
||||
err = uv_translate_sys_error(GetLastError());
|
||||
goto error;
|
||||
else {
|
||||
memcpy(buffer, pipe_prefix, pipe_prefix_len);
|
||||
*size -= pipe_prefix_len;
|
||||
}
|
||||
|
||||
addrlen += pipe_prefix_len;
|
||||
*size = addrlen;
|
||||
buffer[addrlen] = '\0';
|
||||
|
||||
err = 0;
|
||||
err = uv__copy_utf16_to_utf8(name_buf, name_len, buffer+pipe_prefix_len, size);
|
||||
*size += pipe_prefix_len;
|
||||
|
||||
error:
|
||||
uv__free(name_info);
|
||||
|
||||
cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
192
deps/libuv/src/win/process.c
vendored
192
deps/libuv/src/win/process.c
vendored
@ -105,38 +105,26 @@ static void uv__init_global_job_handle(void) {
|
||||
&info,
|
||||
sizeof info))
|
||||
uv_fatal_error(GetLastError(), "SetInformationJobObject");
|
||||
|
||||
|
||||
if (!AssignProcessToJobObject(uv_global_job_handle_, GetCurrentProcess())) {
|
||||
/* Make sure this handle is functional. The Windows kernel has a bug that
|
||||
* if the first use of AssignProcessToJobObject is for a Windows Store
|
||||
* program, subsequent attempts to use the handle with fail with
|
||||
* INVALID_PARAMETER (87). This is possibly because all uses of the handle
|
||||
* must be for the same Terminal Services session. We can ensure it is tied
|
||||
* to our current session now by adding ourself to it. We could remove
|
||||
* ourself afterwards, but there doesn't seem to be a reason to.
|
||||
*/
|
||||
DWORD err = GetLastError();
|
||||
if (err != ERROR_ACCESS_DENIED)
|
||||
uv_fatal_error(err, "AssignProcessToJobObject");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int uv__utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) {
|
||||
int ws_len, r;
|
||||
WCHAR* ws;
|
||||
|
||||
ws_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
s,
|
||||
-1,
|
||||
NULL,
|
||||
0);
|
||||
if (ws_len <= 0) {
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR));
|
||||
if (ws == NULL) {
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
r = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
s,
|
||||
-1,
|
||||
ws,
|
||||
ws_len);
|
||||
assert(r == ws_len);
|
||||
|
||||
*ws_ptr = ws;
|
||||
return 0;
|
||||
return uv__convert_utf8_to_utf16(s, ws_ptr);
|
||||
}
|
||||
|
||||
|
||||
@ -396,7 +384,7 @@ static WCHAR* search_path(const WCHAR *file,
|
||||
name_has_ext);
|
||||
|
||||
while (result == NULL) {
|
||||
if (*dir_end == L'\0') {
|
||||
if (dir_end == NULL || *dir_end == L'\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -539,21 +527,15 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
|
||||
|
||||
/* Count the required size. */
|
||||
for (arg = args; *arg; arg++) {
|
||||
DWORD arg_len;
|
||||
ssize_t arg_len;
|
||||
|
||||
arg_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
*arg,
|
||||
-1,
|
||||
NULL,
|
||||
0);
|
||||
if (arg_len == 0) {
|
||||
return GetLastError();
|
||||
}
|
||||
arg_len = uv_wtf8_length_as_utf16(*arg);
|
||||
if (arg_len < 0)
|
||||
return arg_len;
|
||||
|
||||
dst_len += arg_len;
|
||||
|
||||
if (arg_len > temp_buffer_len)
|
||||
if ((size_t) arg_len > temp_buffer_len)
|
||||
temp_buffer_len = arg_len;
|
||||
|
||||
arg_count++;
|
||||
@ -564,34 +546,28 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
|
||||
dst_len = dst_len * 2 + arg_count * 2;
|
||||
|
||||
/* Allocate buffer for the final command line. */
|
||||
dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR));
|
||||
dst = uv__malloc(dst_len * sizeof(WCHAR));
|
||||
if (dst == NULL) {
|
||||
err = ERROR_OUTOFMEMORY;
|
||||
err = UV_ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Allocate temporary working buffer. */
|
||||
temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR));
|
||||
temp_buffer = uv__malloc(temp_buffer_len * sizeof(WCHAR));
|
||||
if (temp_buffer == NULL) {
|
||||
err = ERROR_OUTOFMEMORY;
|
||||
err = UV_ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
pos = dst;
|
||||
for (arg = args; *arg; arg++) {
|
||||
DWORD arg_len;
|
||||
ssize_t arg_len;
|
||||
|
||||
/* Convert argument to wide char. */
|
||||
arg_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
*arg,
|
||||
-1,
|
||||
temp_buffer,
|
||||
(int) (dst + dst_len - pos));
|
||||
if (arg_len == 0) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
arg_len = uv_wtf8_length_as_utf16(*arg);
|
||||
assert(arg_len > 0);
|
||||
assert(temp_buffer_len >= (size_t) arg_len);
|
||||
uv_wtf8_to_utf16(*arg, temp_buffer, arg_len);
|
||||
|
||||
if (verbatim_arguments) {
|
||||
/* Copy verbatim. */
|
||||
@ -603,6 +579,7 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
|
||||
}
|
||||
|
||||
*pos++ = *(arg + 1) ? L' ' : L'\0';
|
||||
assert(pos <= dst + dst_len);
|
||||
}
|
||||
|
||||
uv__free(temp_buffer);
|
||||
@ -688,55 +665,43 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
||||
WCHAR* ptr;
|
||||
char** env;
|
||||
size_t env_len = 0;
|
||||
int len;
|
||||
size_t len;
|
||||
size_t i;
|
||||
DWORD var_size;
|
||||
size_t var_size;
|
||||
size_t env_block_count = 1; /* 1 for null-terminator */
|
||||
WCHAR* dst_copy;
|
||||
WCHAR** ptr_copy;
|
||||
WCHAR** env_copy;
|
||||
DWORD required_vars_value_len[ARRAY_SIZE(required_vars)];
|
||||
size_t required_vars_value_len[ARRAY_SIZE(required_vars)];
|
||||
|
||||
/* first pass: determine size in UTF-16 */
|
||||
for (env = env_block; *env; env++) {
|
||||
int len;
|
||||
ssize_t len;
|
||||
if (strchr(*env, '=')) {
|
||||
len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
*env,
|
||||
-1,
|
||||
NULL,
|
||||
0);
|
||||
if (len <= 0) {
|
||||
return GetLastError();
|
||||
}
|
||||
len = uv_wtf8_length_as_utf16(*env);
|
||||
if (len < 0)
|
||||
return len;
|
||||
env_len += len;
|
||||
env_block_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* second pass: copy to UTF-16 environment block */
|
||||
dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR));
|
||||
dst_copy = uv__malloc(env_len * sizeof(WCHAR));
|
||||
if (dst_copy == NULL && env_len > 0) {
|
||||
return ERROR_OUTOFMEMORY;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
env_copy = alloca(env_block_count * sizeof(WCHAR*));
|
||||
|
||||
ptr = dst_copy;
|
||||
ptr_copy = env_copy;
|
||||
for (env = env_block; *env; env++) {
|
||||
ssize_t len;
|
||||
if (strchr(*env, '=')) {
|
||||
len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
*env,
|
||||
-1,
|
||||
ptr,
|
||||
(int) (env_len - (ptr - dst_copy)));
|
||||
if (len <= 0) {
|
||||
DWORD err = GetLastError();
|
||||
uv__free(dst_copy);
|
||||
return err;
|
||||
}
|
||||
len = uv_wtf8_length_as_utf16(*env);
|
||||
assert(len > 0);
|
||||
assert((size_t) len <= env_len - (ptr - dst_copy));
|
||||
uv_wtf8_to_utf16(*env, ptr, len);
|
||||
*ptr_copy++ = ptr;
|
||||
ptr += len;
|
||||
}
|
||||
@ -754,7 +719,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
||||
cmp = -1;
|
||||
} else {
|
||||
cmp = env_strncmp(required_vars[i].wide_eq,
|
||||
required_vars[i].len,
|
||||
required_vars[i].len,
|
||||
*ptr_copy);
|
||||
}
|
||||
if (cmp < 0) {
|
||||
@ -777,7 +742,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
||||
dst = uv__malloc((1+env_len) * sizeof(WCHAR));
|
||||
if (!dst) {
|
||||
uv__free(dst_copy);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
for (ptr = dst, ptr_copy = env_copy, i = 0;
|
||||
@ -975,26 +940,26 @@ int uv_spawn(uv_loop_t* loop,
|
||||
|
||||
err = uv__utf8_to_utf16_alloc(options->file, &application);
|
||||
if (err)
|
||||
goto done;
|
||||
goto done_uv;
|
||||
|
||||
err = make_program_args(
|
||||
options->args,
|
||||
options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
|
||||
&arguments);
|
||||
if (err)
|
||||
goto done;
|
||||
goto done_uv;
|
||||
|
||||
if (options->env) {
|
||||
err = make_program_env(options->env, &env);
|
||||
if (err)
|
||||
goto done;
|
||||
goto done_uv;
|
||||
}
|
||||
|
||||
if (options->cwd) {
|
||||
/* Explicit cwd */
|
||||
err = uv__utf8_to_utf16_alloc(options->cwd, &cwd);
|
||||
if (err)
|
||||
goto done;
|
||||
goto done_uv;
|
||||
|
||||
} else {
|
||||
/* Inherit cwd */
|
||||
@ -1025,22 +990,19 @@ int uv_spawn(uv_loop_t* loop,
|
||||
DWORD path_len, r;
|
||||
|
||||
path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
|
||||
if (path_len == 0) {
|
||||
err = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
if (path_len != 0) {
|
||||
alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
|
||||
if (alloc_path == NULL) {
|
||||
err = ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
path = alloc_path;
|
||||
|
||||
alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
|
||||
if (alloc_path == NULL) {
|
||||
err = ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
path = alloc_path;
|
||||
|
||||
r = GetEnvironmentVariableW(L"PATH", path, path_len);
|
||||
if (r == 0 || r >= path_len) {
|
||||
err = GetLastError();
|
||||
goto done;
|
||||
r = GetEnvironmentVariableW(L"PATH", path, path_len);
|
||||
if (r == 0 || r >= path_len) {
|
||||
err = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,6 +1064,7 @@ int uv_spawn(uv_loop_t* loop,
|
||||
* breakaway.
|
||||
*/
|
||||
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
|
||||
process_flags |= CREATE_SUSPENDED;
|
||||
}
|
||||
|
||||
if (!CreateProcessW(application_path,
|
||||
@ -1119,11 +1082,6 @@ int uv_spawn(uv_loop_t* loop,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
|
||||
|
||||
process->process_handle = info.hProcess;
|
||||
process->pid = info.dwProcessId;
|
||||
|
||||
/* If the process isn't spawned as detached, assign to the global job object
|
||||
* so windows will kill it when the parent process dies. */
|
||||
if (!(options->flags & UV_PROCESS_DETACHED)) {
|
||||
@ -1146,6 +1104,19 @@ int uv_spawn(uv_loop_t* loop,
|
||||
}
|
||||
}
|
||||
|
||||
if (process_flags & CREATE_SUSPENDED) {
|
||||
if (ResumeThread(info.hThread) == ((DWORD)-1)) {
|
||||
err = GetLastError();
|
||||
TerminateProcess(info.hProcess, 1);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
|
||||
|
||||
process->process_handle = info.hProcess;
|
||||
process->pid = info.dwProcessId;
|
||||
|
||||
/* Set IPC pid to all IPC pipes. */
|
||||
for (i = 0; i < options->stdio_count; i++) {
|
||||
const uv_stdio_container_t* fdopt = &options->stdio[i];
|
||||
@ -1173,8 +1144,13 @@ int uv_spawn(uv_loop_t* loop,
|
||||
* made or the handle is closed, whichever happens first. */
|
||||
uv__handle_start(process);
|
||||
|
||||
goto done_uv;
|
||||
|
||||
/* Cleanup, whether we succeeded or failed. */
|
||||
done:
|
||||
err = uv_translate_sys_error(err);
|
||||
|
||||
done_uv:
|
||||
uv__free(application);
|
||||
uv__free(application_path);
|
||||
uv__free(arguments);
|
||||
@ -1188,7 +1164,7 @@ int uv_spawn(uv_loop_t* loop,
|
||||
child_stdio_buffer = NULL;
|
||||
}
|
||||
|
||||
return uv_translate_sys_error(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
62
deps/libuv/src/win/tty.c
vendored
62
deps/libuv/src/win/tty.c
vendored
@ -482,9 +482,11 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
|
||||
uv_loop_t* loop;
|
||||
uv_tty_t* handle;
|
||||
uv_req_t* req;
|
||||
DWORD bytes, read_bytes;
|
||||
DWORD bytes;
|
||||
size_t read_bytes;
|
||||
WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3];
|
||||
DWORD chars, read_chars;
|
||||
DWORD chars;
|
||||
DWORD read_chars;
|
||||
LONG status;
|
||||
COORD pos;
|
||||
BOOL read_console_success;
|
||||
@ -525,16 +527,13 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
|
||||
NULL);
|
||||
|
||||
if (read_console_success) {
|
||||
read_bytes = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16,
|
||||
read_chars,
|
||||
handle->tty.rd.read_line_buffer.base,
|
||||
bytes,
|
||||
NULL,
|
||||
NULL);
|
||||
read_bytes = bytes;
|
||||
uv_utf16_to_wtf8(utf16,
|
||||
read_chars,
|
||||
&handle->tty.rd.read_line_buffer.base,
|
||||
&read_bytes);
|
||||
SET_REQ_SUCCESS(req);
|
||||
req->u.io.overlapped.InternalHigh = read_bytes;
|
||||
req->u.io.overlapped.InternalHigh = (DWORD) read_bytes;
|
||||
} else {
|
||||
SET_REQ_ERROR(req, GetLastError());
|
||||
}
|
||||
@ -798,7 +797,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
}
|
||||
|
||||
if (KEV.uChar.UnicodeChar != 0) {
|
||||
int prefix_len, char_len;
|
||||
int prefix_len;
|
||||
size_t char_len;
|
||||
char* last_key_buf;
|
||||
|
||||
/* Character key pressed */
|
||||
if (KEV.uChar.UnicodeChar >= 0xD800 &&
|
||||
@ -819,38 +820,31 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
prefix_len = 0;
|
||||
}
|
||||
|
||||
if (KEV.uChar.UnicodeChar >= 0xDC00 &&
|
||||
KEV.uChar.UnicodeChar < 0xE000) {
|
||||
char_len = sizeof handle->tty.rd.last_key;
|
||||
last_key_buf = &handle->tty.rd.last_key[prefix_len];
|
||||
if (handle->tty.rd.last_utf16_high_surrogate) {
|
||||
/* UTF-16 surrogate pair */
|
||||
WCHAR utf16_buffer[2];
|
||||
utf16_buffer[0] = handle->tty.rd.last_utf16_high_surrogate;
|
||||
utf16_buffer[1] = KEV.uChar.UnicodeChar;
|
||||
char_len = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16_buffer,
|
||||
2,
|
||||
&handle->tty.rd.last_key[prefix_len],
|
||||
sizeof handle->tty.rd.last_key,
|
||||
NULL,
|
||||
NULL);
|
||||
if (uv_utf16_to_wtf8(utf16_buffer,
|
||||
2,
|
||||
&last_key_buf,
|
||||
&char_len))
|
||||
char_len = 0;
|
||||
handle->tty.rd.last_utf16_high_surrogate = 0;
|
||||
} else {
|
||||
/* Single UTF-16 character */
|
||||
char_len = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
&KEV.uChar.UnicodeChar,
|
||||
1,
|
||||
&handle->tty.rd.last_key[prefix_len],
|
||||
sizeof handle->tty.rd.last_key,
|
||||
NULL,
|
||||
NULL);
|
||||
if (uv_utf16_to_wtf8(&KEV.uChar.UnicodeChar,
|
||||
1,
|
||||
&last_key_buf,
|
||||
&char_len))
|
||||
char_len = 0;
|
||||
}
|
||||
|
||||
/* Whatever happened, the last character wasn't a high surrogate. */
|
||||
handle->tty.rd.last_utf16_high_surrogate = 0;
|
||||
|
||||
/* If the utf16 character(s) couldn't be converted something must be
|
||||
* wrong. */
|
||||
if (!char_len) {
|
||||
if (char_len == 0) {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||
handle->read_cb((uv_stream_t*) handle,
|
||||
|
410
deps/libuv/src/win/util.c
vendored
410
deps/libuv/src/win/util.c
vendored
@ -95,7 +95,7 @@ void uv__util_init(void) {
|
||||
|
||||
|
||||
int uv_exepath(char* buffer, size_t* size_ptr) {
|
||||
int utf8_len, utf16_buffer_len, utf16_len;
|
||||
size_t utf8_len, utf16_buffer_len, utf16_len;
|
||||
WCHAR* utf16_buffer;
|
||||
int err;
|
||||
|
||||
@ -123,25 +123,17 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
|
||||
}
|
||||
|
||||
/* Convert to UTF-8 */
|
||||
utf8_len = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16_buffer,
|
||||
-1,
|
||||
buffer,
|
||||
(int) *size_ptr,
|
||||
NULL,
|
||||
NULL);
|
||||
if (utf8_len == 0) {
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
utf8_len = *size_ptr - 1; /* Reserve space for NUL */
|
||||
err = uv_utf16_to_wtf8(utf16_buffer, utf16_len, &buffer, &utf8_len);
|
||||
if (err == UV_ENOBUFS) {
|
||||
utf8_len = *size_ptr - 1;
|
||||
err = 0;
|
||||
}
|
||||
*size_ptr = utf8_len;
|
||||
|
||||
uv__free(utf16_buffer);
|
||||
|
||||
/* utf8_len *does* include the terminating null at this point, but the
|
||||
* returned size shouldn't. */
|
||||
*size_ptr = utf8_len - 1;
|
||||
return 0;
|
||||
return err;
|
||||
|
||||
error:
|
||||
uv__free(utf16_buffer);
|
||||
@ -204,45 +196,14 @@ int uv_cwd(char* buffer, size_t* size) {
|
||||
}
|
||||
|
||||
r = uv__cwd(&utf16_buffer, &utf16_len);
|
||||
if (r < 0) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Check how much space we need */
|
||||
r = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16_buffer,
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (r == 0) {
|
||||
uv__free(utf16_buffer);
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
} else if (r > (int) *size) {
|
||||
uv__free(utf16_buffer);
|
||||
*size = r;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
r = uv__copy_utf16_to_utf8(utf16_buffer, utf16_len, buffer, size);
|
||||
|
||||
/* Convert to UTF-8 */
|
||||
r = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16_buffer,
|
||||
-1,
|
||||
buffer,
|
||||
*size > INT_MAX ? INT_MAX : (int) *size,
|
||||
NULL,
|
||||
NULL);
|
||||
uv__free(utf16_buffer);
|
||||
|
||||
if (r == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
*size = r - 1;
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -252,33 +213,10 @@ int uv_chdir(const char* dir) {
|
||||
WCHAR drive_letter, env_var[4];
|
||||
int r;
|
||||
|
||||
if (dir == NULL) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
utf16_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
dir,
|
||||
-1,
|
||||
NULL,
|
||||
0);
|
||||
if (utf16_len == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
|
||||
if (utf16_buffer == NULL) {
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
if (MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
dir,
|
||||
-1,
|
||||
utf16_buffer,
|
||||
utf16_len) == 0) {
|
||||
uv__free(utf16_buffer);
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
/* Convert to UTF-16 */
|
||||
r = uv__convert_utf8_to_utf16(dir, &utf16_buffer);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (!SetCurrentDirectoryW(utf16_buffer)) {
|
||||
uv__free(utf16_buffer);
|
||||
@ -416,29 +354,14 @@ int uv_set_process_title(const char* title) {
|
||||
|
||||
uv__once_init();
|
||||
|
||||
/* Find out how big the buffer for the wide-char title must be */
|
||||
length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
|
||||
if (!length) {
|
||||
err = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Convert to wide-char string */
|
||||
title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length);
|
||||
if (!title_w) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
|
||||
length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length);
|
||||
if (!length) {
|
||||
err = GetLastError();
|
||||
goto done;
|
||||
}
|
||||
err = uv__convert_utf8_to_utf16(title, &title_w);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* If the title must be truncated insert a \0 terminator there */
|
||||
if (length > MAX_TITLE_LENGTH) {
|
||||
length = wcslen(title_w);
|
||||
if (length >= MAX_TITLE_LENGTH)
|
||||
title_w[MAX_TITLE_LENGTH - 1] = L'\0';
|
||||
}
|
||||
|
||||
if (!SetConsoleTitleW(title_w)) {
|
||||
err = GetLastError();
|
||||
@ -460,20 +383,19 @@ done:
|
||||
|
||||
static int uv__get_process_title(void) {
|
||||
WCHAR title_w[MAX_TITLE_LENGTH];
|
||||
DWORD wlen;
|
||||
|
||||
if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
|
||||
return -1;
|
||||
}
|
||||
wlen = GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR));
|
||||
if (wlen == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return uv__convert_utf16_to_utf8(title_w, wlen, &process_title);
|
||||
}
|
||||
|
||||
|
||||
int uv_get_process_title(char* buffer, size_t size) {
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
if (buffer == NULL || size == 0)
|
||||
return UV_EINVAL;
|
||||
@ -485,9 +407,12 @@ int uv_get_process_title(char* buffer, size_t size) {
|
||||
* If the process_title was never read before nor explicitly set,
|
||||
* we must query it with getConsoleTitleW
|
||||
*/
|
||||
if (!process_title && uv__get_process_title() == -1) {
|
||||
LeaveCriticalSection(&process_title_lock);
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
if (process_title == NULL) {
|
||||
r = uv__get_process_title();
|
||||
if (r) {
|
||||
LeaveCriticalSection(&process_title_lock);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
assert(process_title);
|
||||
@ -833,19 +758,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
continue;
|
||||
|
||||
/* Compute the size of the interface name. */
|
||||
name_size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
adapter->FriendlyName,
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
FALSE);
|
||||
if (name_size <= 0) {
|
||||
uv__free(win_address_buf);
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
uv_address_buf_size += name_size;
|
||||
name_size = uv_utf16_length_as_wtf8(adapter->FriendlyName, -1);
|
||||
uv_address_buf_size += name_size + 1;
|
||||
|
||||
/* Count the number of addresses associated with this interface, and
|
||||
* compute the size. */
|
||||
@ -875,30 +789,25 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
adapter != NULL;
|
||||
adapter = adapter->Next) {
|
||||
IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
|
||||
int name_size;
|
||||
size_t max_name_size;
|
||||
size_t name_size;
|
||||
int r;
|
||||
|
||||
if (adapter->OperStatus != IfOperStatusUp ||
|
||||
adapter->FirstUnicastAddress == NULL)
|
||||
continue;
|
||||
|
||||
/* Convert the interface name to UTF8. */
|
||||
max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf;
|
||||
if (max_name_size > (size_t) INT_MAX)
|
||||
max_name_size = INT_MAX;
|
||||
name_size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
adapter->FriendlyName,
|
||||
-1,
|
||||
name_buf,
|
||||
(int) max_name_size,
|
||||
NULL,
|
||||
FALSE);
|
||||
if (name_size <= 0) {
|
||||
name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf;
|
||||
r = uv__copy_utf16_to_utf8(adapter->FriendlyName,
|
||||
-1,
|
||||
name_buf,
|
||||
&name_size);
|
||||
if (r) {
|
||||
uv__free(win_address_buf);
|
||||
uv__free(uv_address_buf);
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
return r;
|
||||
}
|
||||
name_size += 1; /* Add NUL byte. */
|
||||
|
||||
/* Add an uv_interface_address_t element for every unicast address. */
|
||||
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
|
||||
@ -1061,7 +970,6 @@ int uv_os_homedir(char* buffer, size_t* size) {
|
||||
|
||||
int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||
wchar_t *path;
|
||||
DWORD bufsize;
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
@ -1078,7 +986,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||
if (path == NULL) {
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
len = GetTempPathW(len, path);
|
||||
len = GetTempPathW(len, path);
|
||||
|
||||
if (len == 0) {
|
||||
uv__free(path);
|
||||
@ -1093,34 +1001,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||
path[len] = L'\0';
|
||||
}
|
||||
|
||||
/* Check how much space we need */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
if (bufsize == 0) {
|
||||
uv__free(path);
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
} else if (bufsize > *size) {
|
||||
uv__free(path);
|
||||
*size = bufsize;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
/* Convert to UTF-8 */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
path,
|
||||
-1,
|
||||
buffer,
|
||||
*size,
|
||||
NULL,
|
||||
NULL);
|
||||
uv__free(path);
|
||||
|
||||
if (bufsize == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
*size = bufsize - 1;
|
||||
return 0;
|
||||
return uv__copy_utf16_to_utf8(path, len, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
@ -1131,95 +1012,71 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||
* If utf16 is null terminated, utf16len can be set to -1, otherwise it must
|
||||
* be specified.
|
||||
*/
|
||||
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
|
||||
DWORD bufsize;
|
||||
int uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8) {
|
||||
size_t utf8_len = 0;
|
||||
|
||||
if (utf16 == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Check how much space we need */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16,
|
||||
utf16len,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (bufsize == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
/* Allocate the destination buffer adding an extra byte for the terminating
|
||||
* NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so
|
||||
* we do it ourselves always, just in case. */
|
||||
*utf8 = uv__malloc(bufsize + 1);
|
||||
|
||||
if (*utf8 == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
/* Convert to UTF-8 */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
utf16,
|
||||
utf16len,
|
||||
*utf8,
|
||||
bufsize,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (bufsize == 0) {
|
||||
uv__free(*utf8);
|
||||
*utf8 = NULL;
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
(*utf8)[bufsize] = '\0';
|
||||
return 0;
|
||||
*utf8 = NULL;
|
||||
return uv_utf16_to_wtf8(utf16, utf16len, utf8, &utf8_len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Converts a UTF-8 string into a UTF-16 one. The resulting string is
|
||||
* null-terminated.
|
||||
*
|
||||
* If utf8 is null terminated, utf8len can be set to -1, otherwise it must
|
||||
* be specified.
|
||||
*/
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16) {
|
||||
int bufsize;
|
||||
|
||||
if (utf8 == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Check how much space we need */
|
||||
bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0);
|
||||
/* Check how much space we need (including NUL). */
|
||||
bufsize = uv_wtf8_length_as_utf16(utf8);
|
||||
if (bufsize < 0)
|
||||
return UV__EINVAL;
|
||||
|
||||
if (bufsize == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
/* Allocate the destination buffer adding an extra byte for the terminating
|
||||
* NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so
|
||||
* we do it ourselves always, just in case. */
|
||||
*utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1));
|
||||
/* Allocate the destination buffer. */
|
||||
*utf16 = uv__malloc(sizeof(WCHAR) * bufsize);
|
||||
|
||||
if (*utf16 == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
/* Convert to UTF-16 */
|
||||
bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
|
||||
uv_wtf8_to_utf16(utf8, *utf16, bufsize);
|
||||
|
||||
if (bufsize == 0) {
|
||||
uv__free(*utf16);
|
||||
*utf16 = NULL;
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
(*utf16)[bufsize] = L'\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Converts a UTF-16 string into a UTF-8 one in an existing buffer. The
|
||||
* resulting string is null-terminated.
|
||||
*
|
||||
* If utf16 is null terminated, utf16len can be set to -1, otherwise it must
|
||||
* be specified.
|
||||
*/
|
||||
int uv__copy_utf16_to_utf8(const WCHAR* utf16buffer, size_t utf16len, char* utf8, size_t *size) {
|
||||
int r;
|
||||
|
||||
if (utf8 == NULL || size == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (*size == 0) {
|
||||
*size = uv_utf16_length_as_wtf8(utf16buffer, utf16len);
|
||||
r = UV_ENOBUFS;
|
||||
} else {
|
||||
*size -= 1; /* Reserve space for NUL. */
|
||||
r = uv_utf16_to_wtf8(utf16buffer, utf16len, &utf8, size);
|
||||
}
|
||||
if (r == UV_ENOBUFS)
|
||||
*size += 1; /* Add space for NUL. */
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
HANDLE token;
|
||||
wchar_t username[UNLEN + 1];
|
||||
@ -1384,14 +1241,13 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
|
||||
wchar_t* var;
|
||||
DWORD varlen;
|
||||
wchar_t* name_w;
|
||||
DWORD bufsize;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
if (name == NULL || buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(name, -1, &name_w);
|
||||
r = uv__convert_utf8_to_utf16(name, &name_w);
|
||||
|
||||
if (r != 0)
|
||||
return r;
|
||||
@ -1432,35 +1288,7 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Check how much space we need */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
if (bufsize == 0) {
|
||||
r = uv_translate_sys_error(GetLastError());
|
||||
goto fail;
|
||||
} else if (bufsize > *size) {
|
||||
*size = bufsize;
|
||||
r = UV_ENOBUFS;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Convert to UTF-8 */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
var,
|
||||
-1,
|
||||
buffer,
|
||||
*size,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (bufsize == 0) {
|
||||
r = uv_translate_sys_error(GetLastError());
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*size = bufsize - 1;
|
||||
r = 0;
|
||||
r = uv__copy_utf16_to_utf8(var, len, buffer, size);
|
||||
|
||||
fail:
|
||||
|
||||
@ -1482,12 +1310,12 @@ int uv_os_setenv(const char* name, const char* value) {
|
||||
if (name == NULL || value == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(name, -1, &name_w);
|
||||
r = uv__convert_utf8_to_utf16(name, &name_w);
|
||||
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(value, -1, &value_w);
|
||||
r = uv__convert_utf8_to_utf16(value, &value_w);
|
||||
|
||||
if (r != 0) {
|
||||
uv__free(name_w);
|
||||
@ -1512,7 +1340,7 @@ int uv_os_unsetenv(const char* name) {
|
||||
if (name == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(name, -1, &name_w);
|
||||
r = uv__convert_utf8_to_utf16(name, &name_w);
|
||||
|
||||
if (r != 0)
|
||||
return r;
|
||||
@ -1529,9 +1357,6 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
WCHAR buf[UV_MAXHOSTNAMESIZE];
|
||||
size_t len;
|
||||
char* utf8_str;
|
||||
int convert_result;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
@ -1544,22 +1369,7 @@ int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
if (pGetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str);
|
||||
|
||||
if (convert_result != 0)
|
||||
return convert_result;
|
||||
|
||||
len = strlen(utf8_str);
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
uv__free(utf8_str);
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, utf8_str, len + 1);
|
||||
uv__free(utf8_str);
|
||||
*size = len;
|
||||
return 0;
|
||||
return uv__copy_utf16_to_utf8(buf, -1, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
@ -1665,7 +1475,7 @@ int uv_os_uname(uv_utsname_t* buffer) {
|
||||
HKEY registry_key;
|
||||
WCHAR product_name_w[256];
|
||||
DWORD product_name_w_size;
|
||||
int version_size;
|
||||
size_t version_size;
|
||||
int processor_level;
|
||||
int r;
|
||||
|
||||
@ -1696,7 +1506,7 @@ int uv_os_uname(uv_utsname_t* buffer) {
|
||||
r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
|
||||
0,
|
||||
KEY_QUERY_VALUE,
|
||||
KEY_QUERY_VALUE | KEY_WOW64_64KEY,
|
||||
®istry_key);
|
||||
|
||||
if (r == ERROR_SUCCESS) {
|
||||
@ -1727,37 +1537,29 @@ int uv_os_uname(uv_utsname_t* buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
version_size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
product_name_w,
|
||||
-1,
|
||||
buffer->version,
|
||||
sizeof(buffer->version),
|
||||
NULL,
|
||||
NULL);
|
||||
if (version_size == 0) {
|
||||
r = uv_translate_sys_error(GetLastError());
|
||||
version_size = sizeof(buffer->version);
|
||||
r = uv__copy_utf16_to_utf8(product_name_w,
|
||||
-1,
|
||||
buffer->version,
|
||||
&version_size);
|
||||
if (r)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Append service pack information to the version if present. */
|
||||
if (os_info.szCSDVersion[0] != L'\0') {
|
||||
if (version_size > 0)
|
||||
buffer->version[version_size - 1] = ' ';
|
||||
buffer->version[version_size++] = ' ';
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
os_info.szCSDVersion,
|
||||
-1,
|
||||
buffer->version + version_size,
|
||||
sizeof(buffer->version) - version_size,
|
||||
NULL,
|
||||
NULL) == 0) {
|
||||
r = uv_translate_sys_error(GetLastError());
|
||||
version_size = sizeof(buffer->version) - version_size;
|
||||
r = uv__copy_utf16_to_utf8(os_info.szCSDVersion,
|
||||
-1,
|
||||
buffer->version +
|
||||
sizeof(buffer->version) - version_size,
|
||||
&version_size);
|
||||
if (r)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Populate the sysname field. */
|
||||
|
Reference in New Issue
Block a user