[Bug #3296] windows $B$G(B iconv.dll $B$N;HMQ$9$k(B MSVC runtime DLL $B$N%P!<%8%g%s$,!"(Bruby

Bug #3296: windows e$B$Ge(B iconv.dll e$B$N;HMQ$9$ke(B MSVC runtime DLL
e$B$N%P!<%8%g%s$,!"e(Bruby
e$BK\BN$,;HMQ$9$k$b$N$H0lCW$7$F$$$J$$>l9g$Ke(B[BUG]e$B$,=P$k!#e(B
http://redmine.ruby-lang.org/issues/show/3296

e$B5/I<<Te(B: masaya tarui
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Low
Target version: 1.9.2
ruby -v: ruby 1.9.2dev (2010-05-14 revision 27797) [i386-mswin32_90]

e$BC.2H$G$9!#e(B

e$B%i%s%?%$%`$,0lCW$7$F$$$J$$e(Biconv.dlle$B$r%m!<%I$9$k4D6-$G!"0J2<$N%=!<%9e(B

require ‘iconv’

Iconv.iconv(“utf-8”, “SJIS”, “heh”)
Iconv.iconv(“utf-8”, “X-UKNOWN”, “heh”)

e$B$r<B9T$9$k$H!"e(B
/soft/iconv.rb:4: [BUG] rb_sys_fail(iconv(“utf-8”, “X-UKNOWN”)) - errno
== 0
e$B$H8@$o$l$^$9!#e(B
e$B%i%s%?%$%`$,0lCW$7$F$$$J$$>l9g!"e(Berrnoe$B$r$&$^$/99?7$G$-$J$$$?$a$K!"e(B
iconve$B$G<:GT$7$?>l9g$K!"e(BIconv::BrokenLibrarye$BNc30e(B
e$B$r=PNO$9$k$N$,@5$7$$$O$:$G$9!#e(B

e$B=j$G!":,K\E*$K$Oe(Berrnoe$B$,$&$^$/<h$l$l$P$$$$$?$a!"0J2<$N$h$&$Je(BPatche$B$r=q$$$F$_$^$7$?!#e(B
iconv.dlle$B$G;HMQ$7$F$$$ke(B _errno()
e$B$rD4$Y$F$=$l$r;2>H$9$k$h$&$K$7$^$9!#e(B
e$B<h$j9~$_2DG=$G$7$g$&$+!)e(B

Index: include/ruby/win32.h

— include/ruby/win32.h (e$B%j%S%8%g%se(B 27790)
+++ include/ruby/win32.h (e$B:n6H%3%T!<e(B)
@@ -274,6 +274,9 @@
extern int fcntl(int, int, …);
extern rb_pid_t rb_w32_getpid(void);
extern rb_pid_t rb_w32_getppid(void);
+
+extern void *rb_w32_GetImportFunctionPtr(const char *,const char *);
+
#if !defined(BORLANDC)
extern int rb_w32_isatty(int);
#endif
Index: win32/win32.c

— win32/win32.c (e$B%j%S%8%g%se(B 27790)
+++ win32/win32.c (e$B:n6H%3%T!<e(B)
@@ -29,6 +29,8 @@
#include <share.h>
#include <shlobj.h>
#include <mbstring.h>
+#include <imagehlp.h>
+
#if _MSC_VER >= 1400
#include <crtdbg.h>
#include <rtcapi.h>
@@ -5641,3 +5643,32 @@

 return *ip < 0;

}
#endif
+
+void *
+rb_w32_GetImportFunctionPtr(const char *modname,const char *funcname){

  • HMODULE hmod;
  • ULONG size;
  • const IMAGE_IMPORT_DESCRIPTOR* desc;
  • hmod = GetModuleHandle(modname);
  • if(!hmod)return NULL;
  • desc =
    ImageDirectoryEntryToData(hmod,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);
  • if(!desc)return NULL;
  • while(desc->Name){
  • PIMAGE_THUNK_DATA piat,pint;
  • PIMAGE_IMPORT_BY_NAME pii;
  • pint = (PIMAGE_THUNK_DATA)((char *)hmod + desc->Characteristics);
  • piat = (PIMAGE_THUNK_DATA)((char *)hmod + desc->FirstThunk);
  • while(piat->u1.Function){
  •  pii =  (PIMAGE_IMPORT_BY_NAME)((char *)hmod+ 
    

pint->u1.AddressOfData);

  •  if(strcmp(pii->Name,funcname)==0){
    
  • return (void *)piat->u1.Function;
  •  }
    
  •  piat++;
    
  •  pint++;
    
  • }
  • desc++;
  • }
  • return NULL;
    +}

Index: win32/Makefile.sub

— win32/Makefile.sub (e$B%j%S%8%g%se(B 27790)
+++ win32/Makefile.sub (e$B:n6H%3%T!<e(B)
@@ -212,7 +212,7 @@
EXTLIBS =
!endif
!if !defined(LIBS)
-LIBS = oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib
$(EXTLIBS)
+LIBS = oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib
imagehlp.lib $(EXTLIBS)
!endif
!if “$(ENABLE_WIN95)” == “yes”
LIBS = unicows.lib $(LIBS)
Index: ext/iconv/iconv.c

— ext/iconv/iconv.c (e$B%j%S%8%g%se(B 27790)
+++ ext/iconv/iconv.c (e$B:n6H%3%T!<e(B)
@@ -130,6 +130,14 @@

static VALUE charset_map;

+#ifdef _WIN32
+static int* (* _iconv_errno)(void);
+#undef errno
+#define errno (_iconv_errno())
+#endif
+
+
/

  • Document-method: charset_map

  • call-seq: Iconv.charset_map
    @@ -1212,5 +1220,12 @@

    rb_gc_register_address(&charset_map);
    charset_map = rb_hash_new();
    rb_define_singleton_method(rb_cIconv, “charset_map”,
    charset_map_get, 0);

+#ifdef _WIN32

  • _iconv_errno = rb_w32_GetImportFunctionPtr(“iconv.dll”,“_errno”);
  • if(!_iconv_errno)
  • _iconv_errno = _errno;
    +#endif

}

e$B$J$+$@$G$9!#e(B

At Sat, 15 May 2010 01:24:56 +0900,
masaya tarui wrote in [ruby-dev:41317]:

e$B=j$G!":,K\E*$K$Oe(Berrnoe$B$,$&$^$/<h$l$l$P$$$$$?$a!"0J2<$N$h$&$Je(BPatche$B$r=q$$$F$_$^$7$?!#e(B
iconv.dlle$B$G;HMQ$7$F$$$ke(B _errno() e$B$rD4$Y$F$=$l$r;2>H$9$k$h$&$K$7$^$9!#e(B
e$B<h$j9~$_2DG=$G$7$g$&$+!)e(B

e$B$3$l$@$1$N$?$a$K$=$3$^$G$9$kI,MW$"$k$+$J$!!"$H$$$&$N$,@5D>$J46A[e(B
e$B$G$9$,!"$=$l$OCV$$$F$*$/$K$7$F$b$3$l$@$1$G$O8z2L$,$J$$$H;W$$$^$9!#e(B
e$B$J$<$J$i!"e(Biconv.soe$B$+$i8+$($ke(Berrnoe$B$rJQ$($?$H$3$m$Ge(Brb_sys_fail()e$B$+e(B
e$B$i8+$($ke(Berrnoe$B$K$O$^$C$?$/JQ$o$j$,L5$$$+$i$G$9!#e(B

e$B$3$NLdBj$Oe(Biconve$B$K8B$i$J$$$N$G!"$G$-$k$3$H$J$i3HD%%i%$%V%i%j$r$“e(B
e$B$^$j$$$8$i$:$K<+F0E*$K2r7h$G$-$kJ}K!$,$”$k$H$$$$$N$G$9$,!“Cf$K$Oe(B
e$BJ#?t$N30It%i%$%V%i%j$r%j%s%/$9$k$b$N$b$”$C$?$j$9$k$N$G!"$A$g$C$He(B
e$BFq$7$=$&$K;W$($^$9!#e(B