[前][次][番号順一覧][スレッド一覧]

ruby-changes:11035

From: usa <ko1@a...>
Date: Wed, 25 Feb 2009 17:36:59 +0900 (JST)
Subject: [ruby-changes:11035] Ruby:r22626 (trunk): * io.c (sysopen_func, rb_sysopen_internal, rb_sysopen): open file

usa	2009-02-25 17:36:45 +0900 (Wed, 25 Feb 2009)

  New Revision: 22626

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22626

  Log:
    * 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().

  Modified files:
    trunk/ChangeLog
    trunk/io.c
    trunk/win32/win32.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22625)
+++ ChangeLog	(revision 22626)
@@ -1,3 +1,19 @@
+Wed Feb 25 17:31:32 2009  NAKAMURA Usaku  <usa@r...>
+
+	* 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@r...>
 
 	* win32/Makefile.sub (config.status): use un.rb as cp instead of
Index: io.c
===================================================================
--- io.c	(revision 22625)
+++ io.c	(revision 22626)
@@ -4174,27 +4174,61 @@
     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 @@
 	    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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
         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 @@
 		}
 	    }
 	    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 @@
 			(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 @@
 			}
 #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
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 22625)
+++ win32/win32.c	(revision 22626)
@@ -4151,6 +4151,37 @@
 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;
     DWORD access;
@@ -4165,7 +4196,7 @@
 	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,8 +4312,8 @@
 	/* 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,
-		       create, attr, NULL);
+	h = CreateFileW(file, access, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec,
+			create, attr, NULL);
 	if (h == INVALID_HANDLE_VALUE) {
 	    errno = map_errno(GetLastError());
 	    MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]