~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
450
450
    return unicodedata.normalize('NFC', os.getcwdu())
451
451
 
452
452
 
 
453
def _rename_wrap_exception(rename_func):
 
454
    """Adds extra information to any exceptions that come from rename().
 
455
 
 
456
    The exception has an updated message and 'old_filename' and 'new_filename'
 
457
    attributes.
 
458
    """
 
459
 
 
460
    def _rename_wrapper(old, new):
 
461
        try:
 
462
            rename_func(old, new)
 
463
        except OSError, e:
 
464
            detailed_error = OSError(e.errno, e.strerror +
 
465
                                " [occurred when renaming '%s' to '%s']" %
 
466
                                (old, new))
 
467
            detailed_error.old_filename = old
 
468
            detailed_error.new_filename = new
 
469
            raise detailed_error
 
470
 
 
471
    return _rename_wrapper
 
472
 
 
473
# Default rename wraps os.rename()
 
474
rename = _rename_wrap_exception(os.rename)
 
475
 
453
476
# Default is to just use the python builtins, but these can be rebound on
454
477
# particular platforms.
455
478
abspath = _posix_abspath
460
483
_get_home_dir = _posix_get_home_dir
461
484
getuser_unicode = _posix_getuser_unicode
462
485
getcwd = os.getcwdu
463
 
rename = os.rename
464
486
dirname = os.path.dirname
465
487
basename = os.path.basename
466
488
split = os.path.split
488
510
    normpath = _win32_normpath
489
511
    getcwd = _win32_getcwd
490
512
    mkdtemp = _win32_mkdtemp
491
 
    rename = _win32_rename
 
513
    rename = _rename_wrap_exception(_win32_rename)
492
514
    try:
493
515
        from bzrlib import _walkdirs_win32
494
516
    except ImportError:
2064
2086
# data at once.
2065
2087
MAX_SOCKET_CHUNK = 64 * 1024
2066
2088
 
2067
 
_end_of_stream_errors = [errno.ECONNRESET]
 
2089
_end_of_stream_errors = [errno.ECONNRESET, errno.EPIPE, errno.EINVAL]
2068
2090
for _eno in ['WSAECONNRESET', 'WSAECONNABORTED']:
2069
2091
    _eno = getattr(errno, _eno, None)
2070
2092
    if _eno is not None:
2136
2158
    while sent_total < byte_count:
2137
2159
        try:
2138
2160
            sent = sock.send(buffer(bytes, sent_total, MAX_SOCKET_CHUNK))
2139
 
        except socket.error, e:
 
2161
        except (socket.error, IOError), e:
 
2162
            if e.args[0] in _end_of_stream_errors:
 
2163
                raise errors.ConnectionReset(
 
2164
                    "Error trying to write to socket", e)
2140
2165
            if e.args[0] != errno.EINTR:
2141
2166
                raise
2142
2167
        else:
 
2168
            if sent == 0:
 
2169
                raise errors.ConnectionReset('Sending to %s returned 0 bytes'
 
2170
                                             % (sock,))
2143
2171
            sent_total += sent
2144
 
            report_activity(sent, 'write')
 
2172
            if report_activity is not None:
 
2173
                report_activity(sent, 'write')
2145
2174
 
2146
2175
 
2147
2176
def connect_socket(address):
2525
2554
else:
2526
2555
    is_local_pid_dead = _posix_is_local_pid_dead
2527
2556
 
 
2557
_maybe_ignored = ['EAGAIN', 'EINTR', 'ENOTSUP', 'EOPNOTSUPP', 'EACCES']
 
2558
_fdatasync_ignored = [getattr(errno, name) for name in _maybe_ignored
 
2559
                      if getattr(errno, name, None) is not None]
 
2560
 
2528
2561
 
2529
2562
def fdatasync(fileno):
2530
2563
    """Flush file contents to disk if possible.
2534
2567
    """
2535
2568
    fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
2536
2569
    if fn is not None:
2537
 
        fn(fileno)
 
2570
        try:
 
2571
            fn(fileno)
 
2572
        except IOError, e:
 
2573
            # See bug #1075108, on some platforms fdatasync exists, but can
 
2574
            # raise ENOTSUP. However, we are calling fdatasync to be helpful
 
2575
            # and reduce the chance of corruption-on-powerloss situations. It
 
2576
            # is not a mandatory call, so it is ok to suppress failures.
 
2577
            trace.mutter("ignoring error calling fdatasync: %s" % (e,))
 
2578
            if getattr(e, 'errno', None) not in _fdatasync_ignored:
 
2579
                raise
2538
2580
 
2539
2581
 
2540
2582
def ensure_empty_directory_exists(path, exception_class):