about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-02-27 11:46:26 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-02-27 11:46:26 +0000
commit4ff6e11df26f4504c30fd5f2e981296e83c74dd9 (patch)
tree0fef9fc7e63d9ddcd685add5e24f21bf95d32f3d
parente21bd541a286cd3946a3951e3dad88a0ef46d530 (diff)
downloadzsh-4ff6e11df26f4504c30fd5f2e981296e83c74dd9.tar.gz
zsh-4ff6e11df26f4504c30fd5f2e981296e83c74dd9.tar.xz
zsh-4ff6e11df26f4504c30fd5f2e981296e83c74dd9.zip
24609: try to be safe about using libiconv
-rw-r--r--MACHINES6
-rw-r--r--Src/utils.c23
-rw-r--r--configure.ac5
3 files changed, 30 insertions, 4 deletions
diff --git a/MACHINES b/MACHINES
index 18e56c658..ccb71db1e 100644
--- a/MACHINES
+++ b/MACHINES
@@ -212,7 +212,11 @@ Sun: SunOS 4.1.x
 	This may work, but the first username completion will be _very_
 	slow (as slow as in tcsh).
 
-Sun: Solaris 2.x, 8, 9
+Sun: Solaris 2.x, 8, 9, ...
+	It is recommended that the system library version of iconv()
+	be used rather than libiconv since there are incompatibilities
+	in the way codesets are named.
+
 	The UCB versions of the routines for reading directories are not
 	usable (the struct definitions are incompatible with the ones
 	assumed by zsh).  The symptom of this is that globbed filenames in
diff --git a/Src/utils.c b/Src/utils.c
index eab36de2a..a5b81420f 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -4880,15 +4880,32 @@ getkeystring(char *s, int *len, int how, int *misc)
 		     * If the code set isn't handled, we'd better
 		     * assume it's US-ASCII rather than just failing
 		     * hopelessly.  Solaris has a weird habit of
-		     * returning 646.
+		     * returning 646.  This is handled by the
+		     * native iconv(), but not by GNU iconv; what's
+		     * more, some versions of the native iconv don't
+		     * handle standard names like ASCII.
+		     *
+		     * This should only be a problem if there's a
+		     * mismatch between the NLS and the iconv in use,
+		     * which probably only means if libiconv is in use.
+		     * We checked at configure time if our libraries
+		     * pulled in _libiconv_version, which should be
+		     * a good test.
 		     *
 		     * It shouldn't ever be NULL, but while we're
 		     * being paranoid...
 		     */
-		    if (!codesetstr || !*codesetstr ||
-			!strcmp(codesetstr, "646"))
+#ifdef ICONV_FROM_LIBICONV
+		    if (!codesetstr || !*codesetstr)
 			codesetstr = "US-ASCII";
+#endif
     	    	    cd = iconv_open(codesetstr, "UCS-4BE");
+#ifdef ICONV_FROM_LIBICONV
+		    if (cd == (iconv_t)-1 &&  !strcmp(codesetstr, "646")) {
+			codesetstr = "US-ASCII";
+			cd = iconv_open(codesetstr, "UCS-4BE");
+		    }
+#endif
 		    if (cd == (iconv_t)-1) {
 			zerr("cannot do charset conversion (iconv failed)");
 			CHARSET_FAILED();
diff --git a/configure.ac b/configure.ac
index 8a56a4c05..335eccbfe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -824,8 +824,13 @@ if test "x$ac_cv_header_iconv_h" = "xyes"; then
       [ #include <iconv.h> ])
   fi
 fi
+AH_TEMPLATE([ICONV_FROM_LIBICONV],
+[Define to 1 if iconv() is linked from libiconv])
 if test "x$ac_found_iconv" = xyes; then
   AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
+  AC_TRY_LINK([#include <iconv.h>],
+    [int myversion = _libiconv_version],
+    AC_DEFINE(ICONV_FROM_LIBICONV), )
 fi
 
 dnl Check if iconv uses const in prototype declaration