diff options
author | pquerna <pquerna@13f79535-47bb-0310-9956-ffa450edef68> | 2007-02-28 18:05:37 +0000 |
---|---|---|
committer | pquerna <pquerna@13f79535-47bb-0310-9956-ffa450edef68> | 2007-02-28 18:05:37 +0000 |
commit | f7d28f45e0ad7488a0c508eba0f72a8c1ce5efd9 (patch) | |
tree | ce6297b0e38c56a6b7097dd2a51899bb63b050d0 | |
parent | b833dcb827b0376223064622a5b6c4536c9514b1 (diff) | |
download | libapr-f7d28f45e0ad7488a0c508eba0f72a8c1ce5efd9.tar.gz |
Fix apr_file_writev when buffering is enabled by forcing a flush, rather than writing underneath the write buffer.
PR: 41197
Submitted By: Davi Arnaut
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@512882 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | file_io/os2/readwrite.c | 6 | ||||
-rw-r--r-- | file_io/unix/readwrite.c | 6 | ||||
-rw-r--r-- | test/testfile.c | 32 |
3 files changed, 44 insertions, 0 deletions
diff --git a/file_io/os2/readwrite.c b/file_io/os2/readwrite.c index 2eb011e82..354641abb 100644 --- a/file_io/os2/readwrite.c +++ b/file_io/os2/readwrite.c @@ -197,6 +197,12 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iovec *vec, apr_size_t nvec, apr_size_t *nbytes) { + apr_status_t rv = apr_file_flush(thefile); + + if (rv != APR_SUCCESS) { + return rv; + } + int bytes; if ((bytes = writev(thefile->filedes, vec, nvec)) < 0) { *nbytes = 0; diff --git a/file_io/unix/readwrite.c b/file_io/unix/readwrite.c index 320735d68..56d9bfff6 100644 --- a/file_io/unix/readwrite.c +++ b/file_io/unix/readwrite.c @@ -239,6 +239,12 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iovec *vec, apr_size_t nvec, apr_size_t *nbytes) { + apr_status_t rv = apr_file_flush(thefile); + + if (rv != APR_SUCCESS) { + return rv; + } + #ifdef HAVE_WRITEV apr_ssize_t bytes; diff --git a/test/testfile.c b/test/testfile.c index 0244aa11a..a5bba865f 100644 --- a/test/testfile.c +++ b/test/testfile.c @@ -661,6 +661,37 @@ static void test_writev_full(abts_case *tc, void *data) } +static void test_writev_buffered(abts_case *tc, void *data) +{ + apr_file_t *f; + apr_size_t nbytes; + struct iovec vec[2]; + const char *fname = "data/testwritev_buffered.txt"; + + APR_ASSERT_SUCCESS(tc, "open file for writing", + apr_file_open(&f, fname, + APR_WRITE | APR_CREATE | APR_TRUNCATE | + APR_BUFFERED, APR_OS_DEFAULT, p)); + + nbytes = strlen(TESTSTR); + APR_ASSERT_SUCCESS(tc, "buffered write", + apr_file_write(f, TESTSTR, &nbytes)); + + vec[0].iov_base = LINE1; + vec[0].iov_len = strlen(LINE1); + vec[1].iov_base = LINE2; + vec[1].iov_len = strlen(LINE2); + + APR_ASSERT_SUCCESS(tc, "writev of size 2 to file", + apr_file_writev(f, vec, 2, &nbytes)); + + APR_ASSERT_SUCCESS(tc, "close for writing", + apr_file_close(f)); + + file_contents_equal(tc, fname, TESTSTR LINE1 LINE2, + strlen(TESTSTR) + strlen(LINE1) + strlen(LINE2)); +} + static void test_truncate(abts_case *tc, void *data) { apr_status_t rv; @@ -885,6 +916,7 @@ abts_suite *testfile(abts_suite *suite) abts_run_test(suite, test_puts, NULL); abts_run_test(suite, test_writev, NULL); abts_run_test(suite, test_writev_full, NULL); + abts_run_test(suite, test_writev_buffered, NULL); abts_run_test(suite, test_bigread, NULL); abts_run_test(suite, test_mod_neg, NULL); abts_run_test(suite, test_truncate, NULL); |