summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2012-02-06 20:54:16 +0000
committerbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2012-02-06 20:54:16 +0000
commitfbefa19103b3becb3f27c3c3dd0e7a9712165cbe (patch)
tree8903b8d7816766a90c183c2a1a68d4b19853191f
parent4c11a08dde53cedef71a041300342d1c7ce0ed7d (diff)
downloadlibapr-fbefa19103b3becb3f27c3c3dd0e7a9712165cbe.tar.gz
Backport r1044440 from trunk to 1.4.x.
Fix file_trunc for buffered files. Make sure the write buffer is flushed before truncate call git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@1241173 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES3
-rw-r--r--file_io/unix/seek.c26
2 files changed, 28 insertions, 1 deletions
diff --git a/CHANGES b/CHANGES
index b52e37360..f3213bfc0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes for APR 1.4.6
+ *) Flush write buffer before truncate call on a file.
+ [Mladen Turk]
+
*) Security: oCERT-2011-003
Randomise hashes by providing a seed.
[Bojan Smojver, Branko Čibej, Ruediger Pluem et al.]
diff --git a/file_io/unix/seek.c b/file_io/unix/seek.c
index 77ef96e7d..e70805d7f 100644
--- a/file_io/unix/seek.c
+++ b/file_io/unix/seek.c
@@ -33,7 +33,7 @@ static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
thefile->bufpos = newbufpos;
rv = APR_SUCCESS;
- }
+ }
else {
if (lseek(thefile->filedes, pos, SEEK_SET) != -1) {
thefile->bufpos = thefile->dataRead = 0;
@@ -98,6 +98,30 @@ APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t wh
apr_status_t apr_file_trunc(apr_file_t *fp, apr_off_t offset)
{
+ if (fp->buffered) {
+ int rc = 0;
+ file_lock(fp);
+ if (fp->direction == 1 && fp->bufpos != 0) {
+ apr_off_t len = fp->filePtr + fp->bufpos;
+ if (offset < len) {
+ /* New file end fall below our write buffer limit.
+ * Figure out if and what needs to be flushed.
+ */
+ apr_off_t off = len - offset;
+ if (off >= 0 && off <= fp->bufpos)
+ fp->bufpos = fp->bufpos - (size_t)off;
+ else
+ fp->bufpos = 0;
+ }
+ rc = apr_file_flush_locked(fp);
+ /* Reset buffer positions for write mode */
+ fp->bufpos = fp->direction = fp->dataRead = 0;
+ }
+ if (rc) {
+ return rc;
+ }
+ file_unlock(fp);
+ }
if (ftruncate(fp->filedes, offset) == -1) {
return errno;
}