comparison mercurial/util.py @ 508:42a660abaf75

[PATCH] Harden os.system -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [PATCH] Harden os.system From: Bryan O'Sullivan <bos@serpentine.com> Add util.system function. This is similar to os.system, but will either succeed (if the process finishes with a zero exit code) or raise a util.CommandError (if the process exits uncleanly or is killed by a signal). Add util.explain_exit function. This tends to be ubiquitous in code that calls other processes, and must describe what has gone wrong. Change some uses of os.system over to util.system. manifest hash: e3bf4adcac5b915432ec0af00efdbcef86bea4b1 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCwSipywK+sNU5EO8RAr0RAJkBDt8XQ7mYQAWNHNgTOVt1eyWU1QCfe1oO 2OwxyWqpbRNACVJHHfZ3/Xw= =OaRX -----END PGP SIGNATURE-----
author mpm@selenic.com
date Tue, 28 Jun 2005 02:38:33 -0800
parents 50da4bb9cab6
children 03f27b1381f9
comparison
equal deleted inserted replaced
507:dd8b19114fe7 508:42a660abaf75
4 # 4 #
5 # This software may be used and distributed according to the terms 5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference. 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 import os 8 import os
9
10 class CommandError(Exception): pass
11
12 def explain_exit(code):
13 """return a 2-tuple (desc, code) describing a process's status"""
14 if os.WIFEXITED(code):
15 val = os.WEXITSTATUS(code)
16 return "exited with status %d" % val, val
17 elif os.WIFSIGNALED(code):
18 val = os.WTERMSIG(code)
19 return "killed by signal %d" % val, val
20 elif os.WIFSTOPPED(code):
21 val = os.STOPSIG(code)
22 return "stopped by signal %d" % val, val
23 raise ValueError("invalid exit code")
24
25 def system(cmd, errprefix = "abort"):
26 """execute a shell command that must succeed"""
27 rc = os.system(cmd)
28 if rc:
29 errmsg = "%s: %s %s" % (errprefix, os.path.basename(cmd.split(None, 1)[0]),
30 explain_exit(rc)[0])
31 raise CommandError(errmsg)
9 32
10 def rename(src, dst): 33 def rename(src, dst):
11 try: 34 try:
12 os.rename(src, dst) 35 os.rename(src, dst)
13 except: 36 except: