1
0
Fork 0
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:
usa 2009-02-25 08:36:45 +00:00
parent 3540727af5
commit a898f0fb4b
3 changed files with 96 additions and 17 deletions

View file

@ -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
View file

@ -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

View file

@ -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());