[geany/geany] 127e94: Windows: Convert working directory into locale encoding before spawning commands
Enrico Tröger
git-noreply at geany.org
Sun Nov 13 13:55:39 UTC 2016
Branch: refs/heads/master
Author: Enrico Tröger <enrico.troeger at uvena.de>
Committer: Enrico Tröger <enrico.troeger at uvena.de>
Date: Sun, 13 Nov 2016 13:55:39 UTC
Commit: 127e94199ba92f2584d9c83fb90126e42265bbb9
https://github.com/geany/geany/commit/127e94199ba92f2584d9c83fb90126e42265bbb9
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).
More information about the Commits
mailing list