apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject svn commit: r1862071 - in /apr/apr/trunk: file_io/os2/dir.c file_io/unix/dir.c file_io/win32/dir.c include/apr_file_info.h test/testdir.c
Date Tue, 25 Jun 2019 14:21:57 GMT
Author: jorton
Date: Tue Jun 25 14:21:56 2019
New Revision: 1862071

URL: http://svn.apache.org/viewvc?rev=1862071&view=rev
Log:
Add apr_dir_pread(), a variant of apr_dir_read() which allows callers
to read a directory with constant memory consumption:

* include/apr_file_info.h: Add warning on memory consumption for
  apr_dir_read; declare apr_dir_pread.

* file_io/unix/dir.c (apr_dir_pread): Rename from apr_dir_read and
  take pool argument.  (apr_dir_read): Reimplement using it.

* file_io/win32/dir.c, file_io/os2/dir.c: Likewise, but untested.

* test/testdir.c (test_pread) [APR_POOL_DEBUG]: Add test case.

Modified:
    apr/apr/trunk/file_io/os2/dir.c
    apr/apr/trunk/file_io/unix/dir.c
    apr/apr/trunk/file_io/win32/dir.c
    apr/apr/trunk/include/apr_file_info.h
    apr/apr/trunk/test/testdir.c

Modified: apr/apr/trunk/file_io/os2/dir.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/os2/dir.c?rev=1862071&r1=1862070&r2=1862071&view=diff
==============================================================================
--- apr/apr/trunk/file_io/os2/dir.c (original)
+++ apr/apr/trunk/file_io/os2/dir.c Tue Jun 25 14:21:56 2019
@@ -79,24 +79,28 @@ APR_DECLARE(apr_status_t) apr_dir_close(
     return APR_FROM_OS_ERROR(rv);
 } 
 
-
-
 APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                                        apr_dir_t *thedir)
 {
+    return apr_dir_pread(finfo, wanted, thedir, thedir->pool);
+}
+
+APR_DECLARE(apr_status_t) apr_dir_pread(apr_finfo_t *finfo, apr_int32_t wanted,
+                                        apr_dir_t *thedir, apr_pool_t *pool)
+{
     int rv;
     ULONG entries = 1;
     
     if (thedir->handle == 0) {
         thedir->handle = HDIR_CREATE;
-        rv = DosFindFirst(apr_pstrcat(thedir->pool, thedir->dirname, "/*", NULL), &thedir->handle,

+        rv = DosFindFirst(apr_pstrcat(pool, thedir->dirname, "/*", NULL), &thedir->handle,

                           FILE_ARCHIVED|FILE_DIRECTORY|FILE_SYSTEM|FILE_HIDDEN|FILE_READONLY,

                           &thedir->entry, sizeof(thedir->entry), &entries,
FIL_STANDARD);
     } else {
         rv = DosFindNext(thedir->handle, &thedir->entry, sizeof(thedir->entry),
&entries);
     }
 
-    finfo->pool = thedir->pool;
+    finfo->pool = pool;
     finfo->fname = NULL;
     finfo->valid = 0;
 

Modified: apr/apr/trunk/file_io/unix/dir.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/unix/dir.c?rev=1862071&r1=1862070&r2=1862071&view=diff
==============================================================================
--- apr/apr/trunk/file_io/unix/dir.c (original)
+++ apr/apr/trunk/file_io/unix/dir.c Tue Jun 25 14:21:56 2019
@@ -142,6 +142,12 @@ static apr_filetype_e filetype_from_dire
 apr_status_t apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                           apr_dir_t *thedir)
 {
+    return apr_dir_pread(finfo, wanted, thedir, thedir->pool);
+}
+
+apr_status_t apr_dir_pread(apr_finfo_t *finfo, apr_int32_t wanted,
+                           apr_dir_t *thedir, apr_pool_t *pool)
+{
     apr_status_t ret = 0;
 #ifdef DIRENT_TYPE
     apr_filetype_e type;
@@ -251,7 +257,7 @@ apr_status_t apr_dir_read(apr_finfo_t *f
         apr_cpystrn(end, thedir->entry->d_name, 
                     sizeof fspec - (end - fspec));
 
-        ret = apr_stat(finfo, fspec, APR_FINFO_LINK | wanted, thedir->pool);
+        ret = apr_stat(finfo, fspec, APR_FINFO_LINK | wanted, pool);
         /* We passed a stack name that will disappear */
         finfo->fname = NULL;
     }
@@ -263,7 +269,7 @@ apr_status_t apr_dir_read(apr_finfo_t *f
         /* We don't bail because we fail to stat, when we are only -required-
          * to readdir... but the result will be APR_INCOMPLETE
          */
-        finfo->pool = thedir->pool;
+        finfo->pool = pool;
         finfo->valid = 0;
 #ifdef DIRENT_TYPE
         if (type != APR_UNKFILE) {
@@ -279,7 +285,7 @@ apr_status_t apr_dir_read(apr_finfo_t *f
 #endif
     }
 
-    finfo->name = apr_pstrdup(thedir->pool, thedir->entry->d_name);
+    finfo->name = apr_pstrdup(pool, thedir->entry->d_name);
     finfo->valid |= APR_FINFO_NAME;
 
     if (wanted)

Modified: apr/apr/trunk/file_io/win32/dir.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/win32/dir.c?rev=1862071&r1=1862070&r2=1862071&view=diff
==============================================================================
--- apr/apr/trunk/file_io/win32/dir.c (original)
+++ apr/apr/trunk/file_io/win32/dir.c Tue Jun 25 14:21:56 2019
@@ -91,6 +91,12 @@ APR_DECLARE(apr_status_t) apr_dir_close(
 APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                                        apr_dir_t *thedir)
 {
+    return apr_dir_pread(finfo, wanted, thedir, thedir->pool);
+}
+
+APR_DECLARE(apr_status_t) apr_dir_pread(apr_finfo_t *finfo, apr_int32_t wanted,
+                                        apr_dir_t *thedir, apr_pool_t *pool)
+{
     apr_status_t rv;
     char *fname;
     apr_wchar_t wdirname[APR_PATH_MAX];
@@ -150,7 +156,7 @@ APR_DECLARE(apr_status_t) apr_dir_read(a
 
     fillin_fileinfo(finfo, (WIN32_FILE_ATTRIBUTE_DATA *) thedir->entry,
                     0, 1, fname, wanted);
-    finfo->pool = thedir->pool;
+    finfo->pool = pool;
 
     finfo->valid |= APR_FINFO_NAME;
     finfo->name = fname;

Modified: apr/apr/trunk/include/apr_file_info.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_file_info.h?rev=1862071&r1=1862070&r2=1862071&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_file_info.h (original)
+++ apr/apr/trunk/include/apr_file_info.h Tue Jun 25 14:21:56 2019
@@ -263,11 +263,33 @@ APR_DECLARE(apr_status_t) apr_dir_close(
  *       not be filled in, and you need to check the @c finfo->valid bitmask
  *       to verify that what you're looking for is there. When no more
  *       entries are available, APR_ENOENT is returned.
+ *
+ * @warning Memory will be allocated in the pool passed to apr_dir_open;
+ *          use apr_dir_pread() and a temporary pool to restrict memory
+ *          consumption for a large directory.
  */                        
 APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                                        apr_dir_t *thedir);
 
 /**
+ * Read the next entry from the specified directory. 
+ * @param finfo the file info structure and filled in by apr_dir_read
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
+                 values 
+ * @param thedir the directory descriptor returned from apr_dir_open
+ * @param pool the pool to use for allocations
+ * @remark No ordering is guaranteed for the entries read.
+ *
+ * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
+ *       not be filled in, and you need to check the @c finfo->valid bitmask
+ *       to verify that what you're looking for is there. When no more
+ *       entries are available, APR_ENOENT is returned.
+ */                        
+APR_DECLARE(apr_status_t) apr_dir_pread(apr_finfo_t *finfo, apr_int32_t wanted,
+                                        apr_dir_t *thedir, apr_pool_t *pool);
+
+    
+/**
  * Rewind the directory to the first entry.
  * @param thedir the directory descriptor to rewind.
  */                        

Modified: apr/apr/trunk/test/testdir.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/testdir.c?rev=1862071&r1=1862070&r2=1862071&view=diff
==============================================================================
--- apr/apr/trunk/test/testdir.c (original)
+++ apr/apr/trunk/test/testdir.c Tue Jun 25 14:21:56 2019
@@ -430,6 +430,36 @@ static void test_readmore_info(abts_case
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 }
 
+#if APR_POOL_DEBUG
+static void test_pread(abts_case *tc, void *data)
+{
+    apr_dir_t *dir;
+    apr_finfo_t finfo;
+    apr_size_t before, after;
+    apr_pool_t *subp;
+
+    APR_ASSERT_SUCCESS(tc, "apr_dir_open failed", apr_dir_open(&dir, "data", p));
+    
+    apr_pool_create(&subp, p);
+
+    before = apr_pool_num_bytes(p, 0);
+    
+    APR_ASSERT_SUCCESS(tc, "apr_dir_read failed",
+                       apr_dir_pread(&finfo, APR_FINFO_DIRENT, dir, subp));
+
+    after = apr_pool_num_bytes(p, 0);
+
+    ABTS_PTR_EQUAL(tc, finfo.pool, subp);
+
+    apr_pool_destroy(subp);
+    
+    APR_ASSERT_SUCCESS(tc, "apr_dir_close failed", apr_dir_close(dir));
+
+    ABTS_INT_EQUAL(tc, before, after);
+    
+}
+#endif
+
 abts_suite *testdir(abts_suite *suite)
 {
     suite = ADD_SUITE(suite)
@@ -451,7 +481,10 @@ abts_suite *testdir(abts_suite *suite)
     abts_run_test(suite, test_closedir, NULL);
     abts_run_test(suite, test_uncleared_errno, NULL);
     abts_run_test(suite, test_readmore_info, NULL);
-
+#if APR_POOL_DEBUG
+    abts_run_test(suite, test_pread, NULL);
+#endif
+    
     return suite;
 }
 



Mime
View raw message