directory_iterator::~directory_iterator() { if(handle) { closedir(DIR_HANDLE(handle)); DIR_HANDLE_FREE(handle); } std::free(buf); }
static mode_t dirstat(void * handle, void * entry) { arx_assert(entry != NULL); int fd = dirfd(DIR_HANDLE(handle)); arx_assert(fd != -1); const char * name = reinterpret_cast<dirent *>(entry)->d_name; struct stat buf; int ret = fstatat(fd, name, &buf, 0); arx_assert_msg(ret == 0, "fstatat failed: %d", ret); ARX_UNUSED(ret); return buf.st_mode; }
directory_iterator::directory_iterator(const path & p) : buf(NULL) { handle = DIR_HANDLE_INIT(p, opendir(p.empty() ? "./" : p.string().c_str())); if(DIR_HANDLE(handle)) { // Allocate a large enough buffer for readdir_r. long name_max; #if ((defined(ARX_HAVE_DIRFD) && defined(ARX_HAVE_FPATHCONF)) || defined(ARX_HAVE_PATHCONF)) \ && defined(ARX_HAVE_PC_NAME_MAX) # if defined(ARX_HAVE_DIRFD) && defined(ARX_HAVE_FPATHCONF) name_max = fpathconf(dirfd(DIR_HANDLE(handle)), _PC_NAME_MAX); #else name_max = pathconf(p.string().c_str(), _PC_NAME_MAX); #endif if(name_max == -1) { # if defined(ARX_HAVE_NAME_MAX) name_max = std::max(NAME_MAX, 255); # else arx_assert_msg(false, "cannot determine maximum dirname size"); # endif } #elif defined(ARX_HAVE_NAME_MAX) name_max = std::max(NAME_MAX, 255); #else # error "buffer size for readdir_r cannot be determined" #endif size_t size = (size_t)offsetof(dirent, d_name) + name_max + 1; if(size < sizeof(dirent)) { size = sizeof(dirent); } buf = malloc(size); readdir(handle, buf); } };
static void readdir(void * _handle, void * & _buf) { DIR * handle = DIR_HANDLE(_handle); dirent * buf = reinterpret_cast<dirent *>(_buf); do { dirent * entry; if(readdir_r(handle, buf, &entry) || !entry) { free(_buf), _buf = NULL; return; } } while(!strcmp(buf->d_name, ".") || !strcmp(buf->d_name, "..")); }