Bill Allombert on Thu, 17 Nov 2016 14:56:21 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Windows gp64 writebin creates unreadable file for \p174


On Fri, Nov 04, 2016 at 03:55:39PM +0100, Bill Allombert wrote:
> The issue is that fread is doing some CR/LF conversion.
> We should use fopen(,"rb"). 
> The attached patch seems to fix this bug.
> Maybe there is a better place to set the b flag.

I did another patch which avoid to break readstr.

Cheers,
Bill.
commit 1f4f0c64ecccef331858bd1b9bde33839de3b400
Author: Bill Allombert <Bill.Allombert@math.u-bordeaux1.fr>
Date:   Mon Nov 7 17:36:47 2016 +0100

    writebin, file_is_binary: use fopen mode "b" for windows support

diff --git a/src/language/es.c b/src/language/es.c
index 0a28371..7a1d509 100644
--- a/src/language/es.c
+++ b/src/language/es.c
@@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
 #include "../systems/mingw/pwinver.h"
 #include <windows.h>
 #include <process.h> /* for getpid */
+#include <fcntl.h>
+#include <io.h>      /* for setmode */
 #include "../systems/mingw/mingw.h"
 #endif
 #ifdef __EMSCRIPTEN__
@@ -4405,13 +4407,17 @@ int
 file_is_binary(FILE *f)
 {
   int c = fgetc(f); ungetc(c,f);
-  return (c != EOF && isprint(c) == 0 && isspace(c) == 0);
+  int r = (c != EOF && isprint(c) == 0 && isspace(c) == 0);
+#ifdef _WIN32
+  if (r) { setmode(fileno(f), _O_BINARY); rewind(f); }
+#endif
+  return r;
 }
 
 void
 writebin(const char *name, GEN x)
 {
-  FILE *f = fopen(name,"r");
+  FILE *f = fopen(name,"rb");
   pari_sp av = avma;
   GEN V;
   int already = f? 1: 0;
@@ -4421,7 +4427,7 @@ writebin(const char *name, GEN x)
     fclose(f);
     if (!ok) pari_err_FILE("binary output file",name);
   }
-  f = fopen(name,"a");
+  f = fopen(name,"ab");
   if (!f) pari_err_FILE("binary output file",name);
   if (!already) write_magic(f);