Mercurial > hg-stable
annotate 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 |
rev | line source |
---|---|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
1 # util.py - utility functions and platform specfic implementations |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
2 # |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
4 # |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
7 |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
8 import os |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
9 |
508 | 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) | |
32 | |
421 | 33 def rename(src, dst): |
34 try: | |
35 os.rename(src, dst) | |
36 except: | |
37 os.unlink(dst) | |
38 os.rename(src, dst) | |
39 | |
40 # Platfor specific varients | |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
41 if os.name == 'nt': |
461 | 42 nulldev = 'NUL:' |
43 | |
441 | 44 def is_exec(f, last): |
45 return last | |
46 | |
47 def set_exec(f, mode): | |
48 pass | |
49 | |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
50 def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
51 return path.replace("\\", "/") |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
52 |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
53 def makelock(info, pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
54 ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
55 os.write(ld, info) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
56 os.close(ld) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
57 |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
58 def readlock(pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
59 return file(pathname).read() |
461 | 60 |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
61 else: |
461 | 62 nulldev = '/dev/null' |
63 | |
441 | 64 def is_exec(f, last): |
65 return (os.stat(f).st_mode & 0100 != 0) | |
66 | |
67 def set_exec(f, mode): | |
68 s = os.stat(f).st_mode | |
69 if (s & 0100 != 0) == mode: | |
70 return | |
71 if mode: | |
72 # Turn on +x for every +r bit when making a file executable | |
73 # and obey umask. | |
74 umask = os.umask(0) | |
75 os.umask(umask) | |
76 os.chmod(f, s | (s & 0444) >> 2 & ~umask) | |
77 else: | |
78 os.chmod(f, s & 0666) | |
79 | |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
80 def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
81 return path |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
82 |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
83 def makelock(info, pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
84 os.symlink(info, pathname) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
85 |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
86 def readlock(pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
87 return os.readlink(pathname) |