summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjorton <jorton@13f79535-47bb-0310-9956-ffa450edef68>2004-11-18 21:30:59 +0000
committerjorton <jorton@13f79535-47bb-0310-9956-ffa450edef68>2004-11-18 21:30:59 +0000
commit6f57ada8bc6099fc07327c84055a148ea2be6f9b (patch)
tree686337c2df43f6e52a6686820203f1b884c8d6c7
parent92b947904fbe285eb07d77a04a8c405c44776441 (diff)
downloadlibapr-6f57ada8bc6099fc07327c84055a148ea2be6f9b.tar.gz
* file_io/unix/readwrite.c (file_printf_flush): New
function. (apr_file_printf): Rewrite to handle arbitrary length strings. * test/testfile.c (test_bigfprintf): New function. PR: 28029 Submitted by: Chris Knight <Christopher.D.Knight nasa.gov>, Garrett Rooney <rooneg electricjellyfish.net> git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@76283 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--file_io/unix/readwrite.c47
-rw-r--r--test/testfile.c33
2 files changed, 70 insertions, 10 deletions
diff --git a/file_io/unix/readwrite.c b/file_io/unix/readwrite.c
index 2334ea1a6..4f35dbed5 100644
--- a/file_io/unix/readwrite.c
+++ b/file_io/unix/readwrite.c
@@ -378,22 +378,49 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
return rv;
}
+struct apr_file_printf_data {
+ apr_vformatter_buff_t vbuff;
+ apr_file_t *fptr;
+ char *buf;
+};
+
+static int file_printf_flush(apr_vformatter_buff_t *buff)
+{
+ struct apr_file_printf_data *data = (struct apr_file_printf_data *)buff;
+
+ if (apr_file_write_full(data->fptr, data->buf,
+ data->vbuff.curpos - data->buf, NULL)) {
+ return -1;
+ }
+
+ data->vbuff.curpos = data->buf;
+ return 0;
+}
+
APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr,
const char *format, ...)
{
- apr_status_t cc;
+ struct apr_file_printf_data data;
va_list ap;
- char *buf;
- int len;
+ int count;
- buf = malloc(HUGE_STRING_LEN);
- if (buf == NULL) {
- return 0;
+ /* don't really need a HUGE_STRING_LEN anymore */
+ data.buf = malloc(HUGE_STRING_LEN);
+ if (data.buf == NULL) {
+ return -1;
}
+ data.vbuff.curpos = data.buf;
+ data.vbuff.endpos = data.buf + HUGE_STRING_LEN;
+ data.fptr = fptr;
va_start(ap, format);
- len = apr_vsnprintf(buf, HUGE_STRING_LEN, format, ap);
- cc = apr_file_puts(buf, fptr);
+ count = apr_vformatter(file_printf_flush,
+ (apr_vformatter_buff_t *)&data, format, ap);
+ /* apr_vformatter does not call flush for the last bits */
+ if (count >= 0) file_printf_flush((apr_vformatter_buff_t *)&data);
+
va_end(ap);
- free(buf);
- return (cc == APR_SUCCESS) ? len : -1;
+
+ free(data.buf);
+
+ return count;
}
diff --git a/test/testfile.c b/test/testfile.c
index 8d83ae5d0..cce9efebe 100644
--- a/test/testfile.c
+++ b/test/testfile.c
@@ -592,6 +592,38 @@ static void test_truncate(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}
+static void test_bigfprintf(abts_case *tc, void *data)
+{
+ apr_file_t *f;
+ const char *fname = "data/testbigfprintf.dat";
+ char *to_write;
+ int i;
+
+ apr_file_remove(fname, p);
+
+ APR_ASSERT_SUCCESS(tc, "open test file",
+ apr_file_open(&f, fname,
+ APR_CREATE|APR_WRITE,
+ APR_UREAD|APR_UWRITE, p));
+
+
+ to_write = malloc(HUGE_STRING_LEN + 3);
+
+ for (i = 0; i < HUGE_STRING_LEN + 1; ++i)
+ to_write[i] = 'A' + i%26;
+
+ strcpy(to_write + HUGE_STRING_LEN, "42");
+
+ i = apr_file_printf(f, "%s", to_write);
+ ABTS_INT_EQUAL(tc, HUGE_STRING_LEN + 2, i);
+
+ apr_file_close(f);
+
+ file_contents_equal(tc, fname, to_write, HUGE_STRING_LEN + 2);
+
+ free(to_write);
+}
+
abts_suite *testfile(abts_suite *suite)
{
suite = ADD_SUITE(suite)
@@ -619,6 +651,7 @@ abts_suite *testfile(abts_suite *suite)
abts_run_test(suite, test_bigread, NULL);
abts_run_test(suite, test_mod_neg, NULL);
abts_run_test(suite, test_truncate, NULL);
+ abts_run_test(suite, test_bigfprintf, NULL);
return suite;
}