Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE_OS_Dirent Class Reference

This class is a wrapper for the dirent.h operations. More...

#include <OS_Dirent.h>

Inheritance diagram for ACE_OS_Dirent:

Inheritance graph
[legend]
List of all members.

Static Public Methods

ACE_DIRopendir (const ACE_TCHAR *filename)
void closedir (ACE_DIR *)
direntreaddir (ACE_DIR *)
int readdir_r (ACE_DIR *dirp, struct dirent *entry, struct dirent **result)
long telldir (ACE_DIR *)
void seekdir (ACE_DIR *, long loc)
void rewinddir (ACE_DIR *)
int scandir (const ACE_TCHAR *dirname, struct dirent **namelist[], int(*selector)(const struct dirent *filename), int(*comparator)(const struct dirent **f1, const struct dirent **f2))

Static Private Methods

ACE_DIRopendir_emulation (const ACE_TCHAR *filename)
int scandir_emulation (const ACE_TCHAR *dirname, dirent **namelist[], int(*selector)(const dirent *entry), int(*comparator)(const dirent **f1, const dirent **f2))
void closedir_emulation (ACE_DIR *)
direntreaddir_emulation (ACE_DIR *)

Detailed Description

This class is a wrapper for the dirent.h operations.

Definition at line 94 of file OS_Dirent.h.


Member Function Documentation

ACE_INLINE void ACE_OS_Dirent::closedir ACE_DIR   [static]
 

Definition at line 39 of file OS_Dirent.inl.

References ACE_DIR, and closedir_emulation.

Referenced by ACE_Dirent::close, ACE_Dirent::open, scandir_emulation, and ACE_Dirent::~ACE_Dirent.

00040 {
00041 #if defined (ACE_HAS_DIRENT)
00042 # if defined (ACE_PSOS)
00043 
00044   u_long result = ::close_dir (&(d->xdir));
00045   delete d;
00046   if (result != 0)
00047     errno = result;
00048 
00049 # else /* ! ACE_PSOS */
00050 
00051 #   if defined (ACE_WIN32)
00052   ACE_OS_Dirent::closedir_emulation (d);
00053   delete [] d->directory_name_;
00054   delete d;
00055 #   else /* ACE_WIN32 */
00056   ::closedir (d);
00057 #   endif /* ACE_WIN32 */
00058 
00059 # endif /* ACE_PSOS */
00060 #else /* ACE_HAS_DIRENT */
00061   ACE_UNUSED_ARG (d);
00062 #endif /* ACE_HAS_DIRENT */
00063 }

void ACE_OS_Dirent::closedir_emulation ACE_DIR   [static, private]
 

Definition at line 71 of file OS_Dirent.cpp.

References ACE_DIR, and ACE_OS_Memory::free.

Referenced by closedir.

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 /* ACE_WIN32 */
00085   ACE_UNUSED_ARG (d);
00086 #endif /* ACE_WIN32 */
00087 }

ACE_INLINE ACE_DIR * ACE_OS_Dirent::opendir const ACE_TCHAR   filename [static]
 

Definition at line 5 of file OS_Dirent.inl.

References ACE_DIR, ACE_NEW_RETURN, and ACE_TCHAR.

Referenced by ACE_Dirent::open, and scandir_emulation.

00006 {
00007 #if defined (ACE_HAS_DIRENT)
00008 #  if defined (ACE_PSOS)
00009   // The pointer to the <ACE_DIR> buffer *must* be passed to
00010   // <ACE_OS_Dirent::closedir> to free it and avoid a memory leak.
00011   ACE_DIR *dir;
00012   u_long result;
00013   ACE_NEW_RETURN (dir, ACE_DIR, 0);
00014   result = ::open_dir (ACE_const_cast (ACE_TCHAR *,
00015                                        filename),
00016                        &dir->xdir);
00017   if (result == 0)
00018     return dir;
00019   else
00020     {
00021       errno = result;
00022       return 0;
00023     }
00024 #  else /* ! ACE_PSOS */
00025 #    if defined (ACE_WIN32)
00026   return ::ACE_OS_Dirent::opendir_emulation (filename);
00027 #    else /* ! ACE_WIN32 */
00028   // VxWorks' ::opendir () is declared with a non-const argument.
00029   return ::opendir (ACE_const_cast (ACE_TCHAR *, filename));
00030 #    endif /* ACE_WIN32 */
00031 #  endif /* ACE_PSOS */
00032 #else
00033   ACE_UNUSED_ARG (filename);
00034   ACE_NOTSUP_RETURN (0);
00035 #endif /* ACE_HAS_DIRENT */
00036 }

ACE_DIR * ACE_OS_Dirent::opendir_emulation const ACE_TCHAR   filename [static, private]
 

Definition at line 17 of file OS_Dirent.cpp.

References ACE_DIR, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_TCHAR, ACE_OS_String::strcat, ACE_OS_String::strcpy, and ACE_OS_String::strlen.

00018 {
00019 #if defined (ACE_WIN32)
00020   ACE_DIR *dir;
00021   ACE_TCHAR extra[3] = {0,0,0};
00022 
00023 /*
00024   Note: the semantics of the win32 function FindFirstFile take the
00025   basename(filename) as a pattern to be matched within the dirname(filename).
00026   This is contrary to the behavior of the posix function readdir which treats
00027   basename(filename) as a directory to be opened and read.
00028 
00029   For this reason, we append a slash-star or backslash-star to the supplied
00030   filename so the result is that FindFirstFile will do what we need.
00031 
00032   According to the documentation for FindFirstFile, either a '/' or a '\' may
00033   be used as a directory name separator.
00034 
00035   Of course, it is necessary to ensure that this is only done if the trailing
00036   filespec is not already there.
00037 
00038   Phil Mesnier
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 /* ACE_WIN32 */
00065   ACE_UNUSED_ARG (filename);
00066   ACE_NOTSUP_RETURN (0);
00067 #endif /* ACE_WIN32 */
00068 }

ACE_INLINE struct dirent * ACE_OS_Dirent::readdir ACE_DIR   [static]
 

Definition at line 66 of file OS_Dirent.inl.

References ACE_DIR, and readdir_emulation.

Referenced by ACE_Dirent::read, readdir_r, and scandir_emulation.

00067 {
00068 #if defined (ACE_HAS_DIRENT)
00069 #  if defined (ACE_PSOS)
00070 
00071   u_long result = ::read_dir (&d->xdir, &d->dirent);
00072   if (0 == result)
00073     return &d->dirent;
00074   else
00075     {
00076       errno = result;
00077       return 0;
00078     }
00079 
00080 #  else /* ! ACE_PSOS */
00081 #    if defined (ACE_WIN32)
00082   return ACE_OS_Dirent::readdir_emulation (d);
00083 #    else /* defined (ACE_WIN32) */
00084   return ::readdir (d);
00085 #    endif /* defined (ACE_WIN32) */
00086 #  endif /* ACE_PSOS */
00087 #else
00088   ACE_UNUSED_ARG (d);
00089   ACE_NOTSUP_RETURN (0);
00090 #endif /* ACE_HAS_DIRENT */
00091 }

dirent * ACE_OS_Dirent::readdir_emulation ACE_DIR   [static, private]
 

Definition at line 90 of file OS_Dirent.cpp.

References ACE_DIR, ACE_TCHAR, ACE_OS_Memory::free, ACE_OS_Memory::malloc, ACE_OS_String::strcpy, and ACE_OS_String::strlen.

Referenced by readdir.

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           // Make sure to close the handle explicitly to avoid a leak!
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 /* ACE_WIN32 */
00137   ACE_UNUSED_ARG (d);
00138   ACE_NOTSUP_RETURN (0);
00139 #endif /* ACE_WIN32 */
00140 }

ACE_INLINE int ACE_OS_Dirent::readdir_r ACE_DIR   dirp,
struct dirent   entry,
struct dirent **    result
[static]
 

Definition at line 94 of file OS_Dirent.inl.

References ACE_DIR, and readdir.

Referenced by ACE_Dirent::read.

00097 {
00098 #if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
00099   ACE_UNUSED_ARG (entry);
00100   // <result> has better not be 0!
00101   *result = ACE_OS_Dirent::readdir (dirp);
00102   if (*result)
00103     return 0; // Keep iterating
00104   else
00105     return 1; // Oops, some type of error!
00106 #elif defined (ACE_HAS_DIRENT)  &&  !defined (ACE_LACKS_READDIR_R)
00107 #  if (defined (sun) && (defined (_POSIX_PTHREAD_SEMANTICS) || \
00108                         (_FILE_OFFSET_BITS == 64))) || \
00109       (!defined (sun) && (defined (ACE_HAS_PTHREADS_STD) || \
00110                          defined (ACE_HAS_PTHREADS_DRAFT7) || \
00111                          defined (__USE_POSIX) || \
00112                          defined (HPUX_11)))
00113 #    if defined (__GNUG__) && defined (DIGITAL_UNIX)
00114   return readdir_r (dirp, entry, result);
00115 #    else
00116   return ::readdir_r (dirp, entry, result);
00117 #    endif /* defined (__GNUG__) && defined (DIGITAL_UNIX) */
00118 #  else  /* ! POSIX.1c - this is draft 4 or draft 6 */
00119 #    if defined (HPUX_10)   /* But HP 10.x doesn't follow the draft either */
00120     *result = entry;
00121     return ::readdir_r (dirp, entry);
00122 #    else
00123     // <result> had better not be 0!
00124     *result = ::readdir_r (dirp, entry);
00125     return 0;
00126 #    endif /* HPUX_10 */
00127 #  endif /* ! POSIX.1c */
00128 #else  /* ! ACE_HAS_DIRENT  ||  ACE_LACKS_READDIR_R */
00129   ACE_UNUSED_ARG (dirp);
00130   ACE_UNUSED_ARG (entry);
00131   ACE_UNUSED_ARG (result);
00132   ACE_NOTSUP_RETURN (0);
00133 
00134 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
00135 }

ACE_INLINE void ACE_OS_Dirent::rewinddir ACE_DIR   [static]
 

Definition at line 160 of file OS_Dirent.inl.

References ACE_DIR.

Referenced by ACE_Dirent::rewind.

00161 {
00162 #if defined (ACE_HAS_DIRENT)
00163 # if defined (ACE_LACKS_SEEKDIR)
00164 #  if defined (ACE_LACKS_REWINDDIR)
00165   ACE_UNUSED_ARG (d);
00166 #  else /* ! defined (ACE_LACKS_REWINDDIR) */
00167    ::rewinddir (d);
00168 #  endif /* ! defined (ACE_LACKS_REWINDDIR) */
00169 # else  /* ! ACE_LACKS_SEEKDIR */
00170     // We need to implement <rewinddir> using <seekdir> since it's often
00171     // defined as a macro...
00172    ::seekdir (d, long (0));
00173 # endif /* ! ACE_LACKS_SEEKDIR */
00174 #else
00175   ACE_UNUSED_ARG (d);
00176 #endif /* ACE_HAS_DIRENT */
00177 }

int ACE_OS_Dirent::scandir const ACE_TCHAR   dirname,
struct dirent **    namelist[],
int(*    selector)(const struct dirent *filename),
int(*    comparator)(const struct dirent **f1, const struct dirent **f2)
[static]
 

Referenced by ACE_Dirent_Selector::open.

int ACE_OS_Dirent::scandir_emulation const ACE_TCHAR   dirname,
dirent **    namelist[],
int(*    selector)(const dirent *entry),
int(*    comparator)(const dirent **f1, const dirent **f2)
[static, private]
 

Definition at line 148 of file OS_Dirent.cpp.

References ACE_DIR, ACE_SCANDIR_COMPARATOR, ACE_TCHAR, closedir, ACE_OS_Memory::free, ACE_OS_Memory::malloc, ACE_OS_String::memcpy, opendir, ACE_OS::qsort, readdir, ACE_OS_Memory::realloc, ACE_OS_String::strcpy, and ACE_OS_String::strlen.

00153 {
00154   ACE_DIR *dirp = ACE_OS_Dirent::opendir (dirname);
00155 
00156   if (dirp == 0)
00157     return -1;
00158   // A sanity check here.  "namelist" had better not be zero.
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   // @@ This code shoulduse readdir_r() rather than readdir().
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       // If we get here, we have a dirent that the user likes.
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 /* ACE_LACKS_STRUCT_DIR */
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       // Don't use memcpy here since d_name is now a pointer
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 /* ACE_LACKS_STRUCT_DIR */
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 /* ACE_LACKS_STRUCT_DIR */
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 }

ACE_INLINE void ACE_OS_Dirent::seekdir ACE_DIR  ,
long    loc
[static]
 

Definition at line 149 of file OS_Dirent.inl.

References ACE_DIR.

Referenced by ACE_Dirent::seek.

00150 {
00151 #if defined (ACE_HAS_DIRENT)  &&  !defined (ACE_LACKS_SEEKDIR)
00152   ::seekdir (d, loc);
00153 #else  /* ! ACE_HAS_DIRENT  ||  ACE_LACKS_SEEKDIR */
00154   ACE_UNUSED_ARG (d);
00155   ACE_UNUSED_ARG (loc);
00156 #endif /* ! ACE_HAS_DIRENT  ||  ACE_LACKS_SEEKDIR */
00157 }

ACE_INLINE long ACE_OS_Dirent::telldir ACE_DIR   [static]
 

Definition at line 138 of file OS_Dirent.inl.

References ACE_DIR.

Referenced by ACE_Dirent::tell.

00139 {
00140 #if defined (ACE_HAS_DIRENT)  &&  !defined (ACE_LACKS_TELLDIR)
00141   return ::telldir (d);
00142 #else  /* ! ACE_HAS_DIRENT  ||  ACE_LACKS_TELLDIR */
00143   ACE_UNUSED_ARG (d);
00144   ACE_NOTSUP_RETURN (-1);
00145 #endif /* ! ACE_HAS_DIRENT  ||  ACE_LACKS_TELLDIR */
00146 }


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:51:47 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002