s32 sal_DirectoryGet(const char *path, struct SAL_DIRECTORY_ENTRY *dir, s32 startIndex, s32 count) { s32 fileCount=0; DIR *d; struct dirent *de; uint32_t entriesRead=0; char fullFilename[256]; s32 endIndex=startIndex+count; long loc; d = opendir(path); if (d) { loc=telldir(d); seekdir(d,loc+startIndex); while ((de = readdir(d))) { if(startIndex >= endIndex) { //exit loop break; } //Is entry a file or directory if (de->d_type == 4) // Directory { strcpy(dir[fileCount].filename,de->d_name); strcpy(dir[fileCount].displayName,de->d_name); dir[fileCount].type=SAL_FILE_TYPE_DIRECTORY; } else { //File strcpy(dir[fileCount].filename,de->d_name); strcpy(dir[fileCount].displayName,de->d_name); dir[fileCount].type=SAL_FILE_TYPE_FILE; } fileCount++; startIndex++; } closedir(d); } return SAL_ERROR; // return SAL_OK; }
/* seek to the given name */ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, off_t *ofs) { struct dirent *de; int i; dir->end_of_search = False; if (ISDOT(name)) { dir->offset = DIR_OFFSET_DOTDOT; *ofs = dir->offset; return NT_STATUS_OK; } if (ISDOTDOT(name)) { dir->offset = DIR_OFFSET_BASE; *ofs = dir->offset; return NT_STATUS_OK; } for (i=dir->name_cache_index;i>=0;i--) { struct name_cache_entry *e = &dir->name_cache[i]; if (e->name && strcasecmp_m(name, e->name) == 0) { *ofs = e->offset; return NT_STATUS_OK; } } for (i=NAME_CACHE_SIZE-1;i>dir->name_cache_index;i--) { struct name_cache_entry *e = &dir->name_cache[i]; if (e->name && strcasecmp_m(name, e->name) == 0) { *ofs = e->offset; return NT_STATUS_OK; } } rewinddir(dir->dir); while ((de = readdir(dir->dir))) { if (strcasecmp_m(name, de->d_name) == 0) { dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; *ofs = dir->offset; return NT_STATUS_OK; } } dir->end_of_search = True; return NT_STATUS_OBJECT_NAME_NOT_FOUND; }
dir_node* create_dir_node (struct dirent* entry, dir_node* parent, dir_node* slot ) { dir_node node; assert(entry->d_type == DT_DIR); node.dir_ent = entry; node.parent = parent; assert(node.parent->dir_ent); unsigned int namelen, p_namelen; char * d_name = node.dir_ent->d_name; char * p_name = node.parent->path; namelen = strlen(d_name); p_namelen = strlen(p_name); char* full_path = NULL; full_path = malloc(namelen + p_namelen + 2); assert(full_path); sprintf(full_path, "%s/%s", p_name, d_name); full_path[p_namelen + namelen + 1] = 0; node.path = full_path; DIR* dirp = opendir(node.path); if ( dirp == NULL ) { printf("node.path: %s\n",node.path); } assert(dirp); struct dirent* current = readdir(dirp); assert(current); assert(!strcmp(current->d_name, ".")); assert(current->d_type == DT_DIR); struct dirent* father = readdir(dirp); /* bypass .. */ assert(parent); assert(!strcmp(father->d_name, "..")); assert(father->d_type == DT_DIR); node.dir_ptr = dirp; node.loc = telldir(dirp); int fd = dirfd(dirp); assert(fd < MAXFDNUM); assert(empty_dir_node(slot + fd)); memcpy((dir_node*)(slot + fd), &node, sizeof(node)); ev_io_init(&dir_watcher[fd], dir_cb, fd, EV_LIBUV_KQUEUE_HACK); ev_io_start(loop, &dir_watcher[fd]); return slot + fd; }
char *read_dir(void *stream, unsigned long long *pos, unsigned long long *ino_out, int *len_out, unsigned int *type_out) { DIR *dir = stream; struct dirent *ent; seekdir(dir, *pos); ent = readdir(dir); if (ent == NULL) return NULL; *len_out = strlen(ent->d_name); *ino_out = ent->d_ino; *type_out = ent->d_type; *pos = telldir(dir); return ent->d_name; }
void seekdir(DIR *dirp,long loc) { long base; long offset; if (telldir(dirp)==loc) return; offset=loc%DIRBLKSIZ; base=loc-offset; (void)lseek(dirp->dd_fd,base,0); dirp->dd_loc=dirp->dd_size=0; while(dirp->dd_loc<offset) if (readdir(dirp)==NULL) return; }
int main (int argc, char *argv[]) { if (argc == 1) { argv[1] = "."; } printf("opened %s\n", argv[1]); DIR *d = opendir(argv[1]); struct dirent *e = NULL, se; long int pos = 0; int i = 0; do { if (i == 3) { pos = telldir(d); } e = readdir(d); if (i == 3) { if (e) se = *e; else pos = 0; } i++; } while (e); if (pos) { seekdir(d, pos); e = readdir(d); if (e) { if (se.d_fileno != e->d_fileno || strcmp(se.d_name, e->d_name) != 0) { printf("seekdir -> readdir FAILED\n"); } else { printf("OK\n"); } } else printf("seekdir FAILED!\n"); } closedir(d); return 0; }
static int pr_readdir(const char* path, void* buf, fuse_fill_dir_t filler,off_t offset,struct fuse_file_info* fi) { int res = 0; struct stat st; struct dirent* de; DIR* dp = get_dirp(fi); (void)path; seekdir(dp,offset); while((de = readdir(dp)) != NULL) { struct stat st; memset(&st,0,sizeof(st)); st.st_ino = de->d_ino; st.st_mode = de->d_type << 12; if(filler(buf,de->d_name,&st,telldir(dp))) break; } return res; }
int main() { DIR *dirp = opendir("./"); if (NULL == dirp) { printf("opendir error\n"); } else { struct dirent *pDirent = NULL; while ((pDirent = readdir(dirp)) != NULL) { printf("%d: %s\n", telldir(dirp), pDirent->d_name); } closedir(dirp); } return 0; }
/* * dp_readdir * * Reads the entry of the directory and provides other information * such as i-number, name, length and saves the dir entry position * in a cookie for future calls. */ int dp_readdir(DIR *dirp, unsigned long *cookiep, char *name, int *n_namep, unsigned long *fileidp) { struct dirent *entp; int err = errno; if ((entp = readdir(dirp)) == 0) { if (err == errno) { *n_namep = 0; return (0); } return (errno); } *fileidp = entp->d_ino; (void) strlcpy(name, entp->d_name, *n_namep); *n_namep = entp->d_reclen + 1; *cookiep = telldir(dirp); return (0); }
void dfs(const char *dir) { DIR *cur_dir = opendir(dir); struct dirent *elem; while (elem = readdir(cur_dir)) { if (...) {} struct stat cur_stat; char cur_name[PATH_MAX]; snprintf(cur_name, PATH_MAX, "%s/%s", dir, elem->d_name); lstat(cur_name, &cur_stat); if (S_ISDIR(cur_stat.st_mode)) { off_t offset = telldir(cur_dir); closedir(cur_dir); dfs(cur_name); cur_dir = opendir(dir); seekdir(cur_dir, offset); } if (S_LNK(cur_stat.st_mode)) printf("%s\n", cur_name); } closedir(cur_dir); }
int main(void) { int total_deleted = 0; DIR *d; struct dirent *de; cleanup(); create_files(); d = opendir(TESTDIR); chdir(TESTDIR) == 0 || FAILED(); /* skip past . and .. */ de = readdir(d); strcmp(de->d_name, ".") == 0 || FAILED(); de = readdir(d); strcmp(de->d_name, "..") == 0 || FAILED(); while ((de = readdir(d))) { off_t ofs = telldir(d); unlink(de->d_name) == 0 || FAILED(); /* move one more position on */ readdir(d); /* seek to just after the first readdir() */ seekdir(d, ofs); total_deleted++; } closedir(d); printf("Deleted %d files of %d\n", total_deleted, NUM_FILES); chdir("..") == 0 || FAILED(); rmdir(TESTDIR) == 0 || FAILED(); return 0; }
static int xmp_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct xmp_dirp *d = get_dirp (fi); (void) path; openrfs_fuse_drop_privs (); if (offset != d->offset) { seekdir (d->dp, offset); d->entry = NULL; d->offset = offset; } while (1) { struct stat st; off_t nextoff; if (!d->entry) { d->entry = readdir (d->dp); if (!d->entry) break; } memset (&st, 0, sizeof (st)); st.st_ino = d->entry->d_ino; st.st_mode = d->entry->d_type << 12; nextoff = telldir (d->dp); if (filler (buf, d->entry->d_name, &st, nextoff)) break; d->entry = NULL; d->offset = nextoff; } openrfs_fuse_restore_privs (); return 0; }
TEST(dirent, seekdir_telldir) { DIR* d = opendir("/proc/self"); ASSERT_TRUE(d != NULL); std::vector<long> offset_list; std::vector<std::string> name_list; dirent* e = NULL; offset_list.push_back(telldir(d)); ASSERT_EQ(0L, offset_list.back()); while ((e = readdir(d)) != NULL) { name_list.push_back(e->d_name); offset_list.push_back(telldir(d)); // Make sure telldir() point to the next entry. ASSERT_EQ(e->d_off, offset_list.back()); } long end_offset = telldir(d); // telldir() should not pass the end of the file. ASSERT_EQ(offset_list.back(), end_offset); offset_list.pop_back(); for (size_t i = 0; i < offset_list.size(); ++i) { seekdir(d, offset_list[i]); ASSERT_EQ(offset_list[i], telldir(d)); e = readdir(d); ASSERT_TRUE(e != NULL); ASSERT_STREQ(name_list[i].c_str(), e->d_name); } for (int i = static_cast<int>(offset_list.size()) - 1; i >= 0; --i) { seekdir(d, offset_list[i]); ASSERT_EQ(offset_list[i], telldir(d)); e = readdir(d); ASSERT_TRUE(e != NULL); ASSERT_STREQ(name_list[i].c_str(), e->d_name); } // Seek to the end, read NULL. seekdir(d, end_offset); ASSERT_EQ(end_offset, telldir(d)); errno = 0; ASSERT_EQ(NULL, readdir(d)); ASSERT_EQ(0, errno); ASSERT_EQ(0, closedir(d)); }
int ioctx_readdir_r(IOCtx ioctx, struct diod_dirent *entry, struct diod_dirent **result) { int r; struct dirent* rd_result; if (!ioctx->dir) return EINVAL; r = readdir_r (ioctx->dir, &entry->dir_entry, &rd_result); if (r==0) { /* success */ /* Does the same to diod_dirent as readdir_r() does to dirent */ if (rd_result == NULL) *result = NULL; else *result = entry; #ifdef _DIRENT_HAVE_D_OFF entry->d_off = entry->dir_entry.d_off; #else entry->d_off = telldir (ioctx->dir); #endif } return r; }
/* FIXME: seekdir(previous d_off) OK? * If not, substitute saved_dir_position for d_off in last returned. * If so, get rid of saved_dir_position and 2nd seekdir. */ static u32 _read_dir_linux (Fid *f, u8* buf, u64 offset, u32 count) { int i, n = 0; off_t saved_dir_pos; if (offset == 0) rewinddir (f->dir); else seekdir (f->dir, offset); do { saved_dir_pos = telldir (f->dir); if (!(f->dirent = readdir (f->dir))) /* FIXME: use readdir_r */ break; i = _copy_dirent_linux (f, buf + n, count - n); if (i == 0) { seekdir (f->dir, saved_dir_pos); break; } n += i; } while (n < count); return n; }
void tst_telldir (void) { struct dirent *de; struct dirent old_de; DIR *dir; off_t offset; off_t old_offset; old_offset = 0; dir = opendir("."); if (!dir) { perror("\".\""); } for (;;) { de = readdir(dir); if (!de) break; offset = telldir(dir); if (offset == old_offset) { #ifdef __APPLE__ printf("%llx %llx %s\n", (u64)old_de.d_seekoff, (u64)offset, old_de.d_name); printf("%llx %llx %s\n\n", (u64)de->d_seekoff, (u64)offset, de->d_name); #else printf("%llx %llx %s\n", (u64)old_de.d_off, (u64)offset, old_de.d_name); printf("%llx %llx %s\n\n", (u64)de->d_off, (u64)offset, de->d_name); #endif } old_offset = offset; old_de = *de; } closedir(dir); }
ATF_TC_BODY(seekdir_basic, tc) { DIR *dp; char *wasname; struct dirent *entry; long here; #ifdef __FreeBSD__ #define CREAT(x, m) do { \ int _creat_fd; \ ATF_REQUIRE_MSG((_creat_fd = creat((x), (m))), \ "creat(%s, %x) failed: %s", (x), (m), \ strerror(errno)); \ (void)close(_creat_fd); \ } while(0); ATF_REQUIRE_MSG(mkdir("t", 0755) == 0, "mkdir failed: %s", strerror(errno)); CREAT("t/a", 0600); CREAT("t/b", 0600); CREAT("t/c", 0600); #else mkdir("t", 0755); creat("t/a", 0600); creat("t/b", 0600); creat("t/c", 0600); #endif dp = opendir("t"); if ( dp == NULL) atf_tc_fail("Could not open temp directory."); /* skip two for . and .. */ entry = readdir(dp); entry = readdir(dp); /* get first entry */ entry = readdir(dp); here = telldir(dp); #ifdef __FreeBSD__ ATF_REQUIRE_MSG(here != -1, "telldir failed: %s", strerror(errno)); #endif /* get second entry */ entry = readdir(dp); #ifdef __FreeBSD__ ATF_REQUIRE_MSG(entry != NULL, "readdir failed: %s", strerror(errno)); #endif wasname = strdup(entry->d_name); if (wasname == NULL) atf_tc_fail("cannot allocate memory"); /* get third entry */ entry = readdir(dp); /* try to return to the position after the first entry */ seekdir(dp, here); entry = readdir(dp); if (entry == NULL) atf_tc_fail("entry 1 not found"); if (strcmp(entry->d_name, wasname) != 0) atf_tc_fail("1st seekdir found wrong name"); /* try again, and throw in a telldir() for good measure */ seekdir(dp, here); here = telldir(dp); entry = readdir(dp); if (entry == NULL) atf_tc_fail("entry 2 not found"); if (strcmp(entry->d_name, wasname) != 0) atf_tc_fail("2nd seekdir found wrong name"); /* One more time, to make sure that telldir() doesn't affect result */ seekdir(dp, here); entry = readdir(dp); if (entry == NULL) atf_tc_fail("entry 3 not found"); if (strcmp(entry->d_name, wasname) != 0) atf_tc_fail("3rd seekdir found wrong name"); closedir(dp); #ifdef __FreeBSD__ free(wasname); #endif }
void test() { int err; long loc; DIR *dir; struct dirent *ent; struct dirent ent_r; struct dirent *result; int i; // check bad opendir input dir = opendir("noexist"); assert(!dir); assert(errno == ENOENT); dir = opendir("nocanread"); assert(!dir); assert(errno == EACCES); dir = opendir("foobar/file.txt"); assert(!dir); assert(errno == ENOTDIR); // check bad readdir input //dir = opendir("foobar"); //closedir(dir); //ent = readdir(dir); //assert(!ent); // XXX musl doesn't have enough error handling for this: assert(errno == EBADF); // check bad readdir_r input //dir = opendir("foobar"); //closedir(dir); //err = readdir_r(dir, NULL, &result); // XXX musl doesn't have enough error handling for this: assert(err == EBADF); // // do a normal read with readdir // dir = opendir("foobar"); assert(dir); int seen[3] = { 0, 0, 0 }; for (i = 0; i < 3; i++) { errno = 0; ent = readdir(dir); //printf("ent, errno: %p, %d\n", ent, errno); assert(ent); //printf("%d file: %s (%d : %d)\n", i, ent->d_name, ent->d_reclen, sizeof(*ent)); assert(ent->d_reclen == sizeof(*ent)); if (!seen[0] && !strcmp(ent->d_name, ".")) { assert(ent->d_type & DT_DIR); seen[0] = 1; continue; } if (!seen[1] && !strcmp(ent->d_name, "..")) { assert(ent->d_type & DT_DIR); seen[1] = 1; continue; } if (!seen[2] && !strcmp(ent->d_name, "file.txt")) { assert(ent->d_type & DT_REG); seen[2] = 1; continue; } assert(0 && "odd filename"); } ent = readdir(dir); if (ent) printf("surprising ent: %p : %s\n", ent, ent->d_name); assert(!ent); // test rewinddir rewinddir(dir); ent = readdir(dir); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); // test seek / tell rewinddir(dir); ent = readdir(dir); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); char first[1024]; //printf("first: %s\n", ent->d_name); strcpy(first, ent->d_name); loc = telldir(dir); assert(loc >= 0); ent = readdir(dir); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); ent = readdir(dir); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); seekdir(dir, loc); ent = readdir(dir); assert(ent); //printf("check: %s / %s\n", ent->d_name, first); assert(!strcmp(ent->d_name, first)); // // do a normal read with readdir_r // rewinddir(dir); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(&ent_r == result); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(&ent_r == result); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(&ent_r == result); assert(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "file.txt")); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(!result); err = closedir(dir); assert(!err); puts("success"); }
/** * FSAL_readdir : * Read the entries of an opened directory. * * \param dir_descriptor (input): * Pointer to the directory descriptor filled by FSAL_opendir. * \param start_position (input): * Cookie that indicates the first object to be read during * this readdir operation. * This should be : * - FSAL_READDIR_FROM_BEGINNING for reading the content * of the directory from the beginning. * - The end_position parameter returned by the previous * call to FSAL_readdir. * \param get_attr_mask (input) * Specify the set of attributes to be retrieved for directory entries. * \param buffersize (input) * The size (in bytes) of the buffer where * the direntries are to be stored. * \param pdirent (output) * Adresse of the buffer where the direntries are to be stored. * \param end_position (output) * Cookie that indicates the current position in the directory. * \param nb_entries (output) * Pointer to the number of entries read during the call. * \param end_of_dir (output) * Pointer to a boolean that indicates if the end of dir * has been reached during the call. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t POSIXFSAL_readdir(fsal_dir_t * dir_descriptor, /* IN */ fsal_cookie_t start_pos, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * p_pdirent, /* OUT */ fsal_cookie_t * end_position, /* OUT */ fsal_count_t * p_nb_entries, /* OUT */ fsal_boolean_t * p_end_of_dir /* OUT */ ) { posixfsal_dir_t * p_dir_descriptor = (posixfsal_dir_t *) dir_descriptor; posixfsal_cookie_t start_position, telldir_pos; posixfsal_cookie_t * p_end_position = (posixfsal_cookie_t *) end_position; fsal_status_t st; fsal_posixdb_status_t stdb; fsal_count_t max_dir_entries; struct dirent *dp; struct dirent dpe; struct stat buffstat; fsal_path_t fsalpath; fsal_posixdb_fileinfo_t infofs; int rc; /*****************/ /* sanity checks */ /*****************/ if(!p_dir_descriptor || !p_pdirent || !p_end_position || !p_nb_entries || !p_end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); max_dir_entries = (buffersize / sizeof(fsal_dirent_t)); /***************************/ /* seek into the directory */ /***************************/ memcpy ( (char *)&start_position.data.cookie, (char *)&start_pos.data, sizeof( off_t ) ) ; errno = 0; if(start_position.data.cookie == 0) { rewinddir(p_dir_descriptor->p_dir); rc = errno; } else { seekdir(p_dir_descriptor->p_dir, start_position.data.cookie); rc = errno; } if(rc) { st.major = posix2fsal_error(rc); st.minor = rc; goto readdir_error; } /************************/ /* browse the directory */ /************************/ *p_nb_entries = 0; while(*p_nb_entries < max_dir_entries) { /***********************/ /* read the next entry */ /***********************/ TakeTokenFSCall(); rc = readdir_r(p_dir_descriptor->p_dir, &dpe, &dp); ReleaseTokenFSCall(); if(rc) { st.major = posix2fsal_error(errno); st.minor = errno; goto readdir_error; } /* End of directory */ if(!dp) { *p_end_of_dir = 1; break; } /***********************************/ /* Get information about the entry */ /***********************************/ /* build the full path of the file into "fsalpath */ if(FSAL_IS_ERROR (st = FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &(p_pdirent[*p_nb_entries].name)))) goto readdir_error; memcpy(&fsalpath, &(p_dir_descriptor->path), sizeof(fsal_path_t)); st = fsal_internal_appendFSALNameToFSALPath(&fsalpath, &(p_pdirent[*p_nb_entries].name)); if(FSAL_IS_ERROR(st)) goto readdir_error; /* get object info */ TakeTokenFSCall(); rc = lstat(fsalpath.path, &buffstat); ReleaseTokenFSCall(); if(rc) { st.major = posix2fsal_error(errno); st.minor = errno; goto readdir_error; } if(FSAL_IS_ERROR(st = fsal_internal_posix2posixdb_fileinfo(&buffstat, &infofs))) goto readdir_error; /********************/ /* fills the handle */ /********************/ /* check for "." and ".." */ if(!strcmp(dp->d_name, ".")) { memcpy(&(p_pdirent[*p_nb_entries].handle), &(p_dir_descriptor->handle), sizeof(posixfsal_handle_t)); } else if(!strcmp(dp->d_name, "..")) { stdb = fsal_posixdb_getParentDirHandle(p_dir_descriptor->context.p_conn, &(p_dir_descriptor->handle), (posixfsal_handle_t *) &(p_pdirent[*p_nb_entries].handle)); if(FSAL_POSIXDB_IS_ERROR(stdb) && FSAL_IS_ERROR(st = posixdb2fsal_error(stdb))) goto readdir_error; } else { #ifdef _USE_POSIXDB_READDIR_BLOCK if(p_dir_descriptor->dbentries_count > -1) { /* look for the entry in dbentries */ st = fsal_internal_getInfoFromChildrenList(&(p_dir_descriptor->context), &(p_dir_descriptor->handle), &(p_pdirent[*p_nb_entries].name), &infofs, p_dir_descriptor->p_dbentries, p_dir_descriptor-> dbentries_count, &(p_pdirent[*p_nb_entries]. handle)); } else #endif { /* get handle for the entry */ st = fsal_internal_getInfoFromName(&(p_dir_descriptor->context), &(p_dir_descriptor->handle), &(p_pdirent[*p_nb_entries].name), &infofs, (posixfsal_handle_t *) &(p_pdirent[*p_nb_entries].handle)); } if(FSAL_IS_ERROR(st)) goto readdir_error; } /* end of name check for "." and ".." */ /************************ * Fills the attributes * ************************/ p_pdirent[*p_nb_entries].attributes.asked_attributes = get_attr_mask; st = posix2fsal_attributes(&buffstat, &(p_pdirent[*p_nb_entries].attributes)); if(FSAL_IS_ERROR(st)) goto readdir_error; /* * **/ telldir_pos.data.cookie = telldir(p_dir_descriptor->p_dir); memcpy(&p_pdirent[*p_nb_entries].cookie, &telldir_pos, sizeof(fsal_cookie_t)); p_pdirent[*p_nb_entries].nextentry = NULL; if(*p_nb_entries) p_pdirent[*p_nb_entries - 1].nextentry = &(p_pdirent[*p_nb_entries]); memcpy(p_end_position, &p_pdirent[*p_nb_entries].cookie, sizeof(fsal_cookie_t)); (*p_nb_entries)++; }; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); /* return error, and free what must be freed */ readdir_error: Return(st.major, st.minor, INDEX_FSAL_readdir); }
/* * Common routine for opendir(3), __opendir2(3) and fdopendir(3). */ static DIR * __opendir_common(int fd, const char *name, int flags) { DIR *dirp; int incr; int saved_errno; int unionstack; struct stat statb; dirp = NULL; /* _fstat() the open handler because the file may have changed. */ if (_fstat(fd, &statb) != 0) goto fail; if (!S_ISDIR(statb.st_mode)) { errno = ENOTDIR; goto fail; } if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || (dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) goto fail; dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR)); LIST_INIT(&dirp->dd_td->td_locq); dirp->dd_td->td_loccnt = 0; /* * Use the system page size if that is a multiple of DIRBLKSIZ. * Hopefully this can be a big win someday by allowing page * trades to user space to be done by _getdirentries(). */ incr = getpagesize(); if ((incr % DIRBLKSIZ) != 0) incr = DIRBLKSIZ; /* * Determine whether this directory is the top of a union stack. */ if (flags & DTF_NODUP) { struct statfs sfb; if (_fstatfs(fd, &sfb) < 0) goto fail; unionstack = !strcmp(sfb.f_fstypename, "unionfs") || (sfb.f_flags & MNT_UNION); } else { unionstack = 0; } if (unionstack) { int len = 0; int space = 0; char *buf = 0; char *ddptr = 0; char *ddeptr; int n; struct dirent **dpv; /* * The strategy here is to read all the directory * entries into a buffer, sort the buffer, and * remove duplicate entries by setting the inode * number to zero. */ do { /* * Always make at least DIRBLKSIZ bytes * available to _getdirentries */ if (space < DIRBLKSIZ) { space += incr; len += incr; buf = reallocf(buf, len); if (buf == NULL) goto fail; ddptr = buf + (len - space); } n = _getdirentries(fd, ddptr, space, &dirp->dd_seek); if (n > 0) { ddptr += n; space -= n; } } while (n > 0); ddeptr = ddptr; flags |= __DTF_READALL; /* * Re-open the directory. * This has the effect of rewinding back to the * top of the union stack and is needed by * programs which plan to fchdir to a descriptor * which has also been read -- see fts.c. */ if (flags & DTF_REWIND) { (void)_close(fd); if ((fd = _open(name, O_RDONLY | O_DIRECTORY)) == -1) { saved_errno = errno; free(buf); free(dirp); errno = saved_errno; return (NULL); } } /* * There is now a buffer full of (possibly) duplicate * names. */ dirp->dd_buf = buf; /* * Go round this loop twice... * * Scan through the buffer, counting entries. * On the second pass, save pointers to each one. * Then sort the pointers and remove duplicate names. */ for (dpv = 0;;) { n = 0; ddptr = buf; while (ddptr < ddeptr) { struct dirent *dp; dp = (struct dirent *) ddptr; if ((long)dp & 03L) break; if ((dp->d_reclen <= 0) || (dp->d_reclen > (ddeptr + 1 - ddptr))) break; ddptr += dp->d_reclen; if (dp->d_fileno) { if (dpv) dpv[n] = dp; n++; } } if (dpv) { struct dirent *xp; /* * This sort must be stable. */ mergesort(dpv, n, sizeof(*dpv), opendir_compar); dpv[n] = NULL; xp = NULL; /* * Scan through the buffer in sort order, * zapping the inode number of any * duplicate names. */ for (n = 0; dpv[n]; n++) { struct dirent *dp = dpv[n]; if ((xp == NULL) || strcmp(dp->d_name, xp->d_name)) { xp = dp; } else { dp->d_fileno = 0; } if (dp->d_type == DT_WHT && (flags & DTF_HIDEW)) dp->d_fileno = 0; } free(dpv); break; } else { dpv = malloc((n+1) * sizeof(struct dirent *)); if (dpv == NULL) break; } } dirp->dd_len = len; dirp->dd_size = ddptr - dirp->dd_buf; } else { dirp->dd_len = incr; dirp->dd_size = 0; dirp->dd_buf = malloc(dirp->dd_len); if (dirp->dd_buf == NULL) goto fail; dirp->dd_seek = 0; flags &= ~DTF_REWIND; } dirp->dd_loc = 0; dirp->dd_fd = fd; dirp->dd_flags = flags; dirp->dd_lock = NULL; /* * Set up seek point for rewinddir. */ dirp->dd_rewind = telldir(dirp); return (dirp); fail: saved_errno = errno; free(dirp); (void)_close(fd); errno = saved_errno; return (NULL); }
/** Directory tree is now top / topfile middle2 / middle1 / bottom1 / absfile / bottom2 / file -- read-only / read-only / sub-read-only / file @SYMTestCaseID SYSLIB-STDLIB-CT-1050 @SYMTestCaseDesc Tests for enumeration on directories @SYMTestPriority High @SYMTestActions Tests by opening directories @SYMTestExpectedResults Test must not fail @SYMREQ REQ0000 */ void directory() { int err, count, i, j, fd; DIR *dp; struct dirent *ep; char name[MAXPATHLEN+1]; off_t pos; test_Next("Enumerating Directories"); err=chdir(rootpath); test(err==0); dp=opendir("topfile"); /* test_errno(dp==0,ENOTDIR); -- not convinced about this anyway */ test_errno(dp==0,ENOENT); dp=opendir("no such file"); test_errno(dp==0,ENOENT); //test something sensible happens if someone uses a WDIR inplace of a DIR { WDIR *wp = wopendir((wchar_t*)L"."); test(wp!=0); // Test wants a WDIR passed but won't compile under CW. // Force the compile by casting. The function will still get a WDIR. // DIR inherits from WDIR. ep=readdir((DIR*)wp); test_errno(ep==0,EINVAL); wclosedir(wp); } dp=opendir("."); test(dp!=0); count=0; do { ep=readdir(dp); if (ep && strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) count++; } while (ep!=0); test(count==4); for (i=0; i<4; i++) { rewinddir(dp); for (j=0; j<=i; j++) { ep=readdir(dp); test(ep!=0); } strcpy(name,ep->d_name); rewinddir(dp); for (j=0; j<=i; j++) { ep=readdir(dp); test(ep!=0); } test(strcmp(name,ep->d_name)==0); } for (i=0; i<4; i++) { rewinddir(dp); pos=telldir(dp); for (j=0; j<=i; j++) { pos=telldir(dp); ep=readdir(dp); test(ep!=0); } strcpy(name,ep->d_name); rewinddir(dp); seekdir(dp, pos); ep=readdir(dp); test(ep!=0); test(strcmp(name,ep->d_name)==0); } err=closedir(dp); test(err==0); dp=opendir("middle2"); test(dp!=0); count=0; do { ep=readdir(dp); if (ep && strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) count++; } while (ep!=0); test(count==0); /* empty directory */ rewinddir(dp); fd = open("middle2/extrafile",O_RDWR+O_CREAT,0777); test(fd>=0); err=close(fd); test(err==0); count=0; do { ep=readdir(dp); if (ep && strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) count++; } while (ep!=0); test(count==0); /* shouldn't have noticed the change */ rewinddir(dp); /* and spot the new file */ count=0; do { ep=readdir(dp); if (ep && strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) count++; } while (ep!=0); test(count==1); closedir(dp); dp=opendir("/"); test(dp!=0); count=0; do { ep=readdir(dp); if (ep && strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) count++; } while (ep!=0); test(count>0); closedir(dp); }
static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t offset, struct fuse_file_info *fi, int plus) { struct lo_dirp *d = lo_dirp(fi); char *buf; char *p; size_t rem; int err; (void) ino; buf = calloc(size, 1); if (!buf) return (void) fuse_reply_err(req, ENOMEM); if (offset != d->offset) { seekdir(d->dp, offset); d->entry = NULL; d->offset = offset; } p = buf; rem = size; while (1) { size_t entsize; off_t nextoff; if (!d->entry) { errno = 0; d->entry = readdir(d->dp); if (!d->entry) { if (errno && rem == size) { err = errno; goto error; } break; } } nextoff = telldir(d->dp); if (plus) { struct fuse_entry_param e; err = lo_do_lookup(req, ino, d->entry->d_name, &e); if (err) goto error; entsize = fuse_add_direntry_plus(req, p, rem, d->entry->d_name, &e, nextoff); } else { struct stat st = { .st_ino = d->entry->d_ino, .st_mode = d->entry->d_type << 12, }; entsize = fuse_add_direntry(req, p, rem, d->entry->d_name, &st, nextoff); } if (entsize > rem) break; p += entsize; rem -= entsize; d->entry = NULL; d->offset = nextoff; } fuse_reply_buf(req, buf, size - rem); free(buf); return; error: free(buf); fuse_reply_err(req, err); } static void lo_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t offset, struct fuse_file_info *fi) { lo_do_readdir(req, ino, size, offset, fi, 0); }
mph_off_t Mono_Posix_Syscall_telldir (void *dir) { return telldir ((DIR*) dir); }
ATF_TC_BODY(seekdir_basic, tc) { DIR *dp; char *wasname; struct dirent *entry; long here; mkdir("t", 0755); creat("t/a", 0600); creat("t/b", 0600); creat("t/c", 0600); dp = opendir("t"); if ( dp == NULL) atf_tc_fail("Could not open temp directory."); /* skip two for . and .. */ entry = readdir(dp); entry = readdir(dp); /* get first entry */ entry = readdir(dp); here = telldir(dp); /* get second entry */ entry = readdir(dp); wasname = strdup(entry->d_name); if (wasname == NULL) atf_tc_fail("cannot allocate memory"); /* get third entry */ entry = readdir(dp); /* try to return to the position after the first entry */ seekdir(dp, here); entry = readdir(dp); if (entry == NULL) atf_tc_fail("entry 1 not found"); if (strcmp(entry->d_name, wasname) != 0) atf_tc_fail("1st seekdir found wrong name"); /* try again, and throw in a telldir() for good measure */ seekdir(dp, here); here = telldir(dp); entry = readdir(dp); if (entry == NULL) atf_tc_fail("entry 2 not found"); if (strcmp(entry->d_name, wasname) != 0) atf_tc_fail("2nd seekdir found wrong name"); /* One more time, to make sure that telldir() doesn't affect result */ seekdir(dp, here); entry = readdir(dp); if (entry == NULL) atf_tc_fail("entry 3 not found"); if (strcmp(entry->d_name, wasname) != 0) atf_tc_fail("3rd seekdir found wrong name"); closedir(dp); }
static off_t local_telldir(FsContext *ctx, DIR *dir) { return telldir(dir); }
void test() { int err; int loc; DIR *dir; struct dirent *ent; struct dirent ent_r; struct dirent *result; // check bad opendir input dir = opendir("noexist"); assert(!dir); assert(errno == ENOENT); dir = opendir("nocanread"); assert(!dir); assert(errno == EACCES); dir = opendir("foobar/file.txt"); assert(!dir); assert(errno == ENOTDIR); // check bad readdir input dir = opendir("foobar"); closedir(dir); ent = readdir(dir); assert(!ent); assert(errno == EBADF); // check bad readdir_r input dir = opendir("foobar"); closedir(dir); err = readdir_r(dir, NULL, &result); assert(err == EBADF); // // do a normal read with readdir // dir = opendir("foobar"); assert(dir); ent = readdir(dir); assert(!strcmp(ent->d_name, ".")); assert(ent->d_type & DT_DIR); assert(ent->d_reclen == sizeof(*ent)); ent = readdir(dir); assert(!strcmp(ent->d_name, "..")); assert(ent->d_type & DT_DIR); assert(ent->d_reclen == sizeof(*ent)); ent = readdir(dir); assert(!strcmp(ent->d_name, "file.txt")); assert(ent->d_type & DT_REG); assert(ent->d_reclen == sizeof(*ent)); ent = readdir(dir); assert(!ent); // test rewinddir rewinddir(dir); ent = readdir(dir); assert(!strcmp(ent->d_name, ".")); // test seek / tell rewinddir(dir); ent = readdir(dir); assert(!strcmp(ent->d_name, ".")); loc = telldir(dir); ent = readdir(dir); assert(!strcmp(ent->d_name, "..")); ent = readdir(dir); assert(!strcmp(ent->d_name, "file.txt")); seekdir(dir, loc); ent = readdir(dir); assert(!strcmp(ent->d_name, "..")); // // do a normal read with readdir_r // rewinddir(dir); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(&ent_r == result); assert(!strcmp(ent_r.d_name, ".")); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(&ent_r == result); assert(!strcmp(ent_r.d_name, "..")); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(&ent_r == result); assert(!strcmp(ent_r.d_name, "file.txt")); err = readdir_r(dir, &ent_r, &result); assert(!err); assert(!result); err = closedir(dir); assert(!err); puts("success"); }
int main(int argc, char *argv[]) { int i, j, fd, rc, nops, lastOps; int ag_ops = 0; double ag_interval = 0; double ag_rate = 0; double rate, avg_rate, effective_rate; double startTime, curTime, lastTime, interval; time_t timestamp; char * file; rc = MPI_Init(&argc, &argv); if (rc != MPI_SUCCESS) fatal(myrank, "MPI_Init failed: %d\n", rc); rc = MPI_Comm_size(MPI_COMM_WORLD, &nthreads); if (rc != MPI_SUCCESS) fatal(myrank, "MPI_Comm_size failed: %d\n", rc); rc = MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if (rc != MPI_SUCCESS) fatal(myrank, "MPI_Comm_rank failed: %d\n", rc); process_args(argc, argv); timestamp = time(0); if ((myrank == 0) || debug) { printf("%d: %s starting at %s", myrank, hostname, ctime(×tamp)); } /* if we're not measuring creation rates then precreate * the files we're operating on. */ if ((mode != CREATE) && (mode != MKNOD) && !ignore && (mode != UNLINK || recreate)) { /* create the files in reverse order. When we encounter * a file that already exists, assume the remainder of * the files exist to save time. The timed performance * test scripts make use of this behavior. */ for (i = end, j = 0; i >= begin; i -= dirthreads) { sprintf(filename, filefmt, i); fd = open(filename, openflags, 0644); if (fd < 0) { if (errno == EEXIST) break; rc = errno; fatal(myrank, "precreate open(%s) error: %s\n", filename, strerror(rc)); } j++; close(fd); } dmesg("%d: %s pre-created %d files.\n",myrank,hostname,j); rc = MPI_Barrier(MPI_COMM_WORLD); if (rc != MPI_SUCCESS) fatal(myrank, "prep MPI_Barrier failed: %d\n", rc); } if (order == READDIR) { directory = opendir(dir); if (directory == NULL) { rc = errno; fatal(myrank, "opendir(%s) error: %s\n", dir, strerror(rc)); } timestamp = time(0); j = random() % nfiles; dmesg("%d: %s initializing dir offset %u: %s", myrank, hostname, j, ctime(×tamp)); for (i = 0; i <= j; i++) { if ((dir_entry = readdir(directory)) == NULL) { fatal(myrank, "could not read entry number %d " "in directory %s.\n", i, dir); } } timestamp = time(0); dmesg("%d: index %d, filename %s, offset %ld: " "%s initialization complete: %s", myrank, i, dir_entry->d_name, telldir(directory), hostname, ctime(×tamp)); } if (seconds) { act.sa_handler = sigalrm_handler; (void)sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); alarm(seconds); } rc = MPI_Barrier(MPI_COMM_WORLD); if (rc != MPI_SUCCESS) fatal(myrank, "prep MPI_Barrier failed: %d\n", rc); startTime = lastTime = MPI_Wtime(); nops = lastOps = 0; switch (mode) { case CREATE: for (; begin <= end && !alarm_caught; begin += dirthreads) { snprintf(filename, sizeof(filename), filefmt, begin); fd = open(filename, openflags, 0644); if (fd < 0) { rc = errno; if (rc == EINTR && alarm_caught) break; fatal(myrank, "open(%s) error: %s\n", filename, strerror(rc)); } if (with_xattr) { rc = fsetxattr(fd, xattrname, xattrbuf, xattrlen, XATTR_CREATE); if (rc) { rc = errno; if (rc == EINTR && alarm_caught) break; fatal(myrank, "setxattr(%s) error: %s\n", filename, strerror(rc)); } } if (smallwrite) { rc = write(fd, xattrbuf, xattrlen); if (rc < 0) { rc = errno; if (rc == EINTR && alarm_caught) break; fatal(myrank, "write(%s) error: %s\n", filename, strerror(rc)); } } close(fd); nops++; DISPLAY_PROGRESS(); } dmesg("%d: created %d files, last file '%s'.\n", myrank, nops, filename); break; #ifdef HAVE_MDC_LOOKUP case LOOKUP: fd = open(dir, O_RDONLY); if (fd < 0) { fatal(myrank, "open(dir == '%s') error: %s\n", dir, strerror(errno)); } for (; nops < iters && !alarm_caught;) { char *filename = next_file(); rc = llapi_file_lookup(fd, filename); if (rc < 0) { if (((rc = errno) == EINTR) && alarm_caught) break; fatal(myrank, "llapi_file_lookup(%s) " "error: %s\n", filename, strerror(rc)); } nops++; DISPLAY_PROGRESS(); } break; #endif case MKNOD: for (; begin <= end && !alarm_caught; begin += dirthreads) { snprintf(filename, sizeof(filename), filefmt, begin); rc = mknod(filename, S_IFREG | 0644, 0); if (rc) { rc = errno; if (rc == EINTR && alarm_caught) break; fatal(myrank, "mknod(%s) error: %s\n", filename, strerror(rc)); } if (with_xattr) { rc = setxattr(filename, xattrname, xattrbuf, xattrlen, XATTR_CREATE); if (rc) { rc = errno; if (rc == EINTR && alarm_caught) break; fatal(myrank, "setxattr(%s) error: %s\n", filename, strerror(rc)); } } nops++; DISPLAY_PROGRESS(); } break; case OPEN: for (; nops < iters && !alarm_caught;) { file = next_file(); if ((fd = open(file, openflags, 0644)) < 0) { if (((rc = errno) == EINTR) && alarm_caught) break; fatal(myrank, "open(%s) error: %s\n", file, strerror(rc)); } close(fd); nops++; DISPLAY_PROGRESS(); } break; case STAT: for (; begin <= end && !alarm_caught; begin += dirthreads) { sprintf(filename, filefmt, begin); rc = stat(filename, &statbuf); if (rc) { if (((rc = errno) == EINTR) && alarm_caught) break; if (((rc = errno) == ENOENT) && ignore) continue; fatal(myrank, "stat(%s) error: %s\n", filename, strerror(rc)); } nops++; DISPLAY_PROGRESS(); } break; case UNLINK: for (; begin <= end && !alarm_caught; begin += dirthreads) { sprintf(filename, filefmt, begin); rc = unlink(filename); if (rc) { if (((rc = errno) == EINTR) && alarm_caught) break; if ((rc = errno) == ENOENT) { if (ignore) continue; /* no more files to unlink */ break; } fatal(myrank, "unlink(%s) error: %s\n", filename, strerror(rc)); } nops++; DISPLAY_PROGRESS(); } break; case SETXATTR: for (; begin <= end && !alarm_caught; begin += dirthreads) { snprintf(filename, sizeof(filename), filefmt, begin); rc = setxattr(filename, xattrname, xattrbuf, xattrlen, XATTR_CREATE); if (rc) { rc = errno; if (rc == EINTR && alarm_caught) break; if (rc == ENOENT && ignore) continue; fatal(myrank, "setxattr(%s) error: %s\n", filename, strerror(rc)); } nops++; DISPLAY_PROGRESS(); } break; } rc = MPI_Barrier(MPI_COMM_WORLD); if (rc != MPI_SUCCESS) fatal(myrank, "prep MPI_Barrier failed: %d\n", rc); curTime = MPI_Wtime(); interval = curTime - startTime; rate = (double) (nops) / interval; rc = MPI_Reduce(&nops, &ag_ops, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if (rc != MPI_SUCCESS) { fatal(myrank, "Failure in MPI_Reduce of total ops.\n"); } rc = MPI_Reduce(&interval, &ag_interval, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if (rc != MPI_SUCCESS) { fatal(myrank, "Failure in MPI_Reduce of total interval.\n"); } rc = MPI_Reduce(&rate, &ag_rate, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if (rc != MPI_SUCCESS) { fatal(myrank, "Failure in MPI_Reduce of aggregated rate.\n"); } if (myrank == 0) { curTime = MPI_Wtime(); interval = curTime - startTime; effective_rate = (double) ag_ops / interval; avg_rate = (double) ag_ops / ag_interval; printf("Rate: %.2f eff %.2f aggr %.2f avg client %ss/sec " "(total: %d threads %d %ss %d dirs %d threads/dir %.2f secs)\n", effective_rate, ag_rate, avg_rate, cmd, nthreads, ag_ops, cmd, ndirs, dirthreads, interval); if (mode == UNLINK && !recreate && !ignore && ag_ops != nfiles) printf("Warning: only unlinked %d files instead of %d" "\n", ag_ops, nfiles); } if (recreate) { for (begin = beginsave; begin <= end; begin += dirthreads) { sprintf(filename, filefmt, begin); if ((fd = open(filename, openflags, 0644)) < 0) { rc = errno; if (rc == EEXIST) break; fatal(myrank, "recreate open(%s) error: %s\n", filename, strerror(rc)); } close(fd); } } timestamp = time(0); if ((myrank == 0) || debug) { printf("%d: %s finished at %s", myrank, hostname, ctime(×tamp)); } MPI_Finalize(); return(0); }
ulonglong offset() const { return telldir(_dir); }
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) { return telldir(fs->dir); }
/** * FSAL_readdir : * Read the entries of an opened directory. * * \param dir_descriptor (input): * Pointer to the directory descriptor filled by FSAL_opendir. * \param start_position (input): * Cookie that indicates the first object to be read during * this readdir operation. * This should be : * - FSAL_READDIR_FROM_BEGINNING for reading the content * of the directory from the beginning. * - The end_position parameter returned by the previous * call to FSAL_readdir. * \param get_attr_mask (input) * Specify the set of attributes to be retrieved for directory entries. * \param buffersize (input) * The size (in bytes) of the buffer where * the direntries are to be stored. * \param pdirent (output) * Adresse of the buffer where the direntries are to be stored. * \param end_position (output) * Cookie that indicates the current position in the directory. * \param nb_entries (output) * Pointer to the number of entries read during the call. * \param end_of_dir (output) * Pointer to a boolean that indicates if the end of dir * has been reached during the call. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t LUSTREFSAL_readdir(fsal_dir_t *dir_desc, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_cookie_t start_pos, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * p_pdirent, /* OUT */ fsal_cookie_t * p_end_position, /* OUT */ fsal_count_t * p_nb_entries, /* OUT */ fsal_boolean_t * p_end_of_dir /* OUT */ ) { fsal_status_t st; fsal_count_t max_dir_entries; struct dirent *dp; struct dirent dpe; fsal_path_t fsalpath; int rc; lustrefsal_dir_t * p_dir_descriptor = (lustrefsal_dir_t *)dir_desc; lustrefsal_cookie_t start_position; /*****************/ /* sanity checks */ /*****************/ if(!p_dir_descriptor || !p_pdirent || !p_end_position || !p_nb_entries || !p_end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); max_dir_entries = (buffersize / sizeof(fsal_dirent_t)); memcpy( (char *)& start_position.data.cookie, (char *)&start_pos.data, sizeof( off_t ) ) ; /***************************/ /* seek into the directory */ /***************************/ errno = 0; if(start_position.data.cookie == 0) { rewinddir(p_dir_descriptor->p_dir); rc = errno; } else { seekdir(p_dir_descriptor->p_dir, start_position.data.cookie); rc = errno; } if(rc) Return(posix2fsal_error(rc), rc, INDEX_FSAL_readdir); /************************/ /* browse the directory */ /************************/ *p_nb_entries = 0; while(*p_nb_entries < max_dir_entries) { /***********************/ /* read the next entry */ /***********************/ TakeTokenFSCall(); rc = readdir_r(p_dir_descriptor->p_dir, &dpe, &dp); ReleaseTokenFSCall(); if(rc) { rc = errno; Return(posix2fsal_error(rc), rc, INDEX_FSAL_readdir); } /* End of directory */ if(!dp) { *p_end_of_dir = 1; break; } /***********************************/ /* Get information about the entry */ /***********************************/ /* skip . and .. */ if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; /* build the full path of the file into "fsalpath */ if(FSAL_IS_ERROR (st = FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &(p_pdirent[*p_nb_entries].name)))) ReturnStatus(st, INDEX_FSAL_readdir); memcpy(&fsalpath, &(p_dir_descriptor->path), sizeof(fsal_path_t)); st = fsal_internal_appendNameToPath(&fsalpath, &(p_pdirent[*p_nb_entries].name)); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_readdir); /* get object handle */ TakeTokenFSCall(); st = fsal_internal_Path2Handle((fsal_op_context_t *) &p_dir_descriptor->context, &fsalpath, &(p_pdirent[*p_nb_entries].handle)); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_readdir); /************************ * Fills the attributes * ************************/ p_pdirent[*p_nb_entries].attributes.asked_attributes = get_attr_mask; st = LUSTREFSAL_getattrs(&(p_pdirent[*p_nb_entries].handle), (fsal_op_context_t *) &p_dir_descriptor->context, &p_pdirent[*p_nb_entries].attributes); if(FSAL_IS_ERROR(st)) { FSAL_CLEAR_MASK(p_pdirent[*p_nb_entries].attributes.asked_attributes); FSAL_SET_MASK(p_pdirent[*p_nb_entries].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); } ((lustrefsal_cookie_t *) (&p_pdirent[*p_nb_entries].cookie))->data.cookie = telldir(p_dir_descriptor->p_dir); p_pdirent[*p_nb_entries].nextentry = NULL; if(*p_nb_entries) p_pdirent[*p_nb_entries - 1].nextentry = &(p_pdirent[*p_nb_entries]); memcpy((char *)p_end_position, (char *)&p_pdirent[*p_nb_entries].cookie, sizeof(lustrefsal_cookie_t)); (*p_nb_entries)++; } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); }