diff options
author | jorton <jorton@13f79535-47bb-0310-9956-ffa450edef68> | 2004-11-18 21:30:59 +0000 |
---|---|---|
committer | jorton <jorton@13f79535-47bb-0310-9956-ffa450edef68> | 2004-11-18 21:30:59 +0000 |
commit | 6f57ada8bc6099fc07327c84055a148ea2be6f9b (patch) | |
tree | 686337c2df43f6e52a6686820203f1b884c8d6c7 | |
parent | 92b947904fbe285eb07d77a04a8c405c44776441 (diff) | |
download | libapr-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.c | 47 | ||||
-rw-r--r-- | test/testfile.c | 33 |
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; } |