dirent.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include "dirent.h"
  7. DIR*
  8. opendir(const char* pDirName)
  9. {
  10. struct stat sb;
  11. DIR* pDir;
  12. char* pEndDirName;
  13. int nBufferLen;
  14. /* sanity checks */
  15. if (!pDirName) {
  16. errno = EINVAL;
  17. return NULL;
  18. }
  19. if (stat(pDirName, &sb) != 0) {
  20. errno = ENOENT;
  21. return NULL;
  22. }
  23. if ((sb.st_mode & S_IFMT) != S_IFDIR) {
  24. errno = ENOTDIR;
  25. return NULL;
  26. }
  27. /* allocate a DIR structure to return */
  28. pDir = (DIR *) malloc(sizeof (DIR));
  29. if (!pDir)
  30. return NULL;
  31. /* input directory name length */
  32. nBufferLen = strlen(pDirName);
  33. /* copy input directory name to DIR buffer */
  34. strcpy(pDir->dir_pDirectoryName, pDirName);
  35. /* point to end of the copied directory name */
  36. pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1];
  37. /* if directory name did not end in '/' or '\', add '/' */
  38. if ((*pEndDirName != '/') && (*pEndDirName != '\\')) {
  39. pEndDirName++;
  40. *pEndDirName = '/';
  41. }
  42. /* now append the wildcard character to the buffer */
  43. pEndDirName++;
  44. *pEndDirName = '*';
  45. pEndDirName++;
  46. *pEndDirName = '\0';
  47. /* other values defaulted */
  48. pDir->dir_nNumFiles = 0;
  49. pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
  50. pDir->dir_ulCookie = __DIRENT_COOKIE;
  51. return pDir;
  52. }
  53. void
  54. closedir(DIR *pDir)
  55. {
  56. /* got a valid pointer? */
  57. if (!pDir) {
  58. errno = EINVAL;
  59. return;
  60. }
  61. /* sanity check that this is a DIR pointer */
  62. if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
  63. errno = EINVAL;
  64. return;
  65. }
  66. /* close the WINDOWS32 directory handle */
  67. if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
  68. FindClose(pDir->dir_hDirHandle);
  69. free(pDir);
  70. return;
  71. }
  72. struct dirent *
  73. readdir(DIR* pDir)
  74. {
  75. WIN32_FIND_DATA wfdFindData;
  76. if (!pDir) {
  77. errno = EINVAL;
  78. return NULL;
  79. }
  80. /* sanity check that this is a DIR pointer */
  81. if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
  82. errno = EINVAL;
  83. return NULL;
  84. }
  85. if (pDir->dir_nNumFiles == 0) {
  86. pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData);
  87. if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE)
  88. return NULL;
  89. } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData))
  90. return NULL;
  91. /* bump count for next call to readdir() or telldir() */
  92. pDir->dir_nNumFiles++;
  93. /* fill in struct dirent values */
  94. pDir->dir_sdReturn.d_ino = -1;
  95. strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName);
  96. return &pDir->dir_sdReturn;
  97. }
  98. void
  99. rewinddir(DIR* pDir)
  100. {
  101. if (!pDir) {
  102. errno = EINVAL;
  103. return;
  104. }
  105. /* sanity check that this is a DIR pointer */
  106. if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
  107. errno = EINVAL;
  108. return;
  109. }
  110. /* close the WINDOWS32 directory handle */
  111. if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
  112. if (!FindClose(pDir->dir_hDirHandle))
  113. errno = EBADF;
  114. /* reset members which control readdir() */
  115. pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
  116. pDir->dir_nNumFiles = 0;
  117. return;
  118. }
  119. int
  120. telldir(DIR* pDir)
  121. {
  122. if (!pDir) {
  123. errno = EINVAL;
  124. return -1;
  125. }
  126. /* sanity check that this is a DIR pointer */
  127. if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
  128. errno = EINVAL;
  129. return -1;
  130. }
  131. /* return number of times readdir() called */
  132. return pDir->dir_nNumFiles;
  133. }
  134. void
  135. seekdir(DIR* pDir, long nPosition)
  136. {
  137. if (!pDir)
  138. return;
  139. /* sanity check that this is a DIR pointer */
  140. if (pDir->dir_ulCookie != __DIRENT_COOKIE)
  141. return;
  142. /* go back to beginning of directory */
  143. rewinddir(pDir);
  144. /* loop until we have found position we care about */
  145. for (--nPosition; nPosition && readdir(pDir); nPosition--);
  146. /* flag invalid nPosition value */
  147. if (nPosition)
  148. errno = EINVAL;
  149. return;
  150. }