XS-libuv
view release on metacpan or search on metacpan
libuv-1.49.2/src/win/util.c view on Meta::CPAN
*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.
*/
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 (including NUL). */
bufsize = uv_wtf8_length_as_utf16(utf8);
if (bufsize < 0)
return UV__EINVAL;
/* Allocate the destination buffer. */
*utf16 = uv__malloc(sizeof(WCHAR) * bufsize);
if (*utf16 == NULL)
return UV_ENOMEM;
/* Convert to UTF-16 */
uv_wtf8_to_utf16(utf8, *utf16, bufsize);
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];
wchar_t *path;
DWORD bufsize;
int r;
if (pwd == NULL)
return UV_EINVAL;
/* Get the home directory using GetUserProfileDirectoryW() */
if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
return uv_translate_sys_error(GetLastError());
bufsize = 0;
GetUserProfileDirectoryW(token, NULL, &bufsize);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
r = GetLastError();
CloseHandle(token);
return uv_translate_sys_error(r);
}
path = uv__malloc(bufsize * sizeof(wchar_t));
if (path == NULL) {
CloseHandle(token);
return UV_ENOMEM;
}
if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
r = GetLastError();
CloseHandle(token);
uv__free(path);
return uv_translate_sys_error(r);
}
CloseHandle(token);
/* Get the username using GetUserNameW() */
bufsize = ARRAY_SIZE(username);
if (!GetUserNameW(username, &bufsize)) {
r = GetLastError();
uv__free(path);
/* This should not be possible */
if (r == ERROR_INSUFFICIENT_BUFFER)
return UV_ENOMEM;
return uv_translate_sys_error(r);
}
pwd->homedir = NULL;
r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
uv__free(path);
if (r != 0)
return r;
pwd->username = NULL;
r = uv__convert_utf16_to_utf8(username, -1, &pwd->username);
if (r != 0) {
uv__free(pwd->homedir);
return r;
}
pwd->shell = NULL;
pwd->uid = -1;
pwd->gid = -1;
return 0;
}
int uv_os_get_passwd(uv_passwd_t* pwd) {
return uv__getpwuid_r(pwd);
}
int uv_os_get_passwd2(uv_passwd_t* pwd, uv_uid_t uid) {
return UV_ENOTSUP;
}
int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) {
return UV_ENOTSUP;
}
int uv_os_environ(uv_env_item_t** envitems, int* count) {
wchar_t* env;
wchar_t* penv;
int i, cnt;
uv_env_item_t* envitem;
*envitems = NULL;
*count = 0;
env = GetEnvironmentStringsW();
if (env == NULL)
return 0;
for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);
*envitems = uv__calloc(i, sizeof(**envitems));
if (*envitems == NULL) {
FreeEnvironmentStringsW(env);
return UV_ENOMEM;
}
penv = env;
cnt = 0;
while (*penv != L'\0' && cnt < i) {
char* buf;
char* ptr;
if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0)
goto fail;
/* Using buf + 1 here because we know that `buf` has length at least 1,
* and some special environment variables on Windows start with a = sign. */
ptr = strchr(buf + 1, '=');
if (ptr == NULL) {
uv__free(buf);
goto do_continue;
}
*ptr = '\0';
envitem = &(*envitems)[cnt];
envitem->name = buf;
envitem->value = ptr + 1;
cnt++;
( run in 2.732 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )