# HG changeset patch # User Mads Kiilerich # Date 2009-09-20 20:19:18 # Node ID 4368f582c806d8d8917b8873309d52aac528a3f6 # Parent f8048c3340661b20a916b52b5b3cbe75ec521852 util.system: Use subprocess instead of os.system subprocess allows the environment and working directory to be specified directly, so the hacks for making temporary changes while forking is no longer necessary. This also fixes failures on solaris where the temporary changes can't be undone because there is no unsetenv. diff --git a/mercurial/posix.py b/mercurial/posix.py --- a/mercurial/posix.py +++ b/mercurial/posix.py @@ -165,17 +165,11 @@ def testpid(pid): return inst.errno != errno.ESRCH def explain_exit(code): - """return a 2-tuple (desc, code) describing a process's status""" - if os.WIFEXITED(code): - val = os.WEXITSTATUS(code) - return _("exited with status %d") % val, val - elif os.WIFSIGNALED(code): - val = os.WTERMSIG(code) - return _("killed by signal %d") % val, val - elif os.WIFSTOPPED(code): - val = os.WSTOPSIG(code) - return _("stopped by signal %d") % val, val - raise ValueError(_("invalid exit code")) + """return a 2-tuple (desc, code) describing a subprocess status + (codes from kill are negative - not os.system/wait encoding)""" + if code >= 0: + return _("exited with status %d") % code, code + return _("killed by signal %d") % -code, -code def isowner(st): """Return True if the stat object st is from the current user.""" diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -357,41 +357,26 @@ def system(cmd, environ={}, cwd=None, on if val is True: return '1' return str(val) - oldenv = {} - for k in environ: - oldenv[k] = os.environ.get(k) - if cwd is not None: - oldcwd = os.getcwd() origcmd = cmd if os.name == 'nt': cmd = '"%s"' % cmd - try: - for k, v in environ.iteritems(): - os.environ[k] = py2shell(v) - os.environ['HG'] = hgexecutable() - if cwd is not None and oldcwd != cwd: - os.chdir(cwd) - rc = os.system(cmd) - if sys.platform == 'OpenVMS' and rc & 1: - rc = 0 - if rc and onerr: - errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]), - explain_exit(rc)[0]) - if errprefix: - errmsg = '%s: %s' % (errprefix, errmsg) - try: - onerr.warn(errmsg + '\n') - except AttributeError: - raise onerr(errmsg) - return rc - finally: - for k, v in oldenv.iteritems(): - if v is None: - del os.environ[k] - else: - os.environ[k] = v - if cwd is not None and oldcwd != cwd: - os.chdir(oldcwd) + env = dict(os.environ) + env.update((k, py2shell(v)) for k, v in environ.iteritems()) + env['HG'] = hgexecutable() + rc = subprocess.call(cmd, shell=True, close_fds=closefds, + env=env, cwd=cwd) + if sys.platform == 'OpenVMS' and rc & 1: + rc = 0 + if rc and onerr: + errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]), + explain_exit(rc)[0]) + if errprefix: + errmsg = '%s: %s' % (errprefix, errmsg) + try: + onerr.warn(errmsg + '\n') + except AttributeError: + raise onerr(errmsg) + return rc def checksignature(func): '''wrap a function with code to check for calling errors'''