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.
This commit is contained in:
Jehan 2018-06-19 21:40:28 +02:00
parent 3126f73c80
commit 2b6bfdb125

View File

@ -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)
{