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 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; }
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; }