Branch: refs/heads/master Author: Enrico Tröger enrico.troeger@uvena.de Committer: Enrico Tröger enrico.troeger@uvena.de Date: Sun, 13 Nov 2016 13:55:39 UTC Commit: 127e94199ba92f2584d9c83fb90126e42265bbb9 https://github.com/geany/geany/commit/127e94199ba92f2584d9c83fb90126e42265bb...
Log Message: ----------- Windows: Convert working directory into locale encoding before spawning commands
The working directory is passed in in UTF-8 encoding but Windows API expects locale encoding here, so convert it.
Fixes #1076.
Modified Paths: -------------- src/build.c src/spawn.c src/win32.c src/win32.h
Modified: src/build.c 9 lines changed, 8 insertions(+), 1 deletions(-) =================================================================== @@ -1070,6 +1070,7 @@ static gchar *build_create_shellscript(const gchar *working_dir, const gchar *cm gboolean success = TRUE; #ifdef G_OS_WIN32 gchar *expanded_cmd; + guint codepage; #else gchar *escaped_dir; #endif @@ -1079,9 +1080,15 @@ static gchar *build_create_shellscript(const gchar *working_dir, const gchar *cm close(fd);
#ifdef G_OS_WIN32 + /* We set the console codepage to UTF-8 (65001) before changing the working directory + * because the working directory is in UTF-8 encoding. + * Then we reset it again to the default value before executing the command. */ + codepage = win32_get_console_codepage(); /* Expand environment variables like %blah%. */ expanded_cmd = win32_expand_environment_variables(cmd); - str = g_strdup_printf("cd "%s"\n\n%s\n\n%s\ndel "%%0"\n\npause\n", working_dir, expanded_cmd, (autoclose) ? "" : "pause"); + str = g_strdup_printf( + "chcp 65001 > nul\ncd "%s"\nchcp %u > nul\n\n%s\n\n%s\ndel "%%0"\n\npause\n", + working_dir, codepage, expanded_cmd, (autoclose) ? "" : "pause"); g_free(expanded_cmd); #else escaped_dir = g_shell_quote(working_dir);
Modified: src/spawn.c 48 lines changed, 46 insertions(+), 2 deletions(-) =================================================================== @@ -522,6 +522,9 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch #ifdef G_OS_WIN32 GString *command; GArray *environment; + GError *gerror = NULL; + gchar *locale_working_directory; + gchar *locale_command; gchar *failure;
if (command_line) @@ -568,11 +571,52 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch envp++; }
- failure = spawn_create_process_with_pipes(command->str, working_directory, + // convert working directory into locale encoding + if (g_utf8_validate(working_directory, -1, NULL)) + { + locale_working_directory = g_locale_from_utf8(working_directory, -1, NULL, NULL, &gerror); + if (gerror) { + /* TODO use the code below post-1.28 as it introduces a new string + gchar *msg = g_strdup_printf( + _("Failed to convert working directory into locale encoding: %s"), gerror->message); + g_set_error_literal(error, gerror->domain, gerror->code, msg); + */ + g_set_error_literal(error, gerror->domain, gerror->code, gerror->message); + g_error_free(gerror); + g_string_free(command, TRUE); + g_array_free(environment, TRUE); + g_free(locale_working_directory); + /*g_free(msg);*/ + return FALSE; + } + } + // convert command into locale encoding + if (g_utf8_validate(command->str, -1, NULL)) + { + locale_command = g_locale_from_utf8(command->str, -1, NULL, NULL, &gerror); + if (gerror) { + /* TODO use the code below post-1.28 as it introduces a new string + gchar *msg = g_strdup_printf( + _("Failed to convert command into locale encoding: %s"), gerror->message); + g_set_error_literal(error, gerror->domain, gerror->code, msg); + */ + g_set_error_literal(error, gerror->domain, gerror->code, gerror->message); + g_error_free(gerror); + g_string_free(command, TRUE); + g_array_free(environment, TRUE); + g_free(locale_working_directory); + g_free(locale_command); + /*g_free(msg);*/ + return FALSE; + } + } + failure = spawn_create_process_with_pipes(locale_command, locale_working_directory, envp ? environment->data : NULL, child_pid, stdin_fd, stdout_fd, stderr_fd);
g_string_free(command, TRUE); g_array_free(environment, TRUE); + g_free(locale_working_directory); + g_free(locale_command);
if (failure) { @@ -655,7 +699,7 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch #ifdef ENFILE case G_SPAWN_ERROR_NFILE : en = ENFILE; break; #endif - #ifdef EMFILE + #ifdef EMFILE case G_SPAWN_ERROR_MFILE : en = EMFILE; break; #endif #ifdef EINVAL
Modified: src/win32.c 12 lines changed, 12 insertions(+), 0 deletions(-) =================================================================== @@ -1032,4 +1032,16 @@ gchar *win32_get_user_config_dir(void) return g_build_filename(g_get_user_config_dir(), "geany", NULL); }
+ +/* Retrieve the console codepage + * In case GetConsoleOutputCP() returns 0 (i.e. the application doesn't have an own console window + * fallback to GetOEMCP(). */ +guint win32_get_console_codepage(void) +{ + guint codepage = GetConsoleOutputCP(); + if (codepage == 0) + codepage = GetOEMCP(); + return codepage; +} + #endif
Modified: src/win32.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -68,6 +68,8 @@ gchar *win32_expand_environment_variables(const gchar *str);
gchar *win32_get_user_config_dir(void);
+guint win32_get_console_codepage(void); + G_END_DECLS
#endif /* G_OS_WIN32 */
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).