Project

General

Profile

Feature #12653 » 0001-Use-wide-WinAPI-for-rb_w32_getcwd.patch

davispuh (Dāvis Mosāns), 08/03/2016 06:32 PM

View differences:

win32/win32.c
rb_w32_getcwd(char *buffer, int size)
{
char *p = buffer;
int len;
WCHAR *wbuffer;
int len, r;
VALUE rp;
len = GetCurrentDirectory(0, NULL);
len = GetCurrentDirectoryW(0, NULL);
if (!len) {
errno = map_errno(GetLastError());
return NULL;
}
if (p) {
if (size < len) {
errno = ERANGE;
return NULL;
}
if (buffer && size < len) {
errno = ERANGE;
return NULL;
}
else {
p = malloc(len);
size = len;
if (!p) {
errno = ENOMEM;
return NULL;
}
wbuffer = malloc(len * sizeof(WCHAR));
if (!wbuffer) {
errno = ENOMEM;
return NULL;
}
if (!GetCurrentDirectory(size, p)) {
if (!GetCurrentDirectoryW(len, wbuffer)) {
errno = map_errno(GetLastError());
if (!buffer)
free(p);
free(wbuffer);
return NULL;
}
if (!p) {
size = WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, NULL, 0, NULL, NULL);
p = malloc(size);
if (!p) {
errno = ENOMEM;
return NULL;
}
}
r = WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, p, size, NULL, NULL);
free(wbuffer);
if (r == 0) {
DWORD lastError = GetLastError();
if (!buffer) {
free(p);
}
if (lastError == ERROR_INSUFFICIENT_BUFFER) {
errno = ERANGE;
return NULL;
}
errno = map_errno(lastError);
return NULL;
}
translate_char(p, '\\', '/', filecp());
translate_char(p, '\\', '/', CP_UTF8);
rp = rb_str_conv_enc_opts(rb_utf8_str_new_cstr(p), NULL, rb_filesystem_encoding(), ECONV_UNDEF_REPLACE, Qnil);
if (!buffer) {
free(p);
p = strdup(RSTRING_PTR(rp));
} else {
if (RSTRING_LEN(rp) >= size) {
errno = ERANGE;
return NULL;
}
strncpy(p, RSTRING_PTR(rp), size - 1);
p[size - 1] = '\0';
}
return p;
}
    (1-1/1)