diff options
| author | Hiroki Sato <hrs@FreeBSD.org> | 2013-11-25 01:26:06 +0000 |
|---|---|---|
| committer | Hiroki Sato <hrs@FreeBSD.org> | 2013-11-25 01:26:06 +0000 |
| commit | 7c5b23111c5fd1992047922d4247c4a1ce1bb6c3 (patch) | |
| tree | 7c53259610137077d7bca0370a6246a61e862300 /lib | |
| parent | 1b57cec7d999c971d6c4bcb3df6f6397670e1326 (diff) | |
Notes
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/iconv/citrus_iconv_local.h | 1 | ||||
| -rw-r--r-- | lib/libc/iconv/iconv.c | 6 | ||||
| -rw-r--r-- | lib/libc/iconv/iconvctl.3 | 27 | ||||
| -rw-r--r-- | lib/libiconv_modules/iconv_std/citrus_iconv_std.c | 10 |
4 files changed, 43 insertions, 1 deletions
diff --git a/lib/libc/iconv/citrus_iconv_local.h b/lib/libc/iconv/citrus_iconv_local.h index e673c9a6afa1..12d2fa33fa73 100644 --- a/lib/libc/iconv/citrus_iconv_local.h +++ b/lib/libc/iconv/citrus_iconv_local.h @@ -99,6 +99,7 @@ struct _citrus_iconv_shared { char *ci_convname; bool ci_discard_ilseq; struct iconv_hooks *ci_hooks; + bool ci_ilseq_invalid; }; struct _citrus_iconv { diff --git a/lib/libc/iconv/iconv.c b/lib/libc/iconv/iconv.c index 555efd8616e7..40a1a4e88909 100644 --- a/lib/libc/iconv/iconv.c +++ b/lib/libc/iconv/iconv.c @@ -298,6 +298,12 @@ __bsd_iconvctl(iconv_t cd, int request, void *argument) case ICONV_SET_FALLBACKS: errno = EOPNOTSUPP; return (-1); + case ICONV_GET_ILSEQ_INVALID: + *i = cv->cv_shared->ci_ilseq_invalid ? 1 : 0; + return (0); + case ICONV_SET_ILSEQ_INVALID: + cv->cv_shared->ci_ilseq_invalid = *i; + return (0); default: errno = EINVAL; return (-1); diff --git a/lib/libc/iconv/iconvctl.3 b/lib/libc/iconv/iconvctl.3 index f0121573af99..5bd06ea122c2 100644 --- a/lib/libc/iconv/iconvctl.3 +++ b/lib/libc/iconv/iconvctl.3 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 7, 2009 +.Dd November 25, 2009 .Dt ICONVCTL 3 .Os .Sh NAME @@ -110,6 +110,31 @@ variable, which is passed to via .Fa argument by its address. +.It ICONV_GET_ILSEQ_INVALID +Determines if a character in the input buffer that is valid, +but for which an identical character does not exist in the target +codeset returns +.Er EILSEQ +or not. +The answer is stored in +.Fa argument , +which is of +.Ft int * . +It will be set to 1 if this feature is enabled or set to 0 otherwise. +.It ICONV_SET_ILSEQ_INVALID +Sets whether a character in the input buffer that is valid, +but for which an identical character does not exist in the target +codeset returns +.Er EILSEQ +or not. +If +.Fa argument , +which is of +.Ft int * +is set to 1 it will be enabled, +and if +.Fa argument +is set to 0 it will be disabled. .El .\" XXX: fallbacks are unimplemented and trying to set them will always .\" return EOPNOTSUPP but definitions are provided for source-level diff --git a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c index b30f09928ae8..54a00d0d56ae 100644 --- a/lib/libiconv_modules/iconv_std/citrus_iconv_std.c +++ b/lib/libiconv_modules/iconv_std/citrus_iconv_std.c @@ -543,6 +543,16 @@ _citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict cv, ret = do_conv(is, &csid, &idx); if (ret) { if (ret == E_NO_CORRESPONDING_CHAR) { + /* + * GNU iconv returns EILSEQ when no + * corresponding character in the output. + * Some software depends on this behavior + * though this is against POSIX specification. + */ + if (cv->cv_shared->ci_ilseq_invalid != 0) { + ret = EILSEQ; + goto err; + } inval++; szrout = 0; if ((((flags & _CITRUS_ICONV_F_HIDE_INVALID) == 0) && |
