def _recursive_walk_dir(self, source_path, keep_base_dir=False):
'''
Walk a directory recursively, yielding each file/directory
+
+ Returns the path of an entity. If ``keep_base_dir`` is set,
+ the path returned contains the prefix ``source_path``; otherwise it is
+ relative to the prefix.
'''
source_path = source_path.rstrip(os.sep)
while queue:
cur_path = queue.pop(0)
- # it might have been removed in the mean time
- if not os.path.exists(cur_path):
+ dfd = os.open (cur_path, os.O_DIRECTORY)
+ if dfd == -1: # it might have been removed in the meantime
continue
- for filename in sorted(os.listdir(cur_path)):
- child = os.path.join(cur_path, filename)
- is_dir = os.path.isdir(child)
- status = self.filter_path(child, source_path, is_dir)
- if status == NO_MATCH:
- continue
- if not os.access(child, os.R_OK):
- self.logger.warning('Error accessing possibly locked file %s' % child)
- continue
-
- if status == MATCH:
- yield child[beginning_size:]
-
- if is_dir and (status == MATCH or status == PARENT_MATCH):
- queue.append(child)
+ try:
+ for filename in sorted(os.listdir(dfd)):
+ child = os.path.join(cur_path, filename)
+ is_dir = os.path.isdir(child)
+ status = self.filter_path(child, source_path, is_dir)
+ if status == NO_MATCH:
+ continue
+ if not os.access(child, os.R_OK):
+ self.logger.warning('Error accessing possibly locked file %s' % child)
+ continue
+
+ if status == MATCH:
+ yield child[beginning_size:]
+
+ if is_dir and (status == MATCH or status == PARENT_MATCH):
+ queue.append(child)
+ finally:
+ os.close (dfd)
def _stat_dict(self, path):
'''