def listdirinternal(dfd, req, stat, skip): ret = [] while True: r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0) if r == 0: break if r == -1: raise OSError(ffi.errno, os.strerror(ffi.errno)) cur = ffi.cast("val_attrs_t*", buf) for i in range(r): lgt = cur.length assert lgt == ffi.cast('uint32_t*', cur)[0] ofs = cur.name_info.attr_dataoffset str_lgt = cur.name_info.attr_length base_ofs = ffi.offsetof('val_attrs_t', 'name_info') name = str( ffi.buffer( ffi.cast("char*", cur) + base_ofs + ofs, str_lgt - 1)) tp = attrkinds[cur.obj_type] if name == "." or name == "..": continue if skip == name and tp == statmod.S_ISDIR: return [] if stat: mtime = cur.time.tv_sec mode = (cur.accessmask & ~lib.S_IFMT) | tp ret.append((name, tp, stat_res(st_mode=mode, st_mtime=mtime, st_size=cur.datalength))) else: ret.append((name, tp)) cur += lgt return ret
def listdirinternal(dfd, req, stat, skip): ret = [] while True: r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0) if r == 0: break if r == -1: raise OSError(ffi.errno, os.strerror(ffi.errno)) cur = ffi.cast("val_attrs_t*", buf) for i in range(r): lgt = cur.length assert lgt == ffi.cast('uint32_t*', cur)[0] ofs = cur.name_info.attr_dataoffset str_lgt = cur.name_info.attr_length base_ofs = ffi.offsetof('val_attrs_t', 'name_info') name = str(ffi.buffer(ffi.cast("char*", cur) + base_ofs + ofs, str_lgt - 1)) tp = attrkinds[cur.obj_type] if name == "." or name == "..": continue if skip == name and tp == statmod.S_ISDIR: return [] if stat: mtime = cur.mtime.tv_sec mode = (cur.accessmask & ~lib.S_IFMT)| tp ret.append((name, tp, stat_res(st_mode=mode, st_mtime=mtime, st_size=cur.datalength))) else: ret.append((name, tp)) cur = ffi.cast("val_attrs_t*", int(ffi.cast("intptr_t", cur)) + lgt) return ret
attrkinds[lib.VREG] = statmod.S_IFREG attrkinds[lib.VDIR] = statmod.S_IFDIR attrkinds[lib.VLNK] = statmod.S_IFLNK attrkinds[lib.VBLK] = statmod.S_IFBLK attrkinds[lib.VCHR] = statmod.S_IFCHR attrkinds[lib.VFIFO] = statmod.S_IFIFO attrkinds[lib.VSOCK] = statmod.S_IFSOCK class stat_res(object): def __init__(self, st_mode, st_mtime, st_size): self.st_mode = st_mode self.st_mtime = st_mtime self.st_size = st_size tv_sec_ofs = ffi.offsetof("struct timespec", "tv_sec") buf = ffi.new("char[]", listdir_batch_size) def listdirinternal(dfd, req, stat, skip): ret = [] while True: r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0) if r == 0: break if r == -1: raise OSError(ffi.errno, os.strerror(ffi.errno)) cur = ffi.cast("val_attrs_t*", buf) for i in range(r): lgt = cur.length assert lgt == ffi.cast('uint32_t*', cur)[0] ofs = cur.name_info.attr_dataoffset