[glib: 1/3] glib: Win32 does not accept "wb+" mode for fopen().



commit 2b6bfdb12589ac212ffe05a556034b02ae4af6c2
Author: Jehan <jehan girinstud io>
Date:   Tue Jun 19 21:40:28 2018 +0200

    glib: Win32 does not accept "wb+" mode for fopen().
    
    Nevertheless it accepts "w+b".
    When checking the Win32 documentation of fopen()/_wfopen(), it clearly
    states:
    > In addition to the earlier values, the following characters can be
    > appended to mode to specify the translation mode for newline
    > characters.
    
    This implementation expects 'b' or 't' to be appended, and therefore
    "wb+" ends up with an error, whereas the alias "w+b" works perfectly
    while it is exactly the same thing. So let's just have glib "translate"
    the mode when it can to have it working transparently the same way on
    every platform.

 glib/gstdio.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)
---
diff --git a/glib/gstdio.c b/glib/gstdio.c
index e158de223..ffbd37180 100644
--- a/glib/gstdio.c
+++ b/glib/gstdio.c
@@ -544,6 +544,26 @@ _g_win32_readlink_utf16 (const gunichar2 *filename,
   return result;
 }
 
+static gchar *
+_g_win32_get_mode_alias (const gchar *mode)
+{
+  gchar *alias;
+
+  alias = g_strdup (mode);
+  if (strlen (mode) > 2 && mode[2] == '+')
+    {
+      /* Windows implementation of fopen() does not accept modes such as
+       * "wb+". The 'b' needs to be appended to "w+", i.e. "w+b". Note
+       * that otherwise these 2 modes are supposed to be aliases, hence
+       * swappable at will.
+       */
+      alias[1] = '+';
+      alias[2] = mode[1];
+    }
+
+  return alias;
+}
+
 int
 g_win32_readlink_utf8 (const gchar *filename,
                        gchar       *buf,
@@ -1268,6 +1288,7 @@ g_fopen (const gchar *filename,
 #ifdef G_OS_WIN32
   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
   wchar_t *wmode;
+  gchar   *mode2;
   FILE *retval;
   int save_errno;
 
@@ -1277,7 +1298,9 @@ g_fopen (const gchar *filename,
       return NULL;
     }
 
-  wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
+  mode2 = _g_win32_get_mode_alias (mode);
+  wmode = g_utf8_to_utf16 (mode2, -1, NULL, NULL, NULL);
+  g_free (mode2);
 
   if (wmode == NULL)
     {
@@ -1324,6 +1347,7 @@ g_freopen (const gchar *filename,
 #ifdef G_OS_WIN32
   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
   wchar_t *wmode;
+  gchar   *mode2;
   FILE *retval;
   int save_errno;
 
@@ -1332,8 +1356,10 @@ g_freopen (const gchar *filename,
       errno = EINVAL;
       return NULL;
     }
-  
-  wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
+
+  mode2 = _g_win32_get_mode_alias (mode);
+  wmode = g_utf8_to_utf16 (mode2, -1, NULL, NULL, NULL);
+  g_free (mode2);
 
   if (wmode == NULL)
     {


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