diff -Nur portage.orig/bin/ebuild.sh portage/bin/ebuild.sh --- portage.orig/bin/ebuild.sh 2007-07-17 14:21:50.000000000 +0000 +++ portage/bin/ebuild.sh 2007-07-17 14:22:43.594046285 +0000 @@ -1725,8 +1725,8 @@ unset myarg # Save current environment and touch a success file. (echo for success) umask 002 - set | egrep -v "^SANDBOX_" > "${T}/environment" 2>/dev/null - export | egrep -v "^declare -x SANDBOX_" | \ + set | egrep -v -e "^SANDBOX_" -e "^LD_PRELOAD=" -e "^FAKEROOTKEY=" > "${T}/environment" 2>/dev/null + export | egrep -v -e "^declare -x SANDBOX_" -e "^declare -x LD_PRELOAD=" -e "^declare -x FAKEROOTKEY=" | \ sed 's:^declare -rx:declare -x:' >> "${T}/environment" 2>/dev/null chown portage:portage "${T}/environment" &>/dev/null chmod g+w "${T}/environment" &>/dev/null diff -Nur portage.orig/pym/portage.py portage/pym/portage.py --- portage.orig/pym/portage.py 2007-07-17 14:21:50.000000000 +0000 +++ portage/pym/portage.py 2007-07-17 14:22:57.244279521 +0000 @@ -2277,7 +2277,7 @@ # XXX This would be to replace getstatusoutput completely. # XXX Issue: cannot block execution. Deadlock condition. -def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keywords): +def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, **keywords): """ Spawn a subprocess with extra portage-specific options. Optiosn include: @@ -2305,6 +2305,8 @@ @type droppriv: Boolean @param sesandbox: Enable SELinux Sandboxing (toggles a context switch) @type sesandbox: Boolean + @param fakeroot: Run this command with faked root privileges + @type fakeroot: Boolean @param keywords: Extra options encoded as a dict, to be passed to spawn @type keywords: Dictionary @rtype: Integer @@ -2347,6 +2349,7 @@ restrict = mysettings.get("PORTAGE_RESTRICT","").split() droppriv=(droppriv and "userpriv" in features and not \ ("nouserpriv" in restrict or "userpriv" in restrict)) + fakeroot=(fakeroot and uid and "fakeroot" in features) if droppriv and not uid and portage_gid and portage_uid: keywords.update({"uid":portage_uid,"gid":portage_gid,"groups":userpriv_groups,"umask":002}) @@ -2357,6 +2360,10 @@ if free: keywords["opt_name"] += " bash" spawn_func = portage_exec.spawn_bash + elif fakeroot: + keywords["opt_name"] += " fakeroot" + keywords["fakeroot_state"] = os.path.join(mysettings["T"], "fakeroot.state") + spawn_func = portage_exec.spawn_fakeroot else: keywords["opt_name"] += " sandbox" spawn_func = portage_exec.spawn_sandbox @@ -3875,14 +3882,14 @@ # args are for the to spawn function actionmap = { -"depend": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":0}}, -"setup": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1, "sesandbox":0}}, -"unpack": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":sesandbox}}, -"compile":{"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}}, -"test": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}}, -"install":{"cmd":ebuild_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox}}, -"rpm": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0}}, -"package":{"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0}}, +"depend": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":0, "fakeroot":0}}, +"setup": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1, "sesandbox":0, "fakeroot":0}}, +"unpack": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":sesandbox, "fakeroot":0}}, +"compile":{"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}}, +"test": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}}, +"install":{"cmd":ebuild_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox, "fakeroot":1}}, +"rpm": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":1}}, +"package":{"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":1}}, } # merge the deps in so we have again a 'full' actionmap diff -Nur portage.orig/pym/portage_const.py portage/pym/portage_const.py --- portage.orig/pym/portage_const.py 2007-07-17 14:21:50.000000000 +0000 +++ portage/pym/portage_const.py 2007-07-17 14:22:43.596046317 +0000 @@ -29,6 +29,7 @@ EBUILD_SH_BINARY = PORTAGE_BIN_PATH+"/ebuild.sh" MISC_SH_BINARY = PORTAGE_BIN_PATH + "/misc-functions.sh" SANDBOX_BINARY = "/usr/bin/sandbox" +FAKEROOT_BINARY = "/usr/bin/fakeroot" BASH_BINARY = "/bin/bash" MOVE_BINARY = "/bin/mv" PRELINK_BINARY = "/usr/sbin/prelink" diff -Nur portage.orig/pym/portage_exec.py portage/pym/portage_exec.py --- portage.orig/pym/portage_exec.py 2007-07-17 14:21:51.000000000 +0000 +++ portage/pym/portage_exec.py 2007-07-17 14:22:43.597046334 +0000 @@ -8,7 +8,7 @@ import portage_data from portage_util import dump_traceback -from portage_const import BASH_BINARY, SANDBOX_BINARY +from portage_const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY from portage_exception import CommandNotFound try: @@ -27,6 +27,9 @@ sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and os.access(SANDBOX_BINARY, os.X_OK)) +fakeroot_capable = (os.path.isfile(FAKEROOT_BINARY) and + os.access(FAKEROOT_BINARY, os.X_OK)) + def spawn_bash(mycommand, debug=False, opt_name=None, **keywords): """ Spawns a bash shell running a specific commands @@ -60,6 +63,24 @@ args.append(mycommand) return spawn(args, opt_name=opt_name, **keywords) +def spawn_fakeroot(mycommand, fakeroot_state=None, opt_name=None, **keywords): + if not fakeroot_capable: + return spawn_bash(mycommand, opt_name=opt_name, **keywords) + args=[FAKEROOT_BINARY] + if not opt_name: + opt_name = os.path.basename(mycommand.split()[0]) + if fakeroot_state: + open(fakeroot_state, "a").close() + args.append("-s") + args.append(fakeroot_state) + args.append("-i") + args.append(fakeroot_state) + args.append("--") + args.append(BASH_BINARY) + args.append("-c") + args.append(mycommand) + return spawn(args, opt_name=opt_name, **keywords) + _exithandlers = [] def atexit_register(func, *args, **kargs): """Wrapper around atexit.register that is needed in order to track