diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-25 08:36:45 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-25 08:36:45 +0000 |
commit | a898f0fb4b8e31d86a372f7d1438823195015249 (patch) | |
tree | 2099267d4614d080825666365567b074f4e5e6ef /io.c | |
parent | 3540727af57ee166993da274d924b278a0bd0d9a (diff) | |
download | ruby-a898f0fb4b8e31d86a372f7d1438823195015249.tar.gz |
* io.c (sysopen_func, rb_sysopen_internal, rb_sysopen): open file
by UTF-16'ed filename on Windows.
* io.c (rb_file_open_generic, rb_io_s_sysopen, rb_io_reopen,
argf_next_argv): follow above change.
* io.c (rb_scan_open_args): no longer need to convert filepath here on
Windows.
* win32/wio32.c (rb_w32_wopen): new function to open file by UTF-16'ed
filename.
* win32/win32.c (rb_w32_open): call rb_w32_open().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22626 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 60 |
1 files changed, 46 insertions, 14 deletions
@@ -4174,27 +4174,61 @@ struct sysopen_struct { const char *fname; int oflags; mode_t perm; +#ifdef _WIN32 + int wchar; +#endif }; static VALUE sysopen_func(void *ptr) { struct sysopen_struct *data = ptr; +#ifdef _WIN32 + if (data->wchar) + return (VALUE)rb_w32_wopen(data->fname, data->oflags, data->perm); +#endif return (VALUE)open(data->fname, data->oflags, data->perm); } static int -rb_sysopen_internal(const char *fname, int oflags, mode_t perm) +rb_sysopen_internal(VALUE fname, int oflags, mode_t perm) { +#ifdef _WIN32 + static rb_encoding *utf16 = (rb_encoding *)-1; +#endif struct sysopen_struct data; - data.fname = fname; + data.fname = RSTRING_PTR(fname); data.oflags = oflags; data.perm = perm; +#ifdef _WIN32 + if (utf16 == (rb_encoding *)-1) { + utf16 = rb_enc_find("UTF-16LE"); + if (utf16 == rb_ascii8bit_encoding()) + utf16 = NULL; + } + if (utf16) { + VALUE wfname; + VALUE opthash = rb_hash_new(); + int ecflags; + VALUE ecopts; + rb_hash_aset(opthash, ID2SYM(rb_intern("undef")), + ID2SYM(rb_intern("replace"))); + ecflags = rb_econv_prepare_opts(opthash, &ecopts); + wfname = rb_str_encode(fname, rb_enc_from_encoding(utf16), ecflags, + ecopts); + rb_enc_str_buf_cat(wfname, "", 1, utf16); /* workaround */ + data.fname = RSTRING_PTR(wfname); + data.wchar = 1; + } + else { + data.wchar = 0; + } +#endif return (int)rb_thread_blocking_region(sysopen_func, &data, RUBY_UBF_IO, 0); } static int -rb_sysopen(const char *fname, int oflags, mode_t perm) +rb_sysopen(VALUE fname, int oflags, mode_t perm) { int fd; @@ -4209,7 +4243,7 @@ rb_sysopen(const char *fname, int oflags, mode_t perm) fd = rb_sysopen_internal(fname, oflags, perm); } if (fd < 0) { - rb_sys_fail(fname); + rb_sys_fail(RSTRING_PTR(fname)); } } UPDATE_MAXFD(fd); @@ -4280,7 +4314,7 @@ rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig fptr->mode = fmode; fptr->encs = *convconfig; fptr->pathv = rb_str_new_frozen(filename); - fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), oflags, perm); + fptr->fd = rb_sysopen(fptr->pathv, oflags, perm); io_check_tty(fptr); return io; @@ -4933,7 +4967,7 @@ rb_scan_open_args(int argc, VALUE *argv, opt = pop_last_hash(&argc, argv); rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm); FilePathValue(fname); -#if defined _WIN32 || defined __APPLE__ +#if defined __APPLE__ { static rb_encoding *fs_encoding; rb_encoding *fname_encoding = rb_enc_get(fname); @@ -5039,7 +5073,6 @@ rb_io_s_sysopen(int argc, VALUE *argv) VALUE intmode; int oflags, fd; mode_t perm; - char *path; rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm); FilePathValue(fname); @@ -5056,8 +5089,7 @@ rb_io_s_sysopen(int argc, VALUE *argv) else perm = NUM2UINT(vperm); RB_GC_GUARD(fname) = rb_str_new4(fname); - path = RSTRING_PTR(fname); - fd = rb_sysopen(path, oflags, perm); + fd = rb_sysopen(fname, oflags, perm); return INT2NUM(fd); } @@ -5397,7 +5429,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file) fptr->pathv = rb_str_new_frozen(fname); oflags = rb_io_fmode_oflags(fptr->mode); if (fptr->fd < 0) { - fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), oflags, 0666); + fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666); fptr->stdio_file = 0; return file; } @@ -5422,7 +5454,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file) if (close(fptr->fd) < 0) rb_sys_fail_path(fptr->pathv); fptr->fd = -1; - fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), oflags, 0666); + fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666); } return file; @@ -6229,7 +6261,7 @@ argf_next_argv(VALUE argf) } } else { - int fr = rb_sysopen(fn, O_RDONLY, 0); + int fr = rb_sysopen(ARGF.filename, O_RDONLY, 0); if (ARGF.inplace) { struct stat st; @@ -6254,7 +6286,7 @@ argf_next_argv(VALUE argf) (void)close(fr); (void)unlink(RSTRING_PTR(str)); (void)rename(fn, RSTRING_PTR(str)); - fr = rb_sysopen(RSTRING_PTR(str), O_RDONLY, 0); + fr = rb_sysopen(str, O_RDONLY, 0); #else if (rename(fn, RSTRING_PTR(str)) < 0) { rb_warn("Can't rename %s to %s: %s, skipping file", @@ -6276,7 +6308,7 @@ argf_next_argv(VALUE argf) } #endif } - fw = rb_sysopen(fn, O_WRONLY|O_CREAT|O_TRUNC, 0666); + fw = rb_sysopen(ARGF.filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); #ifndef NO_SAFE_RENAME fstat(fw, &st2); #ifdef HAVE_FCHMOD |