* 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
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>
|
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
|
* 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;
|
const char *fname;
|
||||||
int oflags;
|
int oflags;
|
||||||
mode_t perm;
|
mode_t perm;
|
||||||
|
#ifdef _WIN32
|
||||||
|
int wchar;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
sysopen_func(void *ptr)
|
sysopen_func(void *ptr)
|
||||||
{
|
{
|
||||||
struct sysopen_struct *data = 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);
|
return (VALUE)open(data->fname, data->oflags, data->perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct sysopen_struct data;
|
||||||
data.fname = fname;
|
data.fname = RSTRING_PTR(fname);
|
||||||
data.oflags = oflags;
|
data.oflags = oflags;
|
||||||
data.perm = perm;
|
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);
|
return (int)rb_thread_blocking_region(sysopen_func, &data, RUBY_UBF_IO, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rb_sysopen(const char *fname, int oflags, mode_t perm)
|
rb_sysopen(VALUE fname, int oflags, mode_t perm)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -4209,7 +4243,7 @@ rb_sysopen(const char *fname, int oflags, mode_t perm)
|
|||||||
fd = rb_sysopen_internal(fname, oflags, perm);
|
fd = rb_sysopen_internal(fname, oflags, perm);
|
||||||
}
|
}
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
rb_sys_fail(fname);
|
rb_sys_fail(RSTRING_PTR(fname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UPDATE_MAXFD(fd);
|
UPDATE_MAXFD(fd);
|
||||||
@ -4280,7 +4314,7 @@ rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig
|
|||||||
fptr->mode = fmode;
|
fptr->mode = fmode;
|
||||||
fptr->encs = *convconfig;
|
fptr->encs = *convconfig;
|
||||||
fptr->pathv = rb_str_new_frozen(filename);
|
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);
|
io_check_tty(fptr);
|
||||||
|
|
||||||
return io;
|
return io;
|
||||||
@ -4933,7 +4967,7 @@ rb_scan_open_args(int argc, VALUE *argv,
|
|||||||
opt = pop_last_hash(&argc, argv);
|
opt = pop_last_hash(&argc, argv);
|
||||||
rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
|
rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
|
||||||
FilePathValue(fname);
|
FilePathValue(fname);
|
||||||
#if defined _WIN32 || defined __APPLE__
|
#if defined __APPLE__
|
||||||
{
|
{
|
||||||
static rb_encoding *fs_encoding;
|
static rb_encoding *fs_encoding;
|
||||||
rb_encoding *fname_encoding = rb_enc_get(fname);
|
rb_encoding *fname_encoding = rb_enc_get(fname);
|
||||||
@ -5039,7 +5073,6 @@ rb_io_s_sysopen(int argc, VALUE *argv)
|
|||||||
VALUE intmode;
|
VALUE intmode;
|
||||||
int oflags, fd;
|
int oflags, fd;
|
||||||
mode_t perm;
|
mode_t perm;
|
||||||
char *path;
|
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
|
rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
|
||||||
FilePathValue(fname);
|
FilePathValue(fname);
|
||||||
@ -5056,8 +5089,7 @@ rb_io_s_sysopen(int argc, VALUE *argv)
|
|||||||
else perm = NUM2UINT(vperm);
|
else perm = NUM2UINT(vperm);
|
||||||
|
|
||||||
RB_GC_GUARD(fname) = rb_str_new4(fname);
|
RB_GC_GUARD(fname) = rb_str_new4(fname);
|
||||||
path = RSTRING_PTR(fname);
|
fd = rb_sysopen(fname, oflags, perm);
|
||||||
fd = rb_sysopen(path, oflags, perm);
|
|
||||||
return INT2NUM(fd);
|
return INT2NUM(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5397,7 +5429,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
|
|||||||
fptr->pathv = rb_str_new_frozen(fname);
|
fptr->pathv = rb_str_new_frozen(fname);
|
||||||
oflags = rb_io_fmode_oflags(fptr->mode);
|
oflags = rb_io_fmode_oflags(fptr->mode);
|
||||||
if (fptr->fd < 0) {
|
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;
|
fptr->stdio_file = 0;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@ -5422,7 +5454,7 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
|
|||||||
if (close(fptr->fd) < 0)
|
if (close(fptr->fd) < 0)
|
||||||
rb_sys_fail_path(fptr->pathv);
|
rb_sys_fail_path(fptr->pathv);
|
||||||
fptr->fd = -1;
|
fptr->fd = -1;
|
||||||
fptr->fd = rb_sysopen(RSTRING_PTR(fptr->pathv), oflags, 0666);
|
fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666);
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
@ -6229,7 +6261,7 @@ argf_next_argv(VALUE argf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int fr = rb_sysopen(fn, O_RDONLY, 0);
|
int fr = rb_sysopen(ARGF.filename, O_RDONLY, 0);
|
||||||
|
|
||||||
if (ARGF.inplace) {
|
if (ARGF.inplace) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -6254,7 +6286,7 @@ argf_next_argv(VALUE argf)
|
|||||||
(void)close(fr);
|
(void)close(fr);
|
||||||
(void)unlink(RSTRING_PTR(str));
|
(void)unlink(RSTRING_PTR(str));
|
||||||
(void)rename(fn, 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
|
#else
|
||||||
if (rename(fn, RSTRING_PTR(str)) < 0) {
|
if (rename(fn, RSTRING_PTR(str)) < 0) {
|
||||||
rb_warn("Can't rename %s to %s: %s, skipping file",
|
rb_warn("Can't rename %s to %s: %s, skipping file",
|
||||||
@ -6276,7 +6308,7 @@ argf_next_argv(VALUE argf)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifndef NO_SAFE_RENAME
|
||||||
fstat(fw, &st2);
|
fstat(fw, &st2);
|
||||||
#ifdef HAVE_FCHMOD
|
#ifdef HAVE_FCHMOD
|
||||||
|
@ -4150,6 +4150,37 @@ rb_w32_getppid(void)
|
|||||||
|
|
||||||
int
|
int
|
||||||
rb_w32_open(const char *file, int oflag, ...)
|
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;
|
char flags = 0;
|
||||||
int fd;
|
int fd;
|
||||||
@ -4165,7 +4196,7 @@ rb_w32_open(const char *file, int oflag, ...)
|
|||||||
va_start(arg, oflag);
|
va_start(arg, oflag);
|
||||||
pmode = va_arg(arg, int);
|
pmode = va_arg(arg, int);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
return _open(file, oflag, pmode);
|
return _wopen(file, oflag, pmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
sec.nLength = sizeof(sec);
|
sec.nLength = sizeof(sec);
|
||||||
@ -4281,8 +4312,8 @@ rb_w32_open(const char *file, int oflag, ...)
|
|||||||
/* open with FILE_FLAG_OVERLAPPED if have CancelIo */
|
/* open with FILE_FLAG_OVERLAPPED if have CancelIo */
|
||||||
if (cancel_io)
|
if (cancel_io)
|
||||||
attr |= FILE_FLAG_OVERLAPPED;
|
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);
|
create, attr, NULL);
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
errno = map_errno(GetLastError());
|
errno = map_errno(GetLastError());
|
||||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user