~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Jelmer Vernooij
  • Date: 2010-04-30 11:35:43 UTC
  • mfrom: (5195 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5197.
  • Revision ID: jelmer@samba.org-20100430113543-tiqqhmqa3d8no4iu
merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
from shutil import (
38
38
    rmtree,
39
39
    )
40
 
import signal
41
40
import socket
42
41
import subprocess
43
42
import tempfile
361
360
    return _win32_fixdrive(tempfile.mkdtemp(*args, **kwargs).replace('\\', '/'))
362
361
 
363
362
 
 
363
def _add_rename_error_details(e, old, new):
 
364
    new_e = OSError(e.errno, "failed to rename %s to %s: %s"
 
365
        % (old, new, e.strerror))
 
366
    new_e.filename = old
 
367
    new_e.to_filename = new
 
368
    return new_e
 
369
 
 
370
 
364
371
def _win32_rename(old, new):
365
372
    """We expect to be able to atomically replace 'new' with old.
366
373
 
368
375
    and then deleted.
369
376
    """
370
377
    try:
371
 
        fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
 
378
        fancy_rename(old, new, rename_func=_wrapped_rename, unlink_func=os.unlink)
372
379
    except OSError, e:
373
380
        if e.errno in (errno.EPERM, errno.EACCES, errno.EBUSY, errno.EINVAL):
374
381
            # If we try to rename a non-existant file onto cwd, we get
379
386
        raise
380
387
 
381
388
 
 
389
def _wrapped_rename(old, new):
 
390
    """Rename a file or directory"""
 
391
    try:
 
392
        os.rename(old, new)
 
393
    except (IOError, OSError), e:
 
394
        # this is eventually called by all rename-like functions, so should 
 
395
        # catch all of them
 
396
        raise _add_rename_error_details(e, old, new)
 
397
 
 
398
 
382
399
def _mac_getcwd():
383
400
    return unicodedata.normalize('NFC', os.getcwdu())
384
401
 
389
406
realpath = _posix_realpath
390
407
pathjoin = os.path.join
391
408
normpath = os.path.normpath
 
409
rename = _wrapped_rename # overridden below on win32
392
410
getcwd = os.getcwdu
393
 
rename = os.rename
394
411
dirname = os.path.dirname
395
412
basename = os.path.basename
396
413
split = os.path.split
1363
1380
        False)`).  May be ignored if the feature is not available on this
1364
1381
        platform or Python version.
1365
1382
    """
1366
 
    old_handler = signal.signal(signum, handler)
 
1383
    try:
 
1384
        import signal
 
1385
        siginterrupt = signal.siginterrupt
 
1386
    except ImportError:
 
1387
        # This python implementation doesn't provide signal support, hence no
 
1388
        # handler exists
 
1389
        return None
 
1390
    except AttributeError:
 
1391
        # siginterrupt doesn't exist on this platform, or for this version
 
1392
        # of Python.
 
1393
        siginterrupt = lambda signum, flag: None
1367
1394
    if restart_syscall:
1368
 
        try:
1369
 
            siginterrupt = signal.siginterrupt
1370
 
        except AttributeError: # siginterrupt doesn't exist on this platform, or for this version of
1371
 
            # Python.
1372
 
            pass
1373
 
        else:
 
1395
        def sig_handler(*args):
 
1396
            # Python resets the siginterrupt flag when a signal is
 
1397
            # received.  <http://bugs.python.org/issue8354>
 
1398
            # As a workaround for some cases, set it back the way we want it.
1374
1399
            siginterrupt(signum, False)
 
1400
            # Now run the handler function passed to set_signal_handler.
 
1401
            handler(*args)
 
1402
    else:
 
1403
        sig_handler = handler
 
1404
    old_handler = signal.signal(signum, sig_handler)
 
1405
    if restart_syscall:
 
1406
        siginterrupt(signum, False)
1375
1407
    return old_handler
1376
1408
 
1377
1409
 
1471
1503
 
1472
1504
 
1473
1505
_registered_sigwinch = False
1474
 
 
1475
1506
def watch_sigwinch():
1476
 
    """Register for SIGWINCH, once and only once."""
 
1507
    """Register for SIGWINCH, once and only once.
 
1508
 
 
1509
    Do nothing if the signal module is not available.
 
1510
    """
1477
1511
    global _registered_sigwinch
1478
1512
    if not _registered_sigwinch:
1479
 
        if sys.platform == 'win32':
1480
 
            # Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from
1481
 
            # ReadConsoleInput but I've no idea how to plug that in
1482
 
            # the current design -- vila 20091216
 
1513
        try:
 
1514
            import signal
 
1515
            if getattr(signal, "SIGWINCH", None) is not None:
 
1516
                set_signal_handler(signal.SIGWINCH, _terminal_size_changed)
 
1517
        except ImportError:
 
1518
            # python doesn't provide signal support, nothing we can do about it
1483
1519
            pass
1484
 
        else:
1485
 
            set_signal_handler(signal.SIGWINCH, _terminal_size_changed)
1486
1520
        _registered_sigwinch = True
1487
1521
 
1488
1522
 
1809
1843
            real_handlers[kind](abspath, relpath)
1810
1844
 
1811
1845
 
1812
 
def copy_ownership(dst, src=None):
 
1846
def copy_ownership_from_path(dst, src=None):
1813
1847
    """Copy usr/grp ownership from src file/dir to dst file/dir.
1814
1848
 
1815
1849
    If src is None, the containing directory is used as source. If chown
1831
1865
        trace.warning("Unable to copy ownership from '%s' to '%s': IOError: %s." % (src, dst, e))
1832
1866
 
1833
1867
 
1834
 
def mkdir_with_ownership(path, ownership_src=None):
1835
 
    """Create the directory 'path' with specified ownership.
1836
 
 
1837
 
    If ownership_src is given, copies (chown) usr/grp ownership
1838
 
    from 'ownership_src' to 'path'. If ownership_src is None, use the
1839
 
    containing dir ownership.
1840
 
    """
1841
 
    os.mkdir(path)
1842
 
    copy_ownership(path, ownership_src)
1843
 
 
1844
 
 
1845
 
def open_with_ownership(filename, mode='r', bufsize=-1, ownership_src=None):
1846
 
    """Open the file 'filename' with the specified ownership.
1847
 
 
1848
 
    If ownership_src is specified, copy usr/grp ownership from ownership_src
1849
 
    to filename. If ownership_src is None, copy ownership from containing
1850
 
    directory.
1851
 
    Returns the opened file object.
1852
 
    """
1853
 
    f = open(filename, mode, bufsize)
1854
 
    copy_ownership(filename, ownership_src)
1855
 
    return f
1856
 
 
1857
 
 
1858
1868
def path_prefix_key(path):
1859
1869
    """Generate a prefix-order path key for path.
1860
1870