summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>2001-07-09 20:02:29 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>2001-07-09 20:02:29 +0000
commitb161743f263428a37c8b56c5d2b31698a81000b4 (patch)
treef5daf4d0718ce49c9614f7ac85c78dc9e1a5e550 /ace
parent1ca4201b746610bd8e569f91942ad5bee7c44d82 (diff)
downloadATCD-b161743f263428a37c8b56c5d2b31698a81000b4.tar.gz
ChangeLogTag:Mon Jul 9 06:52:09 2001 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu>
Diffstat (limited to 'ace')
-rw-r--r--ace/Dirent.h4
-rw-r--r--ace/Dirent_Selector.cpp36
-rw-r--r--ace/Dirent_Selector.h64
-rw-r--r--ace/Dirent_Selector.inl13
-rw-r--r--ace/Makefile1
-rw-r--r--ace/Makefile.bor1
-rw-r--r--ace/OS_Dirent.cpp105
-rw-r--r--ace/OS_Dirent.h33
-rw-r--r--ace/OS_Dirent.inl22
-rw-r--r--ace/OS_Memory.h4
-rw-r--r--ace/Reactor.cpp1
-rw-r--r--ace/Service_Object.cpp2
12 files changed, 259 insertions, 27 deletions
diff --git a/ace/Dirent.h b/ace/Dirent.h
index 43ce109683d..0764011cd4d 100644
--- a/ace/Dirent.h
+++ b/ace/Dirent.h
@@ -6,7 +6,7 @@
*
* $Id$
*
- * Define a portable directory-entry manipulation interface.
+ * Define a portable C++ interface to <ACE_OS_Dirent> directory-entry manipulation.
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
@@ -25,7 +25,7 @@
/**
* @class ACE_Dirent
*
- * @brief Define a portable UNIX directory-entry iterator.
+ * @brief Define a portable C++ directory-entry iterator based on the POSIX API.
*/
class ACE_Export ACE_Dirent
{
diff --git a/ace/Dirent_Selector.cpp b/ace/Dirent_Selector.cpp
new file mode 100644
index 00000000000..dce8d7f05ef
--- /dev/null
+++ b/ace/Dirent_Selector.cpp
@@ -0,0 +1,36 @@
+// $Id$
+
+#include "ace/OS.h"
+#include "ace/Dirent_Selector.h"
+
+// Construction/Destruction
+
+ACE_Dirent_Selector::ACE_Dirent_Selector (void)
+ : n_ (0),
+ namelist_ (0)
+{
+}
+
+ACE_Dirent_Selector::~ACE_Dirent_Selector (void)
+{
+}
+
+int
+ACE_Dirent_Selector::open (const ACE_TCHAR *dir,
+ int (*sel)(const dirent *d),
+ int (*cmp) (const dirent **d1,
+ const dirent **d2))
+{
+ n_ = ACE_OS::scandir (dir, &this->namelist_, sel, cmp);
+ return n_;
+}
+
+int
+ACE_Dirent_Selector::close (void)
+{
+ for (--n_; n_>=0; --n_)
+ ACE_OS::free (this->namelist_[n_]);
+
+ ACE_OS::free (this->namelist_);
+ return 0;
+}
diff --git a/ace/Dirent_Selector.h b/ace/Dirent_Selector.h
new file mode 100644
index 00000000000..6f3ea0872fa
--- /dev/null
+++ b/ace/Dirent_Selector.h
@@ -0,0 +1,64 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Dirent_Selector.h
+ *
+ * $Id$
+ *
+ * Define a portable C++ interface to the <ACE_OS_Dirent::scandir> method.
+ *
+ * @author Rich Newman <RNewman@directv.com>
+ */
+//=============================================================================
+
+#ifndef ACE_DIRENT_SELECTOR_H
+#define ACE_DIRENT_SELECTOR_H
+#include "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class ACE_Dirent
+ *
+ * @brief Define a portable C++ directory-entry iterator based on the POSIX <scandir> API.
+ */
+class ACE_Export ACE_Dirent_Selector
+{
+public:
+ /// Constructor
+ ACE_Dirent_Selector (void);
+
+ /// Destructor.
+ virtual ~ACE_Dirent_Selector (void);
+
+ /// Return the length of the list of matching directory entries.
+ int length (void) const;
+
+ /// Return the entry at <index>.
+ dirent *operator[] (const int index) const;
+
+ /// Free up resources.
+ int close (void);
+
+ /// Open the director <dir> and populate the <namelist_> array with
+ /// directory entries that match the <selector> and <comparator>.
+ int open (const ACE_TCHAR *dir,
+ int (*selector)(const dirent *d) = 0,
+ int (*comparator)(const dirent **d1, const dirent **d2) = 0);
+
+protected:
+ /// Ptr to the namelist array.
+ dirent **namelist_;
+
+ /// # of entries in the array.
+ int n_;
+};
+
+#include "ace/Dirent_Selector.inl"
+
+#include "ace/post.h"
+#endif /* ACE_DIRENT_SELECTOR_H */
+
diff --git a/ace/Dirent_Selector.inl b/ace/Dirent_Selector.inl
new file mode 100644
index 00000000000..2bd4f42e024
--- /dev/null
+++ b/ace/Dirent_Selector.inl
@@ -0,0 +1,13 @@
+/* -*- C++ -*- */
+
+ACE_INLINE int
+ACE_Dirent_Selector::length (void) const
+{
+ return n_;
+}
+
+ACE_INLINE dirent *
+ACE_Dirent_Selector::operator[] (const int n) const
+{
+ return this->namelist_[n];
+}
diff --git a/ace/Makefile b/ace/Makefile
index 16d85d03aba..765f2fcf435 100644
--- a/ace/Makefile
+++ b/ace/Makefile
@@ -32,6 +32,7 @@ UTILS_FILES = \
Configuration \
Configuration_Import_Export \
Dirent \
+ Dirent_Selector \
Dynamic \
Flag_Manip \
Functor \
diff --git a/ace/Makefile.bor b/ace/Makefile.bor
index 34dd3e0c4f7..9275f3a9a25 100644
--- a/ace/Makefile.bor
+++ b/ace/Makefile.bor
@@ -49,6 +49,7 @@ OBJFILES = \
$(OBJDIR)\DEV_Connector.obj \
$(OBJDIR)\DEV_IO.obj \
$(OBJDIR)\Dirent.obj \
+ $(OBJDIR)\Dirent_Selector.obj \
$(OBJDIR)\DLL.obj \
$(OBJDIR)\Dump.obj \
$(OBJDIR)\Dynamic.obj \
diff --git a/ace/OS_Dirent.cpp b/ace/OS_Dirent.cpp
index 6f7bfcd3f69..90f3d760eb3 100644
--- a/ace/OS_Dirent.cpp
+++ b/ace/OS_Dirent.cpp
@@ -2,6 +2,8 @@
#include "ace/OS_Dirent.h"
#include "ace/OS_String.h"
+#include "ace/OS_Memory.h"
+#include "ace/Log_Msg.h"
ACE_RCSID(ace, OS_Dirent, "$Id$")
@@ -76,7 +78,7 @@ ACE_OS_Dirent::closedir_emulation (ACE_DIR *d)
#endif /* ACE_WIN32 */
}
-struct dirent *
+dirent *
ACE_OS_Dirent::readdir_emulation (ACE_DIR *d)
{
#if defined (ACE_WIN32)
@@ -116,8 +118,11 @@ ACE_OS_Dirent::readdir_emulation (ACE_DIR *d)
if (d->current_handle_ != INVALID_HANDLE_VALUE)
{
- d->dirent_.d_name = d->fdata_.cFileName;
- return &d->dirent_;
+ d->dirent_ = (dirent *) ACE_OS_Memory::malloc (sizeof (dirent) +
+ ACE_OS_String::strlen (d->fdata_.cFileName));
+ ACE_OS_String::strcpy ((char *) d->dirent_->d_name, d->fdata_.cFileName);
+ d->dirent_->d_reclen = sizeof (dirent) + ACE_OS_String::strlen (d->dirent_->d_name);
+ return d->dirent_;
}
else
return 0;
@@ -126,3 +131,97 @@ ACE_OS_Dirent::readdir_emulation (ACE_DIR *d)
ACE_NOTSUP_RETURN (0);
#endif /* ACE_WIN32 */
}
+
+extern "C"
+{
+ typedef int (*ACE_SCANDIR_COMPARATOR) (const void *, const void *);
+}
+
+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))
+{
+ ACE_DIR *dirp = ACE_OS_Dirent::opendir (dirname);
+
+ if (dirp == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("scandir_emulation cannot open directory %s"),
+ dirname),
+ -1);
+
+ // A sanity check here. "namelist" had better not be zero.
+ if (namelist == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("scandir_emulation namelist == 0!")),
+ -1);
+
+ dirent **vector = 0;
+ dirent *dp;
+ int arena_size = 0;
+
+ int nfiles = 0;
+ int fail = 0;
+
+ // @@ This code shoulduse readdir_r() rather than readdir().
+ for (dp = ACE_OS_Dirent::readdir (dirp);
+ dp != 0;
+ dp = ACE_OS_Dirent::readdir (dirp))
+ {
+ if (selector && (*selector)(dp) == 0)
+ continue;
+
+ // If we get here, we have a dirent that the user likes.
+ if (nfiles == arena_size)
+ {
+ dirent **newv;
+ if (arena_size == 0)
+ arena_size = 10;
+ else
+ arena_size *= 2;
+
+ newv = (dirent **) ACE_OS_Memory::realloc (vector,
+ arena_size * sizeof (dirent *));
+ if (newv == 0)
+ {
+ fail = 1;
+ break;
+ }
+ vector = newv;
+ }
+
+ int dsize = sizeof (dirent) + ACE_OS_String::strlen (dp->d_name) + 1;
+ dirent *newdp = (dirent *) ACE_OS_Memory::malloc (dsize);
+
+ if (newdp == 0)
+ {
+ fail = 1;
+ break;
+ }
+
+ vector[nfiles++] = (dirent *) ACE_OS_String::memcpy (newdp, dp, dsize);
+ }
+
+ if (fail)
+ {
+ ACE_OS_Dirent::closedir (dirp);
+ while (nfiles-- > 0)
+ ACE_OS_Memory::free (vector[nfiles]);
+ ACE_OS_Memory::free (vector);
+ return -1;
+ }
+
+ ACE_OS_Dirent::closedir (dirp);
+
+ *namelist = vector;
+
+ if (comparator)
+ ACE_OS::qsort (*namelist,
+ nfiles,
+ sizeof (dirent *),
+ (ACE_SCANDIR_COMPARATOR) comparator);
+
+ return nfiles;
+}
diff --git a/ace/OS_Dirent.h b/ace/OS_Dirent.h
index 749eb52ac94..ed9f8946b26 100644
--- a/ace/OS_Dirent.h
+++ b/ace/OS_Dirent.h
@@ -12,7 +12,6 @@
*/
//=============================================================================
-
#ifndef ACE_OS_DIRENT_H
#define ACE_OS_DIRENT_H
#include "ace/pre.h"
@@ -44,24 +43,24 @@ struct dirent {
unsigned short d_ino;
unsigned short d_off;
unsigned short d_reclen;
- const ACE_TCHAR *d_name;
+ const ACE_TCHAR d_name[1];
};
struct ACE_DIR {
+ /// The name of the directory we are looking into
ACE_TCHAR *directory_name_;
- // The name of the directory we are looking into
+ /// Remember the handle between calls.
HANDLE current_handle_;
- // Remember the handle between calls.
- dirent dirent_;
- // The struct for the results
+ /// The struct for the results
+ dirent *dirent_;
+ /// The struct for intermediate results.
ACE_TEXT_WIN32_FIND_DATA fdata_;
- // The struct for intermediate results.
+ /// A flag to remember if we started reading already.
int started_reading_;
- // A flag to remember if we started reading already.
};
#elif defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC)
// pHILE+ calls the DIR struct XDIR instead
@@ -86,20 +85,30 @@ class ACE_OS_Export ACE_OS_Dirent
public:
static ACE_DIR *opendir (const ACE_TCHAR *filename);
static void closedir (ACE_DIR *);
- static struct dirent *readdir (ACE_DIR *);
+ static dirent *readdir (ACE_DIR *);
static int readdir_r (ACE_DIR *dirp,
- struct dirent *entry,
- struct dirent **result);
+ dirent *entry,
+ dirent **result);
static long telldir (ACE_DIR *);
static void seekdir (ACE_DIR *,
long loc);
static void rewinddir (ACE_DIR *);
+ static int scandir (const ACE_TCHAR *dirname,
+ dirent **namelist[],
+ int (*selector) (const dirent *filename),
+ int (*comparator) (const dirent **f1,
+ const dirent **f2));
private:
// Win32 emulation functions
static ACE_DIR *opendir_emulation (const ACE_TCHAR *filename);
+ static int scandir_emulation (const ACE_TCHAR *dirname,
+ dirent **namelist[],
+ int (*selector)(const dirent *entry),
+ int (*comparator)(const dirent **f1,
+ const dirent**f2));
static void closedir_emulation (ACE_DIR *);
- static struct dirent *readdir_emulation (ACE_DIR *);
+ static dirent *readdir_emulation (ACE_DIR *);
};
# if defined (ACE_HAS_INLINED_OSCALLS)
diff --git a/ace/OS_Dirent.inl b/ace/OS_Dirent.inl
index a56b0ae58c6..75980e33a7e 100644
--- a/ace/OS_Dirent.inl
+++ b/ace/OS_Dirent.inl
@@ -1,4 +1,4 @@
-/* -*- C++ -*- */
+// -*- C++ -*-
// $Id$
#if defined (ACE_HAS_PACE)
@@ -123,9 +123,9 @@ ACE_OS_Dirent::readdir (ACE_DIR *d)
ACE_INLINE int
ACE_OS_Dirent::readdir_r (ACE_DIR *dirp,
- struct dirent *entry,
- struct dirent **result)
-{
+ struct dirent *entry,
+ struct dirent **result)
+{
#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
return pace_readdir_r (dirp, entry, result);
# elif !defined (ACE_HAS_REENTRANT_FUNCTIONS)
@@ -207,3 +207,17 @@ ACE_OS_Dirent::rewinddir (ACE_DIR *d)
ACE_UNUSED_ARG (d);
#endif /* ACE_HAS_DIRENT */
}
+
+ACE_INLINE int
+ACE_OS_Dirent::scandir (const ACE_TCHAR *dirname,
+ struct dirent **namelist[],
+ int (*selector)(const struct dirent *),
+ int (*comparator) (const struct dirent **f1,
+ const struct dirent **f2))
+{
+#if defined (ACE_HAS_SCANDIR)
+ return ::scandir (dirname, namelist, selector, comparator);
+#else /* ! defined ( ACE_HAS_SCANDIR) */
+ return ACE_OS_Dirent::scandir_emulation (dirname, namelist, selector, comparator);
+#endif /* ACE_HAS_SCANDIR */
+}
diff --git a/ace/OS_Memory.h b/ace/OS_Memory.h
index 61d3195dd86..00f2f3e4666 100644
--- a/ace/OS_Memory.h
+++ b/ace/OS_Memory.h
@@ -12,7 +12,6 @@
*/
//=============================================================================
-
#ifndef ACE_OS_MEMORY_H
#define ACE_OS_MEMORY_H
#include "ace/pre.h"
@@ -100,8 +99,7 @@ typedef void *ACE_MALLOC_T;
/**
* @class ACE_OS_Memory
*
- * @brief This class is a wrapper for memory operations, like
- * malloc, memcpy, etc.
+ * @brief This class is a wrapper for dynamic memory operations.
*
*/
class ACE_OS_Export ACE_OS_Memory
diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp
index ceeb3ff52b5..df535e187a5 100644
--- a/ace/Reactor.cpp
+++ b/ace/Reactor.cpp
@@ -20,7 +20,6 @@
ACE_RCSID(ace, Reactor, "$Id$")
-
ACE_ALLOC_HOOK_DEFINE(ACE_Reactor)
ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl *impl,
diff --git a/ace/Service_Object.cpp b/ace/Service_Object.cpp
index e768ebee113..c5dfa7ce240 100644
--- a/ace/Service_Object.cpp
+++ b/ace/Service_Object.cpp
@@ -1,7 +1,5 @@
// $Id$
-// Service_Object.cpp
-
#include "ace/Service_Types.h"
#include "ace/Service_Object.h"