Index: include/apr_file_io.h
===================================================================
--- include/apr_file_io.h	(revision 603256)
+++ include/apr_file_io.h	(working copy)
@@ -122,6 +122,15 @@
 /** @} */
 
 /**
+ * @defgroup apr_dir_open_flags Dir Open Flags/Routines
+ * @{
+ */
+
+#define APR_DIR_NOCLEANUP  0x00800  /**< Do not register a cleanup
+
+/** @} */
+
+/**
  * @defgroup apr_file_seek_flags File Seek Flags
  * @{
  */
Index: include/apr_portable.h
===================================================================
--- include/apr_portable.h	(revision 603256)
+++ include/apr_portable.h	(working copy)
@@ -379,6 +379,20 @@
                                          apr_pool_t *cont); 
 
 /**
+ * convert the dir from os specific type to apr type.
+ * @param dir The apr dir we are converting to.
+ * @param dirname The full path to the directory (use / on all systems)
+ * @param thedir The os specific dir to convert
+ * @param flags The flags that were used to open this dir
+ * @param cont The pool to use when creating to apr directory.
+ */
+APR_DECLARE(apr_status_t) apr_os_dir_put_ex(apr_dir_t **dir,
+                                         const char *dirname,
+                                         apr_os_dir_t *thedir,
+                                         apr_int32_t flags,
+                                         apr_pool_t *cont); 
+
+/**
  * Convert a socket from the os specific type to the apr type
  * @param sock The pool to use.
  * @param thesock The socket to convert to.
Index: include/apr_file_info.h
===================================================================
--- include/apr_file_info.h	(revision 603256)
+++ include/apr_file_info.h	(working copy)
@@ -246,6 +246,20 @@
                                        apr_pool_t *pool);
 
 /**
+ * return the dirname field of a directory
+ * @param name Pointer to new string containing directory name (on output)
+ * @param thedir the directory who's name should be returned.
+ */                        
+APR_DECLARE(apr_status_t) apr_dir_name_get(char **name, apr_dir_t *thedir);
+
+/**
+ * return the pool field of a directory
+ * @param pool Pointer to the new pool containing the directory pool (on output)
+ * @param thedir the directory who's pool should be returned.
+ */
+APR_DECLARE(apr_status_t) apr_dir_pool_get(apr_pool_t **pool, apr_dir_t *thedir);
+
+/**
  * close the specified directory. 
  * @param thedir the directory descriptor to close.
  */                        
Index: file_io/unix/dir.c
===================================================================
--- file_io/unix/dir.c	(revision 603256)
+++ file_io/unix/dir.c	(working copy)
@@ -71,29 +71,25 @@
 apr_status_t apr_dir_open(apr_dir_t **new, const char *dirname, 
                           apr_pool_t *pool)
 {
-    /* On some platforms (e.g., Linux+GNU libc), d_name[] in struct 
-     * dirent is declared with enough storage for the name.  On other
-     * platforms (e.g., Solaris 8 for Intel), d_name is declared as a
-     * one-byte array.  Note: gcc evaluates this at compile time.
-     */
-    apr_size_t dirent_size = 
-        sizeof(*(*new)->entry) +
-        (sizeof((*new)->entry->d_name) > 1 ? 0 : 255);
     DIR *dir = opendir(dirname);
 
     if (!dir) {
         return errno;
     }
 
-    (*new) = (apr_dir_t *)apr_palloc(pool, sizeof(apr_dir_t));
+    *new = NULL;
+    return apr_os_dir_put_ex(new, dirname, dir, 0, pool);
+}
 
-    (*new)->pool = pool;
-    (*new)->dirname = apr_pstrdup(pool, dirname);
-    (*new)->dirstruct = dir;
-    (*new)->entry = apr_pcalloc(pool, dirent_size);
+apr_status_t apr_dir_name_get(char **name, apr_dir_t *dir)
+{
+    *name = dir->dirname;
+    return APR_SUCCESS;
+}
 
-    apr_pool_cleanup_register((*new)->pool, *new, dir_cleanup,
-                              apr_pool_cleanup_null);
+apr_status_t apr_dir_pool_get(apr_pool_t **pool, apr_dir_t *dir)
+{
+    *pool = dir->pool;
     return APR_SUCCESS;
 }
 
@@ -348,12 +344,40 @@
 apr_status_t apr_os_dir_put(apr_dir_t **dir, apr_os_dir_t *thedir,
                           apr_pool_t *pool)
 {
+    return apr_os_dir_put_ex(dir, NULL, thedir, APR_DIR_NOCLEANUP, pool);
+}
+
+apr_status_t apr_os_dir_put_ex(apr_dir_t **dir,
+                          const char *dirname,
+                          apr_os_dir_t *thedir,
+                          apr_int32_t flags,
+                          apr_pool_t *pool)
+{
+    /* On some platforms (e.g., Linux+GNU libc), d_name[] in struct 
+     * dirent is declared with enough storage for the name.  On other
+     * platforms (e.g., Solaris 8 for Intel), d_name is declared as a
+     * one-byte array.  Note: gcc evaluates this at compile time.
+     */
+    apr_size_t dirent_size = 
+        sizeof(*(*dir)->entry) +
+        (sizeof((*dir)->entry->d_name) > 1 ? 0 : 255);
+
     if ((*dir) == NULL) {
         (*dir) = (apr_dir_t *)apr_pcalloc(pool, sizeof(apr_dir_t));
         (*dir)->pool = pool;
+        (*dir)->entry = apr_pcalloc(pool, dirent_size);
+
+        if (!(flags & APR_DIR_NOCLEANUP)) {
+            apr_pool_cleanup_register((*dir)->pool, *dir, dir_cleanup,
+                                      apr_pool_cleanup_null);
+        }
     }
+
     (*dir)->dirstruct = thedir;
+
+    if (dirname) {
+        (*dir)->dirname = apr_pstrdup(pool, dirname);
+    }
+
     return APR_SUCCESS;
 }
-
-  
