Vbox source code used in libvirt.git is LGPLv2-only. If linked into libvirt.so, then we are legally forbidden from linking an app against both that libvirt.so and any GPLv3 code, such as libreadline. While we'd like to fix libvirt.so to be LGPLv2+ in the future, regardless of whether vbox support was compiled in (by moving vbox support into libvirtd, which can afford to be [L]GPLv2-only), that is a more invasive change; this is a simpler approach that fixes the issue for the libvirt package, even though it doesn't help other GPLv3 apps that want to use libvirt.
* configure.ac (VIRSH_LIBS): Prefer the weaker libedit if vbox code is enabled. * tools/virsh.c (vshReadlineInit, vshReadlineDeinit, main): Make history code conditional on actual readline library. (vshShowVersion): Document which library is in use. * libvirt.spec.in (Requires): Use correct library. Signed-off-by: Eric Blake <ebl...@redhat.com> --- configure.ac | 15 ++++++++++++++- libvirt.spec.in | 8 ++++++++ tools/virsh.c | 21 ++++++++++++++++----- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 3feed8b..b2cebf0 100644 --- a/configure.ac +++ b/configure.ac @@ -1406,7 +1406,20 @@ fi AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"]) dnl virsh libraries -VIRSH_LIBS="$VIRSH_LIBS $READLINE_LIBS" +dnl Use of vbox in libvirt.so renders that library LGPLv2-only, which +dnl is incompatible with GPLv3 readline. If that is the case, we must +dnl use libedit or nothing; libedit supports readline() but not history. +if test "x$with_vbox" != xno; then + if test "x$with_edit" = xyes; then + VIRSH_LIBS="$VIRSH_LIBS $EDIT_LIBS" + READLINE_CFLAGS="$READLINE_CFLAGS $EDIT_CFLAGS -DUSE_EDITLINE" + fi +else + if test "x$lv_use_readline" = xyes; then + VIRSH_LIBS="$VIRSH_LIBS $READLINE_LIBS" + READLINE_CFLAGS="$READLINE_CFLAGS -DUSE_READLINE_HISTORY" + fi +fi AC_SUBST([VIRSH_LIBS]) dnl check if the network driver should be compiled diff --git a/libvirt.spec.in b/libvirt.spec.in index ae1bd21..56ef277 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -406,7 +406,11 @@ BuildRequires: xen-devel BuildRequires: libxml2-devel BuildRequires: xhtml1-dtds BuildRequires: libxslt +%if %{with_vbox} +BuildRequires: libedit-devel +%else BuildRequires: readline-devel +%endif BuildRequires: ncurses-devel BuildRequires: gettext BuildRequires: libtasn1-devel @@ -1017,7 +1021,11 @@ capabilities of XEN %package client Summary: Client side library and utilities of the libvirt library Group: Development/Libraries +%if %{with_vbox} +Requires: libedit +%else Requires: readline +%endif Requires: ncurses # So remote clients can access libvirt over SSH tunnel # (client invokes 'nc' against the UNIX socket on the server) diff --git a/tools/virsh.c b/tools/virsh.c index ac86608..56bc239 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -47,7 +47,9 @@ #include <libxml/xpath.h> #include <libxml/xmlsave.h> -#ifdef HAVE_READLINE_READLINE_H +#if USE_EDITLINE +# include <readline.h> +#elif USE_READLINE # include <readline/readline.h> # include <readline/history.h> #endif @@ -2627,16 +2629,19 @@ vshReadlineCompletion(const char *text, int start, static int -vshReadlineInit(vshControl *ctl) +vshReadlineInit(vshControl *ctl ATTRIBUTE_UNUSED) { - char *userdir = NULL; + char name[] = "virsh"; /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = "virsh"; + rl_readline_name = name; /* Tell the completer that we want a crack first. */ rl_attempted_completion_function = vshReadlineCompletion; +# if USE_READLINE_HISTORY + char *userdir = NULL; + /* Limit the total size of the history buffer */ stifle_history(500); @@ -2663,6 +2668,7 @@ vshReadlineInit(vshControl *ctl) VIR_FREE(userdir); read_history(ctl->historyfile); +# endif /* USE_READLINE_HISTORY */ return 0; } @@ -2670,6 +2676,7 @@ vshReadlineInit(vshControl *ctl) static void vshReadlineDeinit(vshControl *ctl) { +# if USE_READLINE_HISTORY if (ctl->historyfile != NULL) { if (virFileMakePathWithMode(ctl->historydir, 0755) < 0 && errno != EEXIST) { @@ -2680,6 +2687,7 @@ vshReadlineDeinit(vshControl *ctl) write_history(ctl->historyfile); } } +# endif /* USE_READLINE_HISTORY */ VIR_FREE(ctl->historydir); VIR_FREE(ctl->historyfile); @@ -2955,6 +2963,9 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef USE_READLINE vshPrint(ctl, " Readline"); #endif +#ifdef USE_READLINE_HISTORY + vshPrint(ctl, " History"); +#endif #ifdef WITH_DRIVER_MODULES vshPrint(ctl, " Modular"); #endif @@ -3228,7 +3239,7 @@ main(int argc, char **argv) if (ctl->cmdstr == NULL) break; /* EOF */ if (*ctl->cmdstr) { -#if USE_READLINE +#if USE_READLINE_HISTORY add_history(ctl->cmdstr); #endif if (vshCommandStringParse(ctl, ctl->cmdstr)) -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list