Revision c47eddb8
b/lib/utils/io.py | ||
---|---|---|
38 | 38 |
#: Path generating random UUID |
39 | 39 |
_RANDOM_UUID_FILE = "/proc/sys/kernel/random/uuid" |
40 | 40 |
|
41 |
# Possible values for keep_perms in WriteFile() |
|
42 |
KP_NEVER = 0 |
|
43 |
KP_ALWAYS = 1 |
|
44 |
KP_IF_EXISTS = 2 |
|
45 |
|
|
46 |
KEEP_PERMS_VALUES = [ |
|
47 |
KP_NEVER, |
|
48 |
KP_ALWAYS, |
|
49 |
KP_IF_EXISTS, |
|
50 |
] |
|
51 |
|
|
41 | 52 |
|
42 | 53 |
def ErrnoOrStr(err): |
43 | 54 |
"""Format an EnvironmentError exception. |
... | ... | |
82 | 93 |
mode=None, uid=-1, gid=-1, |
83 | 94 |
atime=None, mtime=None, close=True, |
84 | 95 |
dry_run=False, backup=False, |
85 |
prewrite=None, postwrite=None): |
|
96 |
prewrite=None, postwrite=None, keep_perms=KP_NEVER):
|
|
86 | 97 |
"""(Over)write a file atomically. |
87 | 98 |
|
88 | 99 |
The file_name and either fn (a function taking one argument, the |
... | ... | |
119 | 130 |
@param prewrite: function to be called before writing content |
120 | 131 |
@type postwrite: callable |
121 | 132 |
@param postwrite: function to be called after writing content |
133 |
@type keep_perms: members of L{KEEP_PERMS_VALUES} |
|
134 |
@param keep_perms: if L{KP_NEVER} (default), owner, group, and mode are |
|
135 |
taken from the other parameters; if L{KP_ALWAYS}, owner, group, and |
|
136 |
mode are copied from the existing file; if L{KP_IF_EXISTS}, owner, |
|
137 |
group, and mode are taken from the file, and if the file doesn't |
|
138 |
exist, they are taken from the other parameters. It is an error to |
|
139 |
pass L{KP_ALWAYS} when the file doesn't exist or when C{uid}, C{gid}, |
|
140 |
or C{mode} are set to non-default values. |
|
122 | 141 |
|
123 | 142 |
@rtype: None or int |
124 | 143 |
@return: None if the 'close' parameter evaluates to True, |
... | ... | |
138 | 157 |
raise errors.ProgrammerError("Both atime and mtime must be either" |
139 | 158 |
" set or None") |
140 | 159 |
|
160 |
if not keep_perms in KEEP_PERMS_VALUES: |
|
161 |
raise errors.ProgrammerError("Invalid value for keep_perms: %s" % |
|
162 |
keep_perms) |
|
163 |
if keep_perms == KP_ALWAYS and (uid != -1 or gid != -1 or mode is not None): |
|
164 |
raise errors.ProgrammerError("When keep_perms==KP_ALWAYS, 'uid', 'gid'," |
|
165 |
" and 'mode' cannot be set") |
|
166 |
|
|
141 | 167 |
if backup and not dry_run and os.path.isfile(file_name): |
142 | 168 |
CreateBackup(file_name) |
143 | 169 |
|
170 |
if keep_perms == KP_ALWAYS or keep_perms == KP_IF_EXISTS: |
|
171 |
# os.stat() raises an exception if the file doesn't exist |
|
172 |
try: |
|
173 |
file_stat = os.stat(file_name) |
|
174 |
mode = stat.S_IMODE(file_stat.st_mode) |
|
175 |
uid = file_stat.st_uid |
|
176 |
gid = file_stat.st_gid |
|
177 |
except OSError: |
|
178 |
if keep_perms == KP_ALWAYS: |
|
179 |
raise |
|
180 |
# else: if keeep_perms == KP_IF_EXISTS it's ok if the file doesn't exist |
|
181 |
|
|
144 | 182 |
# Whether temporary file needs to be removed (e.g. if any error occurs) |
145 | 183 |
do_remove = True |
146 | 184 |
|
Also available in: Unified diff