~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Vincent Ladeuil
  • Date: 2011-10-03 14:34:45 UTC
  • mto: This revision was merged to the branch mainline in revision 6185.
  • Revision ID: v.ladeuil+lp@free.fr-20111003143445-s382csvk1613x0sp
Remove the warning.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
42
42
 
43
43
from bzrlib import (
44
44
    cache_utf8,
 
45
    config,
45
46
    errors,
46
47
    trace,
47
48
    win32utils,
48
49
    )
 
50
from bzrlib.i18n import gettext
49
51
""")
50
52
 
51
53
from bzrlib.symbol_versioning import (
53
55
    deprecated_in,
54
56
    )
55
57
 
56
 
# sha and md5 modules are deprecated in python2.6 but hashlib is available as
57
 
# of 2.5
58
 
if sys.version_info < (2, 5):
59
 
    import md5 as _mod_md5
60
 
    md5 = _mod_md5.new
61
 
    import sha as _mod_sha
62
 
    sha = _mod_sha.new
63
 
else:
64
 
    from hashlib import (
65
 
        md5,
66
 
        sha1 as sha,
67
 
        )
 
58
from hashlib import (
 
59
    md5,
 
60
    sha1 as sha,
 
61
    )
68
62
 
69
63
 
70
64
import bzrlib
96
90
        user_encoding = get_user_encoding()
97
91
        return [a.decode(user_encoding) for a in sys.argv[1:]]
98
92
    except UnicodeDecodeError:
99
 
        raise errors.BzrError(("Parameter '%r' is unsupported by the current "
100
 
                                                            "encoding." % a))
 
93
        raise errors.BzrError(gettext("Parameter {0!r} encoding is unsupported by {1} "
 
94
            "application locale.").format(a, user_encoding))
101
95
 
102
96
 
103
97
def make_readonly(filename):
197
191
            if e.errno == errno.ENOENT:
198
192
                return False;
199
193
            else:
200
 
                raise errors.BzrError("lstat/stat of (%r): %r" % (f, e))
 
194
                raise errors.BzrError(gettext("lstat/stat of ({0!r}): {1!r}").format(f, e))
201
195
 
202
196
 
203
197
def fancy_rename(old, new, rename_func, unlink_func):
269
263
            else:
270
264
                rename_func(tmp_name, new)
271
265
    if failure_exc is not None:
272
 
        raise failure_exc[0], failure_exc[1], failure_exc[2]
 
266
        try:
 
267
            raise failure_exc[0], failure_exc[1], failure_exc[2]
 
268
        finally:
 
269
            del failure_exc
273
270
 
274
271
 
275
272
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
392
389
# These were already lazily imported into local scope
393
390
# mkdtemp = tempfile.mkdtemp
394
391
# rmtree = shutil.rmtree
 
392
lstat = os.lstat
 
393
fstat = os.fstat
 
394
 
 
395
def wrap_stat(st):
 
396
    return st
 
397
 
395
398
 
396
399
MIN_ABS_PATHLENGTH = 1
397
400
 
407
410
    getcwd = _win32_getcwd
408
411
    mkdtemp = _win32_mkdtemp
409
412
    rename = _win32_rename
 
413
    try:
 
414
        from bzrlib import _walkdirs_win32
 
415
    except ImportError:
 
416
        pass
 
417
    else:
 
418
        lstat = _walkdirs_win32.lstat
 
419
        fstat = _walkdirs_win32.fstat
 
420
        wrap_stat = _walkdirs_win32.wrap_stat
410
421
 
411
422
    MIN_ABS_PATHLENGTH = 3
412
423
 
915
926
    rps = []
916
927
    for f in ps:
917
928
        if f == '..':
918
 
            raise errors.BzrError("sorry, %r not allowed in path" % f)
 
929
            raise errors.BzrError(gettext("sorry, %r not allowed in path") % f)
919
930
        elif (f == '.') or (f == ''):
920
931
            pass
921
932
        else:
926
937
def joinpath(p):
927
938
    for f in p:
928
939
        if (f == '..') or (f is None) or (f == ''):
929
 
            raise errors.BzrError("sorry, %r not allowed in path" % f)
 
940
            raise errors.BzrError(gettext("sorry, %r not allowed in path") % f)
930
941
    return pathjoin(*p)
931
942
 
932
943
 
967
978
    # they tend to happen very early in startup when we can't check config
968
979
    # files etc, and also we want to report all failures but not spam the user
969
980
    # with 10 warnings.
970
 
    from bzrlib import trace
971
981
    exception_str = str(exception)
972
982
    if exception_str not in _extension_load_failures:
973
983
        trace.mutter("failed to load compiled extension: %s" % exception_str)
977
987
def report_extension_load_failures():
978
988
    if not _extension_load_failures:
979
989
        return
980
 
    from bzrlib.config import GlobalConfig
981
 
    if GlobalConfig().get_user_option_as_bool('ignore_missing_extensions'):
 
990
    if config.GlobalStack().get('ignore_missing_extensions'):
982
991
        return
983
992
    # the warnings framework should by default show this only once
984
993
    from bzrlib.trace import warning
1146
1155
 
1147
1156
    if len(base) < MIN_ABS_PATHLENGTH:
1148
1157
        # must have space for e.g. a drive letter
1149
 
        raise ValueError('%r is too short to calculate a relative path'
 
1158
        raise ValueError(gettext('%r is too short to calculate a relative path')
1150
1159
            % (base,))
1151
1160
 
1152
1161
    rp = abspath(path)
1462
1471
    # a similar effect.
1463
1472
 
1464
1473
    # If BZR_COLUMNS is set, take it, user is always right
 
1474
    # Except if they specified 0 in which case, impose no limit here
1465
1475
    try:
1466
 
        return int(os.environ['BZR_COLUMNS'])
 
1476
        width = int(os.environ['BZR_COLUMNS'])
1467
1477
    except (KeyError, ValueError):
1468
 
        pass
 
1478
        width = None
 
1479
    if width is not None:
 
1480
        if width > 0:
 
1481
            return width
 
1482
        else:
 
1483
            return None
1469
1484
 
1470
1485
    isatty = getattr(sys.stdout, 'isatty', None)
1471
1486
    if isatty is None or not isatty():
1875
1890
        s = os.stat(src)
1876
1891
        chown(dst, s.st_uid, s.st_gid)
1877
1892
    except OSError, e:
1878
 
        trace.warning("Unable to copy ownership from '%s' to '%s': IOError: %s." % (src, dst, e))
 
1893
        trace.warning(
 
1894
            'Unable to copy ownership from "%s" to "%s". '
 
1895
            'You may want to set it manually.', src, dst)
 
1896
        trace.log_exception_quietly()
1879
1897
 
1880
1898
 
1881
1899
def path_prefix_key(path):
1993
2011
# data at once.
1994
2012
MAX_SOCKET_CHUNK = 64 * 1024
1995
2013
 
 
2014
_end_of_stream_errors = [errno.ECONNRESET]
 
2015
for _eno in ['WSAECONNRESET', 'WSAECONNABORTED']:
 
2016
    _eno = getattr(errno, _eno, None)
 
2017
    if _eno is not None:
 
2018
        _end_of_stream_errors.append(_eno)
 
2019
del _eno
 
2020
 
 
2021
 
1996
2022
def read_bytes_from_socket(sock, report_activity=None,
1997
2023
        max_read_size=MAX_SOCKET_CHUNK):
1998
2024
    """Read up to max_read_size of bytes from sock and notify of progress.
2006
2032
            bytes = sock.recv(max_read_size)
2007
2033
        except socket.error, e:
2008
2034
            eno = e.args[0]
2009
 
            if eno == getattr(errno, "WSAECONNRESET", errno.ECONNRESET):
 
2035
            if eno in _end_of_stream_errors:
2010
2036
                # The connection was closed by the other side.  Callers expect
2011
2037
                # an empty string to signal end-of-stream.
2012
2038
                return ""
2153
2179
    return file_kind_from_stat_mode(mode)
2154
2180
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
2155
2181
 
2156
 
 
2157
 
def file_kind(f, _lstat=os.lstat):
 
2182
def file_stat(f, _lstat=os.lstat):
2158
2183
    try:
2159
 
        return file_kind_from_stat_mode(_lstat(f).st_mode)
 
2184
        # XXX cache?
 
2185
        return _lstat(f)
2160
2186
    except OSError, e:
2161
2187
        if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
2162
2188
            raise errors.NoSuchFile(f)
2163
2189
        raise
2164
2190
 
 
2191
def file_kind(f, _lstat=os.lstat):
 
2192
    stat_value = file_stat(f, _lstat)
 
2193
    return file_kind_from_stat_mode(stat_value.st_mode)
2165
2194
 
2166
2195
def until_no_eintr(f, *a, **kw):
2167
2196
    """Run f(*a, **kw), retrying if an EINTR error occurs.
2227
2256
            termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2228
2257
        return ch
2229
2258
 
2230
 
 
2231
 
if sys.platform == 'linux2':
 
2259
if sys.platform.startswith('linux'):
2232
2260
    def _local_concurrency():
2233
 
        concurrency = None
2234
 
        prefix = 'processor'
2235
 
        for line in file('/proc/cpuinfo', 'rb'):
2236
 
            if line.startswith(prefix):
2237
 
                concurrency = int(line[line.find(':')+1:]) + 1
2238
 
        return concurrency
 
2261
        try:
 
2262
            return os.sysconf('SC_NPROCESSORS_ONLN')
 
2263
        except (ValueError, OSError, AttributeError):
 
2264
            return None
2239
2265
elif sys.platform == 'darwin':
2240
2266
    def _local_concurrency():
2241
2267
        return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2242
2268
                                stdout=subprocess.PIPE).communicate()[0]
2243
 
elif sys.platform[0:7] == 'freebsd':
 
2269
elif "bsd" in sys.platform:
2244
2270
    def _local_concurrency():
2245
2271
        return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2246
2272
                                stdout=subprocess.PIPE).communicate()[0]
2274
2300
    concurrency = os.environ.get('BZR_CONCURRENCY', None)
2275
2301
    if concurrency is None:
2276
2302
        try:
2277
 
            concurrency = _local_concurrency()
2278
 
        except (OSError, IOError):
2279
 
            pass
 
2303
            import multiprocessing
 
2304
        except ImportError:
 
2305
            # multiprocessing is only available on Python >= 2.6
 
2306
            try:
 
2307
                concurrency = _local_concurrency()
 
2308
            except (OSError, IOError):
 
2309
                pass
 
2310
        else:
 
2311
            concurrency = multiprocessing.cpu_count()
2280
2312
    try:
2281
2313
        concurrency = int(concurrency)
2282
2314
    except (TypeError, ValueError):
2353
2385
    except UnicodeDecodeError:
2354
2386
        raise errors.BzrError("Can't decode username as %s." % \
2355
2387
                user_encoding)
 
2388
    except ImportError, e:
 
2389
        if sys.platform != 'win32':
 
2390
            raise
 
2391
        if str(e) != 'No module named pwd':
 
2392
            raise
 
2393
        # https://bugs.launchpad.net/bzr/+bug/660174
 
2394
        # getpass.getuser() is unable to return username on Windows
 
2395
        # if there is no USERNAME environment variable set.
 
2396
        # That could be true if bzr is running as a service,
 
2397
        # e.g. running `bzr serve` as a service on Windows.
 
2398
        # We should not fail with traceback in this case.
 
2399
        username = u'UNKNOWN'
2356
2400
    return username
 
2401
 
 
2402
 
 
2403
def available_backup_name(base, exists):
 
2404
    """Find a non-existing backup file name.
 
2405
 
 
2406
    This will *not* create anything, this only return a 'free' entry.  This
 
2407
    should be used for checking names in a directory below a locked
 
2408
    tree/branch/repo to avoid race conditions. This is LBYL (Look Before You
 
2409
    Leap) and generally discouraged.
 
2410
 
 
2411
    :param base: The base name.
 
2412
 
 
2413
    :param exists: A callable returning True if the path parameter exists.
 
2414
    """
 
2415
    counter = 1
 
2416
    name = "%s.~%d~" % (base, counter)
 
2417
    while exists(name):
 
2418
        counter += 1
 
2419
        name = "%s.~%d~" % (base, counter)
 
2420
    return name
 
2421
 
 
2422
 
 
2423
def set_fd_cloexec(fd):
 
2424
    """Set a Unix file descriptor's FD_CLOEXEC flag.  Do nothing if platform
 
2425
    support for this is not available.
 
2426
    """
 
2427
    try:
 
2428
        import fcntl
 
2429
        old = fcntl.fcntl(fd, fcntl.F_GETFD)
 
2430
        fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
 
2431
    except (ImportError, AttributeError):
 
2432
        # Either the fcntl module or specific constants are not present
 
2433
        pass
 
2434
 
 
2435
 
 
2436
def find_executable_on_path(name):
 
2437
    """Finds an executable on the PATH.
 
2438
    
 
2439
    On Windows, this will try to append each extension in the PATHEXT
 
2440
    environment variable to the name, if it cannot be found with the name
 
2441
    as given.
 
2442
    
 
2443
    :param name: The base name of the executable.
 
2444
    :return: The path to the executable found or None.
 
2445
    """
 
2446
    path = os.environ.get('PATH')
 
2447
    if path is None:
 
2448
        return None
 
2449
    path = path.split(os.pathsep)
 
2450
    if sys.platform == 'win32':
 
2451
        exts = os.environ.get('PATHEXT', '').split(os.pathsep)
 
2452
        exts = [ext.lower() for ext in exts]
 
2453
        base, ext = os.path.splitext(name)
 
2454
        if ext != '':
 
2455
            if ext.lower() not in exts:
 
2456
                return None
 
2457
            name = base
 
2458
            exts = [ext]
 
2459
    else:
 
2460
        exts = ['']
 
2461
    for ext in exts:
 
2462
        for d in path:
 
2463
            f = os.path.join(d, name) + ext
 
2464
            if os.access(f, os.X_OK):
 
2465
                return f
 
2466
    return None
 
2467
 
 
2468
 
 
2469
def _posix_is_local_pid_dead(pid):
 
2470
    """True if pid doesn't correspond to live process on this machine"""
 
2471
    try:
 
2472
        # Special meaning of unix kill: just check if it's there.
 
2473
        os.kill(pid, 0)
 
2474
    except OSError, e:
 
2475
        if e.errno == errno.ESRCH:
 
2476
            # On this machine, and really not found: as sure as we can be
 
2477
            # that it's dead.
 
2478
            return True
 
2479
        elif e.errno == errno.EPERM:
 
2480
            # exists, though not ours
 
2481
            return False
 
2482
        else:
 
2483
            mutter("os.kill(%d, 0) failed: %s" % (pid, e))
 
2484
            # Don't really know.
 
2485
            return False
 
2486
    else:
 
2487
        # Exists and our process: not dead.
 
2488
        return False
 
2489
 
 
2490
if sys.platform == "win32":
 
2491
    is_local_pid_dead = win32utils.is_local_pid_dead
 
2492
else:
 
2493
    is_local_pid_dead = _posix_is_local_pid_dead
 
2494
 
 
2495
 
 
2496
def fdatasync(fileno):
 
2497
    """Flush file contents to disk if possible.
 
2498
    
 
2499
    :param fileno: Integer OS file handle.
 
2500
    :raises TransportNotPossible: If flushing to disk is not possible.
 
2501
    """
 
2502
    fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
 
2503
    if fn is not None:
 
2504
        fn(fileno)