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