Changeset 476 for trunk/thirds
- Timestamp:
- May 27, 2014, 10:33:43 AM (11 years ago)
- Location:
- trunk/thirds/dirent-win32
- Files:
-
- 1 deleted
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/thirds/dirent-win32/dirent.h
r379 r476 1 #ifndef DIRENT_INCLUDED 2 #define DIRENT_INCLUDED 1 1 /***************************************************************************** 2 * dirent.h - dirent API for Microsoft Visual Studio 3 * 4 * Copyright (C) 2006 Toni Ronkko 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * ``Software''), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Mar 15, 2011, Toni Ronkko 26 * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0. 27 * 28 * Aug 11, 2010, Toni Ronkko 29 * Added d_type and d_namlen fields to dirent structure. The former is 30 * especially useful for determining whether directory entry represents a 31 * file or a directory. For more information, see 32 * http://www.delorie.com/gnu/docs/glibc/libc_270.html 33 * 34 * Aug 11, 2010, Toni Ronkko 35 * Improved conformance to the standards. For example, errno is now set 36 * properly on failure and assert() is never used. Thanks to Peter Brockam 37 * for suggestions. 38 * 39 * Aug 11, 2010, Toni Ronkko 40 * Fixed a bug in rewinddir(): when using relative directory names, change 41 * of working directory no longer causes rewinddir() to fail. 42 * 43 * Dec 15, 2009, John Cunningham 44 * Added rewinddir member function 45 * 46 * Jan 18, 2008, Toni Ronkko 47 * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string 48 * between multi-byte and unicode representations. This makes the 49 * code simpler and also allows the code to be compiled under MingW. Thanks 50 * to Azriel Fasten for the suggestion. 51 * 52 * Mar 4, 2007, Toni Ronkko 53 * Bug fix: due to the strncpy_s() function this file only compiled in 54 * Visual Studio 2005. Using the new string functions only when the 55 * compiler version allows. 56 * 57 * Nov 2, 2006, Toni Ronkko 58 * Major update: removed support for Watcom C, MS-DOS and Turbo C to 59 * simplify the file, updated the code to compile cleanly on Visual 60 * Studio 2005 with both unicode and multi-byte character strings, 61 * removed rewinddir() as it had a bug. 62 * 63 * Aug 20, 2006, Toni Ronkko 64 * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified 65 * comments by removing SGML tags. 66 * 67 * May 14 2002, Toni Ronkko 68 * Embedded the function definitions directly to the header so that no 69 * source modules need to be included in the Visual Studio project. Removed 70 * all the dependencies to other projects so that this very header can be 71 * used independently. 72 * 73 * May 28 1998, Toni Ronkko 74 * First version. 75 *****************************************************************************/ 76 #ifndef DIRENT_H 77 #define DIRENT_H 78 79 #define WIN32_LEAN_AND_MEAN 80 #include <windows.h> 81 #include <string.h> 82 #include <stdlib.h> 83 #include <sys/types.h> 84 #include <sys/stat.h> 85 #include <errno.h> 86 87 /* Entries missing from MSVC 6.0 */ 88 #if !defined(FILE_ATTRIBUTE_DEVICE) 89 # define FILE_ATTRIBUTE_DEVICE 0x40 90 #endif 91 92 /* File type and permission flags for stat() */ 93 #if defined(_MSC_VER) && !defined(S_IREAD) 94 # define S_IFMT _S_IFMT /* file type mask */ 95 # define S_IFDIR _S_IFDIR /* directory */ 96 # define S_IFCHR _S_IFCHR /* character device */ 97 # define S_IFFIFO _S_IFFIFO /* pipe */ 98 # define S_IFREG _S_IFREG /* regular file */ 99 # define S_IREAD _S_IREAD /* read permission */ 100 # define S_IWRITE _S_IWRITE /* write permission */ 101 # define S_IEXEC _S_IEXEC /* execute permission */ 102 #endif 103 #define S_IFBLK 0 /* block device */ 104 #define S_IFLNK 0 /* link */ 105 #define S_IFSOCK 0 /* socket */ 106 107 #if defined(_MSC_VER) 108 # define S_IRUSR S_IREAD /* read, user */ 109 # define S_IWUSR S_IWRITE /* write, user */ 110 # define S_IXUSR 0 /* execute, user */ 111 # define S_IRGRP 0 /* read, group */ 112 # define S_IWGRP 0 /* write, group */ 113 # define S_IXGRP 0 /* execute, group */ 114 # define S_IROTH 0 /* read, others */ 115 # define S_IWOTH 0 /* write, others */ 116 # define S_IXOTH 0 /* execute, others */ 117 #endif 118 119 /* Indicates that d_type field is available in dirent structure */ 120 #define _DIRENT_HAVE_D_TYPE 121 122 /* File type flags for d_type */ 123 #define DT_LNK -100 124 #define DT_UNKNOWN 0 125 #define DT_REG S_IFREG 126 #define DT_DIR S_IFDIR 127 #define DT_FIFO S_IFFIFO 128 #define DT_SOCK S_IFSOCK 129 #define DT_CHR S_IFCHR 130 #define DT_BLK S_IFBLK 131 132 /* Macros for converting between st_mode and d_type */ 133 #define IFTODT(mode) ((mode) & S_IFMT) 134 #define DTTOIF(type) (type) 3 135 4 136 /* 5 6 Declaration of POSIX directory browsing functions and types for Win32. 7 8 Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) 9 History: Created March 1997. Updated June 2003. 10 Rights: See end of file. 11 12 */ 137 * File type macros. Note that block devices, sockets and links cannot be 138 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are 139 * only defined for compatibility. These macros should always return false 140 * on Windows. 141 */ 142 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) 143 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) 144 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) 145 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) 146 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) 147 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) 148 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) 13 149 14 150 #ifdef __cplusplus 15 extern "C" 16 { 17 #endif 18 19 typedef struct DIR DIR; 20 21 struct dirent 22 { 23 char *d_name; 24 }; 25 26 DIR *opendir(const char *); 27 int closedir(DIR *); 28 struct dirent *readdir(DIR *); 29 void rewinddir(DIR *); 30 31 /* 32 33 Copyright Kevlin Henney, 1997, 2003. All rights reserved. 34 35 Permission to use, copy, modify, and distribute this software and its 36 documentation for any purpose is hereby granted without fee, provided 37 that this copyright and permissions notice appear in all copies and 38 derivatives. 39 40 This software is supplied "as is" without express or implied warranty. 41 42 But that said, if there are any problems please get in touch. 43 44 */ 151 extern "C" { 152 #endif 153 154 155 typedef struct dirent 156 { 157 char d_name[MAX_PATH + 1]; /* File name */ 158 size_t d_namlen; /* Length of name without \0 */ 159 int d_type; /* File type */ 160 } dirent; 161 162 163 typedef struct DIR 164 { 165 dirent curentry; /* Current directory entry */ 166 WIN32_FIND_DATAA find_data; /* Private file data */ 167 int cached; /* True if data is valid */ 168 HANDLE search_handle; /* Win32 search handle */ 169 char patt[MAX_PATH + 3]; /* Initial directory name */ 170 } DIR; 171 172 173 /* Forward declarations */ 174 static DIR *opendir(const char *dirname); 175 static struct dirent *readdir(DIR *dirp); 176 static int closedir(DIR *dirp); 177 static void rewinddir(DIR* dirp); 178 179 180 /* Use the new safe string functions introduced in Visual Studio 2005 */ 181 #if defined(_MSC_VER) && _MSC_VER >= 1400 182 # define DIRENT_STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE) 183 #else 184 # define DIRENT_STRNCPY(dest,src,size) strncpy((dest),(src),(size)) 185 #endif 186 187 /* Set errno variable */ 188 #if defined(_MSC_VER) 189 #define DIRENT_SET_ERRNO(x) _set_errno (x) 190 #else 191 #define DIRENT_SET_ERRNO(x) (errno = (x)) 192 #endif 193 194 195 196 /***************************************************************************** 197 * Open directory stream DIRNAME for read and return a pointer to the 198 * internal working area that is used to retrieve individual directory 199 * entries. 200 */ 201 static DIR *opendir(const char *dirname) 202 { 203 DIR *dirp; 204 205 /* ensure that the resulting search pattern will be a valid file name */ 206 if (dirname == NULL) { 207 DIRENT_SET_ERRNO (ENOENT); 208 return NULL; 209 } 210 if (strlen (dirname) + 3 >= MAX_PATH) { 211 DIRENT_SET_ERRNO (ENAMETOOLONG); 212 return NULL; 213 } 214 215 /* construct new DIR structure */ 216 dirp = (DIR*) malloc (sizeof (struct DIR)); 217 if (dirp != NULL) { 218 int error; 219 220 /* 221 * Convert relative directory name to an absolute one. This 222 * allows rewinddir() to function correctly when the current working 223 * directory is changed between opendir() and rewinddir(). 224 */ 225 if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) { 226 char *p; 227 228 /* append the search pattern "\\*\0" to the directory name */ 229 p = strchr (dirp->patt, '\0'); 230 if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') { 231 *p++ = '\\'; 232 } 233 *p++ = '*'; 234 *p = '\0'; 235 236 /* open directory stream and retrieve the first entry */ 237 dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); 238 if (dirp->search_handle != INVALID_HANDLE_VALUE) { 239 /* a directory entry is now waiting in memory */ 240 dirp->cached = 1; 241 error = 0; 242 } else { 243 /* search pattern is not a directory name? */ 244 DIRENT_SET_ERRNO (ENOENT); 245 error = 1; 246 } 247 } else { 248 /* buffer too small */ 249 DIRENT_SET_ERRNO (ENOMEM); 250 error = 1; 251 } 252 253 if (error) { 254 free (dirp); 255 dirp = NULL; 256 } 257 } 258 259 return dirp; 260 } 261 262 263 /***************************************************************************** 264 * Read a directory entry, and return a pointer to a dirent structure 265 * containing the name of the entry in d_name field. Individual directory 266 * entries returned by this very function include regular files, 267 * sub-directories, pseudo-directories "." and "..", but also volume labels, 268 * hidden files and system files may be returned. 269 */ 270 static struct dirent *readdir(DIR *dirp) 271 { 272 DWORD attr; 273 if (dirp == NULL) { 274 /* directory stream did not open */ 275 DIRENT_SET_ERRNO (EBADF); 276 return NULL; 277 } 278 279 /* get next directory entry */ 280 if (dirp->cached != 0) { 281 /* a valid directory entry already in memory */ 282 dirp->cached = 0; 283 } else { 284 /* get the next directory entry from stream */ 285 if (dirp->search_handle == INVALID_HANDLE_VALUE) { 286 return NULL; 287 } 288 if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) { 289 /* the very last entry has been processed or an error occured */ 290 FindClose (dirp->search_handle); 291 dirp->search_handle = INVALID_HANDLE_VALUE; 292 return NULL; 293 } 294 } 295 296 /* copy as a multibyte character string */ 297 DIRENT_STRNCPY ( dirp->curentry.d_name, 298 dirp->find_data.cFileName, 299 sizeof(dirp->curentry.d_name) ); 300 dirp->curentry.d_name[MAX_PATH] = '\0'; 301 302 /* compute the length of name */ 303 dirp->curentry.d_namlen = strlen (dirp->curentry.d_name); 304 305 /* determine file type */ 306 attr = dirp->find_data.dwFileAttributes; 307 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { 308 dirp->curentry.d_type = DT_CHR; 309 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { 310 dirp->curentry.d_type = DT_DIR; 311 } else { 312 dirp->curentry.d_type = DT_REG; 313 } 314 return &dirp->curentry; 315 } 316 317 318 /***************************************************************************** 319 * Close directory stream opened by opendir() function. Close of the 320 * directory stream invalidates the DIR structure as well as any previously 321 * read directory entry. 322 */ 323 static int closedir(DIR *dirp) 324 { 325 if (dirp == NULL) { 326 /* invalid directory stream */ 327 DIRENT_SET_ERRNO (EBADF); 328 return -1; 329 } 330 331 /* release search handle */ 332 if (dirp->search_handle != INVALID_HANDLE_VALUE) { 333 FindClose (dirp->search_handle); 334 dirp->search_handle = INVALID_HANDLE_VALUE; 335 } 336 337 /* release directory structure */ 338 free (dirp); 339 return 0; 340 } 341 342 343 /***************************************************************************** 344 * Resets the position of the directory stream to which dirp refers to the 345 * beginning of the directory. It also causes the directory stream to refer 346 * to the current state of the corresponding directory, as a call to opendir() 347 * would have done. If dirp does not refer to a directory stream, the effect 348 * is undefined. 349 */ 350 static void rewinddir(DIR* dirp) 351 { 352 if (dirp != NULL) { 353 /* release search handle */ 354 if (dirp->search_handle != INVALID_HANDLE_VALUE) { 355 FindClose (dirp->search_handle); 356 } 357 358 /* open new search handle and retrieve the first entry */ 359 dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); 360 if (dirp->search_handle != INVALID_HANDLE_VALUE) { 361 /* a directory entry is now waiting in memory */ 362 dirp->cached = 1; 363 } else { 364 /* failed to re-open directory: no directory entry in memory */ 365 dirp->cached = 0; 366 } 367 } 368 } 45 369 46 370 #ifdef __cplusplus 47 371 } 48 372 #endif 49 50 #endif 373 #endif /*DIRENT_H*/
Note: See TracChangeset
for help on using the changeset viewer.