ext/libuv/src/win/util.c in libuv-2.0.8 vs ext/libuv/src/win/util.c in libuv-2.0.9
- old
+ new
@@ -52,10 +52,14 @@
#define MAX_TITLE_LENGTH 8192
/* The number of nanoseconds in one second. */
#define UV__NANOSEC 1000000000
+/* Max user name length, from iphlpapi.h */
+#ifndef UNLEN
+# define UNLEN 256
+#endif
/* Cached copy of the process title, plus a mutex guarding it. */
static char *process_title;
static CRITICAL_SECTION process_title_lock;
@@ -122,11 +126,11 @@
utf8_len = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
-1,
buffer,
- *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr,
+ (int) *size_ptr,
NULL,
NULL);
if (utf8_len == 0) {
err = GetLastError();
goto error;
@@ -401,46 +405,28 @@
}
static int uv__get_process_title() {
WCHAR title_w[MAX_TITLE_LENGTH];
- int length;
if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
return -1;
}
- /* Find out what the size of the buffer is that we need */
- length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL);
- if (!length) {
+ if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0)
return -1;
- }
- assert(!process_title);
- process_title = (char*)uv__malloc(length);
- if (!process_title) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- /* Do utf16 -> utf8 conversion here */
- if (!WideCharToMultiByte(CP_UTF8,
- 0,
- title_w,
- -1,
- process_title,
- length,
- NULL,
- NULL)) {
- uv__free(process_title);
- return -1;
- }
-
return 0;
}
int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return UV_EINVAL;
+
uv__once_init();
EnterCriticalSection(&process_title_lock);
/*
* If the process_title was never read before nor explicitly set,
@@ -450,11 +436,18 @@
LeaveCriticalSection(&process_title_lock);
return uv_translate_sys_error(GetLastError());
}
assert(process_title);
- strncpy(buffer, process_title, size);
+ len = strlen(process_title) + 1;
+
+ if (size < len) {
+ LeaveCriticalSection(&process_title_lock);
+ return UV_ENOBUFS;
+ }
+
+ memcpy(buffer, process_title, len);
LeaveCriticalSection(&process_title_lock);
return 0;
}
@@ -702,47 +695,13 @@
sppi[i].IdleTime.QuadPart) / 10000;
cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
cpu_info->cpu_times.nice = 0;
-
- len = WideCharToMultiByte(CP_UTF8,
- 0,
- cpu_brand,
+ uv__convert_utf16_to_utf8(cpu_brand,
cpu_brand_size / sizeof(WCHAR),
- NULL,
- 0,
- NULL,
- NULL);
- if (len == 0) {
- err = GetLastError();
- goto error;
- }
-
- assert(len > 0);
-
- /* Allocate 1 extra byte for the null terminator. */
- cpu_info->model = uv__malloc(len + 1);
- if (cpu_info->model == NULL) {
- err = ERROR_OUTOFMEMORY;
- goto error;
- }
-
- if (WideCharToMultiByte(CP_UTF8,
- 0,
- cpu_brand,
- cpu_brand_size / sizeof(WCHAR),
- cpu_info->model,
- len,
- NULL,
- NULL) == 0) {
- err = GetLastError();
- goto error;
- }
-
- /* Ensure that cpu_info->model is null terminated. */
- cpu_info->model[len] = '\0';
+ &(cpu_info->model));
}
uv__free(sppi);
*cpu_count_ptr = cpu_count;
@@ -1116,10 +1075,11 @@
int uv_getrusage(uv_rusage_t *uv_rusage) {
FILETIME createTime, exitTime, kernelTime, userTime;
SYSTEMTIME kernelSystemTime, userSystemTime;
+ PROCESS_MEMORY_COUNTERS memCounters;
int ret;
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
if (ret == 0) {
return uv_translate_sys_error(GetLastError());
@@ -1133,10 +1093,17 @@
ret = FileTimeToSystemTime(&userTime, &userSystemTime);
if (ret == 0) {
return uv_translate_sys_error(GetLastError());
}
+ ret = GetProcessMemoryInfo(GetCurrentProcess(),
+ &memCounters,
+ sizeof(memCounters));
+ if (ret == 0) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
memset(uv_rusage, 0, sizeof(*uv_rusage));
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
userSystemTime.wMinute * 60 +
userSystemTime.wSecond;
@@ -1145,10 +1112,13 @@
uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 +
kernelSystemTime.wMinute * 60 +
kernelSystemTime.wSecond;
uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
+ uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
+ uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
+
return 0;
}
int uv_os_homedir(char* buffer, size_t* size) {
@@ -1286,43 +1256,61 @@
pwd->username = NULL;
pwd->homedir = NULL;
}
-int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) {
+/*
+ * Converts a UTF-16 string into a UTF-8 one. The resulting string is
+ * null-terminated.
+ *
+ * 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;
if (utf16 == NULL)
return UV_EINVAL;
/* Check how much space we need */
- bufsize = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16,
+ utf16len,
+ NULL,
+ 0,
+ NULL,
+ NULL);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
- /* Allocate the destination buffer */
- *utf8 = uv__malloc(bufsize);
+ /* 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,
- -1,
+ utf16len,
*utf8,
bufsize,
NULL,
NULL);
if (bufsize == 0) {
uv__free(*utf8);
+ *utf8 = NULL;
return uv_translate_sys_error(GetLastError());
}
+ (*utf8)[bufsize] = '\0';
return 0;
}
int uv__getpwuid_r(uv_passwd_t* pwd) {
@@ -1364,16 +1352,16 @@
return uv_translate_sys_error(r);
}
pwd->homedir = NULL;
- r = uv__convert_utf16_to_utf8(path, &pwd->homedir);
+ r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
if (r != 0)
return r;
pwd->username = NULL;
- r = uv__convert_utf16_to_utf8(username, &pwd->username);
+ r = uv__convert_utf16_to_utf8(username, -1, &pwd->username);
if (r != 0) {
uv__free(pwd->homedir);
return r;
}