posix_dir_entries.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // $Id$
  3. //
  4. #include<__vic/posix/dir_entries.h>
  5. #include<__vic/throw_errno.h>
  6. #include<cerrno>
  7. namespace __vic { namespace posix {
  8. //----------------------------------------------------------------------------
  9. // True for "." and ".." entries
  10. inline bool dir_entries::is_special(const char *f)
  11. {
  12. return *f == '.' && (f[1] == '\0' || (f[1] == '.' && f[2] == '\0'));
  13. }
  14. //----------------------------------------------------------------------------
  15. dir_entries::dir_entries(const char *path)
  16. : dir(::opendir(path))
  17. {
  18. }
  19. //----------------------------------------------------------------------------
  20. dir_entries::~dir_entries()
  21. {
  22. if(is_open()) ::closedir(dir);
  23. }
  24. //----------------------------------------------------------------------------
  25. bool dir_entries::reopen(const char *path)
  26. {
  27. if(is_open()) close();
  28. DIR *d = ::opendir(path);
  29. if(!d) return false;
  30. dir = d;
  31. return true;
  32. }
  33. //----------------------------------------------------------------------------
  34. void dir_entries::close()
  35. {
  36. if(::closedir(dir)) throw_errno("closedir");
  37. dir = nullptr;
  38. }
  39. //----------------------------------------------------------------------------
  40. const char *dir_entries::next()
  41. {
  42. for(;;)
  43. {
  44. #ifdef __VIC_USE_READDIR
  45. errno = 0;
  46. if(dirent *p = ::readdir(dir))
  47. {
  48. if(!is_special(p->d_name))
  49. {
  50. entry = p;
  51. return p->d_name;
  52. }
  53. }
  54. else // no more entries or error
  55. {
  56. if(int err = errno) throw_errno("readdir", err);
  57. return nullptr; // the end is reached
  58. }
  59. #else // use readdir_r()
  60. dirent *p;
  61. int err = ::readdir_r(dir, &entry, &p);
  62. if(err
  63. #ifdef _AIX
  64. && err != 9 // no entries
  65. #endif
  66. ) throw_errno("readdir_r", err);
  67. if(!p) return nullptr; // the end is reached
  68. if(!is_special(entry.d_name)) return entry.d_name;
  69. #endif
  70. }
  71. }
  72. //----------------------------------------------------------------------------
  73. void dir_entries::rewind()
  74. {
  75. ::rewinddir(dir);
  76. }
  77. //----------------------------------------------------------------------------
  78. }} // namespace