Esempio n. 1
0
void
ide_subprocess_supervisor_set_subprocess (IdeSubprocessSupervisor *self,
                                          IdeSubprocess           *subprocess)
{
  IdeSubprocessSupervisorPrivate *priv = ide_subprocess_supervisor_get_instance_private (self);

  g_return_if_fail (IDE_IS_SUBPROCESS_SUPERVISOR (self));
  g_return_if_fail (!subprocess || IDE_IS_SUBPROCESS (subprocess));

  if (g_set_object (&priv->subprocess, subprocess))
    {
      if (subprocess != NULL)
        {
          g_get_current_time (&priv->last_spawn_time);
          ide_subprocess_wait_async (priv->subprocess,
                                     NULL,
                                     ide_subprocess_supervisor_wait_cb,
                                     g_object_ref (self));
          g_signal_emit (self, signals [SPAWNED], 0, subprocess);
        }
    }
}
Esempio n. 2
0
void
ide_subprocess_wait_check_async (IdeSubprocess       *self,
                                 GCancellable        *cancellable,
                                 GAsyncReadyCallback  callback,
                                 gpointer             user_data)
{
  g_autoptr(GTask) task = NULL;

  IDE_ENTRY;

  g_return_if_fail (IDE_IS_SUBPROCESS (self));
  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));

  task = g_task_new (self, cancellable, callback, user_data);
  g_task_set_source_tag (task, ide_subprocess_wait_check_async);

  ide_subprocess_wait_async (self,
                             cancellable,
                             ide_subprocess_wait_check_cb,
                             g_steal_pointer (&task));

  IDE_EXIT;
}
Esempio n. 3
0
static void
gb_terminal_respawn (GbTerminalView *self,
                     VteTerminal    *terminal)
{
  g_autoptr(GPtrArray) args = NULL;
  g_autoptr(IdeSubprocess) subprocess = NULL;
  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
  g_autofree gchar *workpath = NULL;
  g_autofree gchar *shell = NULL;
  GtkWidget *toplevel;
  GError *error = NULL;
  IdeContext *context;
  IdeVcs *vcs;
  VtePty *pty = NULL;
  GFile *workdir;
  gint64 now;
  int tty_fd = -1;
  gint stdout_fd = -1;
  gint stderr_fd = -1;

  IDE_ENTRY;

  g_assert (GB_IS_TERMINAL_VIEW (self));

  vte_terminal_reset (terminal, TRUE, TRUE);

  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
  if (!IDE_IS_WORKBENCH (toplevel))
    IDE_EXIT;

  /* Prevent flapping */
  now = g_get_monotonic_time ();
  if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10))
    IDE_EXIT;
  self->last_respawn = now;

  context = ide_workbench_get_context (IDE_WORKBENCH (toplevel));
  vcs = ide_context_get_vcs (context);
  workdir = ide_vcs_get_working_directory (vcs);
  workpath = g_file_get_path (workdir);

  shell = gb_terminal_view_discover_shell (NULL, &error);

  if (shell == NULL)
    {
      g_warning ("Failed to discover user shell: %s", error->message);

      /* We prefer bash in flatpak over sh */
      if (ide_is_flatpak ())
        shell = g_strdup ("/bin/bash");
      else
        shell = vte_get_user_shell ();

      g_clear_error (&error);
    }

  args = g_ptr_array_new ();
  g_ptr_array_add (args, (gchar *)shell);
  g_ptr_array_add (args, NULL);

  pty = vte_terminal_pty_new_sync (terminal,
                                   VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP,
                                   NULL,
                                   &error);
  if (pty == NULL)
    IDE_GOTO (failure);

  vte_terminal_set_pty (terminal, pty);

  if (-1 == (tty_fd = gb_vte_pty_create_slave (pty)))
    IDE_GOTO (failure);

  /* dup() is safe as it will inherit O_CLOEXEC */
  if (-1 == (stdout_fd = dup (tty_fd)) || -1 == (stderr_fd = dup (tty_fd)))
    IDE_GOTO (failure);

  /* XXX: It would be nice to allow using the runtimes launcher */
  launcher = ide_subprocess_launcher_new (0);
  ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
  ide_subprocess_launcher_set_clear_env (launcher, FALSE);
  ide_subprocess_launcher_set_cwd (launcher, workpath);
  ide_subprocess_launcher_push_args (launcher, (const gchar * const *)args->pdata);
  ide_subprocess_launcher_take_stdin_fd (launcher, tty_fd);
  ide_subprocess_launcher_take_stdout_fd (launcher, stdout_fd);
  ide_subprocess_launcher_take_stderr_fd (launcher, stderr_fd);
  ide_subprocess_launcher_setenv (launcher, "TERM", "xterm-256color", TRUE);
  ide_subprocess_launcher_setenv (launcher, "INSIDE_GNOME_BUILDER", PACKAGE_VERSION, TRUE);
  ide_subprocess_launcher_setenv (launcher, "SHELL", shell, TRUE);

  tty_fd = -1;
  stdout_fd = -1;
  stderr_fd = -1;

  if (NULL == (subprocess = ide_subprocess_launcher_spawn (launcher, NULL, &error)))
    IDE_GOTO (failure);

  ide_subprocess_wait_async (subprocess,
                             NULL,
                             gb_terminal_view_wait_cb,
                             g_object_ref (terminal));

failure:
  if (tty_fd != -1)
    close (tty_fd);

  if (stdout_fd != -1)
    close (stdout_fd);

  g_clear_object (&pty);

  if (error != NULL)
    {
      g_warning ("%s", error->message);
      g_clear_error (&error);
    }

  IDE_EXIT;
}