/** * gis_page_util_run_reformatter: * * Launches the reformatter, and arranges for the assistant to be hidden for * the duration of its runtime. @callback will be called when the reformatter * exits. * * There is no corresponding _finish() function because (at present) neither * caller actually cares about the result. */ void gis_page_util_run_reformatter (GisPage *page, GAsyncReadyCallback callback, gpointer user_data) { g_autoptr(GTask) task = g_task_new (page, NULL, callback, user_data); g_autoptr(GSubprocessLauncher) launcher = NULL; g_autoptr(GSubprocess) subprocess = NULL; const gchar *locale = setlocale (LC_MESSAGES, NULL); const gchar *command = "/usr/lib/eos-installer/gnome-image-installer"; g_autoptr(GError) error = NULL; launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); g_subprocess_launcher_setenv (launcher, "LANG", locale, TRUE); subprocess = g_subprocess_launcher_spawn (launcher, &error, command, NULL); if (error) { on_reformatter_exited (task, g_steal_pointer (&error)); return; } gis_driver_hide_window (page->driver); g_subprocess_wait_check_async (subprocess, NULL, reformatter_exited_cb, g_steal_pointer (&task)); }
static gboolean spawn_delta_generation (GMainContext *context, int *n_spawned_delta_generate, OstreeRepo *repo, GVariant *params, const char *ref, const char *from, const char *to, GError **error) { g_autoptr(GSubprocessLauncher) launcher = g_subprocess_launcher_new (0); g_autoptr(GSubprocess) subprocess = NULL; const char *argv[] = { "/proc/self/exe", "build-update-repo", "--generate-static-delta-ref", ref, "--generate-static-delta-to", to, NULL, NULL, NULL, NULL }; int i = 6; g_autofree char *exe = NULL; exe = flatpak_readlink ("/proc/self/exe", NULL); if (exe) argv[0] = exe; if (from) { argv[i++] = "--generate-static-delta-from"; argv[i++] = from; } argv[i++] = flatpak_file_get_path_cached (ostree_repo_get_path (repo)); argv[i++] = NULL; g_assert (i <= G_N_ELEMENTS (argv)); while (*n_spawned_delta_generate >= opt_static_delta_jobs) g_main_context_iteration (context, TRUE); subprocess = g_subprocess_launcher_spawnv (launcher, argv, error); if (subprocess == NULL) return FALSE; (*n_spawned_delta_generate)++; g_subprocess_wait_async (subprocess, NULL, delta_generation_done, n_spawned_delta_generate); return TRUE; }
static TestClient * test_client_new (const char *id, MetaWindowClientType type, GError **error) { TestClient *client = g_new0 (TestClient, 1); GSubprocessLauncher *launcher; GSubprocess *subprocess; launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE); g_assert (meta_is_wayland_compositor ()); MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); g_subprocess_launcher_setenv (launcher, "WAYLAND_DISPLAY", meta_wayland_get_wayland_display_name (compositor), TRUE); g_subprocess_launcher_setenv (launcher, "DISPLAY", meta_wayland_get_xwayland_display_name (compositor), TRUE); subprocess = g_subprocess_launcher_spawn (launcher, error, test_client_path, "--client-id", id, type == META_WINDOW_CLIENT_TYPE_WAYLAND ? "--wayland" : NULL, NULL); g_object_unref (launcher); if (!subprocess) return NULL; client->type = type; client->id = g_strdup (id); client->cancellable = g_cancellable_new (); client->subprocess = subprocess; client->in = g_data_output_stream_new (g_subprocess_get_stdin_pipe (subprocess)); client->out = g_data_input_stream_new (g_subprocess_get_stdout_pipe (subprocess)); client->loop = g_main_loop_new (NULL, FALSE); if (client->type == META_WINDOW_CLIENT_TYPE_X11) client->waiter = async_waiter_new (); return client; }
static GSubprocess * gb_beautifier_process_create_for_clang_format (GbBeautifierWorkbenchAddin *self, ProcessState *state, GError *error) { g_autoptr(GSubprocessLauncher) launcher = NULL; GSubprocess *subprocess = NULL; GPtrArray *args; gchar *config_path; gchar *src_path; g_autofree gchar *tmp_workdir = NULL; g_autofree gchar *tmp_config_path = NULL; g_autofree gchar *tmp_src_path = NULL; g_assert (GB_IS_BEAUTIFIER_WORKBENCH_ADDIN (self)); g_assert (state != NULL); config_path = g_file_get_path (state->config_file); src_path = g_file_get_path (state->src_file); g_assert (!ide_str_empty0 (config_path)); g_assert (!ide_str_empty0 (src_path)); g_assert (!ide_str_empty0 (state->lang_id)); if (NULL == (tmp_workdir = g_dir_make_tmp ("gnome-builder-beautify-XXXXXX", &error))) return NULL; state->tmp_workdir_file = g_file_new_for_path (tmp_workdir); tmp_config_path = g_build_filename (tmp_workdir, ".clang-format", NULL); state->tmp_config_file = g_file_new_for_path (tmp_config_path); if (!g_file_copy (state->config_file, state->tmp_config_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) return NULL; tmp_src_path = g_build_filename (tmp_workdir, "src_file", NULL); state->tmp_src_file = g_file_new_for_path (tmp_src_path); if (!g_file_copy (state->src_file, state->tmp_src_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) return NULL; args = g_ptr_array_new (); g_ptr_array_add (args, "clang-format"); g_ptr_array_add (args, "-style=file"); g_ptr_array_add (args, tmp_src_path); g_ptr_array_add (args, NULL); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE); g_subprocess_launcher_set_cwd (launcher, tmp_workdir); subprocess = g_subprocess_launcher_spawnv (launcher, (const gchar * const *)args->pdata, &error); g_ptr_array_free (args, TRUE); return subprocess; }
static gboolean spawn_session (State *state, gboolean run_script, GCancellable *cancellable) { GSubprocessLauncher *launcher = NULL; GSubprocess *subprocess = NULL; GError *error = NULL; gboolean is_running = FALSE; const char *vt; g_debug ("Running X session"); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); g_subprocess_launcher_setenv (launcher, "DISPLAY", state->display_name, TRUE); g_subprocess_launcher_setenv (launcher, "XAUTHORITY", state->auth_file, TRUE); g_subprocess_launcher_setenv (launcher, "DBUS_SESSION_BUS_ADDRESS", state->bus_address, TRUE); vt = g_getenv ("XDG_VTNR"); if (vt != NULL) { g_subprocess_launcher_setenv (launcher, "WINDOWPATH", vt, TRUE); } if (run_script) { subprocess = g_subprocess_launcher_spawn (launcher, &error, GDMCONFDIR "/Xsession", state->session_command, NULL); } else { int ret; char **argv; ret = g_shell_parse_argv (state->session_command, NULL, &argv, &error); if (!ret) { g_debug ("could not parse session arguments: %s", error->message); goto out; } subprocess = g_subprocess_launcher_spawnv (launcher, (const char * const *) argv, &error); g_strfreev (argv); } if (subprocess == NULL) { g_debug ("could not start session: %s", error->message); goto out; } state->session_subprocess = g_object_ref (subprocess); g_subprocess_wait_async (state->session_subprocess, cancellable, (GAsyncReadyCallback) on_session_finished, state); is_running = TRUE; out: g_clear_object (&subprocess); return is_running; }
static gboolean spawn_bus (State *state, GCancellable *cancellable) { GPtrArray *arguments = NULL; GSubprocessLauncher *launcher = NULL; GSubprocess *subprocess = NULL; GInputStream *input_stream = NULL; GDataInputStream *data_stream = NULL; GError *error = NULL; const char *bus_env = NULL; char *bus_address_fd_string; char *bus_address = NULL; gsize bus_address_size; gboolean is_running = FALSE; int ret; int pipe_fds[2]; g_debug ("Running session message bus"); bus_env = g_getenv ("DBUS_SESSION_BUS_ADDRESS"); if (bus_env != NULL) { g_debug ("session message bus already running, not starting another one"); state->bus_address = g_strdup (bus_env); return TRUE; } ret = g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error); if (!ret) { g_debug ("could not open pipe: %s", error->message); goto out; } arguments = g_ptr_array_new (); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); g_subprocess_launcher_setenv (launcher, "DISPLAY", state->display_name, TRUE); g_subprocess_launcher_setenv (launcher, "XAUTHORITY", state->auth_file, TRUE); g_subprocess_launcher_take_fd (launcher, pipe_fds[1], BUS_ADDRESS_FILENO); bus_address_fd_string = g_strdup_printf ("%d", BUS_ADDRESS_FILENO); g_ptr_array_add (arguments, "dbus-daemon"); g_ptr_array_add (arguments, "--print-address"); g_ptr_array_add (arguments, bus_address_fd_string); g_ptr_array_add (arguments, "--session"); g_ptr_array_add (arguments, NULL); subprocess = g_subprocess_launcher_spawnv (launcher, (const char * const *) arguments->pdata, &error); g_free (bus_address_fd_string); g_clear_object (&launcher); g_ptr_array_free (arguments, TRUE); if (subprocess == NULL) { g_debug ("could not start dbus-daemon: %s", error->message); goto out; } input_stream = g_unix_input_stream_new (pipe_fds[0], TRUE); data_stream = g_data_input_stream_new (input_stream); g_clear_object (&input_stream); bus_address = g_data_input_stream_read_line (data_stream, &bus_address_size, cancellable, &error); if (error != NULL) { g_debug ("could not read address from session message bus: %s", error->message); goto out; } if (bus_address == NULL) { g_debug ("session message bus did not write address"); goto out; } state->bus_address = bus_address; state->bus_subprocess = g_object_ref (subprocess); g_subprocess_wait_async (state->bus_subprocess, cancellable, (GAsyncReadyCallback) on_bus_finished, state); is_running = TRUE; out: g_clear_object (&data_stream); g_clear_object (&subprocess); g_clear_object (&launcher); g_clear_error (&error); return is_running; }
static gboolean spawn_x_server (State *state, gboolean allow_remote_connections, GCancellable *cancellable) { GPtrArray *arguments = NULL; GSubprocessLauncher *launcher = NULL; GSubprocess *subprocess = NULL; GInputStream *input_stream = NULL; GDataInputStream *data_stream = NULL; GError *error = NULL; char *auth_file; gboolean is_running = FALSE; int ret; int pipe_fds[2]; char *display_fd_string = NULL; char *vt_string = NULL; char *display_number; gsize display_number_size; auth_file = prepare_auth_file (); g_debug ("Running X server"); ret = g_unix_open_pipe (pipe_fds, FD_CLOEXEC, &error); if (!ret) { g_debug ("could not open pipe: %s", error->message); goto out; } arguments = g_ptr_array_new (); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_INHERIT); g_subprocess_launcher_setenv (launcher, "XORG_RUN_AS_USER_OK", "1", TRUE); g_subprocess_launcher_take_fd (launcher, pipe_fds[1], DISPLAY_FILENO); if (g_getenv ("XDG_VTNR") != NULL) { int vt; vt = atoi (g_getenv ("XDG_VTNR")); if (vt > 0 && vt < 64) { vt_string = g_strdup_printf ("vt%d", vt); } } display_fd_string = g_strdup_printf ("%d", DISPLAY_FILENO); g_ptr_array_add (arguments, X_SERVER); if (vt_string != NULL) { g_ptr_array_add (arguments, vt_string); } g_ptr_array_add (arguments, "-displayfd"); g_ptr_array_add (arguments, display_fd_string); g_ptr_array_add (arguments, "-auth"); g_ptr_array_add (arguments, auth_file); /* If we were compiled with Xserver >= 1.17 we need to specify * '-listen tcp' as the X server dosen't listen on tcp sockets * by default anymore. In older versions we need to pass * -nolisten tcp to disable listening on tcp sockets. */ #ifdef HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY if (allow_remote_connections) { g_ptr_array_add (arguments, "-listen"); g_ptr_array_add (arguments, "tcp"); } #else if (!allow_remote_connections) { g_ptr_array_add (arguments, "-nolisten"); g_ptr_array_add (arguments, "tcp"); } #endif g_ptr_array_add (arguments, "-background"); g_ptr_array_add (arguments, "none"); g_ptr_array_add (arguments, "-noreset"); g_ptr_array_add (arguments, "-keeptty"); g_ptr_array_add (arguments, "-verbose"); if (state->debug_enabled) { g_ptr_array_add (arguments, "7"); } else { g_ptr_array_add (arguments, "3"); } if (state->debug_enabled) { g_ptr_array_add (arguments, "-core"); } g_ptr_array_add (arguments, NULL); subprocess = g_subprocess_launcher_spawnv (launcher, (const char * const *) arguments->pdata, &error); g_free (display_fd_string); g_clear_object (&launcher); g_ptr_array_free (arguments, TRUE); if (subprocess == NULL) { g_debug ("could not start X server: %s", error->message); goto out; } input_stream = g_unix_input_stream_new (pipe_fds[0], TRUE); data_stream = g_data_input_stream_new (input_stream); g_clear_object (&input_stream); display_number = g_data_input_stream_read_line (data_stream, &display_number_size, cancellable, &error); if (error != NULL) { g_debug ("could not read display string from X server: %s", error->message); goto out; } if (display_number == NULL) { g_debug ("X server did not write display string"); goto out; } state->display_name = g_strdup_printf (":%s", display_number); g_clear_pointer (&display_number, g_free); state->auth_file = g_strdup (auth_file); state->x_subprocess = g_object_ref (subprocess); g_subprocess_wait_async (state->x_subprocess, cancellable, (GAsyncReadyCallback) on_x_server_finished, state); is_running = TRUE; out: g_clear_pointer (&auth_file, g_free); g_clear_object (&data_stream); g_clear_object (&subprocess); g_clear_object (&launcher); g_clear_error (&error); return is_running; }
gboolean meta_xwayland_start (MetaXWaylandManager *manager, struct wl_display *wl_display) { int xwayland_client_fd[2]; int displayfd[2]; gboolean started = FALSE; g_autoptr(GSubprocessLauncher) launcher = NULL; GSubprocessFlags flags; GSubprocess *proc; GError *error = NULL; if (!choose_xdisplay (manager)) goto out; /* We want xwayland to be a wayland client so we make a socketpair to setup a * wayland protocol connection. */ if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, xwayland_client_fd) < 0) { g_warning ("xwayland_client_fd socketpair failed\n"); goto out; } if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, displayfd) < 0) { g_warning ("displayfd socketpair failed\n"); goto out; } /* xwayland, please. */ flags = G_SUBPROCESS_FLAGS_NONE; if (getenv ("XWAYLAND_STFU")) { flags |= G_SUBPROCESS_FLAGS_STDOUT_SILENCE; flags |= G_SUBPROCESS_FLAGS_STDERR_SILENCE; } launcher = g_subprocess_launcher_new (flags); g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3); g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4); g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5); g_subprocess_launcher_take_fd (launcher, displayfd[1], 6); g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE); proc = g_subprocess_launcher_spawn (launcher, &error, XWAYLAND_PATH, manager->display_name, "-rootless", "-noreset", "-listen", "4", "-listen", "5", "-displayfd", "6", NULL); if (!proc) { g_error ("Failed to spawn Xwayland: %s", error->message); goto out; } g_subprocess_wait_async (proc, NULL, xserver_died, NULL); g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager); manager->client = wl_client_create (wl_display, xwayland_client_fd[0]); /* We need to run a mainloop until we know xwayland has a binding * for our xserver interface at which point we can assume it's * ready to start accepting connections. */ manager->init_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (manager->init_loop); started = TRUE; out: if (!started) { unlink (manager->lock_file); g_clear_pointer (&manager->lock_file, g_free); } return started; }
static gboolean launch_and_wait_variables_handler(gchar *handler_name, GHashTable *variables, GError **error) { g_autoptr(GSubprocessLauncher) handlelaunch = NULL; g_autoptr(GSubprocess) handleproc = NULL; GError *ierror = NULL; GHashTableIter iter; gchar *key = NULL; gchar *value = NULL; g_autoptr(GDataInputStream) datainstream = NULL; GInputStream *instream; gchar* outline; g_return_val_if_fail(handler_name, FALSE); g_return_val_if_fail(variables, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); handlelaunch = g_subprocess_launcher_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE); /* we copy the variables from the hashtable and add them to the subprocess environment */ g_hash_table_iter_init(&iter, variables); while (g_hash_table_iter_next(&iter, (gpointer*) &key, (gpointer*) &value)) { g_subprocess_launcher_setenv(handlelaunch, g_strdup(key), g_strdup(value), 1); } handleproc = g_subprocess_launcher_spawn( handlelaunch, &ierror, handler_name, NULL, NULL); if (!handleproc) { g_propagate_error(error, ierror); return FALSE; } instream = g_subprocess_get_stdout_pipe(handleproc); datainstream = g_data_input_stream_new(instream); do { outline = g_data_input_stream_read_line(datainstream, NULL, NULL, NULL); if (!outline) continue; if (g_str_has_prefix(outline, "RAUC_")) { gchar **split = g_strsplit(outline, "=", 2); if (g_strv_length(split) != 2) continue; g_hash_table_insert(variables, g_strdup(split[0]), g_strdup(split[1])); g_strfreev(split); } } while (outline); if (!g_subprocess_wait_check(handleproc, NULL, &ierror)) { g_propagate_error(error, ierror); return FALSE; } return TRUE; }
static gboolean archive_spawnv (GFile *dir, char **output, GError **error, const gchar * const *argv) { g_autoptr(GSubprocessLauncher) launcher = NULL; g_autoptr(GSubprocess) subp = NULL; GInputStream *in; g_autoptr(GOutputStream) out = NULL; g_autoptr(GMainLoop) loop = NULL; SpawnData data = {0}; g_autofree gchar *commandline = NULL; launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); if (output) g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); if (dir) { g_autofree char *path = g_file_get_path (dir); g_subprocess_launcher_set_cwd (launcher, path); } commandline = g_strjoinv (" ", (gchar **) argv); g_debug ("Running '%s'", commandline); subp = g_subprocess_launcher_spawnv (launcher, argv, error); if (subp == NULL) return FALSE; loop = g_main_loop_new (NULL, FALSE); data.loop = loop; data.refs = 1; if (output) { data.refs++; in = g_subprocess_get_stdout_pipe (subp); out = g_memory_output_stream_new_resizable (); g_output_stream_splice_async (out, in, G_OUTPUT_STREAM_SPLICE_NONE, 0, NULL, spawn_output_spliced_cb, &data); } g_subprocess_wait_async (subp, NULL, spawn_exit_cb, &data); g_main_loop_run (loop); if (data.error) { g_propagate_error (error, data.error); g_clear_error (&data.splice_error); return FALSE; } if (out) { if (data.splice_error) { g_propagate_error (error, data.splice_error); return FALSE; } /* Null terminate */ g_output_stream_write (out, "\0", 1, NULL, NULL); g_output_stream_close (out, NULL, NULL); *output = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); } return TRUE; }