69
72
from bzrlib import symbol_versioning
75
# Cross platform wall-clock time functionality with decent resolution.
76
# On Linux ``time.clock`` returns only CPU time. On Windows, ``time.time()``
77
# only has a resolution of ~15ms. Note that ``time.clock()`` is not
78
# synchronized with ``time.time()``, this is only meant to be used to find
79
# delta times by subtracting from another call to this function.
80
timer_func = time.time
81
if sys.platform == 'win32':
82
timer_func = time.clock
72
84
# On win32, O_BINARY is used to indicate the file should
73
85
# be opened in binary mode, rather than text mode.
74
86
# On other platforms, O_BINARY doesn't exist, because
75
87
# they always open in binary mode, so it is okay to
76
# OR with 0 on those platforms
88
# OR with 0 on those platforms.
89
# O_NOINHERIT and O_TEXT exists only on win32 too.
77
90
O_BINARY = getattr(os, 'O_BINARY', 0)
91
O_TEXT = getattr(os, 'O_TEXT', 0)
92
O_NOINHERIT = getattr(os, 'O_NOINHERIT', 0)
95
def get_unicode_argv():
97
user_encoding = get_user_encoding()
98
return [a.decode(user_encoding) for a in sys.argv[1:]]
99
except UnicodeDecodeError:
100
raise errors.BzrError(("Parameter '%r' is unsupported by the current "
80
104
def make_readonly(filename):
98
122
:param paths: A container (and hence not None) of paths.
99
123
:return: A set of paths sufficient to include everything in paths via
100
is_inside_any, drawn from the paths parameter.
124
is_inside, drawn from the paths parameter.
105
other_paths = paths.difference([path])
106
if not is_inside_any(other_paths, path):
107
# this is a top level path, we must check it.
108
search_paths.add(path)
130
return path.split('/')
131
sorted_paths = sorted(list(paths), key=sort_key)
133
search_paths = [sorted_paths[0]]
134
for path in sorted_paths[1:]:
135
if not is_inside(search_paths[-1], path):
136
# This path is unique, add it
137
search_paths.append(path)
139
return set(search_paths)
172
204
def fancy_rename(old, new, rename_func, unlink_func):
173
205
"""A fancy rename, when you don't have atomic rename.
175
207
:param old: The old path, to rename from
176
208
:param new: The new path, to rename to
177
209
:param rename_func: The potentially non-atomic rename function
178
:param unlink_func: A way to delete the target file if the full rename succeeds
210
:param unlink_func: A way to delete the target file if the full rename
181
213
# sftp rename doesn't allow overwriting, so play tricks:
182
214
base = os.path.basename(new)
183
215
dirname = os.path.dirname(new)
184
tmp_name = u'tmp.%s.%.9f.%d.%s' % (base, time.time(), os.getpid(), rand_chars(10))
216
# callers use different encodings for the paths so the following MUST
217
# respect that. We rely on python upcasting to unicode if new is unicode
218
# and keeping a str if not.
219
tmp_name = 'tmp.%s.%.9f.%d.%s' % (base, time.time(),
220
os.getpid(), rand_chars(10))
185
221
tmp_name = pathjoin(dirname, tmp_name)
187
223
# Rename the file out of the way, but keep track if it didn't exist
317
360
"""We expect to be able to atomically replace 'new' with old.
319
362
On win32, if new exists, it must be moved out of the way first,
323
366
fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
324
367
except OSError, e:
325
368
if e.errno in (errno.EPERM, errno.EACCES, errno.EBUSY, errno.EINVAL):
326
# If we try to rename a non-existant file onto cwd, we get
327
# EPERM or EACCES instead of ENOENT, this will raise ENOENT
369
# If we try to rename a non-existant file onto cwd, we get
370
# EPERM or EACCES instead of ENOENT, this will raise ENOENT
328
371
# if the old path doesn't exist, sometimes we get EACCES
329
372
# On Linux, we seem to get EBUSY, on Mac we get EINVAL
667
735
date_str = time.strftime(date_fmt, tt)
668
736
return date_str + offset_str
739
# Cache of formatted offset strings
743
def format_date_with_offset_in_original_timezone(t, offset=0,
744
_cache=_offset_cache):
745
"""Return a formatted date string in the original timezone.
747
This routine may be faster then format_date.
749
:param t: Seconds since the epoch.
750
:param offset: Timezone offset in seconds east of utc.
754
tt = time.gmtime(t + offset)
755
date_fmt = _default_format_by_weekday_num[tt[6]]
756
date_str = time.strftime(date_fmt, tt)
757
offset_str = _cache.get(offset, None)
758
if offset_str is None:
759
offset_str = ' %+03d%02d' % (offset / 3600, (offset / 60) % 60)
760
_cache[offset] = offset_str
761
return date_str + offset_str
670
764
def format_local_date(t, offset=0, timezone='original', date_fmt=None,
671
765
show_offset=True):
672
766
"""Return an unicode date string formatted according to the current locale.
829
924
return pathjoin(*p)
927
def parent_directories(filename):
928
"""Return the list of parent directories, deepest first.
930
For example, parent_directories("a/b/c") -> ["a/b", "a"].
933
parts = splitpath(dirname(filename))
935
parents.append(joinpath(parts))
940
_extension_load_failures = []
943
def failed_to_load_extension(exception):
944
"""Handle failing to load a binary extension.
946
This should be called from the ImportError block guarding the attempt to
947
import the native extension. If this function returns, the pure-Python
948
implementation should be loaded instead::
951
>>> import bzrlib._fictional_extension_pyx
952
>>> except ImportError, e:
953
>>> bzrlib.osutils.failed_to_load_extension(e)
954
>>> import bzrlib._fictional_extension_py
956
# NB: This docstring is just an example, not a doctest, because doctest
957
# currently can't cope with the use of lazy imports in this namespace --
960
# This currently doesn't report the failure at the time it occurs, because
961
# they tend to happen very early in startup when we can't check config
962
# files etc, and also we want to report all failures but not spam the user
964
from bzrlib import trace
965
exception_str = str(exception)
966
if exception_str not in _extension_load_failures:
967
trace.mutter("failed to load compiled extension: %s" % exception_str)
968
_extension_load_failures.append(exception_str)
971
def report_extension_load_failures():
972
if not _extension_load_failures:
974
from bzrlib.config import GlobalConfig
975
if GlobalConfig().get_user_option_as_bool('ignore_missing_extensions'):
977
# the warnings framework should by default show this only once
978
from bzrlib.trace import warning
980
"bzr: warning: some compiled extensions could not be loaded; "
981
"see <https://answers.launchpad.net/bzr/+faq/703>")
982
# we no longer show the specific missing extensions here, because it makes
983
# the message too long and scary - see
984
# https://bugs.launchpad.net/bzr/+bug/430529
833
988
from bzrlib._chunks_to_lines_pyx import chunks_to_lines
989
except ImportError, e:
990
failed_to_load_extension(e)
835
991
from bzrlib._chunks_to_lines_py import chunks_to_lines
875
1031
shutil.copyfile(src, dest)
878
# Look Before You Leap (LBYL) is appropriate here instead of Easier to Ask for
879
# Forgiveness than Permission (EAFP) because:
880
# - root can damage a solaris file system by using unlink,
881
# - unlink raises different exceptions on different OSes (linux: EISDIR, win32:
882
# EACCES, OSX: EPERM) when invoked on a directory.
883
1034
def delete_any(path):
884
"""Delete a file or directory."""
1035
"""Delete a file, symlink or directory.
1037
Will delete even if readonly.
1040
_delete_file_or_dir(path)
1041
except (OSError, IOError), e:
1042
if e.errno in (errno.EPERM, errno.EACCES):
1043
# make writable and try again
1046
except (OSError, IOError):
1048
_delete_file_or_dir(path)
1053
def _delete_file_or_dir(path):
1054
# Look Before You Leap (LBYL) is appropriate here instead of Easier to Ask for
1055
# Forgiveness than Permission (EAFP) because:
1056
# - root can damage a solaris file system by using unlink,
1057
# - unlink raises different exceptions on different OSes (linux: EISDIR, win32:
1058
# EACCES, OSX: EPERM) when invoked on a directory.
885
1059
if isdir(path): # Takes care of symlinks
1009
1204
# the target of a move, for example).
1010
1205
current = pathjoin(current, bit, *list(bit_iter))
1012
return current[len(abs_base)+1:]
1207
return current[len(abs_base):].lstrip('/')
1014
1209
# XXX - TODO - we need better detection/integration of case-insensitive
1015
# file-systems; Linux often sees FAT32 devices, for example, so could
1016
# probably benefit from the same basic support there. For now though, only
1017
# Windows gets that support, and it gets it for *all* file-systems!
1018
if sys.platform == "win32":
1210
# file-systems; Linux often sees FAT32 devices (or NFS-mounted OSX
1211
# filesystems), for example, so could probably benefit from the same basic
1212
# support there. For now though, only Windows and OSX get that support, and
1213
# they get it for *all* file-systems!
1214
if sys.platform in ('win32', 'darwin'):
1019
1215
canonical_relpath = _cicp_canonical_relpath
1021
1217
canonical_relpath = relpath
1154
1349
normalized_filename = _inaccessible_normalized_filename
1352
def set_signal_handler(signum, handler, restart_syscall=True):
1353
"""A wrapper for signal.signal that also calls siginterrupt(signum, False)
1354
on platforms that support that.
1356
:param restart_syscall: if set, allow syscalls interrupted by a signal to
1357
automatically restart (by calling `signal.siginterrupt(signum,
1358
False)`). May be ignored if the feature is not available on this
1359
platform or Python version.
1361
old_handler = signal.signal(signum, handler)
1364
siginterrupt = signal.siginterrupt
1365
except AttributeError: # siginterrupt doesn't exist on this platform, or for this version of
1369
siginterrupt(signum, False)
1373
default_terminal_width = 80
1374
"""The default terminal width for ttys.
1376
This is defined so that higher levels can share a common fallback value when
1377
terminal_width() returns None.
1157
1381
def terminal_width():
1158
"""Return estimated terminal width."""
1159
if sys.platform == 'win32':
1160
return win32utils.get_console_size()[0]
1382
"""Return terminal width.
1384
None is returned if the width can't established precisely.
1387
- if BZR_COLUMNS is set, returns its value
1388
- if there is no controlling terminal, returns None
1389
- if COLUMNS is set, returns its value,
1391
From there, we need to query the OS to get the size of the controlling
1395
- get termios.TIOCGWINSZ
1396
- if an error occurs or a negative value is obtained, returns None
1400
- win32utils.get_console_size() decides,
1401
- returns None on error (provided default value)
1404
# If BZR_COLUMNS is set, take it, user is always right
1406
return int(os.environ['BZR_COLUMNS'])
1407
except (KeyError, ValueError):
1410
isatty = getattr(sys.stdout, 'isatty', None)
1411
if isatty is None or not isatty():
1412
# Don't guess, setting BZR_COLUMNS is the recommended way to override.
1415
# If COLUMNS is set, take it, the terminal knows better (even inside a
1416
# given terminal, the application can decide to set COLUMNS to a lower
1417
# value (splitted screen) or a bigger value (scroll bars))
1419
return int(os.environ['COLUMNS'])
1420
except (KeyError, ValueError):
1423
width, height = _terminal_size(None, None)
1425
# Consider invalid values as meaning no width
1431
def _win32_terminal_size(width, height):
1432
width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
1433
return width, height
1436
def _ioctl_terminal_size(width, height):
1163
1438
import struct, fcntl, termios
1164
1439
s = struct.pack('HHHH', 0, 0, 0, 0)
1165
1440
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
1166
width = struct.unpack('HHHH', x)[1]
1441
height, width = struct.unpack('HHHH', x)[0:2]
1442
except (IOError, AttributeError):
1171
width = int(os.environ['COLUMNS'])
1444
return width, height
1446
_terminal_size = None
1447
"""Returns the terminal size as (width, height).
1449
:param width: Default value for width.
1450
:param height: Default value for height.
1452
This is defined specifically for each OS and query the size of the controlling
1453
terminal. If any error occurs, the provided default values should be returned.
1455
if sys.platform == 'win32':
1456
_terminal_size = _win32_terminal_size
1458
_terminal_size = _ioctl_terminal_size
1461
def _terminal_size_changed(signum, frame):
1462
"""Set COLUMNS upon receiving a SIGnal for WINdow size CHange."""
1463
width, height = _terminal_size(None, None)
1464
if width is not None:
1465
os.environ['COLUMNS'] = str(width)
1468
_registered_sigwinch = False
1470
def watch_sigwinch():
1471
"""Register for SIGWINCH, once and only once."""
1472
global _registered_sigwinch
1473
if not _registered_sigwinch:
1474
if sys.platform == 'win32':
1475
# Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from
1476
# ReadConsoleInput but I've no idea how to plug that in
1477
# the current design -- vila 20091216
1480
set_signal_handler(signal.SIGWINCH, _terminal_size_changed)
1481
_registered_sigwinch = True
1180
1484
def supports_executable():
1258
1562
def walkdirs(top, prefix=""):
1259
1563
"""Yield data about all the directories in a tree.
1261
1565
This yields all the data about the contents of a directory at a time.
1262
1566
After each directory has been yielded, if the caller has mutated the list
1263
1567
to exclude some directories, they are then not descended into.
1265
1569
The data yielded is of the form:
1266
1570
((directory-relpath, directory-path-from-top),
1267
1571
[(relpath, basename, kind, lstat, path-from-top), ...]),
1268
1572
- directory-relpath is the relative path of the directory being returned
1269
1573
with respect to top. prefix is prepended to this.
1270
- directory-path-from-root is the path including top for this directory.
1574
- directory-path-from-root is the path including top for this directory.
1271
1575
It is suitable for use with os functions.
1272
1576
- relpath is the relative path within the subtree being walked.
1273
1577
- basename is the basename of the path
1275
1579
present within the tree - but it may be recorded as versioned. See
1276
1580
versioned_kind.
1277
1581
- lstat is the stat data *if* the file was statted.
1278
- planned, not implemented:
1582
- planned, not implemented:
1279
1583
path_from_tree_root is the path from the root of the tree.
1281
:param prefix: Prefix the relpaths that are yielded with 'prefix'. This
1585
:param prefix: Prefix the relpaths that are yielded with 'prefix'. This
1282
1586
allows one to walk a subtree but get paths that are relative to a tree
1283
1587
rooted higher up.
1284
1588
:return: an iterator over the dirs.
1286
1590
#TODO there is a bit of a smell where the results of the directory-
1287
# summary in this, and the path from the root, may not agree
1591
# summary in this, and the path from the root, may not agree
1288
1592
# depending on top and prefix - i.e. ./foo and foo as a pair leads to
1289
1593
# potentially confusing output. We should make this more robust - but
1290
1594
# not at a speed cost. RBC 20060731
1374
1678
# for win98 anyway.
1376
1680
from bzrlib._walkdirs_win32 import Win32ReadDir
1378
_selected_dir_reader = UnicodeDirReader()
1380
1681
_selected_dir_reader = Win32ReadDir()
1381
elif fs_encoding not in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1684
elif fs_encoding in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1382
1685
# ANSI_X3.4-1968 is a form of ASCII
1383
_selected_dir_reader = UnicodeDirReader()
1386
1687
from bzrlib._readdir_pyx import UTF8DirReader
1388
# No optimised code path
1389
_selected_dir_reader = UnicodeDirReader()
1391
1688
_selected_dir_reader = UTF8DirReader()
1689
except ImportError, e:
1690
failed_to_load_extension(e)
1693
if _selected_dir_reader is None:
1694
# Fallback to the python version
1695
_selected_dir_reader = UnicodeDirReader()
1392
1697
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1393
1698
# But we don't actually uses 1-3 in pending, so set them to None
1394
1699
pending = [[_selected_dir_reader.top_prefix_to_starting_dir(top, prefix)]]
1626
def send_all(socket, bytes):
1931
def send_all(socket, bytes, report_activity=None):
1627
1932
"""Send all bytes on a socket.
1629
1934
Regular socket.sendall() can give socket error 10053 on Windows. This
1630
1935
implementation sends no more than 64k at a time, which avoids this problem.
1937
:param report_activity: Call this as bytes are read, see
1938
Transport._report_activity
1632
1940
chunk_size = 2**16
1633
1941
for pos in xrange(0, len(bytes), chunk_size):
1634
until_no_eintr(socket.sendall, bytes[pos:pos+chunk_size])
1942
block = bytes[pos:pos+chunk_size]
1943
if report_activity is not None:
1944
report_activity(len(block), 'write')
1945
until_no_eintr(socket.sendall, block)
1637
1948
def dereference_path(path):
1734
2069
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2073
if sys.platform == 'linux2':
2074
def _local_concurrency():
2076
prefix = 'processor'
2077
for line in file('/proc/cpuinfo', 'rb'):
2078
if line.startswith(prefix):
2079
concurrency = int(line[line.find(':')+1:]) + 1
2081
elif sys.platform == 'darwin':
2082
def _local_concurrency():
2083
return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2084
stdout=subprocess.PIPE).communicate()[0]
2085
elif sys.platform[0:7] == 'freebsd':
2086
def _local_concurrency():
2087
return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2088
stdout=subprocess.PIPE).communicate()[0]
2089
elif sys.platform == 'sunos5':
2090
def _local_concurrency():
2091
return subprocess.Popen(['psrinfo', '-p',],
2092
stdout=subprocess.PIPE).communicate()[0]
2093
elif sys.platform == "win32":
2094
def _local_concurrency():
2095
# This appears to return the number of cores.
2096
return os.environ.get('NUMBER_OF_PROCESSORS')
2098
def _local_concurrency():
2103
_cached_local_concurrency = None
2105
def local_concurrency(use_cache=True):
2106
"""Return how many processes can be run concurrently.
2108
Rely on platform specific implementations and default to 1 (one) if
2109
anything goes wrong.
2111
global _cached_local_concurrency
2113
if _cached_local_concurrency is not None and use_cache:
2114
return _cached_local_concurrency
2116
concurrency = os.environ.get('BZR_CONCURRENCY', None)
2117
if concurrency is None:
2119
concurrency = _local_concurrency()
2120
except (OSError, IOError):
2123
concurrency = int(concurrency)
2124
except (TypeError, ValueError):
2127
_cached_concurrency = concurrency
2131
class UnicodeOrBytesToBytesWriter(codecs.StreamWriter):
2132
"""A stream writer that doesn't decode str arguments."""
2134
def __init__(self, encode, stream, errors='strict'):
2135
codecs.StreamWriter.__init__(self, stream, errors)
2136
self.encode = encode
2138
def write(self, object):
2139
if type(object) is str:
2140
self.stream.write(object)
2142
data, _ = self.encode(object, self.errors)
2143
self.stream.write(data)
2145
if sys.platform == 'win32':
2146
def open_file(filename, mode='r', bufsize=-1):
2147
"""This function is used to override the ``open`` builtin.
2149
But it uses O_NOINHERIT flag so the file handle is not inherited by
2150
child processes. Deleting or renaming a closed file opened with this
2151
function is not blocking child processes.
2153
writing = 'w' in mode
2154
appending = 'a' in mode
2155
updating = '+' in mode
2156
binary = 'b' in mode
2159
# see http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.71%29.aspx
2160
# for flags for each modes.
2170
flags |= os.O_WRONLY
2171
flags |= os.O_CREAT | os.O_TRUNC
2176
flags |= os.O_WRONLY
2177
flags |= os.O_CREAT | os.O_APPEND
2182
flags |= os.O_RDONLY
2184
return os.fdopen(os.open(filename, flags), mode, bufsize)