summaryrefslogtreecommitdiffstats
path: root/pym/portage/_selinux.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2012-07-26 19:42:51 -0700
committerZac Medico <zmedico@gentoo.org>2012-07-26 19:42:51 -0700
commitd938c3ff0a4ef92451cf6381aeb23a6c2d9ad8f2 (patch)
treee7bb683b01facda11f39a0dc2d424ffb2b5a4217 /pym/portage/_selinux.py
parentefb58888bc3900d42c24db9f7ff9f820e93eeb57 (diff)
downloadportage-d938c3ff0a4ef92451cf6381aeb23a6c2d9ad8f2.tar.gz
portage-d938c3ff0a4ef92451cf6381aeb23a6c2d9ad8f2.tar.bz2
portage-d938c3ff0a4ef92451cf6381aeb23a6c2d9ad8f2.zip
_selinux/spawn_wrapper: setexec *after* fork
This avoids any interference with concurrent threads in the calling process.
Diffstat (limited to 'pym/portage/_selinux.py')
-rw-r--r--pym/portage/_selinux.py40
1 files changed, 26 insertions, 14 deletions
diff --git a/pym/portage/_selinux.py b/pym/portage/_selinux.py
index 9470978c4..173714515 100644
--- a/pym/portage/_selinux.py
+++ b/pym/portage/_selinux.py
@@ -95,20 +95,32 @@ def setfscreate(ctx="\n"):
raise OSError(
_("setfscreate: Failed setting fs create context \"%s\".") % ctx)
-def spawn_wrapper(spawn_func, selinux_type):
-
- selinux_type = _unicode_encode(selinux_type,
- encoding=_encodings['content'], errors='strict')
-
- def wrapper_func(*args, **kwargs):
- con = settype(selinux_type)
- setexec(con)
- try:
- return spawn_func(*args, **kwargs)
- finally:
- setexec()
-
- return wrapper_func
+class spawn_wrapper(object):
+ """
+ Create a wrapper function for the given spawn function. When the wrapper
+ is called, it will adjust the arguments such that setexec() to be called
+ *after* the fork (thereby avoiding any interference with concurrent
+ threads in the calling process).
+ """
+ __slots__ = ("_con", "_spawn_func")
+
+ def __init__(self, spawn_func, selinux_type):
+ self._spawn_func = spawn_func
+ selinux_type = _unicode_encode(selinux_type,
+ encoding=_encodings['content'], errors='strict')
+ self._con = settype(selinux_type)
+
+ def __call__(self, *args, **kwargs):
+
+ pre_exec = kwargs.get("pre_exec")
+
+ def _pre_exec():
+ if pre_exec is not None:
+ pre_exec()
+ setexec(self._con)
+
+ kwargs["pre_exec"] = _pre_exec
+ return self._spawn_func(*args, **kwargs)
def symlink(target, link, reflnk):
target = _unicode_encode(target, encoding=_encodings['fs'], errors='strict')