Skip to content

Commit 3bf9bee

Browse files
authored
[mono][aot] Fix support for files with non-ascii characters on windows (#92279)
* [mono][aot] Fix support for files with non-ascii characters Add g_fopen, g_unlink and g_rename which on windows do a utf8 to utf16 conversion and then call the corresponding wide char api. * [mono][eglib] Avoid utf16 conversion if all characters are ASCII
1 parent ba8993f commit 3bf9bee

File tree

3 files changed

+92
-32
lines changed

3 files changed

+92
-32
lines changed

src/mono/mono/eglib/gfile.c

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,27 +105,89 @@ g_file_error_from_errno (gint err_no)
105105
}
106106
}
107107

108-
FILE *
109-
g_fopen (const char *path, const char *mode)
108+
#ifdef HOST_WIN32
109+
static gboolean
110+
is_ascii_string (const gchar *str)
111+
{
112+
while (*str) {
113+
if (!g_isascii (*str))
114+
return FALSE;
115+
}
116+
return TRUE;
117+
}
118+
#endif
119+
120+
FILE*
121+
g_fopen (const gchar *path, const gchar *mode)
110122
{
111123
FILE *fp;
112124

113125
if (!path)
114126
return NULL;
115127

116-
#ifndef HOST_WIN32
117-
fp = fopen (path, mode);
118-
#else
119-
gunichar2 *wPath = g_utf8_to_utf16 (path, -1, 0, 0, 0);
120-
gunichar2 *wMode = g_utf8_to_utf16 (mode, -1, 0, 0, 0);
128+
#ifdef HOST_WIN32
129+
if (is_ascii_string (path) && is_ascii_string (mode)) {
130+
fp = fopen (path, mode);
131+
} else {
132+
gunichar2 *wPath = g_utf8_to_utf16 (path, -1, 0, 0, 0);
133+
gunichar2 *wMode = g_utf8_to_utf16 (mode, -1, 0, 0, 0);
121134

122-
if (!wPath || !wMode)
123-
return NULL;
135+
if (!wPath || !wMode)
136+
return NULL;
124137

125-
fp = _wfopen ((wchar_t *) wPath, (wchar_t *) wMode);
126-
g_free (wPath);
127-
g_free (wMode);
138+
fp = _wfopen ((wchar_t *) wPath, (wchar_t *) wMode);
139+
g_free (wPath);
140+
g_free (wMode);
141+
}
142+
#else
143+
fp = fopen (path, mode);
128144
#endif
129145

130146
return fp;
131147
}
148+
149+
int
150+
g_rename (const gchar *src_path, const gchar *dst_path)
151+
{
152+
#ifdef HOST_WIN32
153+
if (is_ascii_string (src_path) && is_ascii_string (dst_path)) {
154+
return rename (src_path, dst_path);
155+
} else {
156+
gunichar2 *wSrcPath = g_utf8_to_utf16 (src_path, -1, 0, 0, 0);
157+
gunichar2 *wDstPath = g_utf8_to_utf16 (dst_path, -1, 0, 0, 0);
158+
159+
if (!wSrcPath || !wDstPath)
160+
return -1;
161+
162+
int ret = _wrename ((wchar_t *) wSrcPath, (wchar_t *) wDstPath);
163+
g_free (wSrcPath);
164+
g_free (wDstPath);
165+
166+
return ret;
167+
}
168+
#else
169+
return rename (src_path, dst_path);
170+
#endif
171+
}
172+
173+
int
174+
g_unlink (const gchar *path)
175+
{
176+
#ifdef HOST_WIN32
177+
if (is_ascii_string (path)) {
178+
return unlink (path);
179+
} else {
180+
gunichar2 *wPath = g_utf8_to_utf16 (path, -1, 0, 0, 0);
181+
182+
if (!wPath)
183+
return -1;
184+
185+
int ret = _wunlink ((wchar_t *) wPath);
186+
g_free (wPath);
187+
188+
return ret;
189+
}
190+
#else
191+
return unlink (path);
192+
#endif
193+
}

src/mono/mono/eglib/glib.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ gint g_ascii_xdigit_value (gchar c);
391391
#define g_ascii_isalpha(c) (isalpha (c) != 0)
392392
#define g_ascii_isprint(c) (isprint (c) != 0)
393393
#define g_ascii_isxdigit(c) (isxdigit (c) != 0)
394+
#define g_isascii(c) (isascii (c) != 0)
394395

395396
/* FIXME: g_strcasecmp supports utf8 unicode stuff */
396397
#ifdef _MSC_VER
@@ -962,7 +963,9 @@ typedef enum {
962963

963964
G_ENUM_FUNCTIONS (GFileTest)
964965

965-
FILE * g_fopen (const char *path, const char *mode);
966+
FILE* g_fopen (const gchar *path, const gchar *mode);
967+
int g_rename (const gchar *src_path, const gchar *dst_path);
968+
int g_unlink (const gchar *path);
966969
gboolean g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **gerror);
967970
GFileError g_file_error_from_errno (gint err_no);
968971
gint g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **gerror);
@@ -974,11 +977,6 @@ gboolean g_file_test (const gchar *filename, GFileTest test);
974977
#define g_open open
975978
#endif
976979
#ifdef G_OS_WIN32
977-
#define g_unlink _unlink
978-
#else
979-
#define g_unlink unlink
980-
#endif
981-
#ifdef G_OS_WIN32
982980
#define g_write _write
983981
#else
984982
#define g_write write

src/mono/mono/mini/aot-compiler.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5529,7 +5529,7 @@ MONO_RESTORE_WARNING
55295529

55305530
if (acfg->aot_opts.export_symbols_outfile) {
55315531
char *export_symbols_out = g_string_free (export_symbols, FALSE);
5532-
FILE* export_symbols_outfile = fopen (acfg->aot_opts.export_symbols_outfile, "w");
5532+
FILE* export_symbols_outfile = g_fopen (acfg->aot_opts.export_symbols_outfile, "w");
55335533
if (!export_symbols_outfile) {
55345534
fprintf (stderr, "Unable to open specified export_symbols_outfile '%s' to append symbols '%s': %s\n", acfg->aot_opts.export_symbols_outfile, export_symbols_out, strerror (errno));
55355535
g_free (export_symbols_out);
@@ -13446,11 +13446,11 @@ compile_asm (MonoAotCompile *acfg)
1344613446
}
1344713447
#endif
1344813448

13449-
if (0 != rename (tmp_outfile_name, outfile_name)) {
13449+
if (0 != g_rename (tmp_outfile_name, outfile_name)) {
1345013450
if (G_FILE_ERROR_EXIST == g_file_error_from_errno (errno)) {
1345113451
/* Since we are rebuilding the module we need to be able to replace any old copies. Remove old file and retry rename operation. */
13452-
unlink (outfile_name);
13453-
rename (tmp_outfile_name, outfile_name);
13452+
g_unlink (outfile_name);
13453+
g_rename (tmp_outfile_name, outfile_name);
1345413454
}
1345513455
}
1345613456

@@ -13463,7 +13463,7 @@ compile_asm (MonoAotCompile *acfg)
1346313463
#endif
1346413464

1346513465
if (!acfg->aot_opts.save_temps)
13466-
unlink (objfile);
13466+
g_unlink (objfile);
1346713467

1346813468
g_free (tmp_outfile_name);
1346913469
g_free (outfile_name);
@@ -13472,7 +13472,7 @@ compile_asm (MonoAotCompile *acfg)
1347213472
if (acfg->aot_opts.save_temps)
1347313473
aot_printf (acfg, "Retained input file.\n");
1347413474
else
13475-
unlink (acfg->tmpfname);
13475+
g_unlink (acfg->tmpfname);
1347613476

1347713477
return 0;
1347813478
}
@@ -13520,7 +13520,7 @@ load_profile_file (MonoAotCompile *acfg, char *filename)
1352013520
int version;
1352113521
char magic [32];
1352213522

13523-
infile = fopen (filename, "rb");
13523+
infile = g_fopen (filename, "rb");
1352413524
if (!infile) {
1352513525
fprintf (stderr, "Unable to open file '%s': %s.\n", filename, strerror (errno));
1352613526
exit (1);
@@ -14538,7 +14538,7 @@ static void aot_dump (MonoAotCompile *acfg)
1453814538
mono_json_writer_object_end (&writer);
1453914539

1454014540
dumpname = g_strdup_printf ("%s.json", g_path_get_basename (acfg->image->name));
14541-
dumpfile = fopen (dumpname, "w+");
14541+
dumpfile = g_fopen (dumpname, "w+");
1454214542
g_free (dumpname);
1454314543

1454414544
fprintf (dumpfile, "%s", writer.text->str);
@@ -14947,7 +14947,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1494714947
}
1494814948

1494914949
if (acfg->aot_opts.logfile) {
14950-
acfg->logfile = fopen (acfg->aot_opts.logfile, "a+");
14950+
acfg->logfile = g_fopen (acfg->aot_opts.logfile, "a+");
1495114951
}
1495214952

1495314953
if (acfg->aot_opts.trimming_eligible_methods_outfile && acfg->dedup_phase != DEDUP_COLLECT) {
@@ -14961,7 +14961,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1496114961
}
1496214962

1496314963
if (acfg->aot_opts.data_outfile) {
14964-
acfg->data_outfile = fopen (acfg->aot_opts.data_outfile, "w+");
14964+
acfg->data_outfile = g_fopen (acfg->aot_opts.data_outfile, "w+");
1496514965
if (!acfg->data_outfile) {
1496614966
aot_printerrf (acfg, "Unable to create file '%s': %s\n", acfg->aot_opts.data_outfile, strerror (errno));
1496714967
return 1;
@@ -15124,7 +15124,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1512415124
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_EAGER_LOAD);
1512515125

1512615126
if (acfg->aot_opts.instances_logfile_path) {
15127-
acfg->instances_logfile = fopen (acfg->aot_opts.instances_logfile_path, "w");
15127+
acfg->instances_logfile = g_fopen (acfg->aot_opts.instances_logfile_path, "w");
1512815128
if (!acfg->instances_logfile) {
1512915129
aot_printerrf (acfg, "Unable to create logfile: '%s'.\n", acfg->aot_opts.instances_logfile_path);
1513015130
return 1;
@@ -15387,7 +15387,7 @@ create_depfile (MonoAotCompile *acfg)
1538715387
// FIXME: Support other configurations
1538815388
g_assert (acfg->aot_opts.llvm_only && acfg->aot_opts.asm_only && acfg->aot_opts.llvm_outfile);
1538915389

15390-
depfile = fopen (acfg->aot_opts.depfile, "w");
15390+
depfile = g_fopen (acfg->aot_opts.depfile, "w");
1539115391
g_assert (depfile);
1539215392

1539315393
int ntargets = 1;
@@ -15459,14 +15459,14 @@ emit_aot_image (MonoAotCompile *acfg)
1545915459
acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
1546015460
else
1546115461
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
15462-
acfg->fp = fopen (acfg->tmpfname, "w+");
15462+
acfg->fp = g_fopen (acfg->tmpfname, "w+");
1546315463
} else {
1546415464
if (strcmp (acfg->aot_opts.temp_path, "") == 0) {
1546515465
acfg->fp = fdopen (g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL), "w+");
1546615466
} else {
1546715467
acfg->tmpbasename = g_build_filename (acfg->aot_opts.temp_path, "temp", (const char*)NULL);
1546815468
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
15469-
acfg->fp = fopen (acfg->tmpfname, "w+");
15469+
acfg->fp = g_fopen (acfg->tmpfname, "w+");
1547015470
}
1547115471
}
1547215472
if (acfg->fp == 0 && !acfg->aot_opts.llvm_only) {

0 commit comments

Comments
 (0)