diff 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
line wrap: on
line diff
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -7,6 +7,29 @@
 
 import os
 
+class CommandError(Exception): pass
+
+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.STOPSIG(code)
+        return "stopped by signal %d" % val, val
+    raise ValueError("invalid exit code")
+    
+def system(cmd, errprefix = "abort"):
+    """execute a shell command that must succeed"""
+    rc = os.system(cmd)
+    if rc:
+        errmsg = "%s: %s %s" % (errprefix, os.path.basename(cmd.split(None, 1)[0]),
+                                explain_exit(rc)[0])
+        raise CommandError(errmsg)
+
 def rename(src, dst):
     try:
         os.rename(src, dst)