Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kde-base/pykde4: fix bugs in pythonpluginfactorywrapper.c
The logic for checking the return value of fork() was inverted, causing the main process to continue as the child process, while the parent process execs. This can confuse libraries and applications that don't expect their PID to suddenly change, and other misc badness (process gets reparented to init, etc.) Gentoo-bug: https://bugs.gentoo.org/show_bug.cgi?id=555436
- Loading branch information
1 parent
e3d8a51
commit 22aa5c8
Showing
2 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include <dlfcn.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <sys/wait.h> | ||
|
||
#define VERSION_LEN 10 | ||
|
||
#define FORMAT EPREFIX PLUGIN_DIR "/kpython%spluginfactory.so" | ||
|
||
static void *handle; | ||
static void *(*wrapped_qt_plugin_instance)(); | ||
|
||
static void get_python_version(char* out) { | ||
int pipefd[2]; | ||
pipe(pipefd); | ||
pid_t cpid = fork(); | ||
if (cpid > 0) { | ||
close(pipefd[1]); | ||
read(pipefd[0], out, VERSION_LEN); | ||
close(pipefd[0]); | ||
waitpid(cpid, NULL, 0); | ||
} else if (cpid < 0) { | ||
/* fork failed, guess 2.7 */ | ||
strcpy(out, "2.7\n"); | ||
close(pipefd[0]); | ||
close(pipefd[1]); | ||
} else { | ||
close(pipefd[0]); | ||
close(1); | ||
dup2(pipefd[1], 1); | ||
close(pipefd[1]); | ||
close(0); | ||
char *args[] = { "eselect", "python", "show", "--ABI", "--python2", 0 }; | ||
execv(EPREFIX "/usr/bin/eselect", args); | ||
/* exec failed, guess 2.7 */ | ||
write(1, "2.7\n", 4); | ||
exit(0); | ||
} | ||
} | ||
|
||
__attribute__((constructor)) | ||
static void init() { | ||
char buf[VERSION_LEN + 1]; | ||
memset(buf, 0, VERSION_LEN + 1); | ||
get_python_version(buf); | ||
char *s = buf; | ||
while(*s != '\0') { | ||
if(*s == '\n') { | ||
*s = '\0'; | ||
break; | ||
} | ||
++s; | ||
} | ||
int length = strlen(FORMAT) + strlen(buf) + 1; | ||
char *name = malloc(length + 1); | ||
snprintf(name, length, FORMAT, buf); | ||
handle = dlopen(name, RTLD_NOW); | ||
free(name); | ||
wrapped_qt_plugin_instance = dlsym(handle, "qt_plugin_instance"); | ||
} | ||
|
||
__attribute__((destructor)) | ||
static void fini() { | ||
dlclose(handle); | ||
} | ||
|
||
void *qt_plugin_instance() { | ||
return wrapped_qt_plugin_instance(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
# Copyright 1999-2016 Gentoo Foundation | ||
# Distributed under the terms of the GNU General Public License v2 | ||
# $Id$ | ||
|
||
EAPI=5 | ||
|
||
PYTHON_COMPAT=( python{2_7,3_3,3_4} ) | ||
PYTHON_REQ_USE="threads" | ||
OPENGL_REQUIRED="always" | ||
CMAKE_MAKEFILE_GENERATOR="emake" | ||
inherit python-r1 portability kde4-base multilib eutils | ||
|
||
DESCRIPTION="Python bindings for KDE4" | ||
KEYWORDS="~amd64 ~arm ~ppc ~ppc64 ~x86 ~amd64-linux ~x86-linux" | ||
IUSE="akonadi debug doc examples test" | ||
HOMEPAGE="https://techbase.kde.org/Development/Languages/Python" | ||
|
||
REQUIRED_USE="${PYTHON_REQUIRED_USE}" | ||
|
||
RDEPEND=" | ||
${PYTHON_DEPS} | ||
>=dev-python/PyQt4-4.11.1[${PYTHON_USEDEP},dbus,declarative,script,sql,svg,webkit,X] | ||
>=dev-python/sip-4.16.2:=[${PYTHON_USEDEP}] | ||
$(add_kdebase_dep kdelibs 'opengl') | ||
akonadi? ( $(add_kdeapps_dep kdepimlibs) ) | ||
" | ||
DEPEND="${RDEPEND} | ||
dev-lang/python-exec:2[${PYTHON_USEDEP}] | ||
sys-devel/libtool | ||
" | ||
|
||
PATCHES=( "${FILESDIR}/${P}-gcc-5.patch" ) | ||
|
||
pkg_setup() { | ||
kde4-base_pkg_setup | ||
|
||
have_python2=false | ||
|
||
scan_python_versions() { | ||
if [[ ${EPYTHON} == python2.* ]]; then | ||
have_python2=true | ||
fi | ||
} | ||
python_foreach_impl scan_python_versions | ||
|
||
if ! ${have_python2}; then | ||
ewarn "You do not have a Python 2 version selected." | ||
ewarn "kpythonpluginfactory will not be built" | ||
fi | ||
} | ||
|
||
src_prepare() { | ||
kde4-base_src_prepare | ||
|
||
if ! use examples; then | ||
sed -e '/^ADD_SUBDIRECTORY(examples)/s/^/# DISABLED /' -i CMakeLists.txt \ | ||
|| die "Failed to disable examples" | ||
fi | ||
|
||
# See bug 322351 | ||
use arm && epatch "${FILESDIR}/${PN}-4.14.0-arm-sip.patch" | ||
|
||
sed -e 's/kpythonpluginfactory /kpython${PYTHON_SHORT_VERSION}pluginfactory /g' \ | ||
-i kpythonpluginfactory/CMakeLists.txt || die | ||
|
||
if ${have_python2}; then | ||
mkdir -p "${WORKDIR}/wrapper" || die "failed to copy wrapper" | ||
cp "${FILESDIR}/kpythonpluginfactorywrapper.c-r2" "${WORKDIR}/wrapper/kpythonpluginfactorywrapper.c" || die "failed to copy wrapper" | ||
fi | ||
python_copy_sources | ||
|
||
} | ||
|
||
src_configure() { | ||
configuration() { | ||
local mycmakeargs=( | ||
-DWITH_PolkitQt=OFF | ||
-DWITH_QScintilla=OFF | ||
-DPYKDEUIC4_ALTINSTALL=TRUE | ||
-DWITH_Nepomuk=OFF | ||
-DWITH_Soprano=OFF | ||
$(cmake-utils_use_with akonadi KdepimLibs) | ||
-DPYTHON_EXECUTABLE=${PYTHON} | ||
) | ||
local CMAKE_BUILD_DIR=${S}_build-${PYTHON_ABI} | ||
kde4-base_src_configure | ||
} | ||
|
||
python_foreach_impl run_in_build_dir configuration | ||
} | ||
|
||
echo_and_run() { | ||
echo "$@" | ||
"$@" | ||
} | ||
|
||
src_compile() { | ||
compilation() { | ||
local CMAKE_BUILD_DIR=${S}_build-${PYTHON_ABI} | ||
kde4-base_src_compile | ||
} | ||
python_foreach_impl run_in_build_dir compilation | ||
|
||
if ${have_python2}; then | ||
pushd "${WORKDIR}/wrapper" > /dev/null | ||
echo_and_run libtool --tag=CC --mode=compile $(tc-getCC) \ | ||
-shared \ | ||
${CFLAGS} ${CPPFLAGS} \ | ||
-DEPREFIX="\"${EPREFIX}\"" \ | ||
-DPLUGIN_DIR="\"/usr/$(get_libdir)/kde4\"" -c \ | ||
-o kpythonpluginfactorywrapper.lo \ | ||
kpythonpluginfactorywrapper.c | ||
echo_and_run libtool --tag=CC --mode=link $(tc-getCC) \ | ||
-shared -module -avoid-version \ | ||
${CFLAGS} ${LDFLAGS} \ | ||
-o kpythonpluginfactory.la \ | ||
-rpath "${EPREFIX}/usr/$(get_libdir)/kde4" \ | ||
kpythonpluginfactorywrapper.lo \ | ||
$(dlopen_lib) | ||
popd > /dev/null | ||
fi | ||
} | ||
|
||
src_test() { | ||
python_foreach_impl run_in_build_dir kde4-base_src_test | ||
} | ||
|
||
src_install() { | ||
installation() { | ||
emake DESTDIR="${D}" install | ||
|
||
mkdir -p "${D%/}$(python_get_scriptdir)" || die | ||
mv "${ED%/}/usr/bin/pykdeuic4-${EPYTHON/python/}" \ | ||
"${D%/}$(python_get_scriptdir)"/pykdeuic4 || die | ||
|
||
python_fix_shebang "${D%/}$(python_get_scriptdir)"/pykdeuic4 | ||
python_optimize | ||
} | ||
python_foreach_impl run_in_build_dir installation | ||
|
||
dosym ../lib/python-exec/python-exec2 /usr/bin/pykdeuic4 | ||
|
||
# As we don't call the eclass's src_install, we have to install the docs manually | ||
DOCS=("${S}"/{AUTHORS,NEWS,README}) | ||
use doc && HTML_DOCS=("${S}/docs/html/") | ||
einstalldocs | ||
|
||
if ${have_python2}; then | ||
pushd "${WORKDIR}/wrapper" > /dev/null | ||
echo_and_run libtool --mode=install install kpythonpluginfactory.la "${ED}/usr/$(get_libdir)/kde4/kpythonpluginfactory.la" | ||
rm "${ED}/usr/$(get_libdir)/kde4/kpythonpluginfactory.la" | ||
popd > /dev/null | ||
fi | ||
} | ||
|
||
pkg_postinst() { | ||
kde4-base_pkg_postinst | ||
|
||
if use examples; then | ||
echo | ||
elog "PyKDE4 examples have been installed to" | ||
elog "${EPREFIX}/usr/share/apps/${PN}/examples" | ||
echo | ||
fi | ||
} |