gnome-terminal r3250 - trunk/src
- From: chpe svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-terminal r3250 - trunk/src
- Date: Mon, 15 Dec 2008 19:57:47 +0000 (UTC)
Author: chpe
Date: Mon Dec 15 19:57:46 2008
New Revision: 3250
URL: http://svn.gnome.org/viewvc/gnome-terminal?rev=3250&view=rev
Log:
Don't try to send (potentially) non-UTF-8 data as G_TYPE_STRING over
dbus. Use byte arrays instead.
Modified:
trunk/src/terminal-factory-service.xml
trunk/src/terminal-options.c
trunk/src/terminal-options.h
trunk/src/terminal-util.c
trunk/src/terminal-util.h
trunk/src/terminal.c
Modified: trunk/src/terminal-factory-service.xml
==============================================================================
--- trunk/src/terminal-factory-service.xml (original)
+++ trunk/src/terminal-factory-service.xml Mon Dec 15 19:57:46 2008
@@ -1,11 +1,11 @@
<node name="/org/gnome/Terminal">
<interface name="org.gnome.Terminal.Factory">
- <method name="NewTerminal">
- <arg type="s" name="working_directory" direction="in" />
- <arg type="s" name="display_name" direction="in" />
- <arg type="s" name="startup_id" direction="in" />
- <arg type="as" name="environment" direction="in" />
- <arg type="as" name="arguments" direction="in" />
+ <method name="HandleArguments">
+ <arg type="ay" name="working_directory" direction="in" />
+ <arg type="ay" name="display_name" direction="in" />
+ <arg type="ay" name="startup_id" direction="in" />
+ <arg type="ay" name="environment" direction="in" />
+ <arg type="ay" name="arguments" direction="in" />
</method>
</interface>
</node>
Modified: trunk/src/terminal-options.c
==============================================================================
--- trunk/src/terminal-options.c (original)
+++ trunk/src/terminal-options.c Mon Dec 15 19:57:46 2008
@@ -665,7 +665,7 @@
terminal_options_parse (const char *working_directory,
const char *display_name,
const char *startup_id,
- const char **env,
+ char **env,
gboolean ignore_unknown_options,
int *argcp,
char ***argvp,
@@ -689,7 +689,7 @@
options->execute = FALSE;
options->use_factory = TRUE;
- options->env = g_strdupv ((char **) env);
+ options->env = g_strdupv (env);
options->startup_id = g_strdup (startup_id && startup_id[0] ? startup_id : NULL);
options->display_name = g_strdup (display_name);
options->initial_windows = NULL;
Modified: trunk/src/terminal-options.h
==============================================================================
--- trunk/src/terminal-options.h (original)
+++ trunk/src/terminal-options.h Mon Dec 15 19:57:46 2008
@@ -84,7 +84,7 @@
TerminalOptions *terminal_options_parse (const char *working_directory,
const char *display_name,
const char *startup_id,
- const char **env,
+ char **env,
gboolean ignore_unknown_options,
int *argcp,
char ***argvp,
Modified: trunk/src/terminal-util.c
==============================================================================
--- trunk/src/terminal-util.c (original)
+++ trunk/src/terminal-util.c Mon Dec 15 19:57:46 2008
@@ -465,6 +465,144 @@
return NULL;
}
+/* Why? Because dbus-glib sucks, that's why! */
+
+/**
+ * terminal_util_string_to_array:
+ * @string:
+ *
+ * Converts the string @string into a #GArray.
+ *
+ * Returns: a newly allocated #GArray containing @string's bytes.
+ */
+GArray *
+terminal_util_string_to_array (const char *string)
+{
+ GArray *array;
+ gsize len = 0;
+
+ if (string)
+ len = strlen (string);
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), len);
+ return g_array_append_vals (array, string, len);
+}
+
+/**
+ * terminal_util_strv_to_array:
+ * @argc: the length of @argv
+ * @argv: a string array
+ *
+ * Converts the string array @argv of length @argc into a #GArray.
+ *
+ * Returns: a newly allocated #GArray
+ */
+GArray *
+terminal_util_strv_to_array (int argc,
+ char **argv)
+{
+ GArray *array;
+ gsize len = 0;
+ int i;
+ const char nullbyte = 0;
+
+ for (i = 0; i < argc; ++i)
+ len += strlen (argv[i]);
+ if (argc > 0)
+ len += argc - 1;
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), len);
+
+ for (i = 0; i < argc; ++i) {
+ g_array_append_vals (array, argv[i], strlen (argv[i]));
+ if (i < argc)
+ g_array_append_val (array, nullbyte);
+ }
+
+ return array;
+}
+
+/**
+ * terminal_util_array_to_string:
+ * @array:
+ * @error: a #GError to fill in
+ *
+ * Converts @array into a string.
+ *
+ * Returns: a newly allocated string, or %NULL on error
+ */
+char *
+terminal_util_array_to_string (const GArray *array,
+ GError **error)
+{
+ char *string;
+ g_return_val_if_fail (array != NULL, NULL);
+
+ string = g_strndup (array->data, array->len);
+
+ /* Validate */
+ if (strlen (string) < array->len) {
+ g_set_error_literal (error,
+ g_quark_from_static_string ("terminal-error"),
+ 0,
+ "String is shorter than claimed");
+ return NULL;
+ }
+
+ return string;
+}
+
+/**
+ * terminal_util_array_to_strv:
+ * @array:
+ * @argc: a location to store the length of the returned string array
+ * @error: a #GError to fill in
+ *
+ * Converts @array into a string.
+ *
+ * Returns: a newly allocated string array of length * argc, or %NULL on error
+ */
+char **
+terminal_util_array_to_strv (const GArray *array,
+ int *argc,
+ GError **error)
+{
+ GPtrArray *argv;
+ const char *data, *nullbyte;
+ gsize len;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ if (array->len == 0) {
+ *argc = 0;
+ return NULL;
+ }
+
+ argv = g_ptr_array_new ();
+
+ len = array->len;
+ data = array->data;
+
+ do {
+ gsize string_len;
+
+ nullbyte = memchr (data, '\0', len);
+
+ string_len = nullbyte ? nullbyte - data : len;
+ g_ptr_array_add (argv, g_strndup (data, string_len));
+
+ len -= string_len + 1;
+ data += string_len + 1;
+ } while (len > 0);
+
+ if (argc)
+ *argc = argv->len;
+
+ /* NULL terminate */
+ g_ptr_array_add (argv, NULL);
+ return (char **) g_ptr_array_free (argv, FALSE);
+}
+
/* Bidirectional object/widget binding */
typedef struct {
Modified: trunk/src/terminal-util.h
==============================================================================
--- trunk/src/terminal-util.h (original)
+++ trunk/src/terminal-util.h Mon Dec 15 19:57:46 2008
@@ -79,6 +79,18 @@
int *argc,
GError **error);
+GArray *terminal_util_string_to_array (const char *string);
+
+GArray *terminal_util_strv_to_array (int argc,
+ char **argv);
+
+char *terminal_util_array_to_string (const GArray *array,
+ GError **error);
+
+char **terminal_util_array_to_strv (const GArray *array,
+ int *argc,
+ GError **error);
+
typedef enum {
FLAG_INVERT_BOOL = 1 << 0,
} PropertyChangeFlags;
Modified: trunk/src/terminal.c
==============================================================================
--- trunk/src/terminal.c (original)
+++ trunk/src/terminal.c Mon Dec 15 19:57:46 2008
@@ -69,13 +69,13 @@
};
static gboolean
-terminal_factory_new_terminal (TerminalFactory *factory,
- const char *working_directory,
- const char *display_name,
- const char *startup_id,
- const char **argv,
- const char **env,
- GError **error);
+terminal_factory_handle_arguments (TerminalFactory *factory,
+ const GArray *working_directory_array,
+ const GArray *display_name_array,
+ const GArray *startup_id_array,
+ const GArray *argv_array,
+ const GArray *env_array,
+ GError **error);
#include "terminal-factory-client.h"
#include "terminal-factory-server.h"
@@ -214,6 +214,7 @@
{
int i;
char **argv_copy;
+ int argc_copy;
const char *startup_id;
const char *display_name;
GdkDisplay *display;
@@ -234,6 +235,7 @@
for (i = 0; i < argc; ++i)
argv_copy [i] = argv [i];
argv_copy [i] = NULL;
+ argc_copy = argc;
startup_id = g_getenv ("DESKTOP_STARTUP_ID");
@@ -322,43 +324,62 @@
/* Forward to the existing factory and exit */
if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
{
+ char *working_directory;
char **env;
const char *evalue;
- guint i, n;
- GPtrArray *env_array;
+ GPtrArray *env_ptr_array;
+ int i, envc;
+ GArray *working_directory_array, *display_name_array, *startup_id_array;
+ GArray *env_array, *argv_array;
+ gboolean retval;
int ret = EXIT_SUCCESS;
env = g_listenv ();
- n = g_strv_length (env);
- env_array = g_ptr_array_sized_new (n);
- for (i = 0; i < n; ++i)
+ envc = g_strv_length (env);
+ env_ptr_array = g_ptr_array_sized_new (envc);
+ for (i = 0; i < envc; ++i)
{
evalue = g_getenv (env[i]);
if (evalue)
- g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", env[i], evalue));
+ g_ptr_array_add (env_ptr_array, g_strdup_printf ("%s=%s", env[i], evalue));
}
- g_ptr_array_add (env_array, NULL);
+ g_ptr_array_add (env_ptr_array, NULL);
g_strfreev (env);
- env = (char **) g_ptr_array_free (env_array, FALSE);
+ env = (char **) g_ptr_array_free (env_ptr_array, FALSE);
+
+ working_directory = g_get_current_dir ();
+ working_directory_array = terminal_util_string_to_array (working_directory);
+ display_name_array = terminal_util_string_to_array (options->display_name);
+ startup_id_array = terminal_util_string_to_array (options->startup_id);
+ env_array = terminal_util_strv_to_array (envc, env);
+ argv_array = terminal_util_strv_to_array (argc_copy, argv_copy);
proxy = dbus_g_proxy_new_for_name (connection,
TERMINAL_FACTORY_SERVICE_NAME,
TERMINAL_FACTORY_SERVICE_PATH,
TERMINAL_FACTORY_INTERFACE_NAME);
- if (!org_gnome_Terminal_Factory_new_terminal (proxy,
- g_get_current_dir (),
- options->display_name,
- options->startup_id,
- (const char **) env,
- (const char **) argv_copy,
- &error))
+ retval = org_gnome_Terminal_Factory_handle_arguments (proxy,
+ working_directory_array,
+ display_name_array,
+ startup_id_array,
+ env_array,
+ argv_array,
+ &error);
+ g_free (working_directory);
+ g_array_free (working_directory_array, TRUE);
+ g_array_free (display_name_array, TRUE);
+ g_array_free (startup_id_array, TRUE);
+ g_array_free (env_array, TRUE);
+ g_array_free (argv_array, TRUE);
+ g_strfreev (env);
+
+ if (!retval)
{
if (g_error_matches (error, DBUS_GERROR, DBUS_GERROR_UNKNOWN_METHOD))
{
/* Incompatible factory version, fall back, to new instance */
g_printerr (_("Incompatible factory version; creating a new instance.\n"));
- g_strfreev (env);
g_error_free (error);
goto factory_disabled;
@@ -370,7 +391,6 @@
}
g_free (argv_copy);
- g_strfreev (env);
terminal_options_free (options);
exit (ret);
@@ -441,31 +461,61 @@
}
static gboolean
-terminal_factory_new_terminal (TerminalFactory *factory,
- const char *working_directory,
- const char *display_name,
- const char *startup_id,
- const char **env,
- const char **arguments,
- GError **error)
+terminal_factory_handle_arguments (TerminalFactory *factory,
+ const GArray *working_directory_array,
+ const GArray *display_name_array,
+ const GArray *startup_id_array,
+ const GArray *env_array,
+ const GArray *argv_array,
+ GError **error)
{
- TerminalOptions *options;
- char **argv;
+ TerminalOptions *options = NULL;
+ char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
+ char **env = NULL, **argv = NULL, **argv_copy = NULL;
int argc;
+ GError *arg_error = NULL;
+
+ working_directory = terminal_util_array_to_string (working_directory_array, &arg_error);
+ if (arg_error)
+ goto out;
+ display_name = terminal_util_array_to_string (display_name_array, &arg_error);
+ if (arg_error)
+ goto out;
+ startup_id = terminal_util_array_to_string (startup_id_array, &arg_error);
+ if (arg_error)
+ goto out;
+ env = terminal_util_array_to_strv (env_array, NULL, &arg_error);
+ if (arg_error)
+ goto out;
+ argv = terminal_util_array_to_strv (argv_array, &argc, &arg_error);
+ if (arg_error)
+ goto out;
/* Copy the arguments since terminal_options_parse potentially modifies the array */
- argc = g_strv_length ((char **) arguments);
- argv = (char **) g_memdup (arguments, (argc + 1) * sizeof (char *));
+ argv_copy = (char **) g_memdup (argv, (argc + 1) * sizeof (char *));
options = terminal_options_parse (working_directory,
display_name,
startup_id,
env,
TRUE,
- &argc, &argv,
+ &argc, &argv_copy,
error,
NULL);
- g_free (argv);
+
+out:
+ g_free (working_directory);
+ g_free (display_name);
+ g_free (startup_id);
+ g_strfreev (env);
+ g_strfreev (argv);
+ g_free (argv_copy);
+
+ if (arg_error)
+ {
+ g_propagate_error (error, arg_error);
+ return FALSE;
+ }
if (!options)
return FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]