summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Kotkov <kotkov@apache.org>2023-04-12 13:53:14 +0000
committerEvgeny Kotkov <kotkov@apache.org>2023-04-12 13:53:14 +0000
commit4311e2789f05ce53a4d97d8834d5080f76994fe7 (patch)
tree2850f5db75f078a16fc1deadecec5fd0b6435c96
parent1dca0290823d5b14f78023c40f15cd5cd63cd873 (diff)
downloadapr-4311e2789f05ce53a4d97d8834d5080f76994fe7.tar.gz
On 1.7.x branch: Merge r1909088, r1909089 from trunk:
Revert r1808456 (Win32: Don't seek to the end when opening files with APR_FOPEN_APPEND). Add a regression test for the issue where appending to a buffered file was causing the content to be written at offset 0, rather than appended. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.7.x@1909095 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES4
-rw-r--r--file_io/win32/open.c1
-rw-r--r--test/testfile.c96
3 files changed, 50 insertions, 51 deletions
diff --git a/CHANGES b/CHANGES
index ae2fbd7d5..4fe04aa46 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
-*- coding: utf-8 -*-
Changes for APR 1.7.4
+ *) Fix a regression where writing to a file opened with both APR_FOPEN_APPEND
+ and APR_FOPEN_BUFFERED did not properly append the data on Windows.
+ (This regression was introduced in APR 1.7.3) [Evgeny Kotkov]
+
Changes for APR 1.7.3
*) apr-1-config: Fix crosscompiling detection in apr-1-config. PR 66510
diff --git a/file_io/win32/open.c b/file_io/win32/open.c
index f1a46286d..3c00bfc79 100644
--- a/file_io/win32/open.c
+++ b/file_io/win32/open.c
@@ -445,6 +445,7 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname,
if (flag & APR_FOPEN_APPEND) {
(*new)->append = 1;
+ SetFilePointer((*new)->filehand, 0, NULL, FILE_END);
}
if (flag & APR_FOPEN_BUFFERED) {
(*new)->buffered = 1;
diff --git a/test/testfile.c b/test/testfile.c
index 365a7f0b7..bc0e9bba0 100644
--- a/test/testfile.c
+++ b/test/testfile.c
@@ -1637,56 +1637,6 @@ static void test_append_locked(abts_case *tc, void *data)
apr_file_remove(fname, p);
}
-static void test_append_read(abts_case *tc, void *data)
-{
- apr_status_t rv;
- apr_file_t *f;
- const char *fname = "data/testappend_read.dat";
- apr_off_t offset;
- char buf[64];
-
- apr_file_remove(fname, p);
-
- /* Create file with contents. */
- rv = apr_file_open(&f, fname, APR_FOPEN_WRITE | APR_FOPEN_CREATE,
- APR_FPROT_OS_DEFAULT, p);
- APR_ASSERT_SUCCESS(tc, "create file", rv);
-
- rv = apr_file_puts("abc", f);
- APR_ASSERT_SUCCESS(tc, "write to file", rv);
- apr_file_close(f);
-
- /* Re-open it with APR_FOPEN_APPEND. */
- rv = apr_file_open(&f, fname,
- APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_APPEND,
- APR_FPROT_OS_DEFAULT, p);
- APR_ASSERT_SUCCESS(tc, "open file", rv);
-
- /* Test the initial file offset. Even though we used APR_FOPEN_APPEND,
- * the offset should be kept in the beginning of the file until the
- * first append. (Previously, the Windows implementation performed
- * an erroneous seek to the file's end right after opening it.)
- */
- offset = 0;
- rv = apr_file_seek(f, APR_CUR, &offset);
- APR_ASSERT_SUCCESS(tc, "get file offset", rv);
- ABTS_INT_EQUAL(tc, 0, (int)offset);
-
- /* Test reading from the file. */
- rv = apr_file_gets(buf, sizeof(buf), f);
- APR_ASSERT_SUCCESS(tc, "read from file", rv);
- ABTS_STR_EQUAL(tc, "abc", buf);
-
- /* Test the file offset after reading. */
- offset = 0;
- rv = apr_file_seek(f, APR_CUR, &offset);
- APR_ASSERT_SUCCESS(tc, "get file offset", rv);
- ABTS_INT_EQUAL(tc, 3, (int)offset);
-
- apr_file_close(f);
- apr_file_remove(fname, p);
-}
-
static void test_large_write_buffered(abts_case *tc, void *data)
{
apr_status_t rv;
@@ -2227,6 +2177,50 @@ static void test_read_buffered_seek(abts_case *tc, void *data)
apr_file_remove(fname, p);
}
+static void test_append_buffered(abts_case *tc, void *data)
+{
+ apr_status_t rv;
+ apr_file_t *f;
+ const char *fname = "data/testappend_buffered.dat";
+ apr_size_t bytes_written;
+ char buf[64];
+
+ apr_file_remove(fname, p);
+
+ /* Create file with contents. */
+ rv = apr_file_open(&f, fname, APR_FOPEN_WRITE | APR_FOPEN_CREATE,
+ APR_FPROT_OS_DEFAULT, p);
+ APR_ASSERT_SUCCESS(tc, "create file", rv);
+
+ rv = apr_file_write_full(f, "abc", 3, &bytes_written);
+ APR_ASSERT_SUCCESS(tc, "write to file", rv);
+ apr_file_close(f);
+
+ /* Re-open it with APR_FOPEN_APPEND and APR_FOPEN_BUFFERED. */
+ rv = apr_file_open(&f, fname,
+ APR_FOPEN_READ | APR_FOPEN_WRITE |
+ APR_FOPEN_APPEND | APR_FOPEN_BUFFERED,
+ APR_FPROT_OS_DEFAULT, p);
+ APR_ASSERT_SUCCESS(tc, "open file", rv);
+
+ /* Append to the file. */
+ rv = apr_file_write_full(f, "def", 3, &bytes_written);
+ APR_ASSERT_SUCCESS(tc, "write to file", rv);
+ apr_file_close(f);
+
+ rv = apr_file_open(&f, fname, APR_FOPEN_READ,
+ APR_FPROT_OS_DEFAULT, p);
+ APR_ASSERT_SUCCESS(tc, "open file", rv);
+
+ /* Test the file contents. */
+ rv = apr_file_gets(buf, sizeof(buf), f);
+ APR_ASSERT_SUCCESS(tc, "read from file", rv);
+ ABTS_STR_EQUAL(tc, "abcdef", buf);
+
+ apr_file_close(f);
+ apr_file_remove(fname, p);
+}
+
abts_suite *testfile(abts_suite *suite)
{
suite = ADD_SUITE(suite)
@@ -2280,7 +2274,6 @@ abts_suite *testfile(abts_suite *suite)
abts_run_test(suite, test_datasync_on_stream, NULL);
abts_run_test(suite, test_atomic_append, NULL);
abts_run_test(suite, test_append_locked, NULL);
- abts_run_test(suite, test_append_read, NULL);
abts_run_test(suite, test_large_write_buffered, NULL);
abts_run_test(suite, test_two_large_writes_buffered, NULL);
abts_run_test(suite, test_small_and_large_writes_buffered, NULL);
@@ -2292,6 +2285,7 @@ abts_suite *testfile(abts_suite *suite)
abts_run_test(suite, test_read_buffered_spanning_over_bufsize, NULL);
abts_run_test(suite, test_single_byte_reads_buffered, NULL);
abts_run_test(suite, test_read_buffered_seek, NULL);
+ abts_run_test(suite, test_append_buffered, NULL);
return suite;
}