You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by jo...@apache.org on 2005/03/13 03:26:10 UTC
svn commit: r157308 - in httpd/apreq/branches/multi-env-unstable:
include/apreq_util.h library/util.c
Author: joes
Date: Sat Mar 12 18:26:09 2005
New Revision: 157308
URL: http://svn.apache.org/viewcvs?view=rev&rev=157308
Log:
This patch includes two components:
1) Max Kellermann's rewrite of apreq_fwrite
which removes the recursion, and eliminates
the possibility of a "successful zero-byte-write"
infinite loop.
2) Define a copy method for SPOOL buckets. It's
clear from the perl glue's $upload->io() implementation
that on a copy, the original bucket stays a SPOOL
while the copy becomes an ordinary file bucket.
Modified:
httpd/apreq/branches/multi-env-unstable/include/apreq_util.h
httpd/apreq/branches/multi-env-unstable/library/util.c
Modified: httpd/apreq/branches/multi-env-unstable/include/apreq_util.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/include/apreq_util.h?view=diff&r1=157307&r2=157308
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/include/apreq_util.h (original)
+++ httpd/apreq/branches/multi-env-unstable/include/apreq_util.h Sat Mar 12 18:26:09 2005
@@ -297,7 +297,7 @@
e = APR_BUCKET_NEXT(e))
{
apr_bucket *c;
- apr_bucket_copy(e, &c);
+ apr_bucket_copy(e, &c); /*XXX may fail! */
APR_BRIGADE_INSERT_TAIL(d, c);
}
}
Modified: httpd/apreq/branches/multi-env-unstable/library/util.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/util.c?view=diff&r1=157307&r2=157308
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/util.c (original)
+++ httpd/apreq/branches/multi-env-unstable/library/util.c Sat Mar 12 18:26:09 2005
@@ -501,42 +501,50 @@
static apr_status_t apreq_fwritev(apr_file_t *f, struct iovec *v,
int *nelts, apr_size_t *bytes_written)
{
- apr_size_t len, bytes_avail = 0;
- int n = *nelts;
- apr_status_t s = apr_file_writev(f, v, n, &len);
+ apr_size_t len;
+ int n;
+ apr_status_t s;
- *bytes_written = len;
+ *bytes_written = 0;
- if (s != APR_SUCCESS)
- return s;
+ while (1) {
+ /* try to write */
+ s = apr_file_writev(f, v, *nelts, &len);
- while (--n >= 0 && bytes_avail <= len)
- bytes_avail += v[n].iov_len;
+ *bytes_written += len;
+ if (s != APR_SUCCESS)
+ return s;
- if (bytes_avail > len) {
- /* incomplete write: must shift v */
+ /* see how far we've come */
n = 0;
- while (v[n].iov_len <= len) {
- len -= v[n].iov_len;
- ++n;
+ while (n < *nelts && len >= v[n].iov_len)
+ len -= v[n++].iov_len;
+
+ if (n == *nelts) {
+ /* nothing left to write, report success */
+ *nelts = 0;
+ return APR_SUCCESS;
}
+
+ /* incomplete write: must shift v */
v[n].iov_len -= len;
v[n].iov_base = (char *)(v[n].iov_base) + len;
if (n > 0) {
+ /* we're satisfied for now if we can remove one iovec from
+ the "v" array */
(*nelts) -= n;
memmove(v, v + n, sizeof(*v) * *nelts);
+
+ return APR_SUCCESS;
}
- else {
- s = apreq_fwritev(f, v, nelts, &len);
- *bytes_written += len;
- }
- }
- else
- *nelts = 0;
- return s;
+ /* we're still in the first iovec - check for endless loop,
+ and then try again */
+ if (len == 0)
+ return APREQ_ERROR_GENERAL;
+ }
}
@@ -757,13 +765,21 @@
return rv;
}
+static
+apr_status_t spool_bucket_copy(apr_bucket *e, apr_bucket **c)
+{
+ apr_status_t rv = apr_bucket_shared_copy(e, c);
+ (*c)->type = &apr_bucket_type_file;
+ return rv;
+}
+
static const apr_bucket_type_t spool_bucket_type = {
"APREQ_SPOOL", 5, APR_BUCKET_DATA,
spool_bucket_destroy,
spool_bucket_read,
spool_bucket_setaside,
spool_bucket_split,
- apr_bucket_copy_notimpl,
+ spool_bucket_copy,
};
APREQ_DECLARE(apr_file_t *)apreq_brigade_spoolfile(apr_bucket_brigade *bb)