/*! \brief Returns the BDirectory's next entry as an entry_ref. Unlike GetNextDirents() this method ignores the entries "." and "..". \param ref a pointer to an entry_ref to be filled in with the data of the found entry \param traverse specifies whether to follow it, if the found entry is a symbolic link. \note The iterator used be this method is the same one used by GetNextEntry(), GetNextDirents(), Rewind() and CountEntries(). \return - \c B_OK: Everything went fine. - \c B_BAD_VALUE: \c NULL \a ref. - \c B_ENTRY_NOT_FOUND: No more entries found. - \c B_PERMISSION_DENIED: Directory permissions didn't allow operation. - \c B_NO_MEMORY: Insufficient memory for operation. - \c B_LINK_LIMIT: Indicates a cyclic loop within the file system. - \c B_BUSY: A node was busy. - \c B_FILE_ERROR: A general file error. - \c B_NO_MORE_FDS: The application has run out of file descriptors. */ status_t BDirectory::GetNextRef(entry_ref* ref) { status_t error = (ref ? B_OK : B_BAD_VALUE); if (error == B_OK && InitCheck() != B_OK) error = B_FILE_ERROR; if (error == B_OK) { BPrivate::Storage::LongDirEntry entry; bool next = true; while (error == B_OK && next) { if (GetNextDirents(&entry, sizeof(entry), 1) != 1) { error = B_ENTRY_NOT_FOUND; } else { next = (!strcmp(entry.d_name, ".") || !strcmp(entry.d_name, "..")); } } if (error == B_OK) { ref->device = entry.d_pdev; ref->directory = entry.d_pino; error = ref->set_name(entry.d_name); } } return error; }
status_t VirtualDirectoryEntryList::GetNextRef(entry_ref* ref) { BPrivate::Storage::LongDirEntry entry; int32 result = GetNextDirents(&entry, sizeof(entry), 1); if (result < 0) return result; if (result == 0) return B_ENTRY_NOT_FOUND; ref->device = entry.d_pdev; ref->directory = entry.d_pino; return ref->set_name(entry.d_name); }
int32 TNodeWalker::GetNextDirents(struct dirent* ent, size_t size, int32 count) { if (fJustFile != NULL) { if (count == 0) return 0; // simulate GetNextDirents by building a single dirent structure int32 result = build_dirent(fJustFile, ent, size, count); fJustFile = 0; return result; } if (fTopDir == NULL) { // done return 0; } // If requested to include the top directory, return that first. if (fIncludeTopDir) { fIncludeTopDir = false; BEntry entry; if (fTopDir->GetEntry(&entry) < B_OK) return 0; return build_dirent(fJustFile, ent, size, count); } // get the next entry int32 nextDirent = fTopDir->GetNextDirents(ent, size, count); if (nextDirent == 0) { status_t result = PopDirCommon(); if (result != B_OK) return 0; return GetNextDirents(ent, size, count); } // push any directories in the returned entries onto the stack for (int32 i = 0; i < nextDirent; i++) { if (fTopDir->Contains(ent->d_name, B_DIRECTORY_NODE)) { entry_ref ref(ent->d_dev, ent->d_ino, ent->d_name); PushDirCommon(&ref); } ent = (dirent*)((char*)ent + ent->d_reclen); } return nextDirent; }
/*! \brief Returns the number of entries in this directory. CountEntries() uses the directory iterator also used by GetNextEntry(), GetNextRef() and GetNextDirents(). It does a Rewind(), iterates through the entries and Rewind()s again. The entries "." and ".." are not counted. \return - the number of entries in the directory (not counting "." and ".."). - \c B_PERMISSION_DENIED: Directory permissions didn't allow operation. - \c B_NO_MEMORY: Insufficient memory for operation. - \c B_LINK_LIMIT: Indicates a cyclic loop within the file system. - \c B_BUSY: A node was busy. - \c B_FILE_ERROR: A general file error. - \c B_NO_MORE_FDS: The application has run out of file descriptors. \see GetNextEntry(), GetNextRef(), GetNextDirents(), Rewind() */ int32 BDirectory::CountEntries() { status_t error = Rewind(); if (error != B_OK) return error; int32 count = 0; BPrivate::Storage::LongDirEntry entry; while (error == B_OK) { if (GetNextDirents(&entry, sizeof(entry), 1) != 1) break; if (strcmp(entry.d_name, ".") != 0 && strcmp(entry.d_name, "..") != 0) count++; } Rewind(); return (error == B_OK ? count : error); }
int32 TVolWalker::GetNextDirents(struct dirent* ent, size_t size, int32 count) { if (fTopDir == NULL) return B_ENTRY_NOT_FOUND; // get the next dirent status_t result = _inherited::GetNextDirents(ent, size, count); while (result != B_OK) { // we're done with the current volume, go to the next one result = NextVolume(); if (result != B_OK) break; result = GetNextDirents(ent, size, count); } return result; }