~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Robert Collins
  • Date: 2010-04-08 04:34:03 UTC
  • mfrom: (5138 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5139.
  • Revision ID: robertc@robertcollins.net-20100408043403-56z0d07vdqrx7f3t
Update bugfix for 528114 to trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
                  S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
22
22
import sys
23
23
import time
 
24
import codecs
24
25
import warnings
25
26
 
26
27
from bzrlib.lazy_import import lazy_import
27
28
lazy_import(globals(), """
28
 
import codecs
29
29
from datetime import datetime
30
30
import errno
31
31
from ntpath import (abspath as _nt_abspath,
40
40
    rmtree,
41
41
    )
42
42
import signal
 
43
import socket
43
44
import subprocess
44
45
import tempfile
45
46
from tempfile import (
50
51
from bzrlib import (
51
52
    cache_utf8,
52
53
    errors,
 
54
    trace,
53
55
    win32utils,
54
56
    )
55
57
""")
56
58
 
 
59
from bzrlib.symbol_versioning import (
 
60
    deprecated_function,
 
61
    deprecated_in,
 
62
    )
 
63
 
57
64
# sha and md5 modules are deprecated in python2.6 but hashlib is available as
58
65
# of 2.5
59
66
if sys.version_info < (2, 5):
182
189
    try:
183
190
        return _kind_marker_map[kind]
184
191
    except KeyError:
185
 
        raise errors.BzrError('invalid file kind %r' % kind)
 
192
        # Slightly faster than using .get(, '') when the common case is that
 
193
        # kind will be found
 
194
        return ''
186
195
 
187
196
 
188
197
lexists = getattr(os.path, 'lexists', None)
1802
1811
            real_handlers[kind](abspath, relpath)
1803
1812
 
1804
1813
 
 
1814
def copy_ownership(dst, src=None):
 
1815
    """Copy usr/grp ownership from src file/dir to dst file/dir.
 
1816
 
 
1817
    If src is None, the containing directory is used as source. If chown
 
1818
    fails, the error is ignored and a warning is printed.
 
1819
    """
 
1820
    chown = getattr(os, 'chown', None)
 
1821
    if chown is None:
 
1822
        return
 
1823
 
 
1824
    if src == None:
 
1825
        src = os.path.dirname(dst)
 
1826
        if src == '':
 
1827
            src = '.'
 
1828
 
 
1829
    try:
 
1830
        s = os.stat(src)
 
1831
        chown(dst, s.st_uid, s.st_gid)
 
1832
    except OSError, e:
 
1833
        trace.warning("Unable to copy ownership from '%s' to '%s': IOError: %s." % (src, dst, e))
 
1834
 
 
1835
 
 
1836
def mkdir_with_ownership(path, ownership_src=None):
 
1837
    """Create the directory 'path' with specified ownership.
 
1838
 
 
1839
    If ownership_src is given, copies (chown) usr/grp ownership
 
1840
    from 'ownership_src' to 'path'. If ownership_src is None, use the
 
1841
    containing dir ownership.
 
1842
    """
 
1843
    os.mkdir(path)
 
1844
    copy_ownership(path, ownership_src)
 
1845
 
 
1846
 
 
1847
def open_with_ownership(filename, mode='r', bufsize=-1, ownership_src=None):
 
1848
    """Open the file 'filename' with the specified ownership.
 
1849
 
 
1850
    If ownership_src is specified, copy usr/grp ownership from ownership_src
 
1851
    to filename. If ownership_src is None, copy ownership from containing
 
1852
    directory.
 
1853
    Returns the opened file object.
 
1854
    """
 
1855
    f = open(filename, mode, bufsize)
 
1856
    copy_ownership(filename, ownership_src)
 
1857
    return f
 
1858
 
 
1859
 
1805
1860
def path_prefix_key(path):
1806
1861
    """Generate a prefix-order path key for path.
1807
1862
 
1907
1962
        return socket.gethostname().decode(get_user_encoding())
1908
1963
 
1909
1964
 
1910
 
def recv_all(socket, bytes):
 
1965
# We must not read/write any more than 64k at a time from/to a socket so we
 
1966
# don't risk "no buffer space available" errors on some platforms.  Windows in
 
1967
# particular is likely to throw WSAECONNABORTED or WSAENOBUFS if given too much
 
1968
# data at once.
 
1969
MAX_SOCKET_CHUNK = 64 * 1024
 
1970
 
 
1971
def read_bytes_from_socket(sock, report_activity=None,
 
1972
        max_read_size=MAX_SOCKET_CHUNK):
 
1973
    """Read up to max_read_size of bytes from sock and notify of progress.
 
1974
 
 
1975
    Translates "Connection reset by peer" into file-like EOF (return an
 
1976
    empty string rather than raise an error), and repeats the recv if
 
1977
    interrupted by a signal.
 
1978
    """
 
1979
    while 1:
 
1980
        try:
 
1981
            bytes = sock.recv(max_read_size)
 
1982
        except socket.error, e:
 
1983
            eno = e.args[0]
 
1984
            if eno == getattr(errno, "WSAECONNRESET", errno.ECONNRESET):
 
1985
                # The connection was closed by the other side.  Callers expect
 
1986
                # an empty string to signal end-of-stream.
 
1987
                return ""
 
1988
            elif eno == errno.EINTR:
 
1989
                # Retry the interrupted recv.
 
1990
                continue
 
1991
            raise
 
1992
        else:
 
1993
            if report_activity is not None:
 
1994
                report_activity(len(bytes), 'read')
 
1995
            return bytes
 
1996
 
 
1997
 
 
1998
def recv_all(socket, count):
1911
1999
    """Receive an exact number of bytes.
1912
2000
 
1913
2001
    Regular Socket.recv() may return less than the requested number of bytes,
1914
 
    dependning on what's in the OS buffer.  MSG_WAITALL is not available
 
2002
    depending on what's in the OS buffer.  MSG_WAITALL is not available
1915
2003
    on all platforms, but this should work everywhere.  This will return
1916
2004
    less than the requested amount if the remote end closes.
1917
2005
 
1918
2006
    This isn't optimized and is intended mostly for use in testing.
1919
2007
    """
1920
2008
    b = ''
1921
 
    while len(b) < bytes:
1922
 
        new = until_no_eintr(socket.recv, bytes - len(b))
 
2009
    while len(b) < count:
 
2010
        new = read_bytes_from_socket(socket, None, count - len(b))
1923
2011
        if new == '':
1924
2012
            break # eof
1925
2013
        b += new
1926
2014
    return b
1927
2015
 
1928
2016
 
1929
 
def send_all(socket, bytes, report_activity=None):
 
2017
def send_all(sock, bytes, report_activity=None):
1930
2018
    """Send all bytes on a socket.
1931
 
 
1932
 
    Regular socket.sendall() can give socket error 10053 on Windows.  This
1933
 
    implementation sends no more than 64k at a time, which avoids this problem.
1934
 
 
 
2019
 
 
2020
    Breaks large blocks in smaller chunks to avoid buffering limitations on
 
2021
    some platforms, and catches EINTR which may be thrown if the send is
 
2022
    interrupted by a signal.
 
2023
 
 
2024
    This is preferred to socket.sendall(), because it avoids portability bugs
 
2025
    and provides activity reporting.
 
2026
 
1935
2027
    :param report_activity: Call this as bytes are read, see
1936
2028
        Transport._report_activity
1937
2029
    """
1938
 
    chunk_size = 2**16
1939
 
    for pos in xrange(0, len(bytes), chunk_size):
1940
 
        block = bytes[pos:pos+chunk_size]
1941
 
        if report_activity is not None:
1942
 
            report_activity(len(block), 'write')
1943
 
        until_no_eintr(socket.sendall, block)
 
2030
    sent_total = 0
 
2031
    byte_count = len(bytes)
 
2032
    while sent_total < byte_count:
 
2033
        try:
 
2034
            sent = sock.send(buffer(bytes, sent_total, MAX_SOCKET_CHUNK))
 
2035
        except socket.error, e:
 
2036
            if e.args[0] != errno.EINTR:
 
2037
                raise
 
2038
        else:
 
2039
            sent_total += sent
 
2040
            report_activity(sent, 'write')
1944
2041
 
1945
2042
 
1946
2043
def dereference_path(path):
2017
2114
 
2018
2115
 
2019
2116
def until_no_eintr(f, *a, **kw):
2020
 
    """Run f(*a, **kw), retrying if an EINTR error occurs."""
 
2117
    """Run f(*a, **kw), retrying if an EINTR error occurs.
 
2118
    
 
2119
    WARNING: you must be certain that it is safe to retry the call repeatedly
 
2120
    if EINTR does occur.  This is typically only true for low-level operations
 
2121
    like os.read.  If in any doubt, don't use this.
 
2122
 
 
2123
    Keep in mind that this is not a complete solution to EINTR.  There is
 
2124
    probably code in the Python standard library and other dependencies that
 
2125
    may encounter EINTR if a signal arrives (and there is signal handler for
 
2126
    that signal).  So this function can reduce the impact for IO that bzrlib
 
2127
    directly controls, but it is not a complete solution.
 
2128
    """
2021
2129
    # Borrowed from Twisted's twisted.python.util.untilConcludes function.
2022
2130
    while True:
2023
2131
        try:
2027
2135
                continue
2028
2136
            raise
2029
2137
 
 
2138
 
2030
2139
def re_compile_checked(re_string, flags=0, where=""):
2031
2140
    """Return a compiled re, or raise a sensible error.
2032
2141