summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2013-08-13 07:15:01 +0000
committerpeter <peter@FreeBSD.org>2013-08-13 07:15:01 +0000
commit995e1f0063b0515ed5821ebab3aff02dbbe44719 (patch)
tree9bba3bf02dbd5d242b50c29cd7221d5ae286e560 /lib
parentd9e76bbffc59d724ea0ffe9896012f4ac0859bc7 (diff)
downloadFreeBSD-src-995e1f0063b0515ed5821ebab3aff02dbbe44719.zip
FreeBSD-src-995e1f0063b0515ed5821ebab3aff02dbbe44719.tar.gz
The iconv in libc did two things - implement the standard APIs, the GNU
extensions and also tried to be link time compatible with ports libiconv. This splits that functionality and enables the parts that shouldn't interfere with the port by default. WITH_ICONV (now on by default) - adds iconv.h, iconv_open(3) etc. WITH_LIBICONV_COMPAT (off by default) adds the libiconv_open etc API, linker symbols and even a stub libiconv.so.3 that are good enough to be able to 'pkg delete -f libiconv' on a running system and reasonably expect it to work. I have tortured many machines over the last few days to try and reduce the possibilities of foot-shooting as much as I can. I've successfully recompiled to enable and disable the libiconv_compat modes, ports that use libiconv alongside system iconv etc. If you don't enable the WITH_LIBICONV_COMPAT switch, they don't share symbol space. This is an extension of behavior on other system. iconv(3) is a standard libc interface and libiconv port expects to be able to run alongside it on systems that have it. Bumped osreldate.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile5
-rw-r--r--lib/libc/iconv/Symbol.map1
-rw-r--r--lib/libc/iconv/iconv.c34
-rw-r--r--lib/libiconv_compat/Makefile7
-rw-r--r--lib/libiconv_compat/stub.c8
-rw-r--r--lib/libkiconv/xlat16_iconv.c3
6 files changed, 41 insertions, 17 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 71fe4d2..6e64925 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -78,6 +78,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
${_libgpib} \
${_libgssapi} \
${_librpcsec_gss} \
+ ${_libiconv_compat} \
libipsec \
${_libipx} \
libjail \
@@ -189,6 +190,10 @@ _libcxxrt= libcxxrt
_libcplusplus= libc++
.endif
+.if ${MK_LIBICONV_COMPAT} != "no"
+_libiconv_compat= libiconv_compat
+.endif
+
.if ${MK_LIBTHR} != "no"
_libthr= libthr
.endif
diff --git a/lib/libc/iconv/Symbol.map b/lib/libc/iconv/Symbol.map
index 82be46f..feb0d13 100644
--- a/lib/libc/iconv/Symbol.map
+++ b/lib/libc/iconv/Symbol.map
@@ -18,6 +18,7 @@ FBSD_1.2 {
};
FBSD_1.3 {
+ _iconv_version;
iconv;
iconv_open;
iconv_close;
diff --git a/lib/libc/iconv/iconv.c b/lib/libc/iconv/iconv.c
index 9b28ff6..f388e8b 100644
--- a/lib/libc/iconv/iconv.c
+++ b/lib/libc/iconv/iconv.c
@@ -47,17 +47,21 @@
#include "citrus_hash.h"
#include "citrus_iconv.h"
-__weak_reference(libiconv, iconv);
-__weak_reference(libiconv_open, iconv_open);
-__weak_reference(libiconv_open_into, iconv_open_into);
-__weak_reference(libiconv_close, iconv_close);
-__weak_reference(libiconvlist, iconvlist);
-__weak_reference(libiconvctl, iconvctl);
-__weak_reference(libiconv_set_relocation_prefix, iconv_set_relocation_prefix);
+#include <_libiconv_compat.h>
+#ifdef __LIBICONV_COMPAT
+__weak_reference(iconv, libiconv);
+__weak_reference(iconv_open, libiconv_open);
+__weak_reference(iconv_open_into, libiconv_open_into);
+__weak_reference(iconv_close, libiconv_close);
+__weak_reference(iconvlist, libiconvlist);
+__weak_reference(iconvctl, libiconvctl);
+__weak_reference(iconv_set_relocation_prefix, libiconv_set_relocation_prefix);
+__weak_reference(_iconv_version, _libiconv_version);
+#endif
#define ISBADF(_h_) (!(_h_) || (_h_) == (iconv_t)-1)
-int _libiconv_version = _LIBICONV_VERSION;
+int _iconv_version = _ICONV_VERSION;
iconv_t _iconv_open(const char *out, const char *in,
struct _citrus_iconv *prealloc);
@@ -100,14 +104,14 @@ _iconv_open(const char *out, const char *in, struct _citrus_iconv *handle)
}
iconv_t
-libiconv_open(const char *out, const char *in)
+iconv_open(const char *out, const char *in)
{
return (_iconv_open(out, in, NULL));
}
int
-libiconv_open_into(const char *out, const char *in, iconv_allocation_t *ptr)
+iconv_open_into(const char *out, const char *in, iconv_allocation_t *ptr)
{
struct _citrus_iconv *handle;
@@ -116,7 +120,7 @@ libiconv_open_into(const char *out, const char *in, iconv_allocation_t *ptr)
}
int
-libiconv_close(iconv_t handle)
+iconv_close(iconv_t handle)
{
if (ISBADF(handle)) {
@@ -130,7 +134,7 @@ libiconv_close(iconv_t handle)
}
size_t
-libiconv(iconv_t handle, const char **in, size_t *szin, char **out, size_t *szout)
+iconv(iconv_t handle, const char **in, size_t *szin, char **out, size_t *szout)
{
size_t ret;
int err;
@@ -210,7 +214,7 @@ qsort_helper(const void *first, const void *second)
}
void
-libiconvlist(int (*do_one) (unsigned int, const char * const *,
+iconvlist(int (*do_one) (unsigned int, const char * const *,
void *), void *data)
{
char **list, **names;
@@ -264,7 +268,7 @@ __inline const char
}
int
-libiconvctl(iconv_t cd, int request, void *argument)
+iconvctl(iconv_t cd, int request, void *argument)
{
struct _citrus_iconv *cv;
struct iconv_hooks *hooks;
@@ -316,7 +320,7 @@ libiconvctl(iconv_t cd, int request, void *argument)
}
void
-libiconv_set_relocation_prefix(const char *orig_prefix __unused,
+iconv_set_relocation_prefix(const char *orig_prefix __unused,
const char *curr_prefix __unused)
{
diff --git a/lib/libiconv_compat/Makefile b/lib/libiconv_compat/Makefile
new file mode 100644
index 0000000..3dcb3514
--- /dev/null
+++ b/lib/libiconv_compat/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+LIB= iconv
+SHLIB_MAJOR= 3
+SRCS= stub.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libiconv_compat/stub.c b/lib/libiconv_compat/stub.c
new file mode 100644
index 0000000..b4e56a2
--- /dev/null
+++ b/lib/libiconv_compat/stub.c
@@ -0,0 +1,8 @@
+/*
+ * Hacks to support things like the dlopen() in libkiconv.so or
+ * ports that want to hard-code -liconv.
+ *
+ * $FreeBSD$
+ */
+
+int __libiconv_stub__;
diff --git a/lib/libkiconv/xlat16_iconv.c b/lib/libkiconv/xlat16_iconv.c
index f402b78..fee3c77 100644
--- a/lib/libkiconv/xlat16_iconv.c
+++ b/lib/libkiconv/xlat16_iconv.c
@@ -49,8 +49,6 @@
#include "quirks.h"
-typedef void *iconv_t;
-
struct xlat16_table {
uint32_t * idx[0x200];
void * data;
@@ -61,6 +59,7 @@ static struct xlat16_table kiconv_xlat16_open(const char *, const char *, int);
static int chklocale(int, const char *);
#ifdef ICONV_DLOPEN
+typedef void *iconv_t;
static int my_iconv_init(void);
static iconv_t (*my_iconv_open)(const char *, const char *);
static size_t (*my_iconv)(iconv_t, const char **, size_t *, char **, size_t *);
OpenPOWER on IntegriCloud