~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Andrew Bennetts
  • Date: 2011-03-24 00:13:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5739.
  • Revision ID: andrew.bennetts@canonical.com-20110324001310-5w56qjom53j091r3
Minor English tweaks.

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
967
967
    # they tend to happen very early in startup when we can't check config
968
968
    # files etc, and also we want to report all failures but not spam the user
969
969
    # with 10 warnings.
970
 
    from bzrlib import trace
971
970
    exception_str = str(exception)
972
971
    if exception_str not in _extension_load_failures:
973
972
        trace.mutter("failed to load compiled extension: %s" % exception_str)
1462
1461
    # a similar effect.
1463
1462
 
1464
1463
    # If BZR_COLUMNS is set, take it, user is always right
 
1464
    # Except if they specified 0 in which case, impose no limit here
1465
1465
    try:
1466
 
        return int(os.environ['BZR_COLUMNS'])
 
1466
        width = int(os.environ['BZR_COLUMNS'])
1467
1467
    except (KeyError, ValueError):
1468
 
        pass
 
1468
        width = None
 
1469
    if width is not None:
 
1470
        if width > 0:
 
1471
            return width
 
1472
        else:
 
1473
            return None
1469
1474
 
1470
1475
    isatty = getattr(sys.stdout, 'isatty', None)
1471
1476
    if isatty is None or not isatty():
1875
1880
        s = os.stat(src)
1876
1881
        chown(dst, s.st_uid, s.st_gid)
1877
1882
    except OSError, e:
1878
 
        trace.warning("Unable to copy ownership from '%s' to '%s': IOError: %s." % (src, dst, e))
 
1883
        trace.warning(
 
1884
            'Unable to copy ownership from "%s" to "%s". '
 
1885
            'You may want to set it manually.', src, dst)
 
1886
        trace.log_exception_quietly()
1879
1887
 
1880
1888
 
1881
1889
def path_prefix_key(path):
1993
2001
# data at once.
1994
2002
MAX_SOCKET_CHUNK = 64 * 1024
1995
2003
 
 
2004
_end_of_stream_errors = [errno.ECONNRESET]
 
2005
for _eno in ['WSAECONNRESET', 'WSAECONNABORTED']:
 
2006
    _eno = getattr(errno, _eno, None)
 
2007
    if _eno is not None:
 
2008
        _end_of_stream_errors.append(_eno)
 
2009
del _eno
 
2010
 
 
2011
 
1996
2012
def read_bytes_from_socket(sock, report_activity=None,
1997
2013
        max_read_size=MAX_SOCKET_CHUNK):
1998
2014
    """Read up to max_read_size of bytes from sock and notify of progress.
2006
2022
            bytes = sock.recv(max_read_size)
2007
2023
        except socket.error, e:
2008
2024
            eno = e.args[0]
2009
 
            if eno == getattr(errno, "WSAECONNRESET", errno.ECONNRESET):
 
2025
            if eno in _end_of_stream_errors:
2010
2026
                # The connection was closed by the other side.  Callers expect
2011
2027
                # an empty string to signal end-of-stream.
2012
2028
                return ""
2065
2081
            report_activity(sent, 'write')
2066
2082
 
2067
2083
 
 
2084
def connect_socket(address):
 
2085
    # Slight variation of the socket.create_connection() function (provided by
 
2086
    # python-2.6) that can fail if getaddrinfo returns an empty list. We also
 
2087
    # provide it for previous python versions. Also, we don't use the timeout
 
2088
    # parameter (provided by the python implementation) so we don't implement
 
2089
    # it either).
 
2090
    err = socket.error('getaddrinfo returns an empty list')
 
2091
    host, port = address
 
2092
    for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
 
2093
        af, socktype, proto, canonname, sa = res
 
2094
        sock = None
 
2095
        try:
 
2096
            sock = socket.socket(af, socktype, proto)
 
2097
            sock.connect(sa)
 
2098
            return sock
 
2099
 
 
2100
        except socket.error, err:
 
2101
            # 'err' is now the most recent error
 
2102
            if sock is not None:
 
2103
                sock.close()
 
2104
    raise err
 
2105
 
 
2106
 
2068
2107
def dereference_path(path):
2069
2108
    """Determine the real path to a file.
2070
2109
 
2204
2243
            termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2205
2244
        return ch
2206
2245
 
2207
 
 
2208
2246
if sys.platform == 'linux2':
2209
2247
    def _local_concurrency():
2210
 
        concurrency = None
2211
 
        prefix = 'processor'
2212
 
        for line in file('/proc/cpuinfo', 'rb'):
2213
 
            if line.startswith(prefix):
2214
 
                concurrency = int(line[line.find(':')+1:]) + 1
2215
 
        return concurrency
 
2248
        try:
 
2249
            return os.sysconf('SC_NPROCESSORS_ONLN')
 
2250
        except (ValueError, OSError, AttributeError):
 
2251
            return None
2216
2252
elif sys.platform == 'darwin':
2217
2253
    def _local_concurrency():
2218
2254
        return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2219
2255
                                stdout=subprocess.PIPE).communicate()[0]
2220
 
elif sys.platform[0:7] == 'freebsd':
 
2256
elif "bsd" in sys.platform:
2221
2257
    def _local_concurrency():
2222
2258
        return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2223
2259
                                stdout=subprocess.PIPE).communicate()[0]
2251
2287
    concurrency = os.environ.get('BZR_CONCURRENCY', None)
2252
2288
    if concurrency is None:
2253
2289
        try:
2254
 
            concurrency = _local_concurrency()
2255
 
        except (OSError, IOError):
2256
 
            pass
 
2290
            import multiprocessing
 
2291
        except ImportError:
 
2292
            # multiprocessing is only available on Python >= 2.6
 
2293
            try:
 
2294
                concurrency = _local_concurrency()
 
2295
            except (OSError, IOError):
 
2296
                pass
 
2297
        else:
 
2298
            concurrency = multiprocessing.cpu_count()
2257
2299
    try:
2258
2300
        concurrency = int(concurrency)
2259
2301
    except (TypeError, ValueError):
2331
2373
        raise errors.BzrError("Can't decode username as %s." % \
2332
2374
                user_encoding)
2333
2375
    return username
 
2376
 
 
2377
 
 
2378
def available_backup_name(base, exists):
 
2379
    """Find a non-existing backup file name.
 
2380
 
 
2381
    This will *not* create anything, this only return a 'free' entry.  This
 
2382
    should be used for checking names in a directory below a locked
 
2383
    tree/branch/repo to avoid race conditions. This is LBYL (Look Before You
 
2384
    Leap) and generally discouraged.
 
2385
 
 
2386
    :param base: The base name.
 
2387
 
 
2388
    :param exists: A callable returning True if the path parameter exists.
 
2389
    """
 
2390
    counter = 1
 
2391
    name = "%s.~%d~" % (base, counter)
 
2392
    while exists(name):
 
2393
        counter += 1
 
2394
        name = "%s.~%d~" % (base, counter)
 
2395
    return name
 
2396
 
 
2397
 
 
2398
def set_fd_cloexec(fd):
 
2399
    """Set a Unix file descriptor's FD_CLOEXEC flag.  Do nothing if platform
 
2400
    support for this is not available.
 
2401
    """
 
2402
    try:
 
2403
        import fcntl
 
2404
        old = fcntl.fcntl(fd, fcntl.F_GETFD)
 
2405
        fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
 
2406
    except (ImportError, AttributeError):
 
2407
        # Either the fcntl module or specific constants are not present
 
2408
        pass
 
2409
 
 
2410
 
 
2411
def find_executable_on_path(name):
 
2412
    """Finds an executable on the PATH.
 
2413
    
 
2414
    On Windows, this will try to append each extension in the PATHEXT
 
2415
    environment variable to the name, if it cannot be found with the name
 
2416
    as given.
 
2417
    
 
2418
    :param name: The base name of the executable.
 
2419
    :return: The path to the executable found or None.
 
2420
    """
 
2421
    path = os.environ.get('PATH')
 
2422
    if path is None:
 
2423
        return None
 
2424
    path = path.split(os.pathsep)
 
2425
    if sys.platform == 'win32':
 
2426
        exts = os.environ.get('PATHEXT', '').split(os.pathsep)
 
2427
        exts = [ext.lower() for ext in exts]
 
2428
        base, ext = os.path.splitext(name)
 
2429
        if ext != '':
 
2430
            if ext.lower() not in exts:
 
2431
                return None
 
2432
            name = base
 
2433
            exts = [ext]
 
2434
    else:
 
2435
        exts = ['']
 
2436
    for ext in exts:
 
2437
        for d in path:
 
2438
            f = os.path.join(d, name) + ext
 
2439
            if os.access(f, os.X_OK):
 
2440
                return f
 
2441
    return None