Index: include/apr_portable.h
===================================================================
--- include/apr_portable.h	(revision 603256)
+++ include/apr_portable.h	(working copy)
@@ -379,6 +379,18 @@
                                          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 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_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: file_io/win32/dir.c
===================================================================
--- file_io/win32/dir.c	(revision 603256)
+++ file_io/win32/dir.c	(working copy)
@@ -391,3 +391,11 @@
 {
     return APR_ENOTIMPL;
 }
+
+APR_DECLARE(apr_status_t) apr_os_dir_put_ex(apr_dir_t **dir,
+                                         const char *dirname,
+                                         apr_os_dir_t *thedir,
+                                         apr_pool_t *pool)
+{
+    return APR_ENOTIMPL;
+}
Index: file_io/os2/dir.c
===================================================================
--- file_io/os2/dir.c	(revision 603256)
+++ file_io/os2/dir.c	(working copy)
@@ -31,22 +31,8 @@
 
 APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new, const char *dirname, apr_pool_t *pool)
 {
-    apr_dir_t *thedir = (apr_dir_t *)apr_palloc(pool, sizeof(apr_dir_t));
-    
-    if (thedir == NULL)
-        return APR_ENOMEM;
-    
-    thedir->pool = pool;
-    thedir->dirname = apr_pstrdup(pool, dirname);
-
-    if (thedir->dirname == NULL)
-        return APR_ENOMEM;
-
-    thedir->handle = 0;
-    thedir->validentry = FALSE;
-    *new = thedir;
-    apr_pool_cleanup_register(pool, thedir, dir_cleanup, apr_pool_cleanup_null);
-    return APR_SUCCESS;
+    *new = NULL;
+    return apr_os_dir_put_ex(new, dirname, &0, pool);
 }
 
 
@@ -158,10 +144,25 @@
 APR_DECLARE(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, pool);
+}
+
+APR_DECLARE(apr_status_t) apr_os_dir_put_ex(apr_dir_t **dir,
+                                         const char *dirname,
+                                         apr_os_dir_t *thedir,
+                                         apr_pool_t *pool)
+{
     if ((*dir) == NULL) {
         (*dir) = (apr_dir_t *)apr_pcalloc(pool, sizeof(apr_dir_t));
         (*dir)->pool = pool;
+        (*dir)->validentry = FALSE;
+        apr_pool_cleanup_register((*dir)->pool, *dir, dir_cleanup, apr_pool_cleanup_null);
     }
+    else {
+        apr_pool_cleanup_run((*dir)->pool, *dir, dir_cleanup);
+    }
     (*dir)->handle = *thedir;
+    if (dirname)
+        (*dir)->dirname = apr_pstrdup(pool, dirname);
     return APR_SUCCESS;
 }
Index: file_io/unix/dir.c
===================================================================
--- file_io/unix/dir.c	(revision 603256)
+++ file_io/unix/dir.c	(working copy)
@@ -71,30 +71,14 @@
 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)->pool = pool;
-    (*new)->dirname = apr_pstrdup(pool, dirname);
-    (*new)->dirstruct = dir;
-    (*new)->entry = apr_pcalloc(pool, dirent_size);
-
-    apr_pool_cleanup_register((*new)->pool, *new, dir_cleanup,
-                              apr_pool_cleanup_null);
-    return APR_SUCCESS;
+    *new = NULL;
+    return apr_os_dir_put_ex(new, dirname, dir, pool);
 }
 
 apr_status_t apr_dir_close(apr_dir_t *thedir)
@@ -348,12 +332,36 @@
 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, pool);
+}
+
+apr_status_t apr_os_dir_put_ex(apr_dir_t **dir,
+                          const char *dirname,
+                          apr_os_dir_t *thedir,
+                          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);
+
+        apr_pool_cleanup_register((*dir)->pool, *dir, dir_cleanup,
+                                  apr_pool_cleanup_null);
     }
+    else {
+        apr_pool_cleanup_run((*dir)->pool, *dir, dir_cleanup);
+    }
     (*dir)->dirstruct = thedir;
+    if (dirname)
+        (*dir)->dirname = apr_pstrdup(pool, dirname);
     return APR_SUCCESS;
 }
-
-  
