summaryrefslogtreecommitdiff
path: root/test/testmmap.c
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2021-03-02 00:37:18 +0000
committerYann Ylavic <ylavic@apache.org>2021-03-02 00:37:18 +0000
commit17f630750e9e5a40872d8c8c3a48622ed9244d53 (patch)
treea9497308b9bb36677fbb9827617ff237287d6c8c /test/testmmap.c
parent58126550800e0fd66790d216394e61772f329e6c (diff)
downloadapr-17f630750e9e5a40872d8c8c3a48622ed9244d53.tar.gz
Align apr_mmap()ing offset to a page boundary. PR 65158.
This is requirement for unix systems, and otherwise can cause failures or undefined behaviour with some filesystems. Add apr_mmap_t->poffset on unixes to track the offset to the previous page, relative to the user requested/actual offset. This allows ->mm and ->size to still point to the actual data, while munmap() still deletes the full range from the start of the page. Tests updated accordingly. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1887060 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testmmap.c')
-rw-r--r--test/testmmap.c96
1 files changed, 66 insertions, 30 deletions
diff --git a/test/testmmap.c b/test/testmmap.c
index aeff1a66a..5ec0f69c2 100644
--- a/test/testmmap.c
+++ b/test/testmmap.c
@@ -35,18 +35,30 @@ static void not_implemented(abts_case *tc, void *data)
#else
-static char test_string[256]; /* read from the datafile */
+static apr_pool_t *ptest;
+static char *thisfdata; /* read from the datafile */
static apr_mmap_t *themmap = NULL;
static apr_file_t *thefile = NULL;
static char *file1;
static apr_finfo_t thisfinfo;
static apr_size_t thisfsize;
+static struct {
+ const char *filename;
+ apr_off_t offset;
+} test_set[] = {
+ { "/data/mmap_datafile.txt", 0 },
+ { "/data/mmap_large_datafile.txt", 65536 },
+ { "/data/mmap_large_datafile.txt", 66650 }, /* not page aligned */
+ { NULL, }
+};
+
static void create_filename(abts_case *tc, void *data)
{
+ const char *filename = data;
char *oldfileptr;
- apr_filepath_get(&file1, 0, p);
+ apr_filepath_get(&file1, 0, ptest);
#ifndef NETWARE
#ifdef WIN32
ABTS_TRUE(tc, file1[1] == ':');
@@ -57,7 +69,7 @@ static void create_filename(abts_case *tc, void *data)
ABTS_TRUE(tc, file1[strlen(file1) - 1] != '/');
oldfileptr = file1;
- file1 = apr_pstrcat(p, file1,"/data/mmap_datafile.txt" ,NULL);
+ file1 = apr_pstrcat(ptest, file1, filename, NULL);
ABTS_TRUE(tc, oldfileptr != file1);
}
@@ -67,25 +79,15 @@ static void test_file_close(abts_case *tc, void *data)
rv = apr_file_close(thefile);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+ thefile = NULL;
}
-static void read_expected_contents(abts_case *tc, void *data)
-{
- apr_status_t rv;
- apr_size_t nbytes = sizeof(test_string) - 1;
-
- rv = apr_file_read(thefile, test_string, &nbytes);
- ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- test_string[nbytes] = '\0';
- thisfsize = strlen(test_string);
-}
-
static void test_file_open(abts_case *tc, void *data)
{
apr_status_t rv;
rv = apr_file_open(&thefile, file1, APR_FOPEN_READ,
- APR_FPROT_UREAD | APR_FPROT_GREAD, p);
+ APR_FPROT_UREAD | APR_FPROT_GREAD, ptest);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_PTR_NOTNULL(tc, thefile);
}
@@ -96,28 +98,54 @@ static void test_get_filesize(abts_case *tc, void *data)
rv = apr_file_info_get(&thisfinfo, APR_FINFO_NORM, thefile);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- ABTS_ASSERT(tc, "File size mismatch", thisfsize == thisfinfo.size);
+
+ thisfsize = thisfinfo.size;
+ thisfdata = apr_palloc(ptest, thisfsize + 1);
+ ABTS_PTR_NOTNULL(tc, thisfdata);
+}
+
+static void read_expected_contents(abts_case *tc, void *data)
+{
+ apr_off_t *offset = data;
+ apr_size_t nbytes = 0;
+ apr_status_t rv;
+
+ rv = apr_file_read_full(thefile, thisfdata, thisfsize, &nbytes);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+ ABTS_ASSERT(tc, "File size mismatch", nbytes == thisfsize);
+ thisfdata[nbytes] = '\0';
+ ABTS_ASSERT(tc, "File content size mismatch",
+ strlen(thisfdata) == thisfsize);
+ ABTS_ASSERT(tc, "File size too small",
+ (apr_size_t)*offset < thisfsize);
+
+ /* From now, pretend that the file data and size don't include the
+ * offset, this avoids adding/substrating it to thisfdata/thisfsize
+ * all over the place in the next tests.
+ */
+ thisfdata += *offset;
+ thisfsize -= *offset;
}
static void test_mmap_create(abts_case *tc, void *data)
{
+ apr_off_t *offset = data;
apr_status_t rv;
- rv = apr_mmap_create(&themmap, thefile, 0, (apr_size_t) thisfinfo.size,
- APR_MMAP_READ, p);
+ rv = apr_mmap_create(&themmap, thefile, *offset, thisfsize,
+ APR_MMAP_READ, ptest);
ABTS_PTR_NOTNULL(tc, themmap);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}
static void test_mmap_contents(abts_case *tc, void *data)
{
-
ABTS_PTR_NOTNULL(tc, themmap);
ABTS_PTR_NOTNULL(tc, themmap->mm);
ABTS_SIZE_EQUAL(tc, thisfsize, themmap->size);
/* Must use nEquals since the string is not guaranteed to be NULL terminated */
- ABTS_STR_NEQUAL(tc, themmap->mm, test_string, thisfsize);
+ ABTS_STR_NEQUAL(tc, themmap->mm, thisfdata, thisfsize);
}
static void test_mmap_delete(abts_case *tc, void *data)
@@ -127,6 +155,7 @@ static void test_mmap_delete(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, themmap);
rv = apr_mmap_delete(themmap);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+ themmap = NULL;
}
static void test_mmap_offset(abts_case *tc, void *data)
@@ -139,8 +168,9 @@ static void test_mmap_offset(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
/* Must use nEquals since the string is not guaranteed to be NULL terminated */
- ABTS_STR_NEQUAL(tc, addr, test_string + 5, thisfsize-5);
+ ABTS_STR_NEQUAL(tc, addr, thisfdata + 5, thisfsize - 5);
}
+
#endif
abts_suite *testmmap(abts_suite *suite)
@@ -148,15 +178,21 @@ abts_suite *testmmap(abts_suite *suite)
suite = ADD_SUITE(suite)
#if APR_HAS_MMAP
- abts_run_test(suite, create_filename, NULL);
- abts_run_test(suite, test_file_open, NULL);
- abts_run_test(suite, read_expected_contents, NULL);
- abts_run_test(suite, test_get_filesize, NULL);
- abts_run_test(suite, test_mmap_create, NULL);
- abts_run_test(suite, test_mmap_contents, NULL);
- abts_run_test(suite, test_mmap_offset, NULL);
- abts_run_test(suite, test_mmap_delete, NULL);
- abts_run_test(suite, test_file_close, NULL);
+ apr_size_t i;
+ apr_pool_create(&ptest, p);
+ for (i = 0; test_set[i].filename; ++i) {
+ abts_run_test(suite, create_filename, (void *)test_set[i].filename);
+ abts_run_test(suite, test_file_open, NULL);
+ abts_run_test(suite, test_get_filesize, NULL);
+ abts_run_test(suite, read_expected_contents, &test_set[i].offset);
+ abts_run_test(suite, test_mmap_create, &test_set[i].offset);
+ abts_run_test(suite, test_mmap_contents, &test_set[i].offset);
+ abts_run_test(suite, test_mmap_offset, &test_set[i].offset);
+ abts_run_test(suite, test_mmap_delete, NULL);
+ abts_run_test(suite, test_file_close, NULL);
+ apr_pool_clear(ptest);
+ }
+ apr_pool_destroy(ptest);
#else
abts_run_test(suite, not_implemented, NULL);
#endif