Example #1
0
  void terminal::spawn_child(std::string i_command) {
    if ( m_terminal != NULL ) {
      GError *error = NULL;
      gchar **args = NULL;
      GSpawnFlags spawn_flags = G_SPAWN_SEARCH_PATH;

      if ( i_command.empty() ) {
        gchar *user_shell = vte_get_user_shell();

        g_shell_parse_argv(user_shell, 0, &args, 0);

        g_free(user_shell);
      } else {
        g_shell_parse_argv(i_command.c_str(), 0, &args, 0);
      }

      vte_terminal_spawn_sync(m_terminal, VTE_PTY_DEFAULT, NULL, args, NULL, spawn_flags, NULL, NULL, &m_child_pid, NULL, &error);

      if ( error != NULL ) {
        sterm::common::warning("sterm::terminal", "failed to spawn child process");
        sterm::common::debug("sterm::terminal", "VteTerminal error message: %s", error->message);

        g_error_free(error);
      }
      
      g_strfreev(args);
    }
  }
static void
gb_terminal_respawn (GbTerminalView *self,
                     VteTerminal    *terminal)
{
  g_autoptr(GPtrArray) args = NULL;
  g_autofree gchar *workpath = NULL;
  GtkWidget *toplevel;
  GError *error = NULL;
  IdeContext *context;
  IdeVcs *vcs;
  GFile *workdir;
  GPid child_pid;
  gint64 now;

  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))
    return;

  /* Prevent flapping */
  now = g_get_monotonic_time ();
  if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10))
    return;
  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);

  args = g_ptr_array_new_with_free_func (g_free);
  g_ptr_array_add (args, vte_get_user_shell ());
  g_ptr_array_add (args, NULL);

  vte_terminal_spawn_sync (terminal,
                           VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP,
                           workpath,
                           (gchar **)args->pdata,
                           NULL,
                           G_SPAWN_DEFAULT,
                           NULL,
                           NULL,
                           &child_pid,
                           NULL,
                           &error);

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

  vte_terminal_watch_child (terminal, child_pid);
}
Example #3
0
Terminal::Terminal() {
    dock_hint = GdkRectangle{0, 0, 0, 0};
    vte = vte_terminal_new();
    char *argv[] = { vte_get_user_shell(), NULL };
    vte_terminal_spawn_sync(VTE_TERMINAL(vte), VTE_PTY_DEFAULT, NULL, argv, NULL,
                            (GSpawnFlags)0, NULL,
                            NULL, &child_pid, NULL, NULL);
    set_orientation(Gtk::ORIENTATION_VERTICAL);
    scrollbox.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
    scrollbar.set_orientation(Gtk::ORIENTATION_VERTICAL);

    eventbox.add(label);
    eventbox.signal_button_press_event().connect(mem_fun(this, &Terminal::header_button_press));

    VteRegex *regex = vte_regex_new_for_match("(https?://|www\\.)[^\\s]*", -1, PCRE2_MULTILINE, NULL);
    vte_terminal_match_add_regex(VTE_TERMINAL(vte), regex, 0);
    vte_terminal_set_scrollback_lines(VTE_TERMINAL(vte), 10000);
    g_signal_connect(vte, "bell", G_CALLBACK(Terminal::vte_beep), this);
    g_signal_connect(vte, "child-exited", G_CALLBACK(Terminal::vte_child_exited), this);
    g_signal_connect(vte, "button-press-event", G_CALLBACK(Terminal::vte_click), this);
    g_signal_connect(vte, "focus-in-event", G_CALLBACK(Terminal::vte_got_focus), this);
    g_signal_connect(vte, "focus-out-event", G_CALLBACK(Terminal::vte_lost_focus), this);
    g_signal_connect(vte, "selection-changed", G_CALLBACK(Terminal::vte_selection_changed), this);
    g_signal_connect(vte, "window-title-changed", G_CALLBACK(Terminal::vte_title_changed), this);

    searchbar.add(searchentry);
    searchbar.connect_entry(searchentry);
    searchentry.signal_focus_out_event().connect(mem_fun(this, &Terminal::searchentry_lost_focus));
    searchentry.signal_key_release_event().connect(mem_fun(this, &Terminal::searchentry_keypress));

    pack_start(eventbox, false, false, 0);
    pack_start(scrollbox, true, true, 0);
    pack_start(searchbar, false, false, 0);
    gtk_box_pack_start(GTK_BOX(scrollbox.gobj()), vte, true, true, 0);
    scrollbox.pack_start(scrollbar, false, false, 0);
    gtk_range_set_adjustment(GTK_RANGE(scrollbar.gobj()), gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vte)));
    show_all_children();

    find_label.terminal = this;
    find_label.set_alignment(0.0, 0.5);
    find_window->list_box.prepend(find_label);

    std::vector<Gtk::TargetEntry> listTargets;
    listTargets.push_back(Gtk::TargetEntry("SvanTerminal", Gtk::TARGET_SAME_APP, 0));

    eventbox.drag_source_set(listTargets);

    drag_dest_set(listTargets);
    eventbox.signal_drag_begin().connect(sigc::mem_fun(this, &Terminal::on_my_drag_begin));
    eventbox.signal_drag_failed().connect(sigc::mem_fun(this, &Terminal::on_my_drag_failed));
    eventbox.signal_drag_end().connect(sigc::mem_fun(this, &Terminal::on_my_drag_end));
    signal_drag_motion().connect(sigc::mem_fun(this, &Terminal::on_my_drag_motion));
    signal_drag_drop().connect(sigc::mem_fun(this, &Terminal::on_my_drag_drop));
    signal_drag_leave().connect(sigc::mem_fun(this, &Terminal::on_my_drag_leave));
}
Example #4
0
File: reflect.c Project: GNOME/vte
static void
terminal_shell_vte(GtkWidget *terminal)
{
        char *argv[2];

        argv[0] = vte_get_user_shell ();
        argv[1] = NULL;
	vte_terminal_spawn_sync(VTE_TERMINAL(terminal),
                                       VTE_PTY_DEFAULT,
                                       g_get_home_dir() ? g_get_home_dir() : NULL,
                                       argv,
                                       NULL,
                                       0, NULL, NULL,
                                       NULL,
                                       NULL,
                                       NULL);
}
Example #5
0
static void
vte_spawn(VteTerminal* vte, char* working_directory, char* command, char** environment)
{
    GError* error = NULL;
    char** command_argv = NULL;

    /* Parse command into array */
    if (!command)
        command = vte_get_user_shell();
    g_shell_parse_argv(command, NULL, &command_argv, &error);
    if (error) {
        g_printerr("Failed to parse command: %s\n", error->message);
        g_error_free(error);
        exit(EXIT_FAILURE);
    }

    /* Create pty object */
    VtePty* pty = vte_terminal_pty_new_sync(vte, VTE_PTY_NO_HELPER, NULL, &error);
    if (error) {
        g_printerr("Failed to create pty: %s\n", error->message);
        g_error_free(error);
        exit(EXIT_FAILURE);
    }
    vte_terminal_set_pty(vte, pty);

    int child_pid;

    /* Spawn default shell (or specified command) */
    g_spawn_async(working_directory, command_argv, environment,
                  (G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN),  // flags from GSpawnFlags
                  (GSpawnChildSetupFunc)vte_pty_child_setup, // an extra child setup function to run in the child just before exec()
                  pty,          // user data for child_setup
                  &child_pid,   // a location to store the child PID
                  &error);      // return location for a GError
    if (error) {
        g_printerr("%s\n", error->message);
        g_error_free(error);
        exit(EXIT_FAILURE);
    }
    vte_terminal_watch_child(vte, child_pid);
    g_strfreev(command_argv);
}
Example #6
0
static void
activate (GtkApplication* app,
          gpointer        user_data)
{
	GtkWidget *window;
	GtkWidget *bases, *keyLength, *errorBits, *errorTolerance, *playButton,
		*mode, *peerIp, *eveRate, *eveStrategy, *channelNoise, 
		*genBias;
	GtkWidget *windowBox, *optionGrid, *playGrid, *playBox;
	GtkWidget *baseLabel, *keyLengthLabel, *errorBitsLabel, 
		*errorToleranceLabel, *peerIpLabel, *eveRateLabel,
		*eveStrategyLabel, *channelNoiseLabel, *genBiasLabel;
	GtkWidget *tty1;
	GtkWidget *tty2;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Quantum Network Simulator");
  gtk_window_set_default_size (GTK_WINDOW (window), 1280, 720);

	windowBox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
	gtk_container_add(GTK_CONTAINER(window), windowBox);

	playBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
	gtk_container_add(GTK_CONTAINER(windowBox), playBox);

	optionGrid = gtk_grid_new ();
	gtk_container_add(GTK_CONTAINER(playBox), optionGrid);

	playGrid = gtk_grid_new ();
	gtk_grid_set_column_spacing(GTK_GRID(playGrid), 20); 
	gtk_container_add(GTK_CONTAINER(playBox), playGrid);

	mode = gtk_combo_box_text_new ();
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(mode), "Superposition Tutorial");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(mode), "Measurement Tutorial");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(mode), "Classic BB84 Tutorial");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(mode), "Polybase BB84 Tutorial");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(mode), "Bias BB84 Tutorial");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(mode), "Freestyle BB84");
	gtk_grid_attach(GTK_GRID( optionGrid ), mode, 0, 0, 2, 1);

	baseLabel = gtk_label_new("Number of bases");
	bases = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), baseLabel , 0, 1, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), bases , 1, 1, 1, 1);

	keyLengthLabel = gtk_label_new("Key Length");
	keyLength = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), keyLengthLabel , 0, 2, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), keyLength, 1, 2, 1, 1);

	errorBitsLabel = gtk_label_new("Number of error detection bits");
	errorBits = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorBitsLabel , 0, 3, 1, 1);
		gtk_grid_attach(GTK_GRID( optionGrid ), errorBits , 1, 3, 1, 1);

	errorToleranceLabel = gtk_label_new("Number of error bits to tolerate");
	errorTolerance = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorToleranceLabel , 0, 4, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), errorTolerance , 1, 4, 1, 1);

	errorToleranceLabel = gtk_label_new("Peer IP");
	errorTolerance = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorToleranceLabel , 2, 0, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), errorTolerance , 3, 0, 1, 1);

	errorToleranceLabel = gtk_label_new("Eve Eavesdrop Rate");
	errorTolerance = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorToleranceLabel , 2, 1, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), errorTolerance , 3, 1, 1, 1);

	errorToleranceLabel = gtk_label_new("Eve Eavesdrop Strategy");
	errorTolerance = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorToleranceLabel , 2, 2, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), errorTolerance , 3, 2, 1, 1);

	errorToleranceLabel = gtk_label_new("Generator Bias");
	errorTolerance = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorToleranceLabel , 2, 3, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), errorTolerance , 3, 3, 1, 1);

	errorToleranceLabel = gtk_label_new("Channel Noise");
	errorTolerance = gtk_entry_new ();
	gtk_grid_attach(GTK_GRID( optionGrid ), errorToleranceLabel , 2, 4, 1, 1);
	gtk_grid_attach(GTK_GRID( optionGrid ), errorTolerance , 3, 4, 1, 1);

	playButton = gtk_button_new_with_label("PLAY QUANTUM ALGORITHM");
	g_signal_connect (playButton, "clicked", G_CALLBACK(playAlgorithm), playButton);
//	g_signal_connect_swapped (playButton, "clicked", G_CALLBACK(gtk_widget_destroy), window);
	gtk_grid_attach(GTK_GRID( optionGrid ), playButton, 0, 5, 4, 1);

	char *startTerm[2] = {0,0};
	startTerm[0] = vte_get_user_shell();
	GPid pidTerm;

	tty1 = vte_terminal_new();
	vte_terminal_fork_command_full(VTE_TERMINAL(tty1),
		VTE_PTY_DEFAULT,
		NULL, //"/tmp",
		startTerm,
		NULL,
		(GSpawnFlags)(G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH),
		NULL,
		NULL,
		NULL,
		NULL );
	gtk_widget_set_size_request(tty1, 600, 400);
	gtk_grid_attach(GTK_GRID (playGrid ), tty1, 0, 6, 4, 15);
	gtk_widget_set_sensitive(tty1, FALSE);

	tty2 = vte_terminal_new();
	vte_terminal_fork_command_full(VTE_TERMINAL(tty2),
		VTE_PTY_DEFAULT,
		NULL, //"/tmp",
		startTerm,
		NULL,
		(GSpawnFlags)(G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH),
		NULL,
		NULL,
		NULL,
		NULL );
	gtk_widget_set_size_request(tty2, 600, 400);
	gtk_grid_attach(GTK_GRID (playGrid ), tty2, 4, 6, 4, 15);
	gtk_widget_set_sensitive(tty2, FALSE);

	g_object_set_data(G_OBJECT(playButton), "tty1", VTE_TERMINAL(tty1));
	g_object_set_data(G_OBJECT(playButton), "tty2", VTE_TERMINAL(tty2));
	g_object_set_data(G_OBJECT(playButton), "in_mode", GTK_COMBO_BOX_TEXT(mode));
	g_object_set_data(G_OBJECT(playButton), "in_bases", GTK_ENTRY(bases));
	g_object_set_data(G_OBJECT(playButton), "in_keyLength", GTK_ENTRY(keyLength));
	g_object_set_data(G_OBJECT(playButton), "in_errorBits", GTK_ENTRY(errorBits));
	g_object_set_data(G_OBJECT(playButton), "in_errorTolerance", GTK_ENTRY(errorTolerance));

  gtk_widget_show_all (window);
}
Example #7
0
File: daemon.c Project: vain/xiate
gboolean
setup_term(GtkWidget *win, GtkWidget *term, struct term_options *to)
{
    static char *args_default[] = { NULL, NULL, NULL };
    char **args_use;
    size_t i;
    GdkRGBA c_foreground_gdk;
    GdkRGBA c_background_gdk;
    GdkRGBA c_palette_gdk[16];
    GdkRGBA c_gdk;
    VteRegex *url_vregex = NULL;
    GError *err = NULL;
    GSpawnFlags spawn_flags;

    if (to->argv != NULL)
    {
        args_use = to->argv;
        spawn_flags = G_SPAWN_SEARCH_PATH;
    }
    else
    {
        if (args_default[0] == NULL)
        {
            args_default[0] = vte_get_user_shell();
            if (args_default[0] == NULL)
                args_default[0] = "/bin/sh";
            if (login_shell)
                args_default[1] = g_strdup_printf("-%s", args_default[0]);
            else
                args_default[1] = args_default[0];
        }
        args_use = args_default;
        spawn_flags = G_SPAWN_SEARCH_PATH | G_SPAWN_FILE_AND_ARGV_ZERO;
    }

    /* Appearance. */
    term_set_font(NULL, VTE_TERMINAL(term), 0);
    gtk_widget_show_all(win);

    vte_terminal_set_allow_bold(VTE_TERMINAL(term), enable_bold);
    vte_terminal_set_cursor_blink_mode(VTE_TERMINAL(term), VTE_CURSOR_BLINK_OFF);
    vte_terminal_set_geometry_hints_for_window(VTE_TERMINAL(term),
                                               GTK_WINDOW(win));
    vte_terminal_set_mouse_autohide(VTE_TERMINAL(term), TRUE);
    vte_terminal_set_scrollback_lines(VTE_TERMINAL(term), scrollback_lines);

    gdk_rgba_parse(&c_foreground_gdk, c_foreground);
    gdk_rgba_parse(&c_background_gdk, c_background);
    for (i = 0; i < 16; i++)
        gdk_rgba_parse(&c_palette_gdk[i], c_palette[i]);
    vte_terminal_set_colors(VTE_TERMINAL(term), &c_foreground_gdk,
                            &c_background_gdk, c_palette_gdk, 16);

    if (c_bold != NULL)
    {
        gdk_rgba_parse(&c_gdk, c_bold);
        vte_terminal_set_color_bold(VTE_TERMINAL(term), &c_gdk);
    }

    if (c_cursor != NULL)
    {
        gdk_rgba_parse(&c_gdk, c_cursor);
        vte_terminal_set_color_cursor(VTE_TERMINAL(term), &c_gdk);
    }

    if (c_cursor_foreground != NULL)
    {
        gdk_rgba_parse(&c_gdk, c_cursor_foreground);
        vte_terminal_set_color_cursor_foreground(VTE_TERMINAL(term), &c_gdk);
    }

    url_vregex = vte_regex_new_for_match(url_regex, strlen(url_regex),
                                         PCRE2_MULTILINE | PCRE2_CASELESS, &err);
    if (url_vregex == NULL)
        fprintf(stderr, "url_regex: %s\n",
                err == NULL ? "<err is NULL>" : err->message);
    else
    {
        vte_terminal_match_add_regex(VTE_TERMINAL(term), url_vregex, 0);
        vte_regex_unref(url_vregex);
    }

    /* Signals. */
    g_signal_connect(G_OBJECT(term), "bell",
                     G_CALLBACK(sig_bell), win);
    g_signal_connect(G_OBJECT(term), "button-press-event",
                     G_CALLBACK(sig_button_press), NULL);
    if (!to->hold)
        g_signal_connect(G_OBJECT(term), "child-exited",
                         G_CALLBACK(sig_child_exited), win);
    g_signal_connect(G_OBJECT(term), "decrease-font-size",
                     G_CALLBACK(sig_decrease_font_size), win);
    g_signal_connect(G_OBJECT(term), "increase-font-size",
                     G_CALLBACK(sig_increase_font_size), win);
    g_signal_connect(G_OBJECT(term), "key-press-event",
                     G_CALLBACK(sig_key_press), win);
    g_signal_connect(G_OBJECT(term), "resize-window",
                     G_CALLBACK(sig_window_resize), win);
    g_signal_connect(G_OBJECT(term), "window-title-changed",
                     G_CALLBACK(sig_window_title_changed), win);

    /* Spawn child. */
    return vte_terminal_spawn_sync(VTE_TERMINAL(term), VTE_PTY_DEFAULT, to->cwd,
                                   args_use, NULL, spawn_flags,
                                   NULL, NULL, NULL, NULL, NULL);
}
Example #8
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;
}