/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/osutils.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-16 23:15:15 UTC
  • mfrom: (7180 work)
  • mto: This revision was merged to the branch mainline in revision 7183.
  • Revision ID: jelmer@jelmer.uk-20181116231515-zqd2yn6kj8lfydyp
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
107
107
        return [a.decode(user_encoding) for a in sys.argv[1:]]
108
108
    except UnicodeDecodeError:
109
109
        raise errors.BzrError(gettext("Parameter {0!r} encoding is unsupported by {1} "
110
 
            "application locale.").format(a, user_encoding))
 
110
                                      "application locale.").format(a, user_encoding))
111
111
 
112
112
 
113
113
def make_readonly(filename):
191
191
 
192
192
_directory_kind = 'directory'
193
193
 
 
194
 
194
195
def get_umask():
195
196
    """Return the current umask"""
196
197
    # Assume that people aren't messing with the umask while running
227
228
            return True
228
229
        except OSError as e:
229
230
            if e.errno == errno.ENOENT:
230
 
                return False;
 
231
                return False
231
232
            else:
232
 
                raise errors.BzrError(gettext("lstat/stat of ({0!r}): {1!r}").format(f, e))
 
233
                raise errors.BzrError(
 
234
                    gettext("lstat/stat of ({0!r}): {1!r}").format(f, e))
233
235
 
234
236
 
235
237
def fancy_rename(old, new, rename_func, unlink_func):
259
261
    file_existed = False
260
262
    try:
261
263
        rename_func(new, tmp_name)
262
 
    except (errors.NoSuchFile,) as e:
 
264
    except (errors.NoSuchFile,):
263
265
        pass
264
266
    except IOError as e:
265
267
        # RBC 20060103 abstraction leakage: the paramiko SFTP clients rename
269
271
            raise
270
272
    except Exception as e:
271
273
        if (getattr(e, 'errno', None) is None
272
 
            or e.errno not in (errno.ENOENT, errno.ENOTDIR)):
 
274
                or e.errno not in (errno.ENOENT, errno.ENOTDIR)):
273
275
            raise
274
276
    else:
275
277
        file_existed = True
285
287
        # case-insensitive filesystem), so we may have accidentally renamed
286
288
        # source by when we tried to rename target
287
289
        if (file_existed and e.errno in (None, errno.ENOENT)
288
 
            and old.lower() == new.lower()):
 
290
                and old.lower() == new.lower()):
289
291
            # source and target are the same file on a case-insensitive
290
292
            # filesystem, so we don't generate an exception
291
293
            pass
326
328
    # as a special case here by simply removing the first slash, as we consider
327
329
    # that breaking POSIX compatibility for this obscure feature is acceptable.
328
330
    # This is not a paranoid precaution, as we notably get paths like this when
329
 
    # the repo is hosted at the root of the filesystem, i.e. in "/".    
 
331
    # the repo is hosted at the root of the filesystem, i.e. in "/".
330
332
    if path.startswith('//'):
331
333
        path = path[1:]
332
334
    return path
369
371
        return name.decode(user_encoding)
370
372
    except UnicodeDecodeError:
371
373
        raise errors.BzrError("Encoding of username %r is unsupported by %s "
372
 
            "application locale." % (name, user_encoding))
 
374
                              "application locale." % (name, user_encoding))
373
375
 
374
376
 
375
377
def _win32_fixdrive(path):
445
447
            rename_func(old, new)
446
448
        except OSError as e:
447
449
            detailed_error = OSError(e.errno, e.strerror +
448
 
                                " [occurred when renaming '%s' to '%s']" %
449
 
                                (old, new))
 
450
                                     " [occurred when renaming '%s' to '%s']" %
 
451
                                     (old, new))
450
452
            detailed_error.old_filename = old
451
453
            detailed_error.new_filename = new
452
454
            raise detailed_error
483
485
lstat = os.lstat
484
486
fstat = os.fstat
485
487
 
 
488
 
486
489
def wrap_stat(st):
487
490
    return st
488
491
 
515
518
        """
516
519
        exception = excinfo[1]
517
520
        if function in (os.remove, os.rmdir) \
518
 
            and isinstance(exception, OSError) \
519
 
            and exception.errno == errno.EACCES:
 
521
                and isinstance(exception, OSError) \
 
522
                and exception.errno == errno.EACCES:
520
523
            make_writable(path)
521
524
            function(path)
522
525
        else:
560
563
            output_encoding = get_user_encoding()
561
564
            if trace:
562
565
                mutter('encoding stdout as osutils.get_user_encoding() %r',
563
 
                   output_encoding)
 
566
                       output_encoding)
564
567
        else:
565
568
            output_encoding = input_encoding
566
569
            if trace:
567
570
                mutter('encoding stdout as sys.stdin encoding %r',
568
 
                    output_encoding)
 
571
                       output_encoding)
569
572
    else:
570
573
        if trace:
571
574
            mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
574
577
        output_encoding = get_user_encoding()
575
578
        if trace:
576
579
            mutter('cp0 is invalid encoding.'
577
 
               ' encoding stdout as osutils.get_user_encoding() %r',
578
 
               output_encoding)
 
580
                   ' encoding stdout as osutils.get_user_encoding() %r',
 
581
                   output_encoding)
579
582
    # check encoding
580
583
    try:
581
584
        codecs.lookup(output_encoding)
584
587
                         ' unknown terminal encoding %s.\n'
585
588
                         '  Using encoding %s instead.\n'
586
589
                         % (output_encoding, get_user_encoding())
587
 
                        )
 
590
                         )
588
591
        output_encoding = get_user_encoding()
589
592
 
590
593
    return output_encoding
617
620
    except OSError:
618
621
        return False
619
622
 
 
623
 
620
624
def islink(f):
621
625
    """True if f is a symlink."""
622
626
    try:
624
628
    except OSError:
625
629
        return False
626
630
 
 
631
 
627
632
def is_inside(dir, fname):
628
633
    """True if fname is inside dir.
629
634
 
726
731
    # writes fail on some platforms (e.g. Windows with SMB  mounted
727
732
    # drives).
728
733
    if not segment_size:
729
 
        segment_size = 5242880 # 5MB
 
734
        segment_size = 5242880  # 5MB
730
735
    offsets = range(0, len(bytes), segment_size)
731
736
    view = memoryview(bytes)
732
737
    write = file_handle.write
733
738
    for offset in offsets:
734
 
        write(view[offset:offset+segment_size])
 
739
        write(view[offset:offset + segment_size])
735
740
 
736
741
 
737
742
def file_iterator(input_file, readsize=32768):
758
763
    The file cursor should be already at the start.
759
764
    """
760
765
    s = sha()
761
 
    BUFSIZE = 128<<10
 
766
    BUFSIZE = 128 << 10
762
767
    while True:
763
768
        b = f.read(BUFSIZE)
764
769
        if not b:
775
780
    """
776
781
    size = 0
777
782
    s = sha()
778
 
    BUFSIZE = 128<<10
 
783
    BUFSIZE = 128 << 10
779
784
    while True:
780
785
        b = f.read(BUFSIZE)
781
786
        if not b:
791
796
    f = os.open(fname, os.O_RDONLY | O_BINARY | O_NOINHERIT)
792
797
    try:
793
798
        while True:
794
 
            b = os.read(f, 1<<16)
 
799
            b = os.read(f, 1 << 16)
795
800
            if not b:
796
801
                return _hexdigest(s)
797
802
            s.update(b)
837
842
    offset = datetime.fromtimestamp(t) - datetime.utcfromtimestamp(t)
838
843
    return offset.days * 86400 + offset.seconds
839
844
 
 
845
 
840
846
weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
841
847
_default_format_by_weekday_num = [wd + " %Y-%m-%d %H:%M:%S" for wd in weekdays]
842
848
 
854
860
    :param show_offset: Whether to append the timezone.
855
861
    """
856
862
    (date_fmt, tt, offset_str) = \
857
 
               _format_date(t, offset, timezone, date_fmt, show_offset)
 
863
        _format_date(t, offset, timezone, date_fmt, show_offset)
858
864
    date_fmt = date_fmt.replace('%a', weekdays[tt[6]])
859
865
    date_str = time.strftime(date_fmt, tt)
860
866
    return date_str + offset_str
865
871
 
866
872
 
867
873
def format_date_with_offset_in_original_timezone(t, offset=0,
868
 
    _cache=_offset_cache):
 
874
                                                 _cache=_offset_cache):
869
875
    """Return a formatted date string in the original timezone.
870
876
 
871
877
    This routine may be faster then format_date.
898
904
    :param show_offset: Whether to append the timezone.
899
905
    """
900
906
    (date_fmt, tt, offset_str) = \
901
 
               _format_date(t, offset, timezone, date_fmt, show_offset)
 
907
        _format_date(t, offset, timezone, date_fmt, show_offset)
902
908
    date_str = time.strftime(date_fmt, tt)
903
909
    if not isinstance(date_str, text_type):
904
910
        date_str = date_str.decode(get_user_encoding(), 'replace')
947
953
        delta = -delta
948
954
 
949
955
    seconds = delta
950
 
    if seconds < 90: # print seconds up to 90 seconds
 
956
    if seconds < 90:  # print seconds up to 90 seconds
951
957
        if seconds == 1:
952
958
            return '%d second %s' % (seconds, direction,)
953
959
        else:
959
965
        plural_seconds = ''
960
966
    else:
961
967
        plural_seconds = 's'
962
 
    if minutes < 90: # print minutes, seconds up to 90 minutes
 
968
    if minutes < 90:  # print minutes, seconds up to 90 minutes
963
969
        if minutes == 1:
964
970
            return '%d minute, %d second%s %s' % (
965
 
                    minutes, seconds, plural_seconds, direction)
 
971
                minutes, seconds, plural_seconds, direction)
966
972
        else:
967
973
            return '%d minutes, %d second%s %s' % (
968
 
                    minutes, seconds, plural_seconds, direction)
 
974
                minutes, seconds, plural_seconds, direction)
969
975
 
970
976
    hours = int(minutes / 60)
971
977
    minutes -= 60 * hours
980
986
    return '%d hours, %d minute%s %s' % (hours, minutes,
981
987
                                         plural_minutes, direction)
982
988
 
 
989
 
983
990
def filesize(f):
984
991
    """Return size of given open file."""
985
992
    return os.fstat(f.fileno())[stat.ST_SIZE]
986
993
 
987
994
 
988
 
# Alias os.urandom to support platforms (which?) without /dev/urandom and 
 
995
# Alias os.urandom to support platforms (which?) without /dev/urandom and
989
996
# override if it doesn't work. Avoid checking on windows where there is
990
997
# significant initialisation cost that can be avoided for some bzr calls.
991
998
 
1006
1013
 
1007
1014
 
1008
1015
ALNUM = '0123456789abcdefghijklmnopqrstuvwxyz'
 
1016
 
 
1017
 
1009
1018
def rand_chars(num):
1010
1019
    """Return a random string of num alphanumeric characters
1011
1020
 
1021
1030
    return s
1022
1031
 
1023
1032
 
1024
 
## TODO: We could later have path objects that remember their list
1025
 
## decomposition (might be too tricksy though.)
 
1033
# TODO: We could later have path objects that remember their list
 
1034
# decomposition (might be too tricksy though.)
1026
1035
 
1027
1036
def splitpath(p):
1028
1037
    """Turn string into list of parts."""
1163
1172
    Will delete even if readonly.
1164
1173
    """
1165
1174
    try:
1166
 
       _delete_file_or_dir(path)
 
1175
        _delete_file_or_dir(path)
1167
1176
    except (OSError, IOError) as e:
1168
1177
        if e.errno in (errno.EPERM, errno.EACCES):
1169
1178
            # make writable and try again
1182
1191
    # - root can damage a solaris file system by using unlink,
1183
1192
    # - unlink raises different exceptions on different OSes (linux: EISDIR, win32:
1184
1193
    #   EACCES, OSX: EPERM) when invoked on a directory.
1185
 
    if isdir(path): # Takes care of symlinks
 
1194
    if isdir(path):  # Takes care of symlinks
1186
1195
        os.rmdir(path)
1187
1196
    else:
1188
1197
        os.unlink(path)
1267
1276
    if len(base) < MIN_ABS_PATHLENGTH:
1268
1277
        # must have space for e.g. a drive letter
1269
1278
        raise ValueError(gettext('%r is too short to calculate a relative path')
1270
 
            % (base,))
 
1279
                         % (base,))
1271
1280
 
1272
1281
    rp = abspath(path)
1273
1282
 
1318
1327
        lbit = bit.lower()
1319
1328
        try:
1320
1329
            next_entries = _listdir(current)
1321
 
        except OSError: # enoent, eperm, etc
 
1330
        except OSError:  # enoent, eperm, etc
1322
1331
            # We can't find this in the filesystem, so just append the
1323
1332
            # remaining bits.
1324
1333
            current = pathjoin(current, bit, *list(bit_iter))
1335
1344
            break
1336
1345
    return current[len(abs_base):].lstrip('/')
1337
1346
 
 
1347
 
1338
1348
# XXX - TODO - we need better detection/integration of case-insensitive
1339
1349
# file-systems; Linux often sees FAT32 devices (or NFS-mounted OSX
1340
1350
# filesystems), for example, so could probably benefit from the same basic
1345
1355
else:
1346
1356
    canonical_relpath = relpath
1347
1357
 
 
1358
 
1348
1359
def canonical_relpaths(base, paths):
1349
1360
    """Create an iterable to canonicalize a sequence of relative paths.
1350
1361
 
1412
1423
    :return: None or a utf8 revision id.
1413
1424
    """
1414
1425
    if (unicode_or_utf8_string is None
1415
 
        or unicode_or_utf8_string.__class__ == bytes):
 
1426
            or unicode_or_utf8_string.__class__ == bytes):
1416
1427
        return unicode_or_utf8_string
1417
1428
    raise TypeError('Unicode revision ids are no longer supported. '
1418
1429
                    'Revision id generators should be creating utf8 revision '
1430
1441
    :return: None or a utf8 file id.
1431
1442
    """
1432
1443
    if (unicode_or_utf8_string is None
1433
 
        or unicode_or_utf8_string.__class__ == bytes):
 
1444
            or unicode_or_utf8_string.__class__ == bytes):
1434
1445
        return unicode_or_utf8_string
1435
1446
    raise TypeError('Unicode file ids are no longer supported. '
1436
1447
                    'File id generators should be creating utf8 file ids.')
1503
1514
    except AttributeError:
1504
1515
        # siginterrupt doesn't exist on this platform, or for this version
1505
1516
        # of Python.
1506
 
        siginterrupt = lambda signum, flag: None
 
1517
        def siginterrupt(signum, flag): return None
1507
1518
    if restart_syscall:
1508
1519
        def sig_handler(*args):
1509
1520
            # Python resets the siginterrupt flag when a signal is
1534
1545
_terminal_size_state = 'no_data'
1535
1546
_first_terminal_size = None
1536
1547
 
 
1548
 
1537
1549
def terminal_width():
1538
1550
    """Return terminal width.
1539
1551
 
1620
1632
 
1621
1633
 
1622
1634
def _win32_terminal_size(width, height):
1623
 
    width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
 
1635
    width, height = win32utils.get_console_size(
 
1636
        defaultx=width, defaulty=height)
1624
1637
    return width, height
1625
1638
 
1626
1639
 
1627
1640
def _ioctl_terminal_size(width, height):
1628
1641
    try:
1629
 
        import struct, fcntl, termios
 
1642
        import struct
 
1643
        import fcntl
 
1644
        import termios
1630
1645
        s = struct.pack('HHHH', 0, 0, 0, 0)
1631
1646
        x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
1632
1647
        height, width = struct.unpack('HHHH', x)[0:2]
1634
1649
        pass
1635
1650
    return width, height
1636
1651
 
 
1652
 
1637
1653
_terminal_size = None
1638
1654
"""Returns the terminal size as (width, height).
1639
1655
 
1699
1715
        raise errors.IllegalPath(path)
1700
1716
 
1701
1717
 
1702
 
_WIN32_ERROR_DIRECTORY = 267 # Similar to errno.ENOTDIR
 
1718
_WIN32_ERROR_DIRECTORY = 267  # Similar to errno.ENOTDIR
 
1719
 
1703
1720
 
1704
1721
def _is_error_enotdir(e):
1705
1722
    """Check if this exception represents ENOTDIR.
1717
1734
    :return: True if this represents an ENOTDIR error. False otherwise.
1718
1735
    """
1719
1736
    en = getattr(e, 'errno', None)
1720
 
    if (en == errno.ENOTDIR
1721
 
        or (sys.platform == 'win32'
1722
 
            and (en == _WIN32_ERROR_DIRECTORY
1723
 
                 or (en == errno.EINVAL
1724
 
                     and getattr(e, 'winerror', None) == _WIN32_ERROR_DIRECTORY)
1725
 
        ))):
 
1737
    if (en == errno.ENOTDIR or
 
1738
        (sys.platform == 'win32' and
 
1739
            (en == _WIN32_ERROR_DIRECTORY or
 
1740
             (en == errno.EINVAL
 
1741
              and getattr(e, 'winerror', None) == _WIN32_ERROR_DIRECTORY)
 
1742
             ))):
1726
1743
        return True
1727
1744
    return False
1728
1745
 
1755
1772
        rooted higher up.
1756
1773
    :return: an iterator over the dirs.
1757
1774
    """
1758
 
    #TODO there is a bit of a smell where the results of the directory-
 
1775
    # TODO there is a bit of a smell where the results of the directory-
1759
1776
    # summary in this, and the path from the root, may not agree
1760
1777
    # depending on top and prefix - i.e. ./foo and foo as a pair leads to
1761
1778
    # potentially confusing output. We should make this more robust - but
1898
1915
        See DirReader.read_dir for details.
1899
1916
        """
1900
1917
        _utf8_encode = self._utf8_encode
1901
 
        _fs_decode = lambda s: s.decode(_fs_enc)
1902
 
        _fs_encode = lambda s: s.encode(_fs_enc)
 
1918
 
 
1919
        def _fs_decode(s): return s.decode(_fs_enc)
 
1920
 
 
1921
        def _fs_encode(s): return s.encode(_fs_enc)
1903
1922
        _lstat = os.lstat
1904
1923
        _listdir = os.listdir
1905
1924
        _kind_from_mode = file_kind_from_stat_mode
1957
1976
    real_handlers = {'file': shutil.copy2,
1958
1977
                     'symlink': copy_link,
1959
1978
                     'directory': copy_dir,
1960
 
                    }
 
1979
                     }
1961
1980
    real_handlers.update(handlers)
1962
1981
 
1963
1982
    if not os.path.exists(to_path):
1978
1997
    if chown is None:
1979
1998
        return
1980
1999
 
1981
 
    if src == None:
 
2000
    if src is None:
1982
2001
        src = os.path.dirname(dst)
1983
2002
        if src == '':
1984
2003
            src = '.'
1986
2005
    try:
1987
2006
        s = os.stat(src)
1988
2007
        chown(dst, s.st_uid, s.st_gid)
1989
 
    except OSError as e:
 
2008
    except OSError:
1990
2009
        trace.warning(
1991
2010
            'Unable to copy ownership from "%s" to "%s". '
1992
2011
            'You may want to set it manually.', src, dst)
2042
2061
                             ' unknown encoding %s.'
2043
2062
                             ' Continuing with ascii encoding.\n'
2044
2063
                             % user_encoding
2045
 
                            )
 
2064
                             )
2046
2065
        user_encoding = 'ascii'
2047
2066
    else:
2048
2067
        # Get 'ascii' when setlocale has not been called or LANG=C or unset.
2092
2111
 
2093
2112
 
2094
2113
def read_bytes_from_socket(sock, report_activity=None,
2095
 
        max_read_size=MAX_SOCKET_CHUNK):
 
2114
                           max_read_size=MAX_SOCKET_CHUNK):
2096
2115
    """Read up to max_read_size of bytes from sock and notify of progress.
2097
2116
 
2098
2117
    Translates "Connection reset by peer" into file-like EOF (return an
2132
2151
    while len(b) < count:
2133
2152
        new = read_bytes_from_socket(socket, None, count - len(b))
2134
2153
        if new == b'':
2135
 
            break # eof
 
2154
            break  # eof
2136
2155
        b += new
2137
2156
    return b
2138
2157
 
2155
2174
    view = memoryview(bytes)
2156
2175
    while sent_total < byte_count:
2157
2176
        try:
2158
 
            sent = sock.send(view[sent_total:sent_total+MAX_SOCKET_CHUNK])
 
2177
            sent = sock.send(view[sent_total:sent_total + MAX_SOCKET_CHUNK])
2159
2178
        except (socket.error, IOError) as e:
2160
2179
            if e.args[0] in _end_of_stream_errors:
2161
2180
                raise errors.ConnectionReset(
2242
2261
    with open(pathjoin(base, resource_relpath), "rt") as f:
2243
2262
        return f.read()
2244
2263
 
 
2264
 
2245
2265
def file_kind_from_stat_mode_thunk(mode):
2246
2266
    global file_kind_from_stat_mode
2247
2267
    if file_kind_from_stat_mode is file_kind_from_stat_mode_thunk:
2248
2268
        try:
2249
2269
            from ._readdir_pyx import UTF8DirReader
2250
2270
            file_kind_from_stat_mode = UTF8DirReader().kind_from_mode
2251
 
        except ImportError as e:
 
2271
        except ImportError:
2252
2272
            # This is one time where we won't warn that an extension failed to
2253
2273
            # load. The extension is never available on Windows anyway.
2254
2274
            from ._readdir_py import (
2255
2275
                _kind_from_mode as file_kind_from_stat_mode
2256
2276
                )
2257
2277
    return file_kind_from_stat_mode(mode)
 
2278
 
 
2279
 
2258
2280
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
2259
2281
 
 
2282
 
2260
2283
def file_stat(f, _lstat=os.lstat):
2261
2284
    try:
2262
2285
        # XXX cache?
2266
2289
            raise errors.NoSuchFile(f)
2267
2290
        raise
2268
2291
 
 
2292
 
2269
2293
def file_kind(f, _lstat=os.lstat):
2270
2294
    stat_value = file_stat(f, _lstat)
2271
2295
    return file_kind_from_stat_mode(stat_value.st_mode)
2272
2296
 
 
2297
 
2273
2298
def until_no_eintr(f, *a, **kw):
2274
2299
    """Run f(*a, **kw), retrying if an EINTR error occurs.
2275
2300
 
2326
2351
                                stdout=subprocess.PIPE).communicate()[0]
2327
2352
elif sys.platform == 'sunos5':
2328
2353
    def _local_concurrency():
2329
 
        return subprocess.Popen(['psrinfo', '-p',],
 
2354
        return subprocess.Popen(['psrinfo', '-p', ],
2330
2355
                                stdout=subprocess.PIPE).communicate()[0]
2331
2356
elif sys.platform == "win32":
2332
2357
    def _local_concurrency():
2340
2365
 
2341
2366
_cached_local_concurrency = None
2342
2367
 
 
2368
 
2343
2369
def local_concurrency(use_cache=True):
2344
2370
    """Return how many processes can be run concurrently.
2345
2371
 
2367
2393
    except (TypeError, ValueError):
2368
2394
        concurrency = 1
2369
2395
    if use_cache:
2370
 
        _cached_concurrency = concurrency
 
2396
        _cached_local_concurrency = concurrency
2371
2397
    return concurrency
2372
2398
 
2373
2399
 
2419
2445
            else:
2420
2446
                flags |= os.O_WRONLY
2421
2447
            flags |= os.O_CREAT | os.O_APPEND
2422
 
        else: #reading
 
2448
        else:  # reading
2423
2449
            if updating:
2424
2450
                flags |= os.O_RDWR
2425
2451
            else:
2465
2491
 
2466
2492
def find_executable_on_path(name):
2467
2493
    """Finds an executable on the PATH.
2468
 
    
 
2494
 
2469
2495
    On Windows, this will try to append each extension in the PATHEXT
2470
2496
    environment variable to the name, if it cannot be found with the name
2471
2497
    as given.
2472
 
    
 
2498
 
2473
2499
    :param name: The base name of the executable.
2474
2500
    :return: The path to the executable found or None.
2475
2501
    """
2513
2539
            # exists, though not ours
2514
2540
            return False
2515
2541
        else:
2516
 
            mutter("os.kill(%d, 0) failed: %s" % (pid, e))
 
2542
            trace.mutter("os.kill(%d, 0) failed: %s" % (pid, e))
2517
2543
            # Don't really know.
2518
2544
            return False
2519
2545
    else:
2520
2546
        # Exists and our process: not dead.
2521
2547
        return False
2522
2548
 
 
2549
 
2523
2550
if sys.platform == "win32":
2524
2551
    is_local_pid_dead = win32utils.is_local_pid_dead
2525
2552
else:
2532
2559
 
2533
2560
def fdatasync(fileno):
2534
2561
    """Flush file contents to disk if possible.
2535
 
    
 
2562
 
2536
2563
    :param fileno: Integer OS file handle.
2537
2564
    :raises TransportNotPossible: If flushing to disk is not possible.
2538
2565
    """
2552
2579
 
2553
2580
def ensure_empty_directory_exists(path, exception_class):
2554
2581
    """Make sure a local directory exists and is empty.
2555
 
    
 
2582
 
2556
2583
    If it does not exist, it is created.  If it exists and is not empty, an
2557
2584
    instance of exception_class is raised.
2558
2585
    """