2153
2179
return file_kind_from_stat_mode(mode)
2154
2180
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
2157
def file_kind(f, _lstat=os.lstat):
2182
def file_stat(f, _lstat=os.lstat):
2159
return file_kind_from_stat_mode(_lstat(f).st_mode)
2160
2186
except OSError, e:
2161
2187
if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
2162
2188
raise errors.NoSuchFile(f)
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)
2166
2195
def until_no_eintr(f, *a, **kw):
2167
2196
"""Run f(*a, **kw), retrying if an EINTR error occurs.
2227
2256
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2231
if sys.platform == 'linux2':
2259
if sys.platform.startswith('linux'):
2232
2260
def _local_concurrency():
2234
prefix = 'processor'
2235
for line in file('/proc/cpuinfo', 'rb'):
2236
if line.startswith(prefix):
2237
concurrency = int(line[line.find(':')+1:]) + 1
2262
return os.sysconf('SC_NPROCESSORS_ONLN')
2263
except (ValueError, OSError, AttributeError):
2239
2265
elif sys.platform == 'darwin':
2240
2266
def _local_concurrency():
2241
2267
return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2242
2268
stdout=subprocess.PIPE).communicate()[0]
2243
elif sys.platform[0:7] == 'freebsd':
2269
elif "bsd" in sys.platform:
2244
2270
def _local_concurrency():
2245
2271
return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2246
2272
stdout=subprocess.PIPE).communicate()[0]
2274
2300
concurrency = os.environ.get('BZR_CONCURRENCY', None)
2275
2301
if concurrency is None:
2277
concurrency = _local_concurrency()
2278
except (OSError, IOError):
2303
import multiprocessing
2305
# multiprocessing is only available on Python >= 2.6
2307
concurrency = _local_concurrency()
2308
except (OSError, IOError):
2311
concurrency = multiprocessing.cpu_count()
2281
2313
concurrency = int(concurrency)
2282
2314
except (TypeError, ValueError):
2353
2385
except UnicodeDecodeError:
2354
2386
raise errors.BzrError("Can't decode username as %s." % \
2388
except ImportError, e:
2389
if sys.platform != 'win32':
2391
if str(e) != 'No module named pwd':
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'
2356
2400
return username
2403
def available_backup_name(base, exists):
2404
"""Find a non-existing backup file name.
2406
This will *not* create anything, this only return a 'free' entry. This
2407
should be used for checking names in a directory below a locked
2408
tree/branch/repo to avoid race conditions. This is LBYL (Look Before You
2409
Leap) and generally discouraged.
2411
:param base: The base name.
2413
:param exists: A callable returning True if the path parameter exists.
2416
name = "%s.~%d~" % (base, counter)
2419
name = "%s.~%d~" % (base, counter)
2423
def set_fd_cloexec(fd):
2424
"""Set a Unix file descriptor's FD_CLOEXEC flag. Do nothing if platform
2425
support for this is not available.
2429
old = fcntl.fcntl(fd, fcntl.F_GETFD)
2430
fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
2431
except (ImportError, AttributeError):
2432
# Either the fcntl module or specific constants are not present
2436
def find_executable_on_path(name):
2437
"""Finds an executable on the PATH.
2439
On Windows, this will try to append each extension in the PATHEXT
2440
environment variable to the name, if it cannot be found with the name
2443
:param name: The base name of the executable.
2444
:return: The path to the executable found or None.
2446
path = os.environ.get('PATH')
2449
path = path.split(os.pathsep)
2450
if sys.platform == 'win32':
2451
exts = os.environ.get('PATHEXT', '').split(os.pathsep)
2452
exts = [ext.lower() for ext in exts]
2453
base, ext = os.path.splitext(name)
2455
if ext.lower() not in exts:
2463
f = os.path.join(d, name) + ext
2464
if os.access(f, os.X_OK):
2469
def _posix_is_local_pid_dead(pid):
2470
"""True if pid doesn't correspond to live process on this machine"""
2472
# Special meaning of unix kill: just check if it's there.
2475
if e.errno == errno.ESRCH:
2476
# On this machine, and really not found: as sure as we can be
2479
elif e.errno == errno.EPERM:
2480
# exists, though not ours
2483
mutter("os.kill(%d, 0) failed: %s" % (pid, e))
2484
# Don't really know.
2487
# Exists and our process: not dead.
2490
if sys.platform == "win32":
2491
is_local_pid_dead = win32utils.is_local_pid_dead
2493
is_local_pid_dead = _posix_is_local_pid_dead
2496
def fdatasync(fileno):
2497
"""Flush file contents to disk if possible.
2499
:param fileno: Integer OS file handle.
2500
:raises TransportNotPossible: If flushing to disk is not possible.
2502
fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))