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