mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 00:12:19 +01:00 
			
		
		
		
	Merge branch 'wip/Jehan/fopen-modes' into 'master'
glib: Win32 does not accept "wb+" mode for fopen(). See merge request GNOME/glib!119
This commit is contained in:
		| @@ -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) | ||||
|     { | ||||
|   | ||||
| @@ -952,6 +952,56 @@ test_stdio_wrappers (void) | ||||
|   g_rmdir ("mkdir-test"); | ||||
| } | ||||
|  | ||||
| /* Win32 does not support "wb+", but g_fopen() should automatically | ||||
|  * translate this mode to its alias "w+b". | ||||
|  * Also check various other file open modes for correct support accross | ||||
|  * platforms. | ||||
|  * See: https://gitlab.gnome.org/GNOME/glib/merge_requests/119 | ||||
|  */ | ||||
| static void | ||||
| test_fopen_modes (void) | ||||
| { | ||||
|   char        *path = g_build_filename ("temp-fopen", NULL); | ||||
|   gsize        i; | ||||
|   const gchar *modes[] = | ||||
|     { | ||||
|       "w", | ||||
|       "r", | ||||
|       "a", | ||||
|       "w+", | ||||
|       "r+", | ||||
|       "a+", | ||||
|       "wb", | ||||
|       "rb", | ||||
|       "ab", | ||||
|       "w+b", | ||||
|       "r+b", | ||||
|       "a+b", | ||||
|       "wb+", | ||||
|       "rb+", | ||||
|       "ab+" | ||||
|     }; | ||||
|  | ||||
|   g_test_bug ("119"); | ||||
|  | ||||
|   if (g_file_test (path, G_FILE_TEST_EXISTS)) | ||||
|     g_error ("failed, %s exists, cannot test g_fopen()", path); | ||||
|  | ||||
|   for (i = 0; i < G_N_ELEMENTS (modes); i++) | ||||
|     { | ||||
|       FILE *f; | ||||
|  | ||||
|       g_test_message ("Testing fopen() mode '%s'", modes[i]); | ||||
|  | ||||
|       f = g_fopen (path, modes[i]); | ||||
|       g_assert_nonnull (f); | ||||
|       fclose (f); | ||||
|     } | ||||
|  | ||||
|   g_remove (path); | ||||
|   g_free (path); | ||||
| } | ||||
|  | ||||
| int | ||||
| main (int   argc, | ||||
|       char *argv[]) | ||||
| @@ -959,6 +1009,8 @@ main (int   argc, | ||||
|   g_setenv ("LC_ALL", "C", TRUE); | ||||
|   g_test_init (&argc, &argv, NULL); | ||||
|  | ||||
|   g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/merge_requests/"); | ||||
|  | ||||
|   g_test_add_func ("/fileutils/build-path", test_build_path); | ||||
|   g_test_add_func ("/fileutils/build-pathv", test_build_pathv); | ||||
|   g_test_add_func ("/fileutils/build-filename", test_build_filename); | ||||
| @@ -974,6 +1026,7 @@ main (int   argc, | ||||
|   g_test_add_func ("/fileutils/set-contents", test_set_contents); | ||||
|   g_test_add_func ("/fileutils/read-link", test_read_link); | ||||
|   g_test_add_func ("/fileutils/stdio-wrappers", test_stdio_wrappers); | ||||
|   g_test_add_func ("/fileutils/fopen-modes", test_fopen_modes); | ||||
|  | ||||
|   return g_test_run (); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user