void FileSys::add_dir(Dir& dvec) { // push work dir char pwd_buffer[256]; getcwd(pwd_buffer, sizeof(pwd_buffer)); // go into directory char cwd_buffer[256]; getcwd(cwd_buffer, sizeof(cwd_buffer)); strcat(cwd_buffer, "/"); strcat(cwd_buffer, dvec.name.c_str()); //printf("*** Entering %s...\n", cwd_buffer); chdir(cwd_buffer); auto* dir = opendir(cwd_buffer); if (dir == nullptr) { printf("Could not open directory:\n-> %s\n", cwd_buffer); return; } struct dirent* ent; while ((ent = readdir(dir)) != nullptr) { std::string name(ent->d_name); if (name == ".." || name == ".") continue; if (ent->d_type == DT_DIR) { auto& d = dvec.add_dir(ent->d_name); add_dir(d); } else { dvec.add_file(ent->d_name); } } // pop work dir chdir(pwd_buffer); }
void FileSys::add_dir(Dir& dvec) { // push work dir char pwd_buffer[256]; getcwd(pwd_buffer, sizeof(pwd_buffer)); // go into directory char cwd_buffer[256]; getcwd(cwd_buffer, sizeof(cwd_buffer)); strcat(cwd_buffer, "/"); strcat(cwd_buffer, dvec.name.c_str()); int res = chdir(cwd_buffer); // throw immediately when unable to read directory if (res < 0) { fprintf(stderr, "Unable to enter directory %s: %s\n", cwd_buffer, strerror(errno)); throw std::runtime_error("Unable to enter directory " + std::string(cwd_buffer)); } auto* dir = opendir(cwd_buffer); // throw immediately when unable to open directory if (dir == nullptr) { fprintf(stderr, "Unable to open directory %s: %s\n", cwd_buffer, strerror(errno)); throw std::runtime_error("Unable to open directory " + std::string(cwd_buffer)); } std::vector<std::string> sub_dirs; std::vector<std::string> sub_files; struct dirent* ent; while ((ent = readdir(dir)) != nullptr) { std::string name(ent->d_name); if (name == ".." || name == ".") continue; struct stat buf; int res = lstat(ent->d_name, &buf); if (res < 0) { fprintf(stderr, "Stat failed on %s with error %s\n", ent->d_name, strerror(errno)); continue; } if (S_ISDIR(buf.st_mode)) { sub_dirs.push_back(std::move(name)); } else if (S_ISREG(buf.st_mode)) { sub_files.push_back(std::move(name)); } else { fprintf(stderr, "Encountered unknown entry %s\n", ent->d_name); } } // close directory before adding more folders and files res = closedir(dir); if (res < 0) { fprintf(stderr, "Unable to close directory: %s\n", strerror(errno)); throw std::runtime_error("diskbuilder: Failed to close directory"); } // add sub directories for (const auto& dirname : sub_dirs) { auto& d = dvec.add_dir(dirname.c_str()); add_dir(d); } // add files in current directory for (const auto& filename : sub_files) { try { dvec.add_file(filename.c_str()); } catch (std::exception& e) { fprintf(stderr, "%s\n", e.what()); } } // pop work dir res = chdir(pwd_buffer); if (res < 0) { fprintf(stderr, "Unable to return to parent directory %s: %s\n", pwd_buffer, strerror(errno)); throw std::runtime_error("diskbuilder: Failed to return back to parent directory"); } }