/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 bzrlib/osutils.py

  • Committer: Andrew Bennetts
  • Date: 2010-01-15 03:58:20 UTC
  • mfrom: (4963 +trunk)
  • mto: (4973.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4975.
  • Revision ID: andrew.bennetts@canonical.com-20100115035820-ilb3t36swgzq6v1l
MergeĀ lp:bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
from shutil import (
40
40
    rmtree,
41
41
    )
 
42
import signal
42
43
import subprocess
43
44
import tempfile
44
45
from tempfile import (
71
72
from bzrlib import symbol_versioning
72
73
 
73
74
 
 
75
# Cross platform wall-clock time functionality with decent resolution.
 
76
# On Linux ``time.clock`` returns only CPU time. On Windows, ``time.time()``
 
77
# only has a resolution of ~15ms. Note that ``time.clock()`` is not
 
78
# synchronized with ``time.time()``, this is only meant to be used to find
 
79
# delta times by subtracting from another call to this function.
 
80
timer_func = time.time
 
81
if sys.platform == 'win32':
 
82
    timer_func = time.clock
 
83
 
74
84
# On win32, O_BINARY is used to indicate the file should
75
85
# be opened in binary mode, rather than text mode.
76
86
# On other platforms, O_BINARY doesn't exist, because
192
202
    :param old: The old path, to rename from
193
203
    :param new: The new path, to rename to
194
204
    :param rename_func: The potentially non-atomic rename function
195
 
    :param unlink_func: A way to delete the target file if the full rename succeeds
 
205
    :param unlink_func: A way to delete the target file if the full rename
 
206
        succeeds
196
207
    """
197
 
 
198
208
    # sftp rename doesn't allow overwriting, so play tricks:
199
209
    base = os.path.basename(new)
200
210
    dirname = os.path.dirname(new)
201
 
    tmp_name = u'tmp.%s.%.9f.%d.%s' % (base, time.time(), os.getpid(), rand_chars(10))
 
211
    # callers use different encodings for the paths so the following MUST
 
212
    # respect that. We rely on python upcasting to unicode if new is unicode
 
213
    # and keeping a str if not.
 
214
    tmp_name = 'tmp.%s.%.9f.%d.%s' % (base, time.time(),
 
215
                                      os.getpid(), rand_chars(10))
202
216
    tmp_name = pathjoin(dirname, tmp_name)
203
217
 
204
218
    # Rename the file out of the way, but keep track if it didn't exist
1342
1356
    """Return terminal width.
1343
1357
 
1344
1358
    None is returned if the width can't established precisely.
 
1359
 
 
1360
    The rules are:
 
1361
    - if BZR_COLUMNS is set, returns its value
 
1362
    - if there is no controlling terminal, returns None
 
1363
    - if COLUMNS is set, returns its value,
 
1364
 
 
1365
    From there, we need to query the OS to get the size of the controlling
 
1366
    terminal.
 
1367
 
 
1368
    Unices:
 
1369
    - get termios.TIOCGWINSZ
 
1370
    - if an error occurs or a negative value is obtained, returns None
 
1371
 
 
1372
    Windows:
 
1373
    
 
1374
    - win32utils.get_console_size() decides,
 
1375
    - returns None on error (provided default value)
1345
1376
    """
1346
1377
 
1347
1378
    # If BZR_COLUMNS is set, take it, user is always right
1355
1386
        # Don't guess, setting BZR_COLUMNS is the recommended way to override.
1356
1387
        return None
1357
1388
 
1358
 
    if sys.platform == 'win32':
1359
 
        return win32utils.get_console_size(defaultx=None)[0]
1360
 
 
 
1389
    # If COLUMNS is set, take it, the terminal knows better (even inside a
 
1390
    # given terminal, the application can decide to set COLUMNS to a lower
 
1391
    # value (splitted screen) or a bigger value (scroll bars))
 
1392
    try:
 
1393
        return int(os.environ['COLUMNS'])
 
1394
    except (KeyError, ValueError):
 
1395
        pass
 
1396
 
 
1397
    width, height = _terminal_size(None, None)
 
1398
    if width <= 0:
 
1399
        # Consider invalid values as meaning no width
 
1400
        return None
 
1401
 
 
1402
    return width
 
1403
 
 
1404
 
 
1405
def _win32_terminal_size(width, height):
 
1406
    width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
 
1407
    return width, height
 
1408
 
 
1409
 
 
1410
def _ioctl_terminal_size(width, height):
1361
1411
    try:
1362
1412
        import struct, fcntl, termios
1363
1413
        s = struct.pack('HHHH', 0, 0, 0, 0)
1364
1414
        x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
1365
 
        width = struct.unpack('HHHH', x)[1]
 
1415
        height, width = struct.unpack('HHHH', x)[0:2]
1366
1416
    except (IOError, AttributeError):
1367
 
        # If COLUMNS is set, take it
1368
 
        try:
1369
 
            return int(os.environ['COLUMNS'])
1370
 
        except (KeyError, ValueError):
1371
 
            return None
1372
 
 
1373
 
    if width <= 0:
1374
 
        # Consider invalid values as meaning no width
1375
 
        return None
1376
 
 
1377
 
    return width
 
1417
        pass
 
1418
    return width, height
 
1419
 
 
1420
_terminal_size = None
 
1421
"""Returns the terminal size as (width, height).
 
1422
 
 
1423
:param width: Default value for width.
 
1424
:param height: Default value for height.
 
1425
 
 
1426
This is defined specifically for each OS and query the size of the controlling
 
1427
terminal. If any error occurs, the provided default values should be returned.
 
1428
"""
 
1429
if sys.platform == 'win32':
 
1430
    _terminal_size = _win32_terminal_size
 
1431
else:
 
1432
    _terminal_size = _ioctl_terminal_size
 
1433
 
 
1434
 
 
1435
def _terminal_size_changed(signum, frame):
 
1436
    """Set COLUMNS upon receiving a SIGnal for WINdow size CHange."""
 
1437
    width, height = _terminal_size(None, None)
 
1438
    if width is not None:
 
1439
        os.environ['COLUMNS'] = str(width)
 
1440
 
 
1441
if sys.platform == 'win32':
 
1442
    # Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from ReadConsoleInput but
 
1443
    # I've no idea how to plug that in the current design -- vila 20091216
 
1444
    pass
 
1445
else:
 
1446
    signal.signal(signal.SIGWINCH, _terminal_size_changed)
1378
1447
 
1379
1448
 
1380
1449
def supports_executable():
2022
2091
    if use_cache:
2023
2092
        _cached_concurrency = concurrency
2024
2093
    return concurrency
 
2094
 
 
2095
 
 
2096
class UnicodeOrBytesToBytesWriter(codecs.StreamWriter):
 
2097
    """A stream writer that doesn't decode str arguments."""
 
2098
 
 
2099
    def __init__(self, encode, stream, errors='strict'):
 
2100
        codecs.StreamWriter.__init__(self, stream, errors)
 
2101
        self.encode = encode
 
2102
 
 
2103
    def write(self, object):
 
2104
        if type(object) is str:
 
2105
            self.stream.write(object)
 
2106
        else:
 
2107
            data, _ = self.encode(object, self.errors)
 
2108
            self.stream.write(data)