[geany/geany] a45091: spawn: Use Wide API on Windows
Colomban Wendling
git-noreply at geany.org
Sun Nov 13 13:55:40 UTC 2016
Branch: refs/heads/master
Author: Colomban Wendling <ban at herbesfolles.org>
Committer: Enrico Tröger <enrico.troeger at uvena.de>
Date: Sun, 13 Nov 2016 13:55:40 UTC
Commit: a45091413a0dae1bc72546281210674fa250db5c
https://github.com/geany/geany/commit/a45091413a0dae1bc72546281210674fa250db5c
Log Message:
-----------
spawn: Use Wide API on Windows
Try and use Unicode variants of the Windows process creation API in
order to support filenames (and possibly environment) outside the
locale codepage.
WARNING: Implications on using Unicode environment are unknown.
It might affect the called process, or not, not sure.
Modified Paths:
--------------
src/spawn.c
Modified: src/spawn.c
123 lines changed, 66 insertions(+), 57 deletions(-)
===================================================================
@@ -67,6 +67,7 @@
#else
# include "support.h"
#endif
+#include "utils.h"
#if ! GLIB_CHECK_VERSION(2, 31, 20) && ! defined(G_SPAWN_ERROR_TOO_BIG)
# define G_SPAWN_ERROR_TOO_BIG G_SPAWN_ERROR_2BIG
@@ -307,11 +308,11 @@ gboolean spawn_kill_process(GPid pid, GError **error)
#ifdef G_OS_WIN32
-static gchar *spawn_create_process_with_pipes(char *command_line, const char *working_directory,
- void *environment, HANDLE *hprocess, int *stdin_fd, int *stdout_fd, int *stderr_fd)
+static gchar *spawn_create_process_with_pipes(wchar_t *w_command_line, const wchar_t *w_working_directory,
+ void *w_environment, HANDLE *hprocess, int *stdin_fd, int *stdout_fd, int *stderr_fd)
{
enum { WRITE_STDIN, READ_STDOUT, READ_STDERR, READ_STDIN, WRITE_STDOUT, WRITE_STDERR };
- STARTUPINFO startup;
+ STARTUPINFOW startup;
PROCESS_INFORMATION process;
HANDLE hpipe[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
int *fd[3] = { stdin_fd, stdout_fd, stderr_fd };
@@ -372,8 +373,9 @@ static gchar *spawn_create_process_with_pipes(char *command_line, const char *wo
startup.hStdOutput = hpipe[WRITE_STDOUT];
startup.hStdError = hpipe[WRITE_STDERR];
- if (!CreateProcess(NULL, command_line, NULL, NULL, TRUE, pipe_io ? CREATE_NO_WINDOW : 0,
- environment, working_directory, &startup, &process))
+ if (!CreateProcessW(NULL, w_command_line, NULL, NULL, TRUE,
+ CREATE_UNICODE_ENVIRONMENT | (pipe_io ? CREATE_NO_WINDOW : 0),
+ w_environment, w_working_directory, &startup, &process))
{
failed = ""; /* report the message only */
/* further errors will not be reported */
@@ -521,9 +523,9 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch
#ifdef G_OS_WIN32
GString *command;
- GArray *environment;
- gchar *locale_working_directory = NULL;
- gchar *locale_command = NULL;
+ GArray *w_environment;
+ wchar_t *w_working_directory = NULL;
+ wchar_t *w_command = NULL;
gboolean success = TRUE;
if (command_line)
@@ -555,7 +557,7 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch
else
command = g_string_new(NULL);
- environment = g_array_new(TRUE, FALSE, sizeof(char));
+ w_environment = g_array_new(TRUE, FALSE, sizeof(wchar_t));
while (argv && *argv)
spawn_append_argument(command, *argv++);
@@ -566,81 +568,88 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch
while (envp && *envp && success)
{
- gsize locale_entry_len;
- gchar *locale_entry;
+ glong w_entry_len;
+ wchar_t *w_entry;
+ gchar *tmp = NULL;
- if (g_utf8_validate(*envp, -1, NULL))
+ // FIXME: remove this and rely on UTF-8 input
+ if (! g_utf8_validate(*envp, -1, NULL))
{
- /* TODO: better error message */
- locale_entry = g_locale_from_utf8(*envp, -1, NULL, &locale_entry_len, error);
- }
- else
- {
- locale_entry_len = strlen(*envp);
- locale_entry = g_memdup(*envp, locale_entry_len + 1);
+ tmp = utils_get_utf8_from_locale(*envp);
+ *envp = tmp;
}
+ /* TODO: better error message */
+ w_entry = g_utf8_to_utf16(*envp, -1, NULL, &w_entry_len, error);
- if (! locale_entry)
+ if (! w_entry)
success = FALSE;
else
{
/* copy the entry, including NUL terminator */
- g_array_append_vals(environment, locale_entry, locale_entry_len + 1);
- g_free(locale_entry);
+ g_array_append_vals(w_environment, w_entry, w_entry_len + 1);
+ g_free(w_entry);
}
+ g_free(tmp);
envp++;
}
/* convert working directory into locale encoding */
if (success && working_directory)
{
- if (g_utf8_validate(working_directory, -1, NULL))
- {
- GError *gerror = NULL;
+ GError *gerror = NULL;
+ const gchar *utf8_working_directory;
+ gchar *tmp = NULL;
- locale_working_directory = g_locale_from_utf8(working_directory, -1, NULL, NULL, &gerror);
- if (! locale_working_directory)
- {
- /* TODO use the code below post-1.28 as it introduces a new string
- g_set_error(error, gerror->domain, gerror->code,
- _("Failed to convert working directory into locale encoding: %s"), gerror->message);
- */
- g_propagate_error(error, gerror);
- success = FALSE;
- }
- }
+ // FIXME: remove this and rely on UTF-8 input
+ if (! g_utf8_validate(working_directory, -1, NULL))
+ utf8_working_directory = tmp = utils_get_utf8_from_locale(working_directory);
else
- locale_working_directory = g_strdup(working_directory);
+ utf8_working_directory = working_directory;
+
+ w_working_directory = g_utf8_to_utf16(utf8_working_directory, -1, NULL, NULL, &gerror);
+ if (! w_working_directory)
+ {
+ /* TODO use the code below post-1.28 as it introduces a new string
+ g_set_error(error, gerror->domain, gerror->code,
+ _("Failed to convert working directory into locale encoding: %s"), gerror->message);
+ */
+ g_propagate_error(error, gerror);
+ success = FALSE;
+ }
+ g_free(tmp);
}
/* convert command into locale encoding */
if (success)
{
- if (g_utf8_validate(command->str, -1, NULL))
- {
- GError *gerror = NULL;
+ GError *gerror = NULL;
+ const gchar *utf8_cmd;
+ gchar *tmp = NULL;
- locale_command = g_locale_from_utf8(command->str, -1, NULL, NULL, &gerror);
- if (! locale_command)
- {
- /* TODO use the code below post-1.28 as it introduces a new string
- g_set_error(error, gerror->domain, gerror->code,
- _("Failed to convert command into locale encoding: %s"), gerror->message);
- */
- g_propagate_error(error, gerror);
- success = FALSE;
- }
- }
+ // FIXME: remove this and rely on UTF-8 input
+ if (! g_utf8_validate(command->str, -1, NULL))
+ utf8_cmd = tmp = utils_get_utf8_from_locale(command->str);
else
- locale_command = g_strdup(command->str);
+ utf8_cmd = command->str;
+
+ w_command = g_utf8_to_utf16(utf8_cmd, -1, NULL, NULL, &gerror);
+ if (! w_command)
+ {
+ /* TODO use the code below post-1.28 as it introduces a new string
+ g_set_error(error, gerror->domain, gerror->code,
+ _("Failed to convert command into locale encoding: %s"), gerror->message);
+ */
+ g_propagate_error(error, gerror);
+ success = FALSE;
+ }
}
if (success)
{
gchar *failure;
- failure = spawn_create_process_with_pipes(locale_command, locale_working_directory,
- envp ? environment->data : NULL, child_pid, stdin_fd, stdout_fd, stderr_fd);
+ failure = spawn_create_process_with_pipes(w_command, w_working_directory,
+ envp ? w_environment->data : NULL, child_pid, stdin_fd, stdout_fd, stderr_fd);
if (failure)
{
@@ -652,9 +661,9 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch
}
g_string_free(command, TRUE);
- g_array_free(environment, TRUE);
- g_free(locale_working_directory);
- g_free(locale_command);
+ g_array_free(w_environment, TRUE);
+ g_free(w_working_directory);
+ g_free(w_command);
return success;
#else /* 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