/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: Jelmer Vernooij
  • Date: 2010-03-21 21:39:33 UTC
  • mfrom: (5102 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5143.
  • Revision ID: jelmer@samba.org-20100321213933-fexeh9zcoz8oaju2
merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2009 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
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,
85
85
# be opened in binary mode, rather than text mode.
86
86
# On other platforms, O_BINARY doesn't exist, because
87
87
# they always open in binary mode, so it is okay to
88
 
# OR with 0 on those platforms
 
88
# OR with 0 on those platforms.
 
89
# O_NOINHERIT and O_TEXT exists only on win32 too.
89
90
O_BINARY = getattr(os, 'O_BINARY', 0)
 
91
O_TEXT = getattr(os, 'O_TEXT', 0)
 
92
O_NOINHERIT = getattr(os, 'O_NOINHERIT', 0)
90
93
 
91
94
 
92
95
def get_unicode_argv():
179
182
    try:
180
183
        return _kind_marker_map[kind]
181
184
    except KeyError:
182
 
        raise errors.BzrError('invalid file kind %r' % kind)
 
185
        # Slightly faster than using .get(, '') when the common case is that
 
186
        # kind will be found
 
187
        return ''
183
188
 
184
189
 
185
190
lexists = getattr(os.path, 'lexists', None)
202
207
    :param old: The old path, to rename from
203
208
    :param new: The new path, to rename to
204
209
    :param rename_func: The potentially non-atomic rename function
205
 
    :param unlink_func: A way to delete the target file if the full rename succeeds
 
210
    :param unlink_func: A way to delete the target file if the full rename
 
211
        succeeds
206
212
    """
207
 
 
208
213
    # sftp rename doesn't allow overwriting, so play tricks:
209
214
    base = os.path.basename(new)
210
215
    dirname = os.path.dirname(new)
211
 
    tmp_name = u'tmp.%s.%.9f.%d.%s' % (base, time.time(), os.getpid(), rand_chars(10))
 
216
    # callers use different encodings for the paths so the following MUST
 
217
    # respect that. We rely on python upcasting to unicode if new is unicode
 
218
    # and keeping a str if not.
 
219
    tmp_name = 'tmp.%s.%.9f.%d.%s' % (base, time.time(),
 
220
                                      os.getpid(), rand_chars(10))
212
221
    tmp_name = pathjoin(dirname, tmp_name)
213
222
 
214
223
    # Rename the file out of the way, but keep track if it didn't exist
657
666
def sha_file_by_name(fname):
658
667
    """Calculate the SHA1 of a file by reading the full text"""
659
668
    s = sha()
660
 
    f = os.open(fname, os.O_RDONLY | O_BINARY)
 
669
    f = os.open(fname, os.O_RDONLY | O_BINARY | O_NOINHERIT)
661
670
    try:
662
671
        while True:
663
672
            b = os.read(f, 1<<16)
1340
1349
    normalized_filename = _inaccessible_normalized_filename
1341
1350
 
1342
1351
 
 
1352
def set_signal_handler(signum, handler, restart_syscall=True):
 
1353
    """A wrapper for signal.signal that also calls siginterrupt(signum, False)
 
1354
    on platforms that support that.
 
1355
 
 
1356
    :param restart_syscall: if set, allow syscalls interrupted by a signal to
 
1357
        automatically restart (by calling `signal.siginterrupt(signum,
 
1358
        False)`).  May be ignored if the feature is not available on this
 
1359
        platform or Python version.
 
1360
    """
 
1361
    old_handler = signal.signal(signum, handler)
 
1362
    if restart_syscall:
 
1363
        try:
 
1364
            siginterrupt = signal.siginterrupt
 
1365
        except AttributeError: # siginterrupt doesn't exist on this platform, or for this version of
 
1366
            # Python.
 
1367
            pass
 
1368
        else:
 
1369
            siginterrupt(signum, False)
 
1370
    return old_handler
 
1371
 
 
1372
 
1343
1373
default_terminal_width = 80
1344
1374
"""The default terminal width for ttys.
1345
1375
 
1434
1464
    if width is not None:
1435
1465
        os.environ['COLUMNS'] = str(width)
1436
1466
 
1437
 
if sys.platform == 'win32':
1438
 
    # Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from ReadConsoleInput but
1439
 
    # I've no idea how to plug that in the current design -- vila 20091216
1440
 
    pass
1441
 
else:
1442
 
    signal.signal(signal.SIGWINCH, _terminal_size_changed)
 
1467
 
 
1468
_registered_sigwinch = False
 
1469
 
 
1470
def watch_sigwinch():
 
1471
    """Register for SIGWINCH, once and only once."""
 
1472
    global _registered_sigwinch
 
1473
    if not _registered_sigwinch:
 
1474
        if sys.platform == 'win32':
 
1475
            # Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from
 
1476
            # ReadConsoleInput but I've no idea how to plug that in
 
1477
            # the current design -- vila 20091216
 
1478
            pass
 
1479
        else:
 
1480
            set_signal_handler(signal.SIGWINCH, _terminal_size_changed)
 
1481
        _registered_sigwinch = True
1443
1482
 
1444
1483
 
1445
1484
def supports_executable():
2087
2126
    if use_cache:
2088
2127
        _cached_concurrency = concurrency
2089
2128
    return concurrency
 
2129
 
 
2130
 
 
2131
class UnicodeOrBytesToBytesWriter(codecs.StreamWriter):
 
2132
    """A stream writer that doesn't decode str arguments."""
 
2133
 
 
2134
    def __init__(self, encode, stream, errors='strict'):
 
2135
        codecs.StreamWriter.__init__(self, stream, errors)
 
2136
        self.encode = encode
 
2137
 
 
2138
    def write(self, object):
 
2139
        if type(object) is str:
 
2140
            self.stream.write(object)
 
2141
        else:
 
2142
            data, _ = self.encode(object, self.errors)
 
2143
            self.stream.write(data)
 
2144
 
 
2145
if sys.platform == 'win32':
 
2146
    def open_file(filename, mode='r', bufsize=-1):
 
2147
        """This function is used to override the ``open`` builtin.
 
2148
        
 
2149
        But it uses O_NOINHERIT flag so the file handle is not inherited by
 
2150
        child processes.  Deleting or renaming a closed file opened with this
 
2151
        function is not blocking child processes.
 
2152
        """
 
2153
        writing = 'w' in mode
 
2154
        appending = 'a' in mode
 
2155
        updating = '+' in mode
 
2156
        binary = 'b' in mode
 
2157
 
 
2158
        flags = O_NOINHERIT
 
2159
        # see http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.71%29.aspx
 
2160
        # for flags for each modes.
 
2161
        if binary:
 
2162
            flags |= O_BINARY
 
2163
        else:
 
2164
            flags |= O_TEXT
 
2165
 
 
2166
        if writing:
 
2167
            if updating:
 
2168
                flags |= os.O_RDWR
 
2169
            else:
 
2170
                flags |= os.O_WRONLY
 
2171
            flags |= os.O_CREAT | os.O_TRUNC
 
2172
        elif appending:
 
2173
            if updating:
 
2174
                flags |= os.O_RDWR
 
2175
            else:
 
2176
                flags |= os.O_WRONLY
 
2177
            flags |= os.O_CREAT | os.O_APPEND
 
2178
        else: #reading
 
2179
            if updating:
 
2180
                flags |= os.O_RDWR
 
2181
            else:
 
2182
                flags |= os.O_RDONLY
 
2183
 
 
2184
        return os.fdopen(os.open(filename, flags), mode, bufsize)
 
2185
else:
 
2186
    open_file = open