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