1 /* Directory entry code for Window platforms. 2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 3 2006 Free Software Foundation, Inc. 4 This file is part of GNU Make. 5 6 GNU Make is free software; you can redistribute it and/or modify it under the 7 terms of the GNU General Public License as published by the Free Software 8 Foundation; either version 2, or (at your option) any later version. 9 10 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY 11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along with 15 GNU Make; see the file COPYING. If not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ 17 18 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include <errno.h> 22 #include <string.h> 23 #include <stdlib.h> 24 #include "dirent.h" 25 26 27 DIR* 28 opendir(const char* pDirName) 29 { 30 struct stat sb; 31 DIR* pDir; 32 char* pEndDirName; 33 int nBufferLen; 34 35 /* sanity checks */ 36 if (!pDirName) { 37 errno = EINVAL; 38 return NULL; 39 } 40 if (stat(pDirName, &sb) != 0) { 41 errno = ENOENT; 42 return NULL; 43 } 44 if ((sb.st_mode & S_IFMT) != S_IFDIR) { 45 errno = ENOTDIR; 46 return NULL; 47 } 48 49 /* allocate a DIR structure to return */ 50 pDir = (DIR *) malloc(sizeof (DIR)); 51 52 if (!pDir) 53 return NULL; 54 55 /* input directory name length */ 56 nBufferLen = strlen(pDirName); 57 58 /* copy input directory name to DIR buffer */ 59 strcpy(pDir->dir_pDirectoryName, pDirName); 60 61 /* point to end of the copied directory name */ 62 pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1]; 63 64 /* if directory name did not end in '/' or '\', add '/' */ 65 if ((*pEndDirName != '/') && (*pEndDirName != '\\')) { 66 pEndDirName++; 67 *pEndDirName = '/'; 68 } 69 70 /* now append the wildcard character to the buffer */ 71 pEndDirName++; 72 *pEndDirName = '*'; 73 pEndDirName++; 74 *pEndDirName = '\0'; 75 76 /* other values defaulted */ 77 pDir->dir_nNumFiles = 0; 78 pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; 79 pDir->dir_ulCookie = __DIRENT_COOKIE; 80 81 return pDir; 82 } 83 84 void 85 closedir(DIR *pDir) 86 { 87 /* got a valid pointer? */ 88 if (!pDir) { 89 errno = EINVAL; 90 return; 91 } 92 93 /* sanity check that this is a DIR pointer */ 94 if (pDir->dir_ulCookie != __DIRENT_COOKIE) { 95 errno = EINVAL; 96 return; 97 } 98 99 /* close the WINDOWS32 directory handle */ 100 if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) 101 FindClose(pDir->dir_hDirHandle); 102 103 free(pDir); 104 105 return; 106 } 107 108 struct dirent * 109 readdir(DIR* pDir) 110 { 111 WIN32_FIND_DATA wfdFindData; 112 113 if (!pDir) { 114 errno = EINVAL; 115 return NULL; 116 } 117 118 /* sanity check that this is a DIR pointer */ 119 if (pDir->dir_ulCookie != __DIRENT_COOKIE) { 120 errno = EINVAL; 121 return NULL; 122 } 123 124 if (pDir->dir_nNumFiles == 0) { 125 pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData); 126 if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE) 127 return NULL; 128 } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData)) 129 return NULL; 130 131 /* bump count for next call to readdir() or telldir() */ 132 pDir->dir_nNumFiles++; 133 134 /* fill in struct dirent values */ 135 pDir->dir_sdReturn.d_ino = -1; 136 strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName); 137 138 return &pDir->dir_sdReturn; 139 } 140 141 void 142 rewinddir(DIR* pDir) 143 { 144 if (!pDir) { 145 errno = EINVAL; 146 return; 147 } 148 149 /* sanity check that this is a DIR pointer */ 150 if (pDir->dir_ulCookie != __DIRENT_COOKIE) { 151 errno = EINVAL; 152 return; 153 } 154 155 /* close the WINDOWS32 directory handle */ 156 if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) 157 if (!FindClose(pDir->dir_hDirHandle)) 158 errno = EBADF; 159 160 /* reset members which control readdir() */ 161 pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; 162 pDir->dir_nNumFiles = 0; 163 164 return; 165 } 166 167 int 168 telldir(DIR* pDir) 169 { 170 if (!pDir) { 171 errno = EINVAL; 172 return -1; 173 } 174 175 /* sanity check that this is a DIR pointer */ 176 if (pDir->dir_ulCookie != __DIRENT_COOKIE) { 177 errno = EINVAL; 178 return -1; 179 } 180 181 /* return number of times readdir() called */ 182 return pDir->dir_nNumFiles; 183 } 184 185 void 186 seekdir(DIR* pDir, long nPosition) 187 { 188 if (!pDir) 189 return; 190 191 /* sanity check that this is a DIR pointer */ 192 if (pDir->dir_ulCookie != __DIRENT_COOKIE) 193 return; 194 195 /* go back to beginning of directory */ 196 rewinddir(pDir); 197 198 /* loop until we have found position we care about */ 199 for (--nPosition; nPosition && readdir(pDir); nPosition--); 200 201 /* flag invalid nPosition value */ 202 if (nPosition) 203 errno = EINVAL; 204 205 return; 206 } 207