Feature #12653 » 0001-Use-wide-WinAPI-for-rb_w32_getcwd.patch
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;
|
||
}
|