mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
3540727af5
commit
a898f0fb4b
3 changed files with 96 additions and 17 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
Wed Feb 25 17:31:32 2009 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* 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().
|
||||
|
||||
Wed Feb 25 15:05:35 2009 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* win32/Makefile.sub (config.status): use un.rb as cp instead of
|
||||
|
|
60
io.c
60
io.c
|
@ -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
|
||||
|
|
|
@ -4150,6 +4150,37 @@ rb_w32_getppid(void)
|
|||
|
||||
int
|
||||
rb_w32_open(const char *file, int oflag, ...)
|
||||
{
|
||||
UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
||||
int len;
|
||||
WCHAR *wfile;
|
||||
int pmode;
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, oflag);
|
||||
pmode = va_arg(arg, int);
|
||||
va_end(arg);
|
||||
|
||||
if ((oflag & O_TEXT) || !(oflag & ~O_BINARY)) {
|
||||
return _open(file, oflag, pmode);
|
||||
}
|
||||
|
||||
len = MultiByteToWideChar(cp, 0, file, -1, NULL, 0);
|
||||
if (len <= 0) {
|
||||
errno = map_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
wfile = ALLOCA_N(WCHAR, len);
|
||||
MultiByteToWideChar(cp, 0, file, -1, wfile, len);
|
||||
if (len <= 0) {
|
||||
errno = map_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
return rb_w32_wopen(wfile, oflag, pmode);
|
||||
}
|
||||
|
||||
int
|
||||
rb_w32_wopen(const WCHAR *file, int oflag, ...)
|
||||
{
|
||||
char flags = 0;
|
||||
int fd;
|
||||
|
@ -4165,7 +4196,7 @@ rb_w32_open(const char *file, int oflag, ...)
|
|||
va_start(arg, oflag);
|
||||
pmode = va_arg(arg, int);
|
||||
va_end(arg);
|
||||
return _open(file, oflag, pmode);
|
||||
return _wopen(file, oflag, pmode);
|
||||
}
|
||||
|
||||
sec.nLength = sizeof(sec);
|
||||
|
@ -4281,7 +4312,7 @@ rb_w32_open(const char *file, int oflag, ...)
|
|||
/* open with FILE_FLAG_OVERLAPPED if have CancelIo */
|
||||
if (cancel_io)
|
||||
attr |= FILE_FLAG_OVERLAPPED;
|
||||
h = CreateFile(file, access, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec,
|
||||
h = CreateFileW(file, access, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec,
|
||||
create, attr, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = map_errno(GetLastError());
|
||||
|
|
Loading…
Reference in a new issue