[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