2 from bup.helpers import *
5 O_LARGEFILE = os.O_LARGEFILE
10 # the use of fchdir() and lstat() is for two reasons:
11 # - help out the kernel by not making it repeatedly look up the absolute path
12 # - avoid race conditions caused by doing listdir() on a changing symlink
14 def __init__(self, path):
16 self.fd = os.open(path, os.O_RDONLY|O_LARGEFILE|os.O_NOFOLLOW)
28 return os.fstat(self.fd)
31 _IFMT = stat.S_IFMT(0xffffffff) # avoid function call in inner loop
34 for n in os.listdir('.'):
38 add_error(Exception('%s: %s' % (realpath(n), str(e))))
40 if (st.st_mode & _IFMT) == stat.S_IFDIR:
47 def _recursive_dirlist(prepend, xdev):
48 for (name,pst) in _dirlist():
49 if name.endswith('/'):
50 if xdev != None and pst.st_dev != xdev:
51 log('Skipping %r: different filesystem.\n' % (prepend+name))
56 add_error('%s: %s' % (prepend, e))
58 for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev):
61 yield (prepend + name, pst)
64 def recursive_dirlist(paths, xdev):
65 startdir = OsFile('.')
67 assert(type(paths) != type(''))
71 if stat.S_ISLNK(pst.st_mode):
87 if stat.S_ISDIR(pst.st_mode):
89 prepend = os.path.join(path, '')
90 for i in _recursive_dirlist(prepend=prepend, xdev=xdev):