]> Savannah Git Hosting - gnulib.git/commitdiff
fopen-gnu: make 'b' flag can be used with 'e' on Windows
authorDaiki Ueno <ueno@gnu.org>
Thu, 28 May 2020 09:40:49 +0000 (11:40 +0200)
committerDaiki Ueno <ueno@gnu.org>
Thu, 28 May 2020 16:41:46 +0000 (18:41 +0200)
* lib/fopen.c (rpl_fopen): Pass O_BINARY to open, if a 'b' flag is
specified on Windows.
* tests/test-fopen-gnu.c (DATA): New define.
(main): Add test for reading binary files with an 'e' flag.

ChangeLog
lib/fopen.c
tests/test-fopen-gnu.c

index c17b76b72ec2190a0c2631339d0eb1a64eafe70e..ea2716b2f235db4956071abbf12bb0be77908e65 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2020-05-28  Daiki Ueno  <ueno@gnu.org>
+
+       fopen-gnu: make 'b' flag can be used with 'e' on Windows
+       * lib/fopen.c (rpl_fopen): Pass O_BINARY to open, if a 'b' flag is
+       specified on Windows.
+       * tests/test-fopen-gnu.c (DATA): New define.
+       (main): Add test for reading binary files with an 'e' flag.
+
 2020-05-27  Bruno Haible  <bruno@clisp.org>
 
        Don't assume that UNICODE is not defined.
index 20065e4c6f76a766f41f5866e854f0e54b806131..47d7f194df7f9514751f5282c865ae19afbf41fd 100644 (file)
@@ -101,6 +101,10 @@ rpl_fopen (const char *filename, const char *mode)
 #endif
             continue;
           case 'b':
+            /* While it is non-standard, O_BINARY is guaranteed by
+               gnulib <fcntl.h>.  We can also assume that orig_fopen
+               supports the 'b' flag.  */
+            open_flags_standard |= O_BINARY;
 #if GNULIB_FOPEN_GNU
             if (q < fdopen_mode_buf + BUF_SIZE)
               *q++ = *p;
index cae40421abf88d90b191dc4035031eed28e1324a..4d98dcd8550521133c36ae88ccf7c6d9b1c61b34 100644 (file)
 
 #define BASE "test-fopen-gnu.t"
 
+/* 0x1a is an EOF on Windows.  */
+#define DATA "abc\x1adef"
+
 int
 main (void)
 {
   FILE *f;
   int fd;
   int flags;
+  char buf[16];
 
   /* Remove anything from prior partial run.  */
   unlink (BASE "file");
+  unlink (BASE "binary");
 
   /* Create the file.  */
   f = fopen (BASE "file", "w");
@@ -64,8 +69,20 @@ main (void)
   ASSERT (f == NULL);
   ASSERT (errno == EEXIST);
 
+  /* Open a binary file and check that the 'e' mode doesn't interfere.  */
+  f = fopen (BASE "binary", "wbe");
+  ASSERT (f);
+  ASSERT (fwrite (DATA, 1, sizeof (DATA)-1, f) == sizeof (DATA)-1);
+  ASSERT (fclose (f) == 0);
+
+  f = fopen (BASE "binary", "rbe");
+  ASSERT (f);
+  ASSERT (fread (buf, 1, sizeof (buf), f) == sizeof (DATA)-1);
+  ASSERT (fclose (f) == 0);
+
   /* Cleanup.  */
   ASSERT (unlink (BASE "file") == 0);
+  ASSERT (unlink (BASE "binary") == 0);
 
   return 0;
 }