You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by pq...@apache.org on 2004/12/05 03:17:31 UTC

svn commit: r109843 - /apr/apr/trunk/CHANGES /apr/apr/trunk/file_io/unix/fullrw.c /apr/apr/trunk/file_io/unix/readwrite.c /apr/apr/trunk/include/apr_file_io.h /apr/apr/trunk/test/Makefile.in /apr/apr/trunk/test/data /apr/apr/trunk/test/testfile.c

Author: pquerna
Date: Sat Dec  4 18:17:30 2004
New Revision: 109843

URL: http://svn.apache.org/viewcvs?view=rev&rev=109843
Log:
* file_io/unix/fullrw.c: Add apr_file_writev_full to ensure an iovec is 
                         completely written to the file.

* include/apr_file_io.h: Define APR_MAX_IOVEC_SIZE
                         Add public def for apr_file_writev_full.

* file_io/unix/readwrite.c: For systems without writev, ensure that they get 
                            the correct number of bytes written.

* test/*: Add a new test for apr_file_writev_full.

Modified:
   apr/apr/trunk/CHANGES
   apr/apr/trunk/file_io/unix/fullrw.c
   apr/apr/trunk/file_io/unix/readwrite.c
   apr/apr/trunk/include/apr_file_io.h
   apr/apr/trunk/test/Makefile.in
   apr/apr/trunk/test/data/   (props changed)
   apr/apr/trunk/test/testfile.c

Modified: apr/apr/trunk/CHANGES
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/CHANGES?view=diff&rev=109843&p1=apr/apr/trunk/CHANGES&r1=109842&p2=apr/apr/trunk/CHANGES&r2=109843
==============================================================================
--- apr/apr/trunk/CHANGES	(original)
+++ apr/apr/trunk/CHANGES	Sat Dec  4 18:17:30 2004
@@ -1,5 +1,8 @@
 Changes for APR 1.1.0
 
+  *) Add apr_file_writev_full to ensure an entire iovec is writen to a file.
+     [Paul Querna]
+
   *) apr_file_writev will now at least try to write all iovecs on platforms
      that do not support writev. 
      [Paul Querna]

Modified: apr/apr/trunk/file_io/unix/fullrw.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/file_io/unix/fullrw.c?view=diff&rev=109843&p1=apr/apr/trunk/file_io/unix/fullrw.c&r1=109842&p2=apr/apr/trunk/file_io/unix/fullrw.c&r2=109843
==============================================================================
--- apr/apr/trunk/file_io/unix/fullrw.c	(original)
+++ apr/apr/trunk/file_io/unix/fullrw.c	Sat Dec  4 18:17:30 2004
@@ -60,3 +60,37 @@
 
     return status;
 }
+
+APR_DECLARE(apr_status_t) apr_file_writev_full(apr_file_t *thefile,
+                                               const struct iovec *vec,
+                                               apr_size_t nvec,
+                                               apr_size_t *bytes_written)
+{
+    apr_status_t status;
+    apr_size_t total = 0;
+
+    do {
+        int i;
+	apr_size_t amt;
+        status = apr_file_writev(thefile, vec, nvec, &amt);
+ 
+       /* We assume that writev will only write complete iovec areas.
+        * Incomplete writes inside a single area are not supported.
+        * This should be safe according to SuS v2. 
+        */
+        for(i = 0; i < nvec; i++) {
+            total += vec[i].iov_len;
+            if(total >= amt) {
+                vec = &vec[i+1];
+                nvec -= i+1;
+                break;
+            }
+        }
+    } while (status == APR_SUCCESS && nvec > 0);
+
+    if (bytes_written != NULL)
+        *bytes_written = total;
+
+    return status;
+}
+

Modified: apr/apr/trunk/file_io/unix/readwrite.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/file_io/unix/readwrite.c?view=diff&rev=109843&p1=apr/apr/trunk/file_io/unix/readwrite.c&r1=109842&p2=apr/apr/trunk/file_io/unix/readwrite.c&r2=109843
==============================================================================
--- apr/apr/trunk/file_io/unix/readwrite.c	(original)
+++ apr/apr/trunk/file_io/unix/readwrite.c	Sat Dec  4 18:17:30 2004
@@ -244,6 +244,8 @@
     int i, tbytes;
     apr_status_t rv = APR_SUCCESS;
 
+    *nbytes = 0;
+
     for(i = 0; i < nvec; i++){
          tbytes = vec[i].iov_len;
          rv = apr_file_write(thefile, vec[i].iov_base, &tbytes);

Modified: apr/apr/trunk/include/apr_file_io.h
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/apr_file_io.h?view=diff&rev=109843&p1=apr/apr/trunk/include/apr_file_io.h&r1=109842&p2=apr/apr/trunk/include/apr_file_io.h&r2=109843
==============================================================================
--- apr/apr/trunk/include/apr_file_io.h	(original)
+++ apr/apr/trunk/include/apr_file_io.h	Sat Dec  4 18:17:30 2004
@@ -130,6 +130,22 @@
 #define APR_FILE_ATTR_HIDDEN     0x04          /**< File is hidden */
 /** @} */
 
+/**
+ * @defgroup apr_file_writev{_full} max iovec size
+ * @{
+ */
+#if defined(DOXYGEN)
+#define APR_MAX_IOVEC_SIZE 1024                /**< System dependent maximum 
+                                                    size of an iovec array */
+#elif defined(IOV_MAX)
+#define APR_MAX_IOVEC_SIZE IOV_MAX
+#elif defined(MAX_IOVEC)
+#define APR_MAX_IOVEC_SIZE MAX_IOVEC
+#else
+#define APR_MAX_IOVEC_SIZE 1024
+#endif
+/** @} */
+
 /** File attributes */
 typedef apr_uint32_t apr_fileattrs_t;
 
@@ -413,6 +429,24 @@
                                               apr_size_t nbytes, 
                                               apr_size_t *bytes_written);
 
+
+/**
+ * Write data from iovec array to the specified file, ensuring that all of the
+ * data is written before returning.
+ * @param thefile The file descriptor to write to.
+ * @param vec The array from which to get the data to write to the file.
+ * @param nvec The number of elements in the struct iovec array. This must 
+ *             be smaller than APR_MAX_IOVEC_SIZE.  If it isn't, the function 
+ *             will fail with APR_EINVAL.
+ * @param nbytes The number of bytes written.
+ *
+ * @remark apr_file_writev_full is available even if the underlying
+ * operating system doesn't provide writev().
+ */
+APR_DECLARE(apr_status_t) apr_file_writev_full(apr_file_t *thefile,
+                                               const struct iovec *vec,
+                                               apr_size_t nvec,
+                                               apr_size_t *nbytes);
 /**
  * Write a character into the specified file.
  * @param ch The character to write.

Modified: apr/apr/trunk/test/Makefile.in
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/test/Makefile.in?view=diff&rev=109843&p1=apr/apr/trunk/test/Makefile.in&r1=109842&p2=apr/apr/trunk/test/Makefile.in&r2=109843
==============================================================================
--- apr/apr/trunk/test/Makefile.in	(original)
+++ apr/apr/trunk/test/Makefile.in	Sat Dec  4 18:17:30 2004
@@ -31,7 +31,8 @@
 CLEAN_TARGETS = testfile.tmp mod_test.slo proc_child@EXEEXT@ occhild@EXEEXT@ \
 	readchild@EXEEXT@ tryread@EXEEXT@ sockchild@EXEEXT@ \
 	globalmutexchild@EXEEXT@ lfstests/large.bin \
-	data/testputs.txt data/testbigfprintf.dat data/testwritev.txt
+	data/testputs.txt data/testbigfprintf.dat data/testwritev.txt \
+        testwritev_full.txt
 CLEAN_SUBDIRS = internal
 
 INCDIR=../include

Modified: apr/apr/trunk/test/testfile.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/test/testfile.c?view=diff&rev=109843&p1=apr/apr/trunk/test/testfile.c&r1=109842&p2=apr/apr/trunk/test/testfile.c&r2=109843
==============================================================================
--- apr/apr/trunk/test/testfile.c	(original)
+++ apr/apr/trunk/test/testfile.c	Sat Dec  4 18:17:30 2004
@@ -595,6 +595,42 @@
 
 }
 
+static void test_writev_full(abts_case *tc, void *data)
+{
+    apr_file_t *f;
+    int nbytes;
+    struct iovec vec[5];
+    const char *fname = "data/testwritev_full.txt";
+
+    APR_ASSERT_SUCCESS(tc, "open file for writing",
+                       apr_file_open(&f, fname, 
+                                     APR_WRITE|APR_CREATE|APR_TRUNCATE, 
+                                     APR_OS_DEFAULT, p));
+    
+    vec[0].iov_base = LINE1;
+    vec[0].iov_len = strlen(LINE1);
+    vec[1].iov_base = LINE2;
+    vec[1].iov_len = strlen(LINE2);
+    vec[2].iov_base = LINE1;
+    vec[2].iov_len = strlen(LINE1);
+    vec[3].iov_base = LINE1;
+    vec[3].iov_len = strlen(LINE1);
+    vec[4].iov_base = LINE2;
+    vec[4].iov_len = strlen(LINE2);
+
+    APR_ASSERT_SUCCESS(tc, "writev_full of size 5 to file",
+                       apr_file_writev_full(f, vec, 5, &nbytes));
+
+    ABTS_INT_EQUAL(tc, strlen(LINE1)*3 + strlen(LINE2)*2, nbytes);
+
+    APR_ASSERT_SUCCESS(tc, "close for writing",
+                       apr_file_close(f));
+
+    file_contents_equal(tc, fname, LINE1 LINE2 LINE1 LINE1 LINE2, 
+                        strlen(LINE1)*3 + strlen(LINE2)*2);
+
+}
+
 static void test_truncate(abts_case *tc, void *data)
 {
     apr_status_t rv;
@@ -691,6 +727,7 @@
     abts_run_test(suite, test_gets, NULL);
     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_bigread, NULL);
     abts_run_test(suite, test_mod_neg, NULL);
     abts_run_test(suite, test_truncate, NULL);

Re: svn commit: r109843 - /apr/apr/trunk/CHANGES /apr/apr/trunk/file_io/unix/fullrw.c /apr/apr/trunk/file_io/unix/readwrite.c /apr/apr/trunk/include/apr_file_io.h /apr/apr/trunk/test/Makefile.in /apr/apr/trunk/test/data /apr/apr/trunk/test/testfile.c

Posted by Joe Orton <jo...@redhat.com>.
On Sun, Dec 05, 2004 at 02:17:31AM -0000, Paul Querna wrote:
> --- apr/apr/trunk/file_io/unix/fullrw.c	(original)
> +++ apr/apr/trunk/file_io/unix/fullrw.c	Sat Dec  4 18:17:30 2004
> @@ -60,3 +60,37 @@
>  
>      return status;
>  }
> +
> +APR_DECLARE(apr_status_t) apr_file_writev_full(apr_file_t *thefile,
> +                                               const struct iovec *vec,
> +                                               apr_size_t nvec,
> +                                               apr_size_t *bytes_written)
> +{
> +    apr_status_t status;
> +    apr_size_t total = 0;
> +
> +    do {
> +        int i;

Should be apr_size_t.

> +	apr_size_t amt;

ASCII character 9! noooo...

> +        status = apr_file_writev(thefile, vec, nvec, &amt);
> + 
> +       /* We assume that writev will only write complete iovec areas.
> +        * Incomplete writes inside a single area are not supported.
> +        * This should be safe according to SuS v2. 

No, there's no such guarantee; the function needs to check for that case
and should probably just call _write_full() on the remainder of that
vector.

Again style nits here:

> +        */
> +        for(i = 0; i < nvec; i++) {

for (

> +            total += vec[i].iov_len;
> +            if(total >= amt) {

if (