LTKCPP-- LLRP Toolkit C Plus Plus Library
|
00001 /* 00002 00003 Implementation of POSIX directory browsing functions and types for Win32. 00004 00005 Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) 00006 History: Created March 1997. Updated June 2003. 00007 Rights: See end of file. 00008 00009 */ 00010 00011 #include "dirent.h" 00012 #include <errno.h> 00013 #include <io.h> /* _findfirst and _findnext set errno iff they return -1 */ 00014 #include <stdlib.h> 00015 #include <string.h> 00016 00017 #ifdef __cplusplus 00018 extern "C" 00019 { 00020 #endif 00021 00022 struct DIR 00023 { 00024 long handle; /* -1 for failed rewind */ 00025 struct _finddata_t info; 00026 struct dirent result; /* d_name null iff first time */ 00027 char *name; /* null-terminated char string */ 00028 }; 00029 00030 DIR *opendir(const char *name) 00031 { 00032 DIR *dir = 0; 00033 00034 if(name && name[0]) 00035 { 00036 size_t base_length = strlen(name); 00037 const char *all = /* search pattern must end with suitable wildcard */ 00038 strchr("/\\", name[base_length - 1]) ? "*" : "/*"; 00039 00040 if((dir = (DIR *) malloc(sizeof *dir)) != 0 && 00041 (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) 00042 { 00043 strcat(strcpy(dir->name, name), all); 00044 00045 if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1) 00046 { 00047 dir->result.d_name = 0; 00048 } 00049 else /* rollback */ 00050 { 00051 free(dir->name); 00052 free(dir); 00053 dir = 0; 00054 } 00055 } 00056 else /* rollback */ 00057 { 00058 free(dir); 00059 dir = 0; 00060 errno = ENOMEM; 00061 } 00062 } 00063 else 00064 { 00065 errno = EINVAL; 00066 } 00067 00068 return dir; 00069 } 00070 00071 int closedir(DIR *dir) 00072 { 00073 int result = -1; 00074 00075 if(dir) 00076 { 00077 if(dir->handle != -1) 00078 { 00079 result = _findclose(dir->handle); 00080 } 00081 00082 free(dir->name); 00083 free(dir); 00084 } 00085 00086 if(result == -1) /* map all errors to EBADF */ 00087 { 00088 errno = EBADF; 00089 } 00090 00091 return result; 00092 } 00093 00094 struct dirent *readdir(DIR *dir) 00095 { 00096 struct dirent *result = 0; 00097 00098 if(dir && dir->handle != -1) 00099 { 00100 if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) 00101 { 00102 result = &dir->result; 00103 result->d_name = dir->info.name; 00104 } 00105 } 00106 else 00107 { 00108 errno = EBADF; 00109 } 00110 00111 return result; 00112 } 00113 00114 void rewinddir(DIR *dir) 00115 { 00116 if(dir && dir->handle != -1) 00117 { 00118 _findclose(dir->handle); 00119 dir->handle = (long) _findfirst(dir->name, &dir->info); 00120 dir->result.d_name = 0; 00121 } 00122 else 00123 { 00124 errno = EBADF; 00125 } 00126 } 00127 00128 #ifdef __cplusplus 00129 } 00130 #endif 00131 00132 /* 00133 00134 Copyright Kevlin Henney, 1997, 2003. All rights reserved. 00135 00136 Permission to use, copy, modify, and distribute this software and its 00137 documentation for any purpose is hereby granted without fee, provided 00138 that this copyright and permissions notice appear in all copies and 00139 derivatives. 00140 00141 This software is supplied "as is" without express or implied warranty. 00142 00143 But that said, if there are any problems please get in touch. 00144 00145 */