85
87
# be opened in binary mode, rather than text mode.
86
88
# On other platforms, O_BINARY doesn't exist, because
87
89
# they always open in binary mode, so it is okay to
88
# OR with 0 on those platforms
90
# OR with 0 on those platforms.
91
# O_NOINHERIT and O_TEXT exists only on win32 too.
89
92
O_BINARY = getattr(os, 'O_BINARY', 0)
93
O_TEXT = getattr(os, 'O_TEXT', 0)
94
O_NOINHERIT = getattr(os, 'O_NOINHERIT', 0)
92
97
def get_unicode_argv():
663
668
def sha_file_by_name(fname):
664
669
"""Calculate the SHA1 of a file by reading the full text"""
666
f = os.open(fname, os.O_RDONLY | O_BINARY)
671
f = os.open(fname, os.O_RDONLY | O_BINARY | O_NOINHERIT)
669
674
b = os.read(f, 1<<16)
1346
1351
normalized_filename = _inaccessible_normalized_filename
1354
def set_signal_handler(signum, handler, restart_syscall=True):
1355
"""A wrapper for signal.signal that also calls siginterrupt(signum, False)
1356
on platforms that support that.
1358
:param restart_syscall: if set, allow syscalls interrupted by a signal to
1359
automatically restart (by calling `signal.siginterrupt(signum,
1360
False)`). May be ignored if the feature is not available on this
1361
platform or Python version.
1363
old_handler = signal.signal(signum, handler)
1366
siginterrupt = signal.siginterrupt
1367
except AttributeError: # siginterrupt doesn't exist on this platform, or for this version of
1371
siginterrupt(signum, False)
1349
1375
default_terminal_width = 80
1350
1376
"""The default terminal width for ttys.
1453
1479
# the current design -- vila 20091216
1456
signal.signal(signal.SIGWINCH, _terminal_size_changed)
1482
set_signal_handler(signal.SIGWINCH, _terminal_size_changed)
1457
1483
_registered_sigwinch = True
1780
1806
real_handlers[kind](abspath, relpath)
1809
def copy_ownership(dst, src=None):
1810
"""Copy usr/grp ownership from src file/dir to dst file/dir.
1812
If src is None, the containing directory is used as source. If chown
1813
fails, the error is ignored and a warning is printed.
1815
has_chown = getattr(os, 'chown')
1816
if has_chown is None: return
1819
src = os.path.dirname(dst)
1825
os.chown(dst, s.st_uid, s.st_gid)
1827
trace.warning("Unable to copy ownership from '%s' to '%s': IOError: %s." % (src, dst, e))
1830
def mkdir_with_ownership(path, ownership_src=None):
1831
"""Create the directory 'path' with specified ownership.
1833
If ownership_src is given, copies (chown) usr/grp ownership
1834
from 'ownership_src' to 'path'. If ownership_src is None, use the
1835
containing dir ownership.
1838
copy_ownership(path, ownership_src)
1841
def open_with_ownership(filename, mode='r', bufsize=-1, ownership_src=None):
1842
"""Open the file 'filename' with the specified ownership.
1844
If ownership_src is specified, copy usr/grp ownership from ownership_src
1845
to filename. If ownership_src is None, copy ownership from containing
1847
Returns the opened file object.
1849
f = open(filename, mode, bufsize)
1850
copy_ownership(filename, ownership_src)
1783
1854
def path_prefix_key(path):
1784
1855
"""Generate a prefix-order path key for path.
2118
2189
data, _ = self.encode(object, self.errors)
2119
2190
self.stream.write(data)
2192
if sys.platform == 'win32':
2193
def open_file(filename, mode='r', bufsize=-1):
2194
"""This function is used to override the ``open`` builtin.
2196
But it uses O_NOINHERIT flag so the file handle is not inherited by
2197
child processes. Deleting or renaming a closed file opened with this
2198
function is not blocking child processes.
2200
writing = 'w' in mode
2201
appending = 'a' in mode
2202
updating = '+' in mode
2203
binary = 'b' in mode
2206
# see http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.71%29.aspx
2207
# for flags for each modes.
2217
flags |= os.O_WRONLY
2218
flags |= os.O_CREAT | os.O_TRUNC
2223
flags |= os.O_WRONLY
2224
flags |= os.O_CREAT | os.O_APPEND
2229
flags |= os.O_RDONLY
2231
return os.fdopen(os.open(filename, flags), mode, bufsize)