~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Vincent Ladeuil
  • Date: 2011-02-10 12:37:27 UTC
  • mto: This revision was merged to the branch mainline in revision 5661.
  • Revision ID: v.ladeuil+lp@free.fr-20110210123727-8e0pu4wtlt6fj7nf
thread is already a python module, avoid confusion and use cethread instead.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
from bzrlib import (
44
44
    cache_utf8,
45
 
    config,
46
45
    errors,
47
46
    trace,
48
47
    win32utils,
49
48
    )
50
 
from bzrlib.i18n import gettext
51
49
""")
52
50
 
53
51
from bzrlib.symbol_versioning import (
55
53
    deprecated_in,
56
54
    )
57
55
 
58
 
from hashlib import (
59
 
    md5,
60
 
    sha1 as sha,
61
 
    )
 
56
# sha and md5 modules are deprecated in python2.6 but hashlib is available as
 
57
# of 2.5
 
58
if sys.version_info < (2, 5):
 
59
    import md5 as _mod_md5
 
60
    md5 = _mod_md5.new
 
61
    import sha as _mod_sha
 
62
    sha = _mod_sha.new
 
63
else:
 
64
    from hashlib import (
 
65
        md5,
 
66
        sha1 as sha,
 
67
        )
62
68
 
63
69
 
64
70
import bzrlib
90
96
        user_encoding = get_user_encoding()
91
97
        return [a.decode(user_encoding) for a in sys.argv[1:]]
92
98
    except UnicodeDecodeError:
93
 
        raise errors.BzrError(gettext("Parameter {0!r} encoding is unsupported by {1} "
94
 
            "application locale.").format(a, user_encoding))
 
99
        raise errors.BzrError(("Parameter '%r' is unsupported by the current "
 
100
                                                            "encoding." % a))
95
101
 
96
102
 
97
103
def make_readonly(filename):
191
197
            if e.errno == errno.ENOENT:
192
198
                return False;
193
199
            else:
194
 
                raise errors.BzrError(gettext("lstat/stat of ({0!r}): {1!r}").format(f, e))
 
200
                raise errors.BzrError("lstat/stat of (%r): %r" % (f, e))
195
201
 
196
202
 
197
203
def fancy_rename(old, new, rename_func, unlink_func):
263
269
            else:
264
270
                rename_func(tmp_name, new)
265
271
    if failure_exc is not None:
266
 
        try:
267
 
            raise failure_exc[0], failure_exc[1], failure_exc[2]
268
 
        finally:
269
 
            del failure_exc
 
272
        raise failure_exc[0], failure_exc[1], failure_exc[2]
270
273
 
271
274
 
272
275
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
389
392
# These were already lazily imported into local scope
390
393
# mkdtemp = tempfile.mkdtemp
391
394
# rmtree = shutil.rmtree
392
 
lstat = os.lstat
393
 
fstat = os.fstat
394
 
 
395
 
def wrap_stat(st):
396
 
    return st
397
 
 
398
395
 
399
396
MIN_ABS_PATHLENGTH = 1
400
397
 
410
407
    getcwd = _win32_getcwd
411
408
    mkdtemp = _win32_mkdtemp
412
409
    rename = _win32_rename
413
 
    try:
414
 
        from bzrlib import _walkdirs_win32
415
 
    except ImportError:
416
 
        pass
417
 
    else:
418
 
        lstat = _walkdirs_win32.lstat
419
 
        fstat = _walkdirs_win32.fstat
420
 
        wrap_stat = _walkdirs_win32.wrap_stat
421
410
 
422
411
    MIN_ABS_PATHLENGTH = 3
423
412
 
926
915
    rps = []
927
916
    for f in ps:
928
917
        if f == '..':
929
 
            raise errors.BzrError(gettext("sorry, %r not allowed in path") % f)
 
918
            raise errors.BzrError("sorry, %r not allowed in path" % f)
930
919
        elif (f == '.') or (f == ''):
931
920
            pass
932
921
        else:
937
926
def joinpath(p):
938
927
    for f in p:
939
928
        if (f == '..') or (f is None) or (f == ''):
940
 
            raise errors.BzrError(gettext("sorry, %r not allowed in path") % f)
 
929
            raise errors.BzrError("sorry, %r not allowed in path" % f)
941
930
    return pathjoin(*p)
942
931
 
943
932
 
987
976
def report_extension_load_failures():
988
977
    if not _extension_load_failures:
989
978
        return
990
 
    if config.GlobalStack().get('ignore_missing_extensions'):
 
979
    from bzrlib.config import GlobalConfig
 
980
    if GlobalConfig().get_user_option_as_bool('ignore_missing_extensions'):
991
981
        return
992
982
    # the warnings framework should by default show this only once
993
983
    from bzrlib.trace import warning
1155
1145
 
1156
1146
    if len(base) < MIN_ABS_PATHLENGTH:
1157
1147
        # must have space for e.g. a drive letter
1158
 
        raise ValueError(gettext('%r is too short to calculate a relative path')
 
1148
        raise ValueError('%r is too short to calculate a relative path'
1159
1149
            % (base,))
1160
1150
 
1161
1151
    rp = abspath(path)
2179
2169
    return file_kind_from_stat_mode(mode)
2180
2170
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
2181
2171
 
2182
 
def file_stat(f, _lstat=os.lstat):
 
2172
 
 
2173
def file_kind(f, _lstat=os.lstat):
2183
2174
    try:
2184
 
        # XXX cache?
2185
 
        return _lstat(f)
 
2175
        return file_kind_from_stat_mode(_lstat(f).st_mode)
2186
2176
    except OSError, e:
2187
2177
        if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
2188
2178
            raise errors.NoSuchFile(f)
2189
2179
        raise
2190
2180
 
2191
 
def file_kind(f, _lstat=os.lstat):
2192
 
    stat_value = file_stat(f, _lstat)
2193
 
    return file_kind_from_stat_mode(stat_value.st_mode)
2194
2181
 
2195
2182
def until_no_eintr(f, *a, **kw):
2196
2183
    """Run f(*a, **kw), retrying if an EINTR error occurs.
2256
2243
            termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2257
2244
        return ch
2258
2245
 
2259
 
if sys.platform.startswith('linux'):
 
2246
 
 
2247
if sys.platform == 'linux2':
2260
2248
    def _local_concurrency():
2261
 
        try:
2262
 
            return os.sysconf('SC_NPROCESSORS_ONLN')
2263
 
        except (ValueError, OSError, AttributeError):
2264
 
            return None
 
2249
        concurrency = None
 
2250
        prefix = 'processor'
 
2251
        for line in file('/proc/cpuinfo', 'rb'):
 
2252
            if line.startswith(prefix):
 
2253
                concurrency = int(line[line.find(':')+1:]) + 1
 
2254
        return concurrency
2265
2255
elif sys.platform == 'darwin':
2266
2256
    def _local_concurrency():
2267
2257
        return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2268
2258
                                stdout=subprocess.PIPE).communicate()[0]
2269
 
elif "bsd" in sys.platform:
 
2259
elif sys.platform[0:7] == 'freebsd':
2270
2260
    def _local_concurrency():
2271
2261
        return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2272
2262
                                stdout=subprocess.PIPE).communicate()[0]
2300
2290
    concurrency = os.environ.get('BZR_CONCURRENCY', None)
2301
2291
    if concurrency is None:
2302
2292
        try:
2303
 
            import multiprocessing
2304
 
        except ImportError:
2305
 
            # multiprocessing is only available on Python >= 2.6
2306
 
            try:
2307
 
                concurrency = _local_concurrency()
2308
 
            except (OSError, IOError):
2309
 
                pass
2310
 
        else:
2311
 
            concurrency = multiprocessing.cpu_count()
 
2293
            concurrency = _local_concurrency()
 
2294
        except (OSError, IOError):
 
2295
            pass
2312
2296
    try:
2313
2297
        concurrency = int(concurrency)
2314
2298
    except (TypeError, ValueError):
2385
2369
    except UnicodeDecodeError:
2386
2370
        raise errors.BzrError("Can't decode username as %s." % \
2387
2371
                user_encoding)
2388
 
    except ImportError, e:
2389
 
        if sys.platform != 'win32':
2390
 
            raise
2391
 
        if str(e) != 'No module named pwd':
2392
 
            raise
2393
 
        # https://bugs.launchpad.net/bzr/+bug/660174
2394
 
        # getpass.getuser() is unable to return username on Windows
2395
 
        # if there is no USERNAME environment variable set.
2396
 
        # That could be true if bzr is running as a service,
2397
 
        # e.g. running `bzr serve` as a service on Windows.
2398
 
        # We should not fail with traceback in this case.
2399
 
        username = u'UNKNOWN'
2400
2372
    return username
2401
2373
 
2402
2374
 
2464
2436
            if os.access(f, os.X_OK):
2465
2437
                return f
2466
2438
    return None
2467
 
 
2468
 
 
2469
 
def _posix_is_local_pid_dead(pid):
2470
 
    """True if pid doesn't correspond to live process on this machine"""
2471
 
    try:
2472
 
        # Special meaning of unix kill: just check if it's there.
2473
 
        os.kill(pid, 0)
2474
 
    except OSError, e:
2475
 
        if e.errno == errno.ESRCH:
2476
 
            # On this machine, and really not found: as sure as we can be
2477
 
            # that it's dead.
2478
 
            return True
2479
 
        elif e.errno == errno.EPERM:
2480
 
            # exists, though not ours
2481
 
            return False
2482
 
        else:
2483
 
            mutter("os.kill(%d, 0) failed: %s" % (pid, e))
2484
 
            # Don't really know.
2485
 
            return False
2486
 
    else:
2487
 
        # Exists and our process: not dead.
2488
 
        return False
2489
 
 
2490
 
if sys.platform == "win32":
2491
 
    is_local_pid_dead = win32utils.is_local_pid_dead
2492
 
else:
2493
 
    is_local_pid_dead = _posix_is_local_pid_dead
2494
 
 
2495
 
 
2496
 
def fdatasync(fileno):
2497
 
    """Flush file contents to disk if possible.
2498
 
    
2499
 
    :param fileno: Integer OS file handle.
2500
 
    :raises TransportNotPossible: If flushing to disk is not possible.
2501
 
    """
2502
 
    fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
2503
 
    if fn is not None:
2504
 
        fn(fileno)