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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}