staticvoid CheckProcSelf(std::set<std::string>& names) { // We have a good idea of what should be in /proc/self.
ASSERT_TRUE(names.contains("."));
ASSERT_TRUE(names.contains(".."));
ASSERT_TRUE(names.contains("cmdline"));
ASSERT_TRUE(names.contains("fd"));
ASSERT_TRUE(names.contains("stat"));
}
template <typename DirEntT> void ScanEntries(DirEntT** entries, int entry_count,
std::set<std::string>& name_set, std::vector<std::string>& name_list) { for (size_t i = 0; i < static_cast<size_t>(entry_count); ++i) {
name_set.insert(entries[i]->d_name);
name_list.push_back(entries[i]->d_name);
free(entries[i]);
}
free(entries);
}
TEST(dirent, scandir_scandir64) { // Get everything from /proc/self...
dirent** entries; int entry_count = scandir("/proc/self", &entries, nullptr, alphasort);
ASSERT_GE(entry_count, 0);
// Turn the directory entries into a set and vector of the names.
std::set<std::string> name_set;
std::vector<std::string> unsorted_name_list;
ScanEntries(entries, entry_count, name_set, unsorted_name_list);
// No duplicates.
ASSERT_EQ(name_set.size(), unsorted_name_list.size());
// All entries sorted.
std::vector<std::string> sorted_name_list(unsorted_name_list);
std::sort(sorted_name_list.begin(), sorted_name_list.end());
ASSERT_EQ(sorted_name_list, unsorted_name_list);
// scandir64 returned the same results as scandir.
std::set<std::string> name_set64;
std::vector<std::string> unsorted_name_list64;
ScanEntries(entries64, entry_count64, name_set64, unsorted_name_list64);
ASSERT_EQ(name_set, name_set64);
ASSERT_EQ(unsorted_name_list, unsorted_name_list64);
CheckProcSelf(name_set);
}
TEST(dirent, scandirat_scandirat64) { #if !defined(ANDROID_HOST_MUSL) // Get everything from /proc/self...
dirent** entries; int entry_count = scandir("/proc/self", &entries, nullptr, alphasort);
ASSERT_GE(entry_count, 0);
int proc_fd = open("/proc", O_DIRECTORY);
ASSERT_NE(-1, proc_fd);
TEST(dirent, readdir) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != nullptr);
std::set<std::string> name_set;
errno = 0;
dirent* e; while ((e = readdir(d)) != nullptr) {
name_set.insert(e->d_name);
} // Reading to the end of the directory is not an error. // readdir(3) returns NULL, but leaves errno as 0.
ASSERT_ERRNO(0);
ASSERT_EQ(closedir(d), 0);
CheckProcSelf(name_set);
}
TEST(dirent, readdir64_smoke) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != nullptr);
std::set<std::string> name_set;
errno = 0;
dirent64* e; while ((e = readdir64(d)) != nullptr) {
name_set.insert(e->d_name);
} // Reading to the end of the directory is not an error. // readdir64(3) returns NULL, but leaves errno as 0.
ASSERT_ERRNO(0);
ASSERT_EQ(closedir(d), 0);
CheckProcSelf(name_set);
}
TEST(dirent, readdir_r) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != nullptr);
std::set<std::string> name_set;
errno = 0;
dirent storage;
dirent* e = nullptr; while (readdir_r(d, &storage, &e) == 0 && e != nullptr) {
name_set.insert(e->d_name);
} // Reading to the end of the directory is not an error. // readdir_r(3) returns NULL, but leaves errno as 0.
ASSERT_ERRNO(0);
ASSERT_EQ(closedir(d), 0);
CheckProcSelf(name_set);
}
TEST(dirent, readdir64_r_smoke) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != nullptr);
std::set<std::string> name_set;
errno = 0;
dirent64 storage;
dirent64* e = nullptr; while (readdir64_r(d, &storage, &e) == 0 && e != nullptr) {
name_set.insert(e->d_name);
} // Reading to the end of the directory is not an error. // readdir64_r(3) returns NULL, but leaves errno as 0.
ASSERT_ERRNO(0);
ASSERT_EQ(closedir(d), 0);
CheckProcSelf(name_set);
}
TEST(dirent, rewinddir) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != nullptr);
// Get all the names once...
std::vector<std::string> pass1;
dirent* e; while ((e = readdir(d)) != nullptr) {
pass1.push_back(e->d_name);
}
// ...rewind...
rewinddir(d);
// ...and get all the names again.
std::vector<std::string> pass2; while ((e = readdir(d)) != nullptr) {
pass2.push_back(e->d_name);
}
ASSERT_EQ(closedir(d), 0);
// We should have seen the same names in the same order both times.
ASSERT_EQ(pass1.size(), pass2.size()); for (size_t i = 0; i < pass1.size(); ++i) {
ASSERT_EQ(pass1[i], pass2[i]);
}
}
TEST(dirent, seekdir_telldir) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != nullptr);
std::vector<long> offset_list;
std::vector<std::string> name_list;
dirent* e = nullptr;
while ((e = readdir(d)) != nullptr) {
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 != nullptr);
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 != nullptr);
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));
ASSERT_ERRNO_FAILURE(0, nullptr, readdir(d));
ASSERT_EQ(0, closedir(d));
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.