]> Savannah Git Hosting - gnulib.git/commitdiff
af_alg: Fix state of stream after sendfile() succeeds.
authorBruno Haible <bruno@clisp.org>
Sun, 24 Jun 2018 22:41:03 +0000 (00:41 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 25 Jun 2018 00:56:38 +0000 (02:56 +0200)
* lib/af_alg.c (afalg_stream): Invoke fflush and lseek, to ensure that
the stream is correctly positioned afterwards.
* modules/crypto/af_alg (Depends-on): Add fflush.
* tests/test-digest.h (test_digest_on_files): Verify that after the
operation the stream is positioned at end of file.

ChangeLog
lib/af_alg.c
modules/crypto/af_alg
tests/test-digest.h

index 3890bcadca2f0c41698c13e0740ed95341460512..33da642c3b4bac8a51aec774d159c0f4bddb920f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-06-24  Bruno Haible  <bruno@clisp.org>
+
+       af_alg: Fix state of stream after sendfile() succeeds.
+       * lib/af_alg.c (afalg_stream): Invoke fflush and lseek, to ensure that
+       the stream is correctly positioned afterwards.
+       * modules/crypto/af_alg (Depends-on): Add fflush.
+       * tests/test-digest.h (test_digest_on_files): Verify that after the
+       operation the stream is positioned at end of file.
+
 2018-06-24  Jim Meyering  <meyering@fb.com>
 
        canon-host: take GCC9's advice rather than ignoring warning
index 555eb2be6bab5e381eb8b11de7975428929b8265..2753ab9a420e0a9f78f6a87c52fec127943b009f 100644 (file)
@@ -113,18 +113,47 @@ afalg_stream (FILE *stream, const char *alg,
   int fd = fileno (stream);
   int result;
   struct stat st;
-  off_t nseek = 0; /* Number of bytes to seek (backwards) in case of error.  */
   off_t off = ftello (stream);
   if (0 <= off && fstat (fd, &st) == 0
       && (S_ISREG (st.st_mode) || S_TYPEISSHM (&st) || S_TYPEISTMO (&st))
       && off < st.st_size && st.st_size - off < SYS_BUFSIZE_MAX)
     {
-      off_t nbytes = st.st_size - off;
-      result = sendfile (ofd, fd, &off, nbytes) == nbytes ? 0 : -EAFNOSUPPORT;
+      /* Make sure the offset of fileno (stream) reflects how many bytes
+         have been read from stream before this function got invoked.
+         Note: fflush on an input stream after ungetc does not work as expected
+         on some platforms.  Therefore this situation is not supported here.  */
+      if (fflush (stream))
+        result = -EIO;
+      else
+        {
+          off_t nbytes = st.st_size - off;
+          if (sendfile (ofd, fd, &off, nbytes) == nbytes)
+            {
+              if (read (ofd, resblock, hashlen) == hashlen)
+                {
+                  /* The input buffers of stream are no longer valid.  */
+                  if (lseek (fd, off, SEEK_SET) != (off_t)-1)
+                    result = 0;
+                  else
+                    /* The file position of fd has not changed.  */
+                    result = -EAFNOSUPPORT;
+                }
+              else
+                /* The file position of fd has not changed.  */
+                result = -EAFNOSUPPORT;
+            }
+          else
+            /* The file position of fd has not changed.  */
+            result = -EAFNOSUPPORT;
+       }
     }
   else
     {
       /* sendfile not possible, do a classic read-write loop.  */
+
+      /* Number of bytes to seek (backwards) in case of error.  */
+      off_t nseek = 0;
+
       for (;;)
         {
           char buf[BLOCKSIZE];
@@ -154,14 +183,14 @@ afalg_stream (FILE *stream, const char *alg,
               break;
             }
         }
-    }
 
-  if (result == 0 && read (ofd, resblock, hashlen) != hashlen)
-    {
-      if (nseek == 0 || fseeko (stream, nseek, SEEK_CUR) == 0)
-        result = -EAFNOSUPPORT;
-      else
-        result = -EIO;
+      if (result == 0 && read (ofd, resblock, hashlen) != hashlen)
+        {
+          if (nseek == 0 || fseeko (stream, nseek, SEEK_CUR) == 0)
+            result = -EAFNOSUPPORT;
+          else
+            result = -EIO;
+        }
     }
   close (ofd);
   return result;
index 2ad25febbf2af75a8b7f5dcbb542a585dea77ed3..95273d495f814cfa6a5915c277999cfa3d026c7c 100644 (file)
@@ -9,6 +9,7 @@ m4/af_alg.m4
 
 Depends-on:
 c99             [test $USE_AF_ALG = 1]
+fflush          [test $USE_AF_ALG = 1]
 fseeko          [test $USE_AF_ALG = 1]
 ftello          [test $USE_AF_ALG = 1]
 sys_socket
index 369ef9f6a85c669536e89674c919475508e9ddb0..c58d3dad87a3d80d2e0895aa382c5de462430217 100644 (file)
@@ -129,6 +129,12 @@ test_digest_on_files (int (*streamfunc) (FILE *, void *),
             fprintf (stderr, "\n");
             exit (1);
           }
+        /* Verify that fp is now positioned at end of file.  */
+        if (getc (fp) != EOF)
+          {
+            fprintf (stderr, "%s left the stream not at EOF\n", streamfunc_name);
+            exit (1);
+          }
         fclose (fp);
         free (digest - 1);
       }