2153
2178
return file_kind_from_stat_mode(mode)
2154
2179
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
2157
def file_kind(f, _lstat=os.lstat):
2181
def file_stat(f, _lstat=os.lstat):
2159
return file_kind_from_stat_mode(_lstat(f).st_mode)
2160
2185
except OSError, e:
2161
2186
if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
2162
2187
raise errors.NoSuchFile(f)
2190
def file_kind(f, _lstat=os.lstat):
2191
stat_value = file_stat(f, _lstat)
2192
return file_kind_from_stat_mode(stat_value.st_mode)
2166
2194
def until_no_eintr(f, *a, **kw):
2167
2195
"""Run f(*a, **kw), retrying if an EINTR error occurs.
2227
2255
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
2231
if sys.platform == 'linux2':
2258
if sys.platform.startswith('linux'):
2232
2259
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
2261
return os.sysconf('SC_NPROCESSORS_ONLN')
2262
except (ValueError, OSError, AttributeError):
2239
2264
elif sys.platform == 'darwin':
2240
2265
def _local_concurrency():
2241
2266
return subprocess.Popen(['sysctl', '-n', 'hw.availcpu'],
2242
2267
stdout=subprocess.PIPE).communicate()[0]
2243
elif sys.platform[0:7] == 'freebsd':
2268
elif "bsd" in sys.platform:
2244
2269
def _local_concurrency():
2245
2270
return subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
2246
2271
stdout=subprocess.PIPE).communicate()[0]
2274
2299
concurrency = os.environ.get('BZR_CONCURRENCY', None)
2275
2300
if concurrency is None:
2277
concurrency = _local_concurrency()
2278
except (OSError, IOError):
2302
import multiprocessing
2304
# multiprocessing is only available on Python >= 2.6
2306
concurrency = _local_concurrency()
2307
except (OSError, IOError):
2310
concurrency = multiprocessing.cpu_count()
2281
2312
concurrency = int(concurrency)
2282
2313
except (TypeError, ValueError):
2353
2384
except UnicodeDecodeError:
2354
2385
raise errors.BzrError("Can't decode username as %s." % \
2387
except ImportError, e:
2388
if sys.platform != 'win32':
2390
if str(e) != 'No module named pwd':
2392
# https://bugs.launchpad.net/bzr/+bug/660174
2393
# getpass.getuser() is unable to return username on Windows
2394
# if there is no USERNAME environment variable set.
2395
# That could be true if bzr is running as a service,
2396
# e.g. running `bzr serve` as a service on Windows.
2397
# We should not fail with traceback in this case.
2398
username = u'UNKNOWN'
2356
2399
return username
2402
def available_backup_name(base, exists):
2403
"""Find a non-existing backup file name.
2405
This will *not* create anything, this only return a 'free' entry. This
2406
should be used for checking names in a directory below a locked
2407
tree/branch/repo to avoid race conditions. This is LBYL (Look Before You
2408
Leap) and generally discouraged.
2410
:param base: The base name.
2412
:param exists: A callable returning True if the path parameter exists.
2415
name = "%s.~%d~" % (base, counter)
2418
name = "%s.~%d~" % (base, counter)
2422
def set_fd_cloexec(fd):
2423
"""Set a Unix file descriptor's FD_CLOEXEC flag. Do nothing if platform
2424
support for this is not available.
2428
old = fcntl.fcntl(fd, fcntl.F_GETFD)
2429
fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
2430
except (ImportError, AttributeError):
2431
# Either the fcntl module or specific constants are not present
2435
def find_executable_on_path(name):
2436
"""Finds an executable on the PATH.
2438
On Windows, this will try to append each extension in the PATHEXT
2439
environment variable to the name, if it cannot be found with the name
2442
:param name: The base name of the executable.
2443
:return: The path to the executable found or None.
2445
path = os.environ.get('PATH')
2448
path = path.split(os.pathsep)
2449
if sys.platform == 'win32':
2450
exts = os.environ.get('PATHEXT', '').split(os.pathsep)
2451
exts = [ext.lower() for ext in exts]
2452
base, ext = os.path.splitext(name)
2454
if ext.lower() not in exts:
2462
f = os.path.join(d, name) + ext
2463
if os.access(f, os.X_OK):
2468
def _posix_is_local_pid_dead(pid):
2469
"""True if pid doesn't correspond to live process on this machine"""
2471
# Special meaning of unix kill: just check if it's there.
2474
if e.errno == errno.ESRCH:
2475
# On this machine, and really not found: as sure as we can be
2478
elif e.errno == errno.EPERM:
2479
# exists, though not ours
2482
mutter("os.kill(%d, 0) failed: %s" % (pid, e))
2483
# Don't really know.
2486
# Exists and our process: not dead.
2489
if sys.platform == "win32":
2490
is_local_pid_dead = win32utils.is_local_pid_dead
2492
is_local_pid_dead = _posix_is_local_pid_dead
2495
def fdatasync(fileno):
2496
"""Flush file contents to disk if possible.
2498
:param fileno: Integer OS file handle.
2499
:raises TransportNotPossible: If flushing to disk is not possible.
2501
fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))