From 36c9cddf6cc5306b792669ce31825a6e2d065a5c Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 20 Aug 2009 14:56:23 +0000 Subject: * io.c (rb_sysopen): moved sysopen_struct from rb_sysopen_internal. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++++ io.c | 74 +++++++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c64cc9157..abcfd7db5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Aug 20 23:56:15 2009 Nobuyoshi Nakada + + * io.c (rb_sysopen): moved sysopen_struct from rb_sysopen_internal. + Thu Aug 20 23:39:51 2009 Yusuke Endoh * parse.y (reduce_nodes_gen): preserve NODE_FL_NEWLINE flag during diff --git a/io.c b/io.c index 16cb9b5607..263c40a768 100644 --- a/io.c +++ b/io.c @@ -4406,7 +4406,7 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, } struct sysopen_struct { - const char *fname; + VALUE fname; int oflags; mode_t perm; #ifdef _WIN32 @@ -4414,62 +4414,76 @@ struct sysopen_struct { #endif }; -static VALUE -sysopen_func(void *ptr) -{ - struct sysopen_struct *data = ptr; #ifdef _WIN32 - if (data->wchar) - return (VALUE)rb_w32_wopen((WCHAR *)data->fname, data->oflags, - data->perm); -#endif - return (VALUE)open(data->fname, data->oflags, data->perm); -} - -static int -rb_sysopen_internal(VALUE fname, int oflags, mode_t perm) +static rb_encoding * +w32_utf16(void) { -#ifdef _WIN32 static rb_encoding *utf16 = (rb_encoding *)-1; -#endif - struct sysopen_struct data; - 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; } + return utf16; +} + +static int +w32_conv_to_utf16(volatile VALUE *strp) +{ + rb_encoding *utf16 = w32_utf16(); if (utf16) { - VALUE wfname = rb_str_encode(fname, rb_enc_from_encoding(utf16), 0, - Qnil); - rb_enc_str_buf_cat(wfname, "", 1, utf16); /* workaround */ - data.fname = RSTRING_PTR(wfname); - data.wchar = 1; + VALUE wstr = rb_str_encode(*strp, rb_enc_from_encoding(utf16), 0, Qnil); + rb_enc_str_buf_cat(wstr, "", 1, utf16); /* workaround */ + *strp = wstr; + return 1; } else { - data.wchar = 0; + return 0; } +} #endif - return (int)rb_thread_blocking_region(sysopen_func, &data, RUBY_UBF_IO, 0); + +static VALUE +sysopen_func(void *ptr) +{ + const struct sysopen_struct *data = ptr; + const char *fname = RSTRING_PTR(data->fname); +#ifdef _WIN32 + if (data->wchar) + return (VALUE)rb_w32_wopen((WCHAR *)fname, data->oflags, data->perm); +#endif + return (VALUE)open(fname, data->oflags, data->perm); +} + +static inline int +rb_sysopen_internal(const struct sysopen_struct *data) +{ + return (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0); } static int rb_sysopen(VALUE fname, int oflags, mode_t perm) { int fd; + struct sysopen_struct data; #ifdef O_BINARY oflags |= O_BINARY; #endif + data.fname = fname; + data.oflags = oflags; + data.perm = perm; +#ifdef _WIN32 + if ((data.wchar = w32_conv_to_utf16(&data.fname)) != 0) { + OBJ_FREEZE(data.fname); + } +#endif - fd = rb_sysopen_internal(fname, oflags, perm); + fd = rb_sysopen_internal(&data); if (fd < 0) { if (errno == EMFILE || errno == ENFILE) { rb_gc(); - fd = rb_sysopen_internal(fname, oflags, perm); + fd = rb_sysopen_internal(&data); } if (fd < 0) { rb_sys_fail(RSTRING_PTR(fname)); -- cgit v1.2.3