summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2006-02-06 19:25:08 +0000
committerZac Medico <zmedico@gentoo.org>2006-02-06 19:25:08 +0000
commit6557c596b6e3dd749c5bad942d10621e908b1f0d (patch)
tree124fbd1e816cc98f9b4558e19a0b21ebfc9aab3c
parent7c5461984be838833d9f41a4a0e08e8f90871a04 (diff)
downloadportage-6557c596b6e3dd749c5bad942d10621e908b1f0d.tar.gz
portage-6557c596b6e3dd749c5bad942d10621e908b1f0d.tar.bz2
portage-6557c596b6e3dd749c5bad942d10621e908b1f0d.zip
wrap all relevant atexit usage due to incompatibility with os.execv (needed for emerge to restart itself)
svn path=/main/trunk/; revision=2674
-rwxr-xr-xbin/emerge6
-rw-r--r--pym/portage.py5
-rw-r--r--pym/portage_exec.py36
-rw-r--r--pym/portage_locks.py4
4 files changed, 43 insertions, 8 deletions
diff --git a/bin/emerge b/bin/emerge
index e9aa65dd5..f9cd87081 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -9,7 +9,7 @@ sys.path = ["/usr/lib/portage/pym"]+sys.path
import portage
-import emergehelp,xpak,string,re,commands,time,shutil,traceback,atexit,signal,socket,types
+import emergehelp,xpak,string,re,commands,time,shutil,traceback,signal,socket,types
from stat import *
from output import *
@@ -492,7 +492,7 @@ def emergeexit():
emergelog(" *** terminating.")
if "notitles" not in portage.features:
xtermTitleReset()
-atexit.register(emergeexit)
+portage.atexit_register(emergeexit)
def emergeexitsig(signum, frame):
signal.signal(signal.SIGINT, signal.SIG_IGN)
@@ -2119,7 +2119,7 @@ class depgraph:
if len(mymergelist) > mergecount:
emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
del portage.mtimedb["resume"]["mergelist"][0]
- portage.portageexit()
+ portage.run_exitfuncs()
mynewargv=[sys.argv[0],"--resume"]
badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
for arg in myopts:
diff --git a/pym/portage.py b/pym/portage.py
index f5949bd5e..abc48ddf2 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -19,7 +19,7 @@ except:
raise SystemExit, 127
try:
- import os,string,types,atexit,signal,fcntl
+ import os,string,types,signal,fcntl
import time,cPickle,traceback,copy
import re,pwd,grp,commands
import shlex,shutil
@@ -95,6 +95,7 @@ try:
import portage_gpg
import portage_locks
import portage_exec
+ from portage_exec import atexit_register, run_exitfuncs
from portage_locks import unlockfile,unlockdir,lockfile,lockdir
import portage_checksum
from portage_checksum import perform_md5,perform_checksum,prelink_capable
@@ -6901,7 +6902,7 @@ def portageexit():
close_portdbapi_caches()
commit_mtimedb()
-atexit.register(portageexit)
+atexit_register(portageexit)
if (secpass==2) and (not os.environ.has_key("SANDBOX_ACTIVE")):
if settings["PORTAGE_CALLER"] in ["emerge","fixpackages"]:
diff --git a/pym/portage_exec.py b/pym/portage_exec.py
index db3c8be36..31b379396 100644
--- a/pym/portage_exec.py
+++ b/pym/portage_exec.py
@@ -7,6 +7,7 @@
import os, atexit, signal, sys
import portage_data
+from portage_util import dump_traceback
from portage_const import BASH_BINARY, SANDBOX_BINARY
@@ -39,6 +40,39 @@ def spawn_sandbox(mycommand, opt_name=None, **keywords):
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
+ what is registered. For example, when portage restarts itself via
+ os.execv, the atexit module does not work so we have to do it
+ manually by calling the run_exitfuncs() function in this module."""
+ _exithandlers.append((func, args, kargs))
+
+def run_exitfuncs():
+ """This should behave identically to the routine performed by
+ the atexit module at exit time. It's only necessary to call this
+ function when atexit will not work (because of os.execv, for
+ example)."""
+
+ # This function is a copy of the private atexit._run_exitfuncs()
+ # from the python 2.4.2 sources. The only difference from the
+ # original function is in the output to stderr.
+ exc_info = None
+ while _exithandlers:
+ func, targs, kargs = _exithandlers.pop()
+ try:
+ func(*targs, **kargs)
+ except SystemExit:
+ exc_info = sys.exc_info()
+ except:
+ dump_traceback("Error in portage_exec.run_exitfuncs", noiselevel=0)
+ exc_info = sys.exc_info()
+
+ if exc_info is not None:
+ raise exc_info[0], exc_info[1], exc_info[2]
+
+atexit.register(run_exitfuncs)
+
# We need to make sure that any processes spawned are killed off when
# we exit. spawn() takes care of adding and removing pids to this list
# as it creates and cleans up processes.
@@ -55,7 +89,7 @@ def cleanup():
# of spawn().
pass
-atexit.register(cleanup)
+atexit_register(cleanup)
def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
uid=None, gid=None, groups=None, umask=None, logfile=None,
diff --git a/pym/portage_locks.py b/pym/portage_locks.py
index 241ff9df9..09daa2e4d 100644
--- a/pym/portage_locks.py
+++ b/pym/portage_locks.py
@@ -4,7 +4,6 @@
# $Id: /var/cvsroot/gentoo-src/portage/pym/portage_locks.py,v 1.18.2.2 2005/01/16 02:35:33 carpaski Exp $
-import atexit
import errno
import os
import stat
@@ -15,6 +14,7 @@ import portage_exception
import portage_file
import portage_util
import portage_data
+from portage_exec import atexit_register
from portage_localization import _
HARDLINK_FD = -2
@@ -30,7 +30,7 @@ def add_hardlock_file_to_cleanup(path):
if os.path.isdir(mypath):
hardlock_path_list = mypath[:]
-atexit.register(clean_my_hardlocks)
+atexit_register(clean_my_hardlocks)
def lockdir(mydir):
return lockfile(mydir,wantnewlockfile=1)