[gnome-terminal] client: Separate running a command from running the user's shell



commit b815eb113efeedda990b039bd6873407a7df5a9b
Author: Christian Persch <chpe gnome org>
Date:   Sun Dec 16 00:01:07 2012 +0100

    client: Separate running a command from running the user's shell

 src/client.c                |   21 ++++++++--
 src/terminal-client-utils.c |    9 ++++-
 src/terminal-client-utils.h |    3 +-
 src/terminal-gdbus.c        |    4 ++
 src/terminal-screen.c       |   87 ++++++++++++++++++++----------------------
 src/terminal-screen.h       |    5 +--
 src/terminal.c              |    9 ++--
 7 files changed, 77 insertions(+), 61 deletions(-)
---
diff --git a/src/client.c b/src/client.c
index 83e1810..53a49e5 100644
--- a/src/client.c
+++ b/src/client.c
@@ -122,7 +122,8 @@ usage (gint *argc, gchar **argv[], gboolean use_stdout)
   program_name = g_path_get_basename ((*argv)[0]);
   s = g_strdup_printf (_("Commands:\n"
                          "  help    Shows this information\n"
-                         "  open    Create a new terminal\n"
+                         "  run     Create a new terminal running the specified command\n"
+                         "  shell   Create a new terminal running the user shell\n"
                          "\n"
                          "Use \"%s COMMAND --help\" to get help on each command.\n"),
                        program_name);
@@ -563,6 +564,7 @@ build_create_options_variant (OptionData *data)
  */
 static GVariant *
 build_exec_options_variant (OptionData *data,
+                            gboolean shell,
                             GUnixFDList **fd_list)
 {
   GVariantBuilder builder;
@@ -570,7 +572,8 @@ build_exec_options_variant (OptionData *data,
   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
 
   terminal_client_append_exec_options (&builder,
-                                       data->working_directory);
+                                       data->working_directory,
+                                       shell);
 
   if (data->fd_array != NULL) {
     int i, n_fds;
@@ -619,6 +622,7 @@ receiver_child_exited_cb (TerminalReceiver *receiver,
 static gboolean
 handle_open (int *argc,
              char ***argv,
+             const char *command,
              gboolean request_completion,
              const gchar *completion_cur,
              const gchar *completion_prev,
@@ -632,7 +636,7 @@ handle_open (int *argc,
   GVariant *arguments;
   GUnixFDList *fd_list;
 
-  modify_argv0_for_command (argc, argv, "open");
+  modify_argv0_for_command (argc, argv, command);
 
   data = parse_arguments (argc, argv, &error);
   if (data == NULL) {
@@ -641,6 +645,11 @@ handle_open (int *argc,
     return FALSE;
   }
 
+  if (g_strcmp0 (command, "run") == 0 && data->exec_argc == 0) {
+     _printerr ("\"run\" needs the command to run as arguments after --\n");
+    return FALSE;
+  }
+
   factory = terminal_factory_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                      G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
                                                      G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
@@ -693,7 +702,7 @@ handle_open (int *argc,
 
   g_free (object_path);
 
-  arguments = build_exec_options_variant (data, &fd_list);
+  arguments = build_exec_options_variant (data, g_strcmp0 (command, "shell") == 0, &fd_list);
   if (!terminal_receiver_call_exec_sync (receiver,
                                          arguments,
                                          g_variant_new_bytestring_array ((const char * const *) data->exec_argv, data->exec_argc),
@@ -824,10 +833,12 @@ main (gint argc, gchar *argv[])
         }
       goto out;
     }
-  else if (g_strcmp0 (command, "open") == 0)
+  else if (g_strcmp0 (command, "run") == 0 ||
+           g_strcmp0 (command, "shell") == 0)
     {
       if (handle_open (&argc,
                        &argv,
+                       command,
                        request_completion,
                        completion_cur,
                        completion_prev,
diff --git a/src/terminal-client-utils.c b/src/terminal-client-utils.c
index a38d182..f5642e7 100644
--- a/src/terminal-client-utils.c
+++ b/src/terminal-client-utils.c
@@ -92,12 +92,14 @@ terminal_client_append_create_instance_options (GVariantBuilder *builder,
  * terminal_client_append_exec_options:
  * @builder: a #GVariantBuilder of #GVariantType "a{sv}"
  * @working_directory: (allow-none): the cwd, or %NULL
+ * @shell:
  *
  * Appends the environment and the working directory to @builder.
  */
 void 
 terminal_client_append_exec_options (GVariantBuilder *builder,
-                                     const char      *working_directory)
+                                     const char      *working_directory,
+                                     gboolean         shell)
 {
   char **envv;
 
@@ -122,6 +124,11 @@ terminal_client_append_exec_options (GVariantBuilder *builder,
     g_variant_builder_add (builder, "{sv}", 
                            "cwd", g_variant_new_bytestring (working_directory));
 
+  if (shell)
+    g_variant_builder_add (builder, "{sv}",
+                           "shell",
+                           g_variant_new_boolean (TRUE));
+
   g_strfreev (envv);
 }
 
diff --git a/src/terminal-client-utils.h b/src/terminal-client-utils.h
index 14a1693..2547d7f 100644
--- a/src/terminal-client-utils.h
+++ b/src/terminal-client-utils.h
@@ -35,7 +35,8 @@ void terminal_client_append_create_instance_options (GVariantBuilder *builder,
                                                      gboolean         fullscreen_window);
 
 void terminal_client_append_exec_options            (GVariantBuilder *builder,
-                                                     const char      *working_directory);
+                                                     const char      *working_directory,
+                                                     gboolean         shell);
 
 void terminal_client_get_fallback_startup_id        (char           **startup_id);
 
diff --git a/src/terminal-gdbus.c b/src/terminal-gdbus.c
index 2997cb2..10254a6 100644
--- a/src/terminal-gdbus.c
+++ b/src/terminal-gdbus.c
@@ -100,6 +100,7 @@ terminal_receiver_impl_exec (TerminalReceiver *receiver,
   TerminalReceiverImpl *impl = TERMINAL_RECEIVER_IMPL (receiver);
   TerminalReceiverImplPrivate *priv = impl->priv;
   const char *working_directory;
+  gboolean shell;
   char **exec_argv, **envv;
   gsize exec_argc;
   GVariant *fd_array;
@@ -115,6 +116,8 @@ terminal_receiver_impl_exec (TerminalReceiver *receiver,
 
   if (!g_variant_lookup (options, "cwd", "^&ay", &working_directory))
     working_directory = NULL;
+  if (!g_variant_lookup (options, "shell", "b", &shell))
+    shell = FALSE;
   if (!g_variant_lookup (options, "environ", "^a&ay", &envv))
     envv = NULL;
 
@@ -170,6 +173,7 @@ terminal_receiver_impl_exec (TerminalReceiver *receiver,
   if (!terminal_screen_exec (priv->screen,
                              exec_argc > 0 ? exec_argv : NULL,
                              envv,
+                             shell,
                              working_directory,
                              fd_list, fd_array,
                              &error)) {
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 7d3d372..445c0c6 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -79,6 +79,7 @@ struct _TerminalScreenPrivate
   char *initial_working_directory;
   char **initial_env;
   char **override_command;
+  gboolean shell;
   int child_pid;
   int pty_fd;
   double font_scale;
@@ -101,7 +102,6 @@ enum {
   PROP_PROFILE,
   PROP_ICON_TITLE,
   PROP_ICON_TITLE_SET,
-  PROP_OVERRIDE_COMMAND,
   PROP_TITLE,
   PROP_INITIAL_ENVIRONMENT
 };
@@ -154,6 +154,10 @@ static char* terminal_screen_check_match       (TerminalScreen            *scree
                                                 int                   row,
                                                 int                  *flavor);
 
+static void terminal_screen_set_override_command (TerminalScreen  *screen,
+                                                  char           **argv,
+                                                  gboolean         shell);
+
 static guint signals[LAST_SIGNAL];
 
 #define USERCHARS "-[:alnum:]"
@@ -376,9 +380,6 @@ terminal_screen_get_property (GObject *object,
       case PROP_ICON_TITLE_SET:
         g_value_set_boolean (value, terminal_screen_get_icon_title_set (screen));
         break;
-      case PROP_OVERRIDE_COMMAND:
-        g_value_set_boxed (value, terminal_screen_get_override_command (screen));
-        break;
       case PROP_INITIAL_ENVIRONMENT:
         g_value_set_boxed (value, terminal_screen_get_initial_environment (screen));
         break;
@@ -404,9 +405,6 @@ terminal_screen_set_property (GObject *object,
       case PROP_PROFILE:
         terminal_screen_set_profile (screen, g_value_get_object (value));
         break;
-      case PROP_OVERRIDE_COMMAND:
-        terminal_screen_set_override_command (screen, g_value_get_boxed (value));
-        break;
       case PROP_INITIAL_ENVIRONMENT:
         terminal_screen_set_initial_environment (screen, g_value_get_boxed (value));
         break;
@@ -506,13 +504,6 @@ terminal_screen_class_init (TerminalScreenClass *klass)
 
   g_object_class_install_property
     (object_class,
-     PROP_OVERRIDE_COMMAND,
-     g_param_spec_boxed ("override-command", NULL, NULL,
-                         G_TYPE_STRV,
-                         G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
-  g_object_class_install_property
-    (object_class,
      PROP_TITLE,
      g_param_spec_string ("title", NULL, NULL,
                           NULL,
@@ -633,7 +624,9 @@ terminal_screen_new (GSettings       *profile,
   priv->initial_working_directory = g_strdup (working_dir);
 
   if (override_command)
-    terminal_screen_set_override_command (screen, override_command);
+    terminal_screen_set_override_command (screen, override_command, FALSE);
+  else
+    terminal_screen_set_override_command (screen, NULL, TRUE);
 
   if (child_env)
     terminal_screen_set_initial_environment (screen, child_env);
@@ -648,6 +641,7 @@ gboolean
 terminal_screen_exec (TerminalScreen *screen,
                       char          **argv,
                       char          **envv,
+                      gboolean        shell,
                       const char     *cwd,
                       GUnixFDList    *fd_list,
                       GVariant       *fd_array,
@@ -662,9 +656,7 @@ terminal_screen_exec (TerminalScreen *screen,
   priv = screen->priv;
 
   terminal_screen_set_initial_environment (screen, envv);
-
-  if (argv)
-    terminal_screen_set_override_command (screen, argv);
+  terminal_screen_set_override_command (screen, argv, shell);
 
   g_free (priv->initial_working_directory);
   priv->initial_working_directory = g_strdup (cwd);
@@ -1086,9 +1078,10 @@ terminal_screen_get_profile (TerminalScreen *screen)
   return priv->profile;
 }
 
-void
+static void
 terminal_screen_set_override_command (TerminalScreen *screen,
-                                      char          **argv)
+                                      char          **argv,
+                                      gboolean        shell)
 {
   TerminalScreenPrivate *priv;
 
@@ -1096,15 +1089,11 @@ terminal_screen_set_override_command (TerminalScreen *screen,
 
   priv = screen->priv;
   g_strfreev (priv->override_command);
-  priv->override_command = g_strdupv (argv);
-}
-
-const char**
-terminal_screen_get_override_command (TerminalScreen *screen)
-{
-  g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
-
-  return (const char**) screen->priv->override_command;
+  if (argv)
+    priv->override_command = g_strdupv (argv);
+  else
+    priv->override_command = NULL;
+  priv->shell = shell;
 }
 
 void
@@ -1143,23 +1132,7 @@ get_child_command (TerminalScreen *screen,
 
   *argv_p = argv = NULL;
 
-  if (priv->override_command)
-    {
-      argv = g_strdupv (priv->override_command);
-
-      *spawn_flags_p |= G_SPAWN_SEARCH_PATH;
-    }
-  else if (g_settings_get_boolean (profile, TERMINAL_PROFILE_USE_CUSTOM_COMMAND_KEY))
-    {
-      const char *argv_str;
-
-      g_settings_get (profile, TERMINAL_PROFILE_CUSTOM_COMMAND_KEY, "&s", &argv_str);
-      if (!g_shell_parse_argv (argv_str, NULL, &argv, err))
-        return FALSE;
-
-      *spawn_flags_p |= G_SPAWN_SEARCH_PATH;
-    }
-  else
+  if (priv->shell)
     {
       const char *only_name;
       char *shell;
@@ -1186,6 +1159,28 @@ get_child_command (TerminalScreen *screen,
 
       *spawn_flags_p |= G_SPAWN_FILE_AND_ARGV_ZERO;
     }
+  else if (priv->override_command)
+    {
+      argv = g_strdupv (priv->override_command);
+
+      *spawn_flags_p |= G_SPAWN_SEARCH_PATH;
+    }
+  else if (g_settings_get_boolean (profile, TERMINAL_PROFILE_USE_CUSTOM_COMMAND_KEY))
+    {
+      const char *argv_str;
+
+      g_settings_get (profile, TERMINAL_PROFILE_CUSTOM_COMMAND_KEY, "&s", &argv_str);
+      if (!g_shell_parse_argv (argv_str, NULL, &argv, err))
+        return FALSE;
+
+      *spawn_flags_p |= G_SPAWN_SEARCH_PATH;
+    }
+  else
+    {
+      g_set_error_literal (err, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+                           _("No command supplied nor shell requested"));
+      return FALSE;
+    }
 
   *argv_p = argv;
 
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index 47c8c75..d91e9c1 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -84,6 +84,7 @@ TerminalScreen *terminal_screen_new (GSettings       *profile,
 gboolean terminal_screen_exec (TerminalScreen *screen,
                                char          **argv,
                                char          **envv,
+                               gboolean        shell,
                                const char     *cwd,
                                GUnixFDList    *fd_list,
                                GVariant       *fd_array,
@@ -95,10 +96,6 @@ void terminal_screen_set_profile (TerminalScreen *screen,
                                   GSettings      *profile);
 GSettings* terminal_screen_get_profile (TerminalScreen *screen);
 
-void         terminal_screen_set_override_command (TerminalScreen  *screen,
-                                                   char           **argv);
-const char** terminal_screen_get_override_command (TerminalScreen  *screen);
-
 void         terminal_screen_set_initial_environment (TerminalScreen  *screen,
                                                       char           **argv);
 char **      terminal_screen_get_initial_environment (TerminalScreen  *screen);
diff --git a/src/terminal.c b/src/terminal.c
index 036104e..36a776d 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -169,13 +169,14 @@ handle_options (TerminalFactory *factory,
 
           g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
 
-          terminal_client_append_exec_options (&builder,
-                                               it->working_dir ? it->working_dir 
-                                                               : options->default_working_dir);
-
           argv = it->exec_argv ? it->exec_argv : options->exec_argv,
           argc = argv ? g_strv_length (argv) : 0;
 
+          terminal_client_append_exec_options (&builder,
+                                               it->working_dir ? it->working_dir 
+                                                               : options->default_working_dir,
+                                               argc == 0);
+
           if (!terminal_receiver_call_exec_sync (receiver,
                                                  g_variant_builder_end (&builder),
                                                  g_variant_new_bytestring_array ((const char * const *) argv, argc),



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]