89
93
user_encoding = get_user_encoding()
90
94
return [a.decode(user_encoding) for a in sys.argv[1:]]
91
95
except UnicodeDecodeError:
92
raise errors.BzrError("Parameter %r encoding is unsupported by %s "
93
"application locale." % (a, user_encoding))
96
raise errors.BzrError(gettext("Parameter {0!r} encoding is unsupported by {1} "
97
"application locale.").format(a, user_encoding))
96
100
def make_readonly(filename):
98
102
mod = os.lstat(filename).st_mode
99
103
if not stat.S_ISLNK(mod):
100
104
mod = mod & 0777555
101
os.chmod(filename, mod)
105
chmod_if_possible(filename, mod)
104
108
def make_writable(filename):
105
109
mod = os.lstat(filename).st_mode
106
110
if not stat.S_ISLNK(mod):
108
os.chmod(filename, mod)
112
chmod_if_possible(filename, mod)
115
def chmod_if_possible(filename, mode):
116
# Set file mode if that can be safely done.
117
# Sometimes even on unix the filesystem won't allow it - see
118
# https://bugs.launchpad.net/bzr/+bug/606537
120
# It is probably faster to just do the chmod, rather than
121
# doing a stat, and then trying to compare
122
os.chmod(filename, mode)
123
except (IOError, OSError),e:
124
# Permission/access denied seems to commonly happen on smbfs; there's
125
# probably no point warning about it.
126
# <https://bugs.launchpad.net/bzr/+bug/606537>
127
if getattr(e, 'errno') in (errno.EPERM, errno.EACCES):
128
trace.mutter("ignore error on chmod of %r: %r" % (
111
134
def minimum_path_selection(paths):
190
213
if e.errno == errno.ENOENT:
193
raise errors.BzrError("lstat/stat of (%r): %r" % (f, e))
216
raise errors.BzrError(gettext("lstat/stat of ({0!r}): {1!r}").format(f, e))
196
219
def fancy_rename(old, new, rename_func, unlink_func):
272
295
# choke on a Unicode string containing a relative path if
273
296
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
275
_fs_enc = sys.getfilesystemencoding() or 'utf-8'
276
298
def _posix_abspath(path):
277
299
# jam 20060426 rather than encoding to fsencoding
278
300
# copy posixpath.abspath, but use os.getcwdu instead
279
301
if not posixpath.isabs(path):
280
302
path = posixpath.join(getcwd(), path)
281
return posixpath.normpath(path)
303
return _posix_normpath(path)
284
306
def _posix_realpath(path):
285
307
return posixpath.realpath(path.encode(_fs_enc)).decode(_fs_enc)
310
def _posix_normpath(path):
311
path = posixpath.normpath(path)
312
# Bug 861008: posixpath.normpath() returns a path normalized according to
313
# the POSIX standard, which stipulates (for compatibility reasons) that two
314
# leading slashes must not be simplified to one, and only if there are 3 or
315
# more should they be simplified as one. So we treat the leading 2 slashes
316
# as a special case here by simply removing the first slash, as we consider
317
# that breaking POSIX compatibility for this obscure feature is acceptable.
318
# This is not a paranoid precaution, as we notably get paths like this when
319
# the repo is hosted at the root of the filesystem, i.e. in "/".
320
if path.startswith('//'):
325
def _posix_path_from_environ(key):
326
"""Get unicode path from `key` in environment or None if not present
328
Note that posix systems use arbitrary byte strings for filesystem objects,
329
so a path that raises BadFilenameEncoding here may still be accessible.
331
val = os.environ.get(key, None)
335
return val.decode(_fs_enc)
336
except UnicodeDecodeError:
337
# GZ 2011-12-12:Ideally want to include `key` in the exception message
338
raise errors.BadFilenameEncoding(val, _fs_enc)
341
def _posix_getuser_unicode():
342
"""Get username from environment or password database as unicode"""
343
name = getpass.getuser()
344
user_encoding = get_user_encoding()
346
return name.decode(user_encoding)
347
except UnicodeDecodeError:
348
raise errors.BzrError("Encoding of username %r is unsupported by %s "
349
"application locale." % (name, user_encoding))
288
352
def _win32_fixdrive(path):
289
353
"""Force drive letters to be consistent.
877
945
return os.fstat(f.fileno())[stat.ST_SIZE]
880
# Define rand_bytes based on platform.
882
# Python 2.4 and later have os.urandom,
883
# but it doesn't work on some arches
885
rand_bytes = os.urandom
886
except (NotImplementedError, AttributeError):
887
# If python doesn't have os.urandom, or it doesn't work,
888
# then try to first pull random data from /dev/urandom
948
# Alias os.urandom to support platforms (which?) without /dev/urandom and
949
# override if it doesn't work. Avoid checking on windows where there is
950
# significant initialisation cost that can be avoided for some bzr calls.
952
rand_bytes = os.urandom
954
if rand_bytes.__module__ != "nt":
890
rand_bytes = file('/dev/urandom', 'rb').read
891
# Otherwise, use this hack as a last resort
892
except (IOError, OSError):
957
except NotImplementedError:
893
958
# not well seeded, but better than nothing
894
959
def rand_bytes(n):
1736
1801
global _selected_dir_reader
1737
1802
if _selected_dir_reader is None:
1738
fs_encoding = _fs_enc.upper()
1739
1803
if sys.platform == "win32" and win32utils.winver == 'Windows NT':
1740
1804
# Win98 doesn't have unicode apis like FindFirstFileW
1741
1805
# TODO: We possibly could support Win98 by falling back to the
1747
1811
_selected_dir_reader = Win32ReadDir()
1748
1812
except ImportError:
1750
elif fs_encoding in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
1751
# ANSI_X3.4-1968 is a form of ASCII
1814
elif _fs_enc in ('utf-8', 'ascii'):
1753
1816
from bzrlib._readdir_pyx import UTF8DirReader
1754
1817
_selected_dir_reader = UTF8DirReader()
1990
2053
return get_terminal_encoding()
2056
_message_encoding = None
2059
def get_message_encoding():
2060
"""Return the encoding used for messages
2062
While the message encoding is a general setting it should usually only be
2063
needed for decoding system error strings such as from OSError instances.
2065
global _message_encoding
2066
if _message_encoding is None:
2067
if os.name == "posix":
2069
# This is a process-global setting that can change, but should in
2070
# general just get set once at process startup then be constant.
2071
_message_encoding = locale.getlocale(locale.LC_MESSAGES)[1]
2073
# On windows want the result of GetACP() which this boils down to.
2074
_message_encoding = get_user_encoding()
2075
return _message_encoding or "ascii"
1993
2078
def get_host_name():
1994
2079
"""Return the current unicode host name.
2300
2384
if concurrency is None:
2302
2386
import multiprocessing
2387
concurrency = multiprocessing.cpu_count()
2388
except (ImportError, NotImplementedError):
2304
2389
# multiprocessing is only available on Python >= 2.6
2390
# and multiprocessing.cpu_count() isn't implemented on all
2306
2393
concurrency = _local_concurrency()
2307
2394
except (OSError, IOError):
2310
concurrency = multiprocessing.cpu_count()
2312
2397
concurrency = int(concurrency)
2313
2398
except (TypeError, ValueError):
2375
2460
open_file = open
2378
def getuser_unicode():
2379
"""Return the username as unicode.
2382
user_encoding = get_user_encoding()
2383
username = getpass.getuser().decode(user_encoding)
2384
except UnicodeDecodeError:
2385
raise errors.BzrError("Can't decode username as %s." % \
2387
except ImportError, e:
2388
if sys.platform != 'win32':
2390
if str(e) != 'No module named pwd':
2392
# https://bugs.launchpad.net/bzr/+bug/660174
2393
# getpass.getuser() is unable to return username on Windows
2394
# if there is no USERNAME environment variable set.
2395
# That could be true if bzr is running as a service,
2396
# e.g. running `bzr serve` as a service on Windows.
2397
# We should not fail with traceback in this case.
2398
username = u'UNKNOWN'
2402
2463
def available_backup_name(base, exists):
2403
2464
"""Find a non-existing backup file name.
2501
2562
fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
2502
2563
if fn is not None:
2567
def ensure_empty_directory_exists(path, exception_class):
2568
"""Make sure a local directory exists and is empty.
2570
If it does not exist, it is created. If it exists and is not empty, an
2571
instance of exception_class is raised.
2576
if e.errno != errno.EEXIST:
2578
if os.listdir(path) != []:
2579
raise exception_class(path)
2582
def is_environment_error(evalue):
2583
"""True if exception instance is due to a process environment issue
2585
This includes OSError and IOError, but also other errors that come from
2586
the operating system or core libraries but are not subclasses of those.
2588
if isinstance(evalue, (EnvironmentError, select.error)):
2590
if sys.platform == "win32" and win32utils._is_pywintypes_error(evalue):