static void gbp_vagrant_runtime_provider_load_async (GbpVagrantRuntimeProvider *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_autoptr(IdeSubprocessLauncher) launcher = NULL; g_autoptr(IdeSubprocess) subprocess = NULL; g_autoptr(IdeTask) task = NULL; g_autoptr(GError) error = NULL; g_assert (IDE_IS_MAIN_THREAD ()); g_assert (GBP_IS_VAGRANT_RUNTIME_PROVIDER (self)); g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); task = ide_task_new (self, cancellable, callback, user_data); ide_task_set_source_tag (task, gbp_vagrant_runtime_provider_load_async); launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE); ide_subprocess_launcher_set_cwd (launcher, g_get_home_dir ()); ide_subprocess_launcher_set_run_on_host (launcher, TRUE); ide_subprocess_launcher_push_argv (launcher, "which"); ide_subprocess_launcher_push_argv (launcher, "vagrant"); if (!(subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error))) ide_task_return_error (task, g_steal_pointer ((&error))); else ide_subprocess_wait_check_async (subprocess, cancellable, (GAsyncReadyCallback) check_vagrant_available_cb, g_steal_pointer (&task)); }
static gchar * gb_terminal_view_discover_shell (GCancellable *cancellable, GError **error) { g_autoptr(IdeSubprocessLauncher) launcher = NULL; g_autoptr(IdeSubprocess) subprocess = NULL; g_autofree gchar *command = NULL; g_autofree gchar *stdout_buf = NULL; g_auto(GStrv) argv = NULL; g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); if (cached_shell != NULL) return g_strdup (cached_shell); command = g_strdup_printf ("sh -c 'getent passwd | grep ^%s: | cut -f 7 -d :'", g_get_user_name ()); if (!g_shell_parse_argv (command, NULL, &argv, error)) return NULL; launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE); ide_subprocess_launcher_set_run_on_host (launcher, TRUE); ide_subprocess_launcher_set_clear_env (launcher, FALSE); ide_subprocess_launcher_set_cwd (launcher, g_get_home_dir ()); ide_subprocess_launcher_push_args (launcher, (const gchar * const *)argv); subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, error); if (subprocess == NULL) return NULL; if (!ide_subprocess_communicate_utf8 (subprocess, NULL, cancellable, &stdout_buf, NULL, error)) return NULL; if (stdout_buf != NULL) { g_strstrip (stdout_buf); if (stdout_buf[0] == '/') cached_shell = g_steal_pointer (&stdout_buf); } if (cached_shell == NULL) g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error when discovering user shell"); return g_strdup (cached_shell); }
void gbp_vagrant_runtime_provider_command_async (GbpVagrantRuntimeProvider *self, const gchar * const *command, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_autoptr(IdeSubprocessLauncher) launcher = NULL; g_autoptr(IdeSubprocess) subprocess = NULL; g_autoptr(IdeTask) task = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) workdir = NULL; IdeContext *context; g_assert (GBP_IS_VAGRANT_RUNTIME_PROVIDER (self)); g_assert (command != NULL && command[0] != NULL); g_assert (g_str_equal ("vagrant", command[0])); g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); task = ide_task_new (self, cancellable, callback, user_data); ide_task_set_source_tag (task, gbp_vagrant_runtime_provider_command_async); context = ide_object_get_context (IDE_OBJECT (self)); workdir = ide_context_ref_workdir (context); launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_SILENCE); ide_subprocess_launcher_set_cwd (launcher, g_file_peek_path (workdir)); ide_subprocess_launcher_push_args (launcher, command); if (!g_strv_contains (command, "--machine-readable")) ide_subprocess_launcher_push_argv (launcher, "--machine-readable"); if (!(subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error))) ide_task_return_error (task, g_steal_pointer (&error)); else ide_subprocess_communicate_utf8_async (subprocess, NULL, cancellable, (GAsyncReadyCallback) gbp_vagrant_runtime_provider_command_cb, g_steal_pointer (&task)); }
static gboolean ide_subprocess_supervisor_real_supervise (IdeSubprocessSupervisor *self, IdeSubprocessLauncher *launcher) { g_autoptr(IdeSubprocess) subprocess = NULL; g_autoptr(GError) error = NULL; g_assert (IDE_IS_SUBPROCESS_SUPERVISOR (self)); g_assert (IDE_IS_SUBPROCESS_LAUNCHER (launcher)); ide_subprocess_supervisor_reset (self); subprocess = ide_subprocess_launcher_spawn (launcher, NULL, &error); if (subprocess != NULL) ide_subprocess_supervisor_set_subprocess (self, subprocess); else g_warning ("%s", error->message); return TRUE; }
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; }