author | mpm@selenic.com |
Sun, 03 Jul 2005 20:47:29 -0800 | |
changeset 603 | bc5d058e65e9 |
parent 556 | f6c6fa15ff70 |
child 667 | 31a9aa890016 |
permissions | -rw-r--r-- |
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 |
|
556 | 10 |
def unique(g): |
11 |
seen = {} |
|
12 |
for f in g: |
|
13 |
if f not in seen: |
|
14 |
seen[f] = 1 |
|
15 |
yield f |
|
16 |
||
508 | 17 |
class CommandError(Exception): pass |
18 |
||
19 |
def explain_exit(code): |
|
20 |
"""return a 2-tuple (desc, code) describing a process's status""" |
|
21 |
if os.WIFEXITED(code): |
|
22 |
val = os.WEXITSTATUS(code) |
|
23 |
return "exited with status %d" % val, val |
|
24 |
elif os.WIFSIGNALED(code): |
|
25 |
val = os.WTERMSIG(code) |
|
26 |
return "killed by signal %d" % val, val |
|
27 |
elif os.WIFSTOPPED(code): |
|
28 |
val = os.STOPSIG(code) |
|
29 |
return "stopped by signal %d" % val, val |
|
30 |
raise ValueError("invalid exit code") |
|
515 | 31 |
|
521 | 32 |
def system(cmd, errprefix=None): |
508 | 33 |
"""execute a shell command that must succeed""" |
34 |
rc = os.system(cmd) |
|
35 |
if rc: |
|
521 | 36 |
errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), |
37 |
explain_exit(rc)[0]) |
|
38 |
if errprefix: |
|
39 |
errmsg = "%s: %s" % (errprefix, errmsg) |
|
508 | 40 |
raise CommandError(errmsg) |
41 |
||
421 | 42 |
def rename(src, dst): |
43 |
try: |
|
44 |
os.rename(src, dst) |
|
45 |
except: |
|
46 |
os.unlink(dst) |
|
47 |
os.rename(src, dst) |
|
48 |
||
49 |
# Platfor specific varients |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
50 |
if os.name == 'nt': |
461 | 51 |
nulldev = 'NUL:' |
52 |
||
441 | 53 |
def is_exec(f, last): |
54 |
return last |
|
55 |
||
56 |
def set_exec(f, mode): |
|
57 |
pass |
|
515 | 58 |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
59 |
def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
60 |
return path.replace("\\", "/") |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
61 |
|
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
62 |
def makelock(info, pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
63 |
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
|
64 |
os.write(ld, info) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
65 |
os.close(ld) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
66 |
|
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
67 |
def readlock(pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
68 |
return file(pathname).read() |
461 | 69 |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
70 |
else: |
461 | 71 |
nulldev = '/dev/null' |
72 |
||
441 | 73 |
def is_exec(f, last): |
74 |
return (os.stat(f).st_mode & 0100 != 0) |
|
75 |
||
76 |
def set_exec(f, mode): |
|
77 |
s = os.stat(f).st_mode |
|
78 |
if (s & 0100 != 0) == mode: |
|
79 |
return |
|
80 |
if mode: |
|
81 |
# Turn on +x for every +r bit when making a file executable |
|
82 |
# and obey umask. |
|
83 |
umask = os.umask(0) |
|
84 |
os.umask(umask) |
|
85 |
os.chmod(f, s | (s & 0444) >> 2 & ~umask) |
|
86 |
else: |
|
87 |
os.chmod(f, s & 0666) |
|
88 |
||
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
89 |
def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
90 |
return path |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
91 |
|
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
92 |
def makelock(info, pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
93 |
os.symlink(info, pathname) |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
94 |
|
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
95 |
def readlock(pathname): |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
96 |
return os.readlink(pathname) |