Unverified Commit 7d940e36 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #3888 from mattn/fix-locale

fix path locales
parents e1438744 16c2ac25
...@@ -110,15 +110,17 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) ...@@ -110,15 +110,17 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj)
mrb_value *argv; mrb_value *argv;
mrb_value pathv; mrb_value pathv;
mrb_int argc, i; mrb_int argc, i;
const char *path; char *path;
mrb_get_args(mrb, "*", &argv, &argc); mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
pathv = mrb_convert_type(mrb, argv[i], MRB_TT_STRING, "String", "to_str"); pathv = mrb_convert_type(mrb, argv[i], MRB_TT_STRING, "String", "to_str");
path = mrb_string_value_cstr(mrb, &pathv); path = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &pathv), -1);
if (UNLINK(path) < 0) { if (UNLINK(path) < 0) {
mrb_locale_free(path);
mrb_sys_fail(mrb, path); mrb_sys_fail(mrb, path);
} }
mrb_locale_free(path);
} }
return mrb_fixnum_value(argc); return mrb_fixnum_value(argc);
} }
...@@ -127,19 +129,25 @@ static mrb_value ...@@ -127,19 +129,25 @@ static mrb_value
mrb_file_s_rename(mrb_state *mrb, mrb_value obj) mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
{ {
mrb_value from, to; mrb_value from, to;
const char *src, *dst; char *src, *dst;
mrb_get_args(mrb, "SS", &from, &to); mrb_get_args(mrb, "SS", &from, &to);
src = mrb_string_value_cstr(mrb, &from); src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1);
dst = mrb_string_value_cstr(mrb, &to); dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1);
if (rename(src, dst) < 0) { if (rename(src, dst) < 0) {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) {
mrb_locale_free(src);
mrb_locale_free(dst);
return mrb_fixnum_value(0); return mrb_fixnum_value(0);
} }
#endif #endif
mrb_locale_free(src);
mrb_locale_free(dst);
mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to)));
} }
mrb_locale_free(src);
mrb_locale_free(dst);
return mrb_fixnum_value(0); return mrb_fixnum_value(0);
} }
...@@ -153,9 +161,10 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass) ...@@ -153,9 +161,10 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass)
size_t ridx; size_t ridx;
mrb_value s; mrb_value s;
mrb_get_args(mrb, "S", &s); mrb_get_args(mrb, "S", &s);
path = mrb_str_to_cstr(mrb, s); path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, s), -1);
_splitpath((const char*)path, vname, dname, NULL, NULL); _splitpath((const char*)path, vname, dname, NULL, NULL);
snprintf(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname); snprintf(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname);
mrb_locale_free(path);
ridx = strlen(buffer); ridx = strlen(buffer);
if (ridx == 0) { if (ridx == 0) {
strncpy(buffer, ".", 2); /* null terminated */ strncpy(buffer, ".", 2); /* null terminated */
...@@ -171,18 +180,21 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass) ...@@ -171,18 +180,21 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass)
char *dname, *path; char *dname, *path;
mrb_value s; mrb_value s;
mrb_get_args(mrb, "S", &s); mrb_get_args(mrb, "S", &s);
path = mrb_str_to_cstr(mrb, s); path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, s), -1);
if ((dname = dirname(path)) == NULL) { if ((dname = dirname(path)) == NULL) {
mrb_locale_free(path);
mrb_sys_fail(mrb, "dirname"); mrb_sys_fail(mrb, "dirname");
} }
#endif mrb_locale_free(path);
return mrb_str_new_cstr(mrb, dname); return mrb_str_new_cstr(mrb, dname);
#endif
} }
static mrb_value static mrb_value
mrb_file_basename(mrb_state *mrb, mrb_value klass) mrb_file_basename(mrb_state *mrb, mrb_value klass)
{ {
// NOTE: Do not use mrb_locale_from_utf8 here
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
char bname[_MAX_DIR]; char bname[_MAX_DIR];
char extname[_MAX_EXT]; char extname[_MAX_EXT];
...@@ -190,6 +202,7 @@ mrb_file_basename(mrb_state *mrb, mrb_value klass) ...@@ -190,6 +202,7 @@ mrb_file_basename(mrb_state *mrb, mrb_value klass)
size_t ridx; size_t ridx;
char buffer[_MAX_DIR + _MAX_EXT]; char buffer[_MAX_DIR + _MAX_EXT];
mrb_value s; mrb_value s;
mrb_get_args(mrb, "S", &s); mrb_get_args(mrb, "S", &s);
path = mrb_str_to_cstr(mrb, s); path = mrb_str_to_cstr(mrb, s);
ridx = strlen(path); ridx = strlen(path);
...@@ -233,10 +246,13 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass) ...@@ -233,10 +246,13 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
s = mrb_str_append(mrb, s, pathname); s = mrb_str_append(mrb, s, pathname);
pathname = s; pathname = s;
} }
cpath = mrb_str_to_cstr(mrb, pathname); cpath = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, pathname), -1);
result = mrb_str_buf_new(mrb, PATH_MAX); result = mrb_str_buf_new(mrb, PATH_MAX);
if (realpath(cpath, RSTRING_PTR(result)) == NULL) if (realpath(cpath, RSTRING_PTR(result)) == NULL) {
mrb_locale_free(cpath);
mrb_sys_fail(mrb, cpath); mrb_sys_fail(mrb, cpath);
}
mrb_locale_free(cpath);
mrb_str_resize(mrb, result, strlen(RSTRING_PTR(result))); mrb_str_resize(mrb, result, strlen(RSTRING_PTR(result)));
return result; return result;
} }
...@@ -245,12 +261,14 @@ mrb_value ...@@ -245,12 +261,14 @@ mrb_value
mrb_file__getwd(mrb_state *mrb, mrb_value klass) mrb_file__getwd(mrb_state *mrb, mrb_value klass)
{ {
mrb_value path; mrb_value path;
char buf[MAXPATHLEN], *utf8;
path = mrb_str_buf_new(mrb, MAXPATHLEN); if (GETCWD(buf, MAXPATHLEN) == NULL) {
if (GETCWD(RSTRING_PTR(path), MAXPATHLEN) == NULL) {
mrb_sys_fail(mrb, "getcwd(2)"); mrb_sys_fail(mrb, "getcwd(2)");
} }
mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); utf8 = mrb_utf8_from_locale(buf, -1);
path = mrb_str_new_cstr(mrb, utf8);
mrb_utf8_free(utf8);
return path; return path;
} }
...@@ -263,11 +281,12 @@ mrb_file_is_absolute_path(const char *path) ...@@ -263,11 +281,12 @@ mrb_file_is_absolute_path(const char *path)
static mrb_value static mrb_value
mrb_file__gethome(mrb_state *mrb, mrb_value klass) mrb_file__gethome(mrb_state *mrb, mrb_value klass)
{ {
#ifndef _WIN32
mrb_value username; mrb_value username;
mrb_int argc; mrb_int argc;
char *home; char *home;
mrb_value path;
#ifndef _WIN32
argc = mrb_get_args(mrb, "|S", &username); argc = mrb_get_args(mrb, "|S", &username);
if (argc == 0) { if (argc == 0) {
home = getenv("HOME"); home = getenv("HOME");
...@@ -288,10 +307,26 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) ...@@ -288,10 +307,26 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%S", username); mrb_raisef(mrb, E_ARGUMENT_ERROR, "non-absolute home of ~%S", username);
} }
} }
return mrb_str_new_cstr(mrb, home); home = mrb_locale_from_utf8(home, -1);
path = mrb_str_new_cstr(mrb, home);
mrb_utf8_free(home);
return path;
#else #else
if (argc == 0) {
home = getenv("USERPROFILE");
if (home == NULL) {
return mrb_nil_value(); return mrb_nil_value();
}
if (!mrb_file_is_absolute_path(home)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home");
}
} else {
return mrb_nil_value();
}
home = mrb_locale_from_utf8(home, -1);
path = mrb_str_new_cstr(mrb, home);
mrb_utf8_free(home);
return path;
#endif #endif
} }
...@@ -340,12 +375,16 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass) ...@@ -340,12 +375,16 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
int ai = mrb_gc_arena_save(mrb); int ai = mrb_gc_arena_save(mrb);
mrb_get_args(mrb, "SS", &from, &to); mrb_get_args(mrb, "SS", &from, &to);
src = mrb_str_to_cstr(mrb, from); src = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, from), -1);
dst = mrb_str_to_cstr(mrb, to); dst = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, to), -1);
if (symlink(src, dst) == -1) { if (symlink(src, dst) == -1) {
mrb_locale_free(src);
mrb_locale_free(dst);
mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to)));
} }
mrb_locale_free(src);
mrb_locale_free(dst);
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
#endif #endif
return mrb_fixnum_value(0); return mrb_fixnum_value(0);
...@@ -360,10 +399,12 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) { ...@@ -360,10 +399,12 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) {
mrb_get_args(mrb, "i*", &mode, &filenames, &argc); mrb_get_args(mrb, "i*", &mode, &filenames, &argc);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
char *path = mrb_str_to_cstr(mrb, filenames[i]); char *path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, filenames[i]), -1);
if (CHMOD(path, mode) == -1) { if (CHMOD(path, mode) == -1) {
mrb_locale_free(path);
mrb_sys_fail(mrb, path); mrb_sys_fail(mrb, path);
} }
mrb_locale_free(path);
} }
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
...@@ -376,24 +417,28 @@ mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) { ...@@ -376,24 +417,28 @@ mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) {
mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform"); mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform");
return mrb_nil_value(); // unreachable return mrb_nil_value(); // unreachable
#else #else
char *path, *buf; char *path, *buf, *tmp;
size_t bufsize = 100; size_t bufsize = 100;
ssize_t rc; ssize_t rc;
mrb_value ret; mrb_value ret;
int ai = mrb_gc_arena_save(mrb); int ai = mrb_gc_arena_save(mrb);
mrb_get_args(mrb, "z", &path); mrb_get_args(mrb, "z", &path);
tmp = mrb_locale_from_utf8(path, -1);
buf = (char *)mrb_malloc(mrb, bufsize); buf = (char *)mrb_malloc(mrb, bufsize);
while ((rc = readlink(path, buf, bufsize)) == (ssize_t)bufsize && rc != -1) { while ((rc = readlink(tmp, buf, bufsize)) == (ssize_t)bufsize && rc != -1) {
bufsize *= 2; bufsize *= 2;
buf = (char *)mrb_realloc(mrb, buf, bufsize); buf = (char *)mrb_realloc(mrb, buf, bufsize);
} }
mrb_locale_free(tmp);
if (rc == -1) { if (rc == -1) {
mrb_free(mrb, buf); mrb_free(mrb, buf);
mrb_sys_fail(mrb, path); mrb_sys_fail(mrb, path);
} }
ret = mrb_str_new(mrb, buf, rc); tmp = mrb_utf8_from_locale(buf, -1);
ret = mrb_str_new(mrb, tmp, rc);
mrb_locale_free(tmp);
mrb_free(mrb, buf); mrb_free(mrb, buf);
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
......
...@@ -63,11 +63,15 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) ...@@ -63,11 +63,15 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass); tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass);
if (mrb_test(tmp)) { if (mrb_test(tmp)) {
char *path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, obj), -1);
int ret;
if (do_lstat) { if (do_lstat) {
return LSTAT(mrb_str_to_cstr(mrb, obj), st); ret = LSTAT(path, st);
} else { } else {
return stat(mrb_str_to_cstr(mrb, obj), st); ret = stat(path, st);
} }
mrb_locale_free(path);
return ret;
} }
return -1; return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment