124
124
_directory_kind = 'directory'
127
stat.S_IFDIR:_directory_kind,
128
stat.S_IFCHR:'chardev',
129
stat.S_IFBLK:'block',
132
stat.S_IFLNK:'symlink',
133
stat.S_IFSOCK:'socket',
137
def file_kind_from_stat_mode(stat_mode, _formats=_formats, _unknown='unknown'):
138
"""Generate a file kind from a stat mode. This is used in walkdirs.
140
Its performance is critical: Do not mutate without careful benchmarking.
143
return _formats[stat_mode & 0170000]
148
def file_kind(f, _lstat=os.lstat, _mapper=file_kind_from_stat_mode):
150
return _mapper(_lstat(f).st_mode)
152
if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
153
raise errors.NoSuchFile(f)
158
127
"""Return the current umask"""
159
128
# Assume that people aren't messing with the umask while running
1201
1170
_lstat = os.lstat
1202
1171
_directory = _directory_kind
1203
1172
_listdir = os.listdir
1204
_kind_from_mode = _formats.get
1173
_kind_from_mode = file_kind_from_stat_mode
1205
1174
pending = [(safe_unicode(prefix), "", _directory, None, safe_unicode(top))]
1207
1176
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1223
1192
for name in names:
1224
1193
abspath = top_slash + name
1225
1194
statvalue = _lstat(abspath)
1226
kind = _kind_from_mode(statvalue.st_mode & 0170000, 'unknown')
1195
kind = _kind_from_mode(statvalue.st_mode)
1227
1196
append((relprefix + name, name, kind, statvalue, abspath))
1228
1197
yield (relroot, top), dirblock
1292
1261
# ANSI_X3.4-1968 is a form of ASCII
1293
1262
_selected_dir_reader = UnicodeDirReader()
1295
_selected_dir_reader = UTF8DirReader()
1265
from bzrlib._readdir_pyx import UTF8DirReader
1267
# No optimised code path
1268
_selected_dir_reader = UnicodeDirReader()
1270
_selected_dir_reader = UTF8DirReader()
1296
1271
# 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1297
1272
# But we don't actually uses 1-3 in pending, so set them to None
1298
pending = [_selected_dir_reader.top_prefix_to_starting_dir(top, prefix)]
1273
pending = [[_selected_dir_reader.top_prefix_to_starting_dir(top, prefix)]]
1299
1274
read_dir = _selected_dir_reader.read_dir
1300
1275
_directory = _directory_kind
1302
relroot, _, _, _, top = pending.pop()
1303
dirblock = read_dir(relroot, top)
1277
relroot, _, _, _, top = pending[-1].pop()
1280
dirblock = sorted(read_dir(relroot, top))
1304
1281
yield (relroot, top), dirblock
1305
1282
# push the user specified dirs from dirblock
1306
pending.extend(d for d in reversed(dirblock) if d[2] == _directory)
1309
class UTF8DirReader(DirReader):
1310
"""A dir reader for utf8 file systems."""
1312
def top_prefix_to_starting_dir(self, top, prefix=""):
1313
"""See DirReader.top_prefix_to_starting_dir."""
1314
return (safe_utf8(prefix), None, None, None, safe_utf8(top))
1316
def read_dir(self, prefix, top):
1317
"""Read a single directory from a utf8 file system.
1319
All paths in and out are utf8.
1321
This sub-function is called when we know the filesystem is already in utf8
1322
encoding. So we don't need to transcode filenames.
1324
See DirReader.read_dir for details.
1327
# Use C accelerated directory listing.
1328
_listdir = _read_dir
1329
_kind_from_mode = _formats.get
1332
relprefix = prefix + '/'
1335
top_slash = top + '/'
1338
append = dirblock.append
1339
# read_dir supplies in should-stat order.
1340
for _, name in sorted(_listdir(top)):
1341
abspath = top_slash + name
1342
statvalue = _lstat(abspath)
1343
kind = _kind_from_mode(statvalue.st_mode & 0170000, 'unknown')
1344
append((relprefix + name, name, kind, statvalue, abspath))
1283
next = [d for d in reversed(dirblock) if d[2] == _directory]
1285
pending.append(next)
1349
1288
class UnicodeDirReader(DirReader):
1388
1327
name_utf8 = _utf8_encode(name)[0]
1389
1328
abspath = top_slash + name
1390
1329
statvalue = _lstat(abspath)
1391
kind = _kind_from_mode(statvalue.st_mode & 0170000, 'unknown')
1330
kind = _kind_from_mode(statvalue.st_mode)
1392
1331
append((relprefix + name_utf8, name_utf8, kind, statvalue, abspath))
1393
1332
return dirblock
1608
1547
return open(filename, 'rU').read()
1612
from bzrlib._readdir_pyx import read_dir as _read_dir
1614
from bzrlib._readdir_py import read_dir as _read_dir
1550
def file_kind_from_stat_mode_thunk(mode):
1551
global file_kind_from_stat_mode
1552
if file_kind_from_stat_mode is file_kind_from_stat_mode_thunk:
1554
from bzrlib._readdir_pyx import UTF8DirReader
1555
file_kind_from_stat_mode = UTF8DirReader().kind_from_mode
1557
from bzrlib._readdir_py import (
1558
_kind_from_mode as _file_kind_from_stat_mode
1560
return file_kind_from_stat_mode(mode)
1561
file_kind_from_stat_mode = file_kind_from_stat_mode_thunk
1564
def file_kind(f, _lstat=os.lstat):
1566
return file_kind_from_stat_mode(_lstat(f).st_mode)
1568
if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
1569
raise errors.NoSuchFile(f)