00001
00002
00003 #include "ace/OS_NS_dirent.h"
00004
00005 ACE_RCSID(ace, OS_NS_dirent, "OS_NS_dirent.cpp,v 1.8 2006/06/08 11:59:22 jtc Exp")
00006
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_dirent.inl"
00009 #endif
00010
00011 #include "ace/OS_NS_errno.h"
00012 #include "ace/OS_NS_string.h"
00013 #include "ace/Log_Msg.h"
00014 #include "ace/OS_NS_stdlib.h"
00015
00016
00017
00018 #if defined (ACE_WIN32) && defined (_MSC_VER)
00019 extern "C"
00020 {
00021 typedef int (__cdecl *ACE_SCANDIR_COMPARATOR) (const void *, const void *);
00022 }
00023 #else
00024 extern "C"
00025 {
00026 typedef int (*ACE_SCANDIR_COMPARATOR) (const void *, const void *);
00027 }
00028 #endif
00029
00030
00031
00032
00033
00034
00035 #if defined (ACE_WIN32)
00036 # if !defined (INVALID_FILE_ATTRIBUTES)
00037 # define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
00038 # endif
00039 # if !defined (INVALID_SET_FILE_POINTER)
00040 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
00041 # endif
00042 #endif
00043
00044 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00045
00046 #if defined (ACE_LACKS_CLOSEDIR)
00047 void
00048 ACE_OS::closedir_emulation (ACE_DIR *d)
00049 {
00050 #if defined (ACE_WIN32)
00051 if (d->current_handle_ != INVALID_HANDLE_VALUE)
00052 ::FindClose (d->current_handle_);
00053
00054 d->current_handle_ = INVALID_HANDLE_VALUE;
00055 d->started_reading_ = 0;
00056 if (d->dirent_ != 0)
00057 {
00058 ACE_OS::free (d->dirent_->d_name);
00059 ACE_OS::free (d->dirent_);
00060 }
00061 #else
00062 ACE_UNUSED_ARG (d);
00063 #endif
00064 }
00065 #endif
00066
00067 #if defined (ACE_LACKS_OPENDIR)
00068 ACE_DIR *
00069 ACE_OS::opendir_emulation (const ACE_TCHAR *filename)
00070 {
00071 #if defined (ACE_WIN32)
00072 ACE_DIR *dir;
00073 ACE_TCHAR extra[3] = {0,0,0};
00074
00075
00076 DWORD fileAttribute = ACE_TEXT_GetFileAttributes (filename);
00077 if (fileAttribute == INVALID_FILE_ATTRIBUTES
00078 || !(fileAttribute & FILE_ATTRIBUTE_DIRECTORY))
00079 return 0;
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 size_t lastchar = ACE_OS::strlen (filename);
00100 if (lastchar > 0)
00101 {
00102 if (filename[lastchar-1] != '*')
00103 {
00104 if (filename[lastchar-1] != '/' && filename[lastchar-1] != '\\')
00105 ACE_OS::strcpy (extra, ACE_LIB_TEXT ("/*"));
00106 else
00107 ACE_OS::strcpy (extra, ACE_LIB_TEXT ("*"));
00108 }
00109 }
00110
00111 ACE_NEW_RETURN (dir, ACE_DIR, 0);
00112 ACE_NEW_RETURN (dir->directory_name_,
00113 ACE_TCHAR[lastchar + ACE_OS::strlen (extra) + 1],
00114 0);
00115 ACE_OS::strcpy (dir->directory_name_, filename);
00116 if (extra[0])
00117 ACE_OS::strcat (dir->directory_name_, extra);
00118 dir->current_handle_ = INVALID_HANDLE_VALUE;
00119 dir->started_reading_ = 0;
00120 dir->dirent_ = 0;
00121 return dir;
00122 #else
00123 ACE_UNUSED_ARG (filename);
00124 ACE_NOTSUP_RETURN (0);
00125 #endif
00126 }
00127 #endif
00128
00129 #if defined (ACE_LACKS_READDIR)
00130 struct ACE_DIRENT *
00131 ACE_OS::readdir_emulation (ACE_DIR *d)
00132 {
00133 #if defined (ACE_WIN32)
00134 if (d->dirent_ != 0)
00135 {
00136 ACE_OS::free (d->dirent_->d_name);
00137 ACE_OS::free (d->dirent_);
00138 d->dirent_ = 0;
00139 }
00140
00141 if (!d->started_reading_)
00142 {
00143 d->current_handle_ = ACE_TEXT_FindFirstFile (d->directory_name_,
00144 &d->fdata_);
00145 d->started_reading_ = 1;
00146 }
00147 else
00148 {
00149 int retval = ACE_TEXT_FindNextFile (d->current_handle_,
00150 &d->fdata_);
00151 if (retval == 0)
00152 {
00153
00154 ::FindClose (d->current_handle_);
00155 d->current_handle_ = INVALID_HANDLE_VALUE;
00156 }
00157 }
00158
00159 if (d->current_handle_ != INVALID_HANDLE_VALUE)
00160 {
00161 d->dirent_ = (ACE_DIRENT *)
00162 ACE_OS::malloc (sizeof (ACE_DIRENT));
00163
00164 if (d->dirent_ != 0)
00165 {
00166 d->dirent_->d_name = (ACE_TCHAR*)
00167 ACE_OS::malloc ((ACE_OS::strlen (d->fdata_.cFileName) + 1)
00168 * sizeof (ACE_TCHAR));
00169 ACE_OS::strcpy (d->dirent_->d_name, d->fdata_.cFileName);
00170 d->dirent_->d_reclen = sizeof (ACE_DIRENT);
00171 }
00172
00173 return d->dirent_;
00174 }
00175 else
00176 return 0;
00177 #else
00178 ACE_UNUSED_ARG (d);
00179 ACE_NOTSUP_RETURN (0);
00180 #endif
00181 }
00182 #endif
00183
00184 #if !defined (ACE_HAS_SCANDIR)
00185 int
00186 ACE_OS::scandir_emulation (const ACE_TCHAR *dirname,
00187 ACE_DIRENT **namelist[],
00188 int (*selector) (const ACE_DIRENT *entry),
00189 int (*comparator) (const ACE_DIRENT **f1,
00190 const ACE_DIRENT **f2))
00191 {
00192 ACE_DIR *dirp = ACE_OS::opendir (dirname);
00193
00194 if (dirp == 0)
00195 return -1;
00196
00197 else if (namelist == 0)
00198 return -1;
00199
00200 ACE_DIRENT **vector = 0;
00201 ACE_DIRENT *dp = 0;
00202 int arena_size = 0;
00203
00204 int nfiles = 0;
00205 int fail = 0;
00206
00207
00208 for (dp = ACE_OS::readdir (dirp);
00209 dp != 0;
00210 dp = ACE_OS::readdir (dirp))
00211 {
00212 if (selector && (*selector)(dp) == 0)
00213 continue;
00214
00215
00216 if (nfiles == arena_size)
00217 {
00218 ACE_DIRENT **newv = 0;
00219 if (arena_size == 0)
00220 arena_size = 10;
00221 else
00222 arena_size *= 2;
00223
00224 newv = (ACE_DIRENT **) ACE_OS::realloc (vector,
00225 arena_size * sizeof (ACE_DIRENT *));
00226 if (newv == 0)
00227 {
00228 fail = 1;
00229 break;
00230 }
00231 vector = newv;
00232 }
00233
00234 #if defined (ACE_LACKS_STRUCT_DIR)
00235 ACE_DIRENT *newdp = (ACE_DIRENT *) ACE_OS::malloc (sizeof (ACE_DIRENT));
00236 #else
00237 size_t dsize =
00238 sizeof (ACE_DIRENT) +
00239 ((ACE_OS::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
00240 ACE_DIRENT *newdp = (ACE_DIRENT *) ACE_OS::malloc (dsize);
00241 #endif
00242
00243 if (newdp == 0)
00244 {
00245 fail = 1;
00246 break;
00247 }
00248
00249 #if defined (ACE_LACKS_STRUCT_DIR)
00250 newdp->d_name = (ACE_TCHAR*) ACE_OS::malloc (
00251 (ACE_OS::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
00252
00253 if (newdp->d_name == 0)
00254 {
00255 fail = 1;
00256 ACE_OS::free (newdp);
00257 break;
00258 }
00259
00260
00261 newdp->d_ino = dp->d_ino;
00262 newdp->d_off = dp->d_off;
00263 newdp->d_reclen = dp->d_reclen;
00264 ACE_OS::strcpy (newdp->d_name, dp->d_name);
00265 vector[nfiles++] = newdp;
00266 #else
00267 vector[nfiles++] = (ACE_DIRENT *) ACE_OS::memcpy (newdp, dp, dsize);
00268 #endif
00269 }
00270
00271 if (fail)
00272 {
00273 ACE_OS::closedir (dirp);
00274 while (nfiles-- > 0)
00275 {
00276 #if defined (ACE_LACKS_STRUCT_DIR)
00277 ACE_OS::free (vector[nfiles]->d_name);
00278 #endif
00279 ACE_OS::free (vector[nfiles]);
00280 }
00281 ACE_OS::free (vector);
00282 return -1;
00283 }
00284
00285 ACE_OS::closedir (dirp);
00286
00287 *namelist = vector;
00288
00289 if (comparator)
00290 ACE_OS::qsort (*namelist,
00291 nfiles,
00292 sizeof (ACE_DIRENT *),
00293 (ACE_SCANDIR_COMPARATOR) comparator);
00294
00295 return nfiles;
00296 }
00297 #endif
00298
00299 ACE_END_VERSIONED_NAMESPACE_DECL