Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: our libc included iconv library



I have added code to only use the output format up to the // mark to libc.  
The diff is attached.

If this seems reasonable, I'll request a pull-up to 5.0 if it's not too late 
to do those.

--Michael


On Wednesday 04 February 2009 03:40:31 Takahiro Kambe wrote:
> Hi,
>
> In message <4988665B.2040401%flame.org@localhost>
>       on Tue, 03 Feb 2009 09:44:27 -0600,
>
>       Michael Graff <explorer%flame.org@localhost> wrote:
> > This is actually a Ruby problem, but it is not the first time I have
> > encountered incompatibilities with the iconv functions included within
> > NetBSD's libc and "expected" behavior from the GPL'd libiconv.
>
> Maybe you know, this problem isn't Ruby specific but PHP.
>
> > Case in point is this little Ruby snippit:
>
> As for Ruby, it is recommended avoiding to use Iconv class but
> String#encode function and "ruby -w" warns for using gnu libiconv
> (and gnu libc) own extention.
>
> Unfortunately, it is available Ruby 1.9 and later, but it is Ruby's
> way to deal with this GNU iconv problem.  (And needs more and more
> time.)
>
> > This Iconv.iconv() call is in Ruby on Rails 2.2.2, and requires a patch
>
> Too bad.  Many people dosen't understand what they do with iconv.
>
> > to "fix" it.  However, all the patch does is cause it to ignore the
> > exception.  This really isn't what one wants.
>
> Yes.  But problem exists in such code fragment using iconv.
>
> > The only other OS which seems to have this problem are older version of
> > Solaris.  I would think we could do better?
>
> As I heard before, (Open)Solaris had good implementation of iconv
> (without GNU iconv/libc extention, of course) and (Open)Solaris had
> the same problem.
>
> Dose latest Solaris provide GNU libiconv only or accept GNU iconv/libc
> extention?
>
> > I can see two options here.  One is to add the // options to our libc
> > iconv (probably hard) and the other is to require the gpl'd libiconv be
> > linked into ruby.
>
> As for pkgsrc ruby, a possible solution is adding option to prefer
> libiconv.
>
> Best regards.


Index: iconv/iconv.c
===================================================================
RCS file: /cvsroot/src/lib/libc/iconv/iconv.c,v
retrieving revision 1.8
retrieving revision 1.10
diff -u -r1.8 -r1.10
--- iconv/iconv.c       11 Jan 2009 02:46:28 -0000      1.8
+++ iconv/iconv.c       3 Mar 2009 15:42:43 -0000       1.10
@@ -1,4 +1,4 @@
-/*     $NetBSD: iconv.c,v 1.8 2009/01/11 02:46:28 christos Exp $       */
+/*     $NetBSD: iconv.c,v 1.10 2009/03/03 15:42:43 explorer Exp $      */
 
 /*-
  * Copyright (c)2003 Citrus Project,
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: iconv.c,v 1.8 2009/01/11 02:46:28 christos Exp $");
+__RCSID("$NetBSD: iconv.c,v 1.10 2009/03/03 15:42:43 explorer Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -47,6 +47,8 @@
 
 #ifdef HAVE_CITRUS
 #include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
 #include "citrus_types.h"
 #include "citrus_module.h"
 #include "citrus_esdb.h"
@@ -55,14 +57,34 @@
 
 #define ISBADF(_h_)    (!(_h_) || (_h_) == (iconv_t)-1)
 
-
 iconv_t
 iconv_open(const char *out, const char *in)
 {
        int ret;
        struct _citrus_iconv *handle;
+       char *out_truncated;
+       char *p;
+
+       /*
+        * Remove anything following a //, as these are options (like
+        * //ignore, //translate, etc) and we just don't handle them.
+        * This is for compatibilty wiht software that uses thees
+        * blindly.
+        */
+       out_truncated = strdup(out);
+       if (out_truncated == NULL) {
+               errno = ENOMEM;
+               return ((iconv_t)-1);
+       }
+               
+       p = out_truncated;
+       while (*p != '/' && *p != 0)
+               p++;
+       if (p[0] == '/' && p[1] == '/')
+               p[0] = 0;
 
-       ret = _citrus_iconv_open(&handle, _PATH_ICONV, in, out);
+       ret = _citrus_iconv_open(&handle, _PATH_ICONV, in, out_truncated);
+       free(out_truncated);
        if (ret) {
                errno = ret == ENOENT? EINVAL : ret;
                return ((iconv_t)-1);


Home | Main Index | Thread Index | Old Index