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.
This commit is contained in:
Peter Wemm 2013-08-13 07:15:01 +00:00
parent db8645f05e
commit 0ff204bbd1
12 changed files with 122 additions and 42 deletions

View File

@ -31,6 +31,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20130813:
WITH_ICONV has been split into two feature sets. WITH_ICONV now
enables just the iconv* functionality and is now on by default.
WITH_LIBICONV_COMPAT enables the libiconv api and link time
compatability. Set WITHOUT_ICONV to build the old way.
20130806:
INVARIANTS option now enables DEBUG for code with OpenSolaris and
Illumos origin, including ZFS. If you have INVARIANTS in your

View File

@ -72,10 +72,6 @@ _dev_ieee488= dev/ieee488
INCS+= hesiod.h
.endif
.if ${MK_ICONV} != "no"
INCS+= iconv.h
.endif
.if ${MK_BLUETOOTH} != "no"
LSUBSUBDIRS+= netgraph/bluetooth/include
.endif
@ -85,6 +81,20 @@ LSUBSUBDIRS+= netgraph/bluetooth/include
_netipx= netipx
#.endif
# Handle the #define aliases for libiconv
.if ${MK_ICONV} == "yes"
CLEANFILES+= _libiconv_compat.h
INCS+= _libiconv_compat.h iconv.h
_libiconv_compat.h: ${.CURDIR}/Makefile
echo "/* Indicate whether libiconv symbols are present */" > _libiconv_compat.h
.if ${MK_LIBICONV_COMPAT} == "yes"
echo "#define __LIBICONV_COMPAT" >> _libiconv_compat.h
.else
echo "#undef __LIBICONV_COMPAT" >> _libiconv_compat.h
.endif
.endif
# Define SHARED to indicate whether you want symbolic links to the system
# source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is
# probably only useful for developers and should be avoided if you do not

View File

@ -41,20 +41,23 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#define iconv_open libiconv_open
#define iconv_close libiconv_close
#define iconv libiconv
#define iconv_t libiconv_t
#include <_libiconv_compat.h>
#ifdef __LIBICONV_COMPAT
#define libiconv_open iconv_open
#define libiconv_close iconv_close
#define libiconv iconv
#define libiconv_t iconv_t
#endif
struct __tag_iconv_t;
typedef struct __tag_iconv_t *iconv_t;
__BEGIN_DECLS
iconv_t libiconv_open(const char *, const char *);
size_t libiconv(iconv_t, const char ** __restrict,
size_t * __restrict, char ** __restrict,
size_t * __restrict);
int libiconv_close(iconv_t);
iconv_t iconv_open(const char *, const char *);
size_t iconv(iconv_t, const char ** __restrict,
size_t * __restrict, char ** __restrict,
size_t * __restrict);
int iconv_close(iconv_t);
/*
* non-portable interfaces for iconv
*/
@ -67,20 +70,28 @@ size_t __iconv(iconv_t, const char **, size_t *, char **,
/*
* GNU interfaces for iconv
*/
#define iconv_open_into libiconv_open_into
#define iconvctl libiconvctl
#define iconvlist libiconvlist
#ifdef __LIBICONV_COMPAT
#define libiconv_open_into iconv_open_into
#define libiconvctl iconvctl
#define libiconvlist iconvlist
#define libiconv_set_relocation_prefix iconv_set_relocation_prefix
#endif
/* We have iconvctl() */
#define _LIBICONV_VERSION 0x0108
extern int _libiconv_version;
#define _ICONV_VERSION 0x0108
extern int _iconv_version;
#ifdef __LIBICONV_COMPAT
#define _libiconv_version _iconv_version
#define _LIBICONV_VERSION _ICONV_VERSION
#endif
typedef struct {
void *spaceholder[64];
} iconv_allocation_t;
int iconv_open_into(const char *, const char *, iconv_allocation_t *);
void libiconv_set_relocation_prefix (const char *orig_prefix,
void iconv_set_relocation_prefix(const char *orig_prefix,
const char *curr_prefix);
/*

View File

@ -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

View File

@ -18,6 +18,7 @@ FBSD_1.2 {
};
FBSD_1.3 {
_iconv_version;
iconv;
iconv_open;
iconv_close;

View File

@ -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)
{

View File

@ -0,0 +1,7 @@
# $FreeBSD$
LIB= iconv
SHLIB_MAJOR= 3
SRCS= stub.c
.include <bsd.lib.mk>

View File

@ -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__;

View File

@ -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 *);

View File

@ -292,6 +292,7 @@ __DEFAULT_YES_OPTIONS = \
GPIO \
GROFF \
HTML \
ICONV \
INET \
INET6 \
INFO \
@ -377,7 +378,7 @@ __DEFAULT_NO_OPTIONS = \
GNU_PATCH \
GPL_DTC \
HESIOD \
ICONV \
LIBICONV_COMPAT \
INSTALL_AS_USER \
LDNS_UTILS \
NMTREE \
@ -484,6 +485,10 @@ MK_BIND_NAMED:= no
MK_BIND_UTILS:= no
.endif
.if ${MK_ICONV} == "no"
MK_LIBICONV_COMPAT:= no
.endif
.if ${MK_LDNS} == "no"
MK_LDNS_UTILS:= no
.endif

View File

@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1000042 /* Master, propagated to newvers */
#define __FreeBSD_version 1000043 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View File

@ -2198,6 +2198,27 @@ OLD_FILES+=usr/share/man/man5/hesiod.conf.5.gz
# to be filled in
#.endif
.if ${MK_ICONV} == no
OLD_FILES+=usr/bin/iconv
OLD_FILES+=usr/bin/mkcsmapper
OLD_FILES+=usr/bin/mkesdb
OLD_FILES+=usr/include/_libiconv_compat.h
OLD_FILES+=usr/include/iconv.h
OLD_FILES+=usr/share/man/man1/iconv.1.gz
OLD_FILES+=usr/share/man/man1/mkcsmapper.1.gz
OLD_FILES+=usr/share/man/man1/mkesdb.1.gz
OLD_FILES+=usr/share/man/man3/__iconv.3.gz
OLD_FILES+=usr/share/man/man3/__iconv_free_list.3.gz
OLD_FILES+=usr/share/man/man3/__iconv_get_list.3.gz
OLD_FILES+=usr/share/man/man3/iconv.3.gz
OLD_FILES+=usr/share/man/man3/iconv_canonicalize.3.gz
OLD_FILES+=usr/share/man/man3/iconv_close.3.gz
OLD_FILES+=usr/share/man/man3/iconv_open.3.gz
OLD_FILES+=usr/share/man/man3/iconv_open_into.3.gz
OLD_FILES+=usr/share/man/man3/iconvctl.3.gz
OLD_FILES+=usr/share/man/man3/iconvlist.3.gz
.endif
.if ${MK_INET6} == no
OLD_FILES+=sbin/ping6
OLD_FILES+=sbin/rtsol
@ -3338,6 +3359,13 @@ OLD_FILES+=usr/share/man/man8/verify_krb5_conf.8.gz
# to be filled in
#.endif
.if ${MK_LIBICONV_COMPAT} == no
OLD_FILES+=usr/lib/libiconv.a
OLD_FILES+=usr/lib/libiconv.so
OLD_FILES+=usr/lib/libiconv.so.3
OLD_FILES+=usr/lib/libiconv_p.a
.endif
.if ${MK_LIBCPLUSPLUS} == no
OLD_LIBS+=lib/libcxxrt.so.1
OLD_FILES+=usr/lib/libc++.a
@ -4347,7 +4375,3 @@ OLD_FILES+=usr/bin/svnserve
OLD_FILES+=usr/bin/svnsync
OLD_FILES+=usr/bin/svnversion
.endif
.if ${MK_ICONV} == no
OLD_FILES+=usr/bin/iconv
.endif