int main(int argc, char **argv) {
    const char *pty_path;
    int pty_in_fd, pty_out_fd;
    GInputStream *stdin, *instream;
    GOutputStream *stdout, *outstream;
    GMainLoop *loop;
    GError *error = NULL;

    if (argc != 2) {
        g_printerr("Usage: gnome-hwtest-terminal-splice <pty>\n");
        exit(1);
    }

    pty_path = argv[1];

    pty_in_fd = open(pty_path, O_RDONLY);
    if (pty_in_fd == -1)
        die_errno("Opening PTY for reading");

    pty_out_fd = open(pty_path, O_WRONLY);
    if (pty_out_fd == -1)
        die_errno("Opening PTY for writing");

    make_raw (0);
    make_raw (pty_in_fd);

    stdin = g_unix_input_stream_new(0, FALSE);
    stdout = g_unix_output_stream_new(1, FALSE);
    instream = g_unix_input_stream_new(pty_in_fd, FALSE);
    outstream = g_unix_output_stream_new(pty_out_fd, FALSE);

    loop = g_main_loop_new (NULL, FALSE);

    g_output_stream_splice_async(stdout, instream,
                                 G_OUTPUT_STREAM_SPLICE_NONE,
                                 G_PRIORITY_DEFAULT, NULL,
                                 on_eof, loop);
    check_error("Splicing stdout to PTY", error);

    g_output_stream_splice_async(outstream, stdin,
                                 G_OUTPUT_STREAM_SPLICE_NONE,
                                 G_PRIORITY_DEFAULT, NULL,
                                 on_eof, loop);
    check_error("Splicing stdin from PTY", error);

    g_main_loop_run (loop);

    return 0;
}
Example #2
0
static gboolean
gedit_main_load_from_stdin (GeditWindow *window,
                            gboolean     jump_to)
{
#ifdef G_OS_UNIX
	GInputStream *stream;
	const GeditEncoding *encoding;
	gint line_position;
	gint column_position;
	GeditCommandLine *command_line;

	command_line = gedit_command_line_get_default ();

	encoding = gedit_command_line_get_encoding (command_line);
	line_position = gedit_command_line_get_line_position (command_line);
	column_position = gedit_command_line_get_column_position (command_line);

	/* Construct a stream for stdin */
	stream = g_unix_input_stream_new (STDIN_FILENO, TRUE);

	gedit_window_create_tab_from_stream (window,
	                                     stream,
	                                     encoding,
	                                     line_position,
	                                     column_position,
	                                     jump_to);
	g_object_unref (stream);
	return TRUE;
#else
	return FALSE;
#endif
}
Example #3
0
/**
 * ot_openat_read_stream:
 * @dfd: Directory file descriptor
 * @path: Subpath
 * @follow: Whether or not to follow symbolic links
 * @out_istream: (out): Return location for input stream
 * @cancellable: Cancellable
 * @error: Error
 *
 * Open a file for reading starting from @dfd for @path.
 * The @follow parameter determines whether or not to follow
 * if the last element of @path is a symbolic link.  Intermediate
 * symlink path components are always followed.
 */
gboolean
ot_openat_read_stream (int             dfd,
                       const char     *path,
                       gboolean        follow,
                       GInputStream  **out_istream,
                       GCancellable   *cancellable,
                       GError        **error)
{
  gboolean ret = FALSE;
  int fd = -1;
  int flags = O_RDONLY | O_NOCTTY | O_CLOEXEC;

  if (!follow)
    flags |= O_NOFOLLOW;

  do
    fd = openat (dfd, path, flags, 0);
  while (G_UNLIKELY (fd == -1 && errno == EINTR));
  if (fd == -1)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }

  *out_istream = g_unix_input_stream_new (fd, TRUE);
  ret = TRUE;
 out:
  return ret;
}
Example #4
0
/**
 * test_pipe:
 * @is: (out) (allow-none): used to return a #GInputStream
 * @os: (out) (allow-none): used to return a #GOutputStream
 * @error: used to raise an error
 *
 * Return a "pipe to self" connecting @is to @os. This can be used
 * as a unidirectional pipe to or from a child process, for instance.
 *
 * See test_bidi_pipe() if you want to emulate a bidirectional pipe
 * via a pair of unidirectional pipes.
 *
 * Returns: %TRUE on success
 */
gboolean
test_pipe (GInputStream  **is,
           GOutputStream **os,
           GError        **error)
{
    int pipefd[2];
    int ret;

    ret = pipe (pipefd);

    if (ret != 0)
    {
        int e = errno;

        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (e),
                     "%s", g_strerror (e));
        return FALSE;
    }

    if (is != NULL)
        *is = g_unix_input_stream_new (pipefd[0], TRUE);
    else
        close (pipefd[0]);

    if (os != NULL)
        *os = g_unix_output_stream_new (pipefd[1], TRUE);
    else
        close (pipefd[1]);

    return TRUE;
}
Example #5
0
/**
 * gs_file_read_noatime:
 * @file: a #GFile
 * @cancellable: a #GCancellable
 * @error: a #GError
 *
 * Like g_file_read(), but try to avoid updating the file's
 * access time.  This should be used by background scanning
 * components such as search indexers, antivirus programs, etc.
 *
 * Returns: (transfer full): A new input stream, or %NULL on error
 */
GInputStream *
gs_file_read_noatime (GFile         *file,
                      GCancellable  *cancellable,
                      GError       **error)
{
    const char *path = NULL;
    int fd;

    if (g_cancellable_set_error_if_cancelled (cancellable, error))
        return NULL;

    path = gs_file_get_path_cached (file);
    if (path == NULL)
    {
        char *uri;
        uri = g_file_get_uri (file);
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
                     "%s has no associated path", uri);
        g_free (uri);
        return NULL;
    }

    if (!gs_file_openat_noatime (AT_FDCWD, path, &fd, cancellable, error))
        return NULL;

    return g_unix_input_stream_new (fd, TRUE);
}
Example #6
0
static gboolean
dracut_supports_reproducible (GFile *root, gboolean *supported,
                              GCancellable  *cancellable, GError **error)
{
    int pid, stdout[2];
    if (pipe (stdout) < 0)
    {
        glnx_set_error_from_errno (error);
        return FALSE;
    }

    pid = fork ();
    if (pid < 0)
    {
        close (stdout[0]);
        close (stdout[1]);
        glnx_set_error_from_errno (error);
        return FALSE;
    }

    /* Check that --reproducible is present in the --help output.  */
    if (pid == 0)
    {
        int null;
        char *child_argv[] = { "dracut", "--help", NULL };

        null = open ("/dev/null", O_RDWR);
        if (null < 0
                || close (stdout[0]) < 0
                || dup2 (stdout[1], 1) < 0
                || dup2 (null, 0) < 0
                || dup2 (null, 2) < 0)
            _exit (1);

        run_sync_in_root (root, "dracut", child_argv, NULL);
        _exit (1);
    }
    else
    {
        gsize read = 0;
        /* the dracut 0.43 --help output is about 8Kb, leave some room.  */
        const gsize buffer_size = 16384;
        g_autofree gchar *buffer = g_new (gchar, buffer_size);
        g_autoptr(GInputStream) in = g_unix_input_stream_new (stdout[0], TRUE);

        if (close (stdout[1]) < 0)
        {
            glnx_set_error_from_errno (error);
            return FALSE;
        }

        if (!g_input_stream_read_all (in, buffer, buffer_size, &read,
                                      cancellable, error))
            return FALSE;

        *supported = g_strstr_len (buffer, read, "--reproducible") != NULL;
        return TRUE;
    }
}
static gboolean
sysroot_setup_stdout_redirect (RpmostreedSysroot *self,
                               GError **error)
{
  g_autoptr(GInputStream) stream = NULL;
  g_autoptr(GSource) source = NULL;
  StdoutClosure *closure;
  gint pipefd[2];
  gboolean ret = FALSE;

  /* XXX libostree logs messages to systemd's journal and also to stdout.
   *     Redirect our own stdout back to ourselves so we can capture those
   *     messages and pass them on to clients.  Admittedly hokey but avoids
   *     hacking libostree directly (for now). */

  closure = g_slice_new0 (StdoutClosure);
  g_weak_ref_set (&closure->sysroot, self);

  /* Save the real stdout before overwriting its file descriptor. */
  closure->real_stdout = g_unix_output_stream_new (dup (STDOUT_FILENO), FALSE);

  if (pipe (pipefd) < 0)
    {
      glnx_set_prefix_error_from_errno (error, "%s", "pipe() failed");
      goto out;
    }

  if (dup2 (pipefd[1], STDOUT_FILENO) < 0)
    {
      glnx_set_prefix_error_from_errno (error, "%s", "dup2() failed");
      goto out;
    }

  stream = g_memory_input_stream_new ();
  closure->data_stream = g_data_input_stream_new (stream);
  g_clear_object (&stream);

  stream = g_unix_input_stream_new (pipefd[0], FALSE);

  source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (stream),
                                                  NULL);
  /* Transfer ownership of the StdoutClosure. */
  g_source_set_callback (source,
                         (GSourceFunc) sysroot_stdout_ready_cb,
                         closure,
                         (GDestroyNotify) stdout_closure_free);
  closure = NULL;

  self->stdout_source_id = g_source_attach (source, NULL);

  ret = TRUE;

out:
  if (closure != NULL)
    stdout_closure_free (closure);

  return ret;
}
static gboolean
schedule_wakeups_with_timerfd (GoaAlarm *self)
{
#ifdef HAVE_TIMERFD
  struct itimerspec timer_spec;
  int fd;
  int result;
  GSource *source;
  static gboolean seen_before = FALSE;

  if (!seen_before)
    {
      g_debug ("GoaAlarm: trying to use kernel timer");
      seen_before = TRUE;
    }

  fd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC | TFD_NONBLOCK);

  if (fd < 0)
    {
      g_debug ("GoaAlarm: could not create timer fd: %m");
      return FALSE;
    }

  memset (&timer_spec, 0, sizeof (timer_spec));
  timer_spec.it_value.tv_sec = g_date_time_to_unix (self->priv->time) + 1;

  result = timerfd_settime (fd,
                            TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
                            &timer_spec, NULL);

  if (result < 0)
    {
      g_debug ("GoaAlarm: could not set timer: %m");
      return FALSE;
    }

  self->priv->type = GOA_ALARM_TYPE_TIMER;
  self->priv->stream = g_unix_input_stream_new (fd, TRUE);

  source =
    g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM
                                           (self->priv->stream),
                                           NULL);
  self->priv->scheduled_wakeup_source = source;
  g_source_set_callback (self->priv->scheduled_wakeup_source,
                         (GSourceFunc) on_timer_source_ready, self,
                         (GDestroyNotify) clear_wakeup_source_pointer);
  g_source_attach (self->priv->scheduled_wakeup_source, self->priv->context);
  g_source_unref (source);

  return TRUE;

#endif /*HAVE_TIMERFD */

  return FALSE;
}
Example #9
0
static void
let_me_quit (GMainLoop *loop)
{
  GInputStream *g_stdin = g_unix_input_stream_new (0, FALSE);
  GSource *source = g_pollable_input_stream_create_source (
      G_POLLABLE_INPUT_STREAM (g_stdin), NULL);

  g_source_set_callback (source, (GSourceFunc) stdin_func, loop, NULL);
  g_source_attach (source, NULL);
  g_printf ("Hit Enter to stop logging. (Do not hit Control-C.)\n");
}
Example #10
0
gint
main (gint argc,
      gchar *argv[])
{
  g_autoptr(GDBusConnection) connection = NULL;
  g_autoptr(IpcGitService) service = NULL;
  g_autoptr(GOutputStream) stdout_stream = NULL;
  g_autoptr(GInputStream) stdin_stream = NULL;
  g_autoptr(GIOStream) stream = NULL;
  g_autoptr(GMainLoop) main_loop = NULL;
  g_autoptr(GError) error = NULL;

  g_set_prgname ("gnome-builder-git");
  g_set_application_name ("gnome-builder-git");

  prctl (PR_SET_PDEATHSIG, SIGTERM);

  signal (SIGPIPE, SIG_IGN);

  ggit_init ();

  g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_func, NULL);

  if (!g_unix_set_fd_nonblocking (STDIN_FILENO, TRUE, &error) ||
      !g_unix_set_fd_nonblocking (STDOUT_FILENO, TRUE, &error))
    goto error;

  main_loop = g_main_loop_new (NULL, FALSE);
  stdin_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
  stdout_stream = g_unix_output_stream_new (STDOUT_FILENO, FALSE);
  stream = g_simple_io_stream_new (stdin_stream, stdout_stream);

  if (!(connection = create_connection (stream, main_loop, &error)))
    goto error;

  service = ipc_git_service_impl_new ();

  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service),
                                         connection,
                                         "/org/gnome/Builder/Git",
                                         &error))
    goto error;

  g_dbus_connection_start_message_processing (connection);
  g_main_loop_run (main_loop);

  return EXIT_SUCCESS;

error:
  if (error != NULL)
    g_printerr ("%s\n", error->message);

  return EXIT_FAILURE;
}
Example #11
0
/**
 * gs_console_get_stdin:
 *
 * Returns: (transfer none): The singleton stream connected to standard input
 */
GInputStream *
gs_console_get_stdin (void)
{
#ifdef G_OS_UNIX
  static gsize instance = 0;

  if (g_once_init_enter (&instance))
    g_once_init_leave (&instance, (gsize) g_unix_input_stream_new (0, FALSE));
  
  return (GInputStream*) instance;
#else
  g_error ("not implemented");
#endif
}
Example #12
0
static gboolean
open_source_stream (GInputStream **out_source_stream,
                    GCancellable *cancellable,
                    GError **error)
{
  g_autoptr(GInputStream) source_stream = NULL;
  guint n_keyrings = 0;
  gboolean ret = FALSE;

  if (opt_keyrings != NULL)
    n_keyrings = g_strv_length (opt_keyrings);

  if (opt_stdin)
    {
      source_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
    }
  else
    {
      g_autoptr(GPtrArray) streams = NULL;
      guint ii;

      streams = g_ptr_array_new_with_free_func (g_object_unref);

      for (ii = 0; ii < n_keyrings; ii++)
        {
          g_autoptr(GFile) file = NULL;
          GFileInputStream *input_stream = NULL;

          file = g_file_new_for_path (opt_keyrings[ii]);
          input_stream = g_file_read (file, cancellable, error);

          if (input_stream == NULL)
            goto out;

          /* Takes ownership. */
          g_ptr_array_add (streams, input_stream);
        }

       /* Chain together all the --keyring options as one long stream. */
       source_stream = (GInputStream *) ostree_chain_input_stream_new (streams);
    }

  *out_source_stream = g_steal_pointer (&source_stream);

  ret = TRUE;

out:
  return ret;
}
int main(void)
{
    pid_t parent_pid;
    GInputStream *stdin_unix_stream;

  /* Nuke the environment to get a well-known and sanitized
   * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS
   * environment variable and similar.
   */
    if (clearenv () != 0) {
        FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno));
        return 1;
    }

#if !GLIB_CHECK_VERSION(2,36,0)
    g_type_init();
#endif

    loop = g_main_loop_new(NULL, FALSE);

    authority = polkit_authority_get_sync(NULL, NULL);
    parent_pid = getppid ();
    if (parent_pid == 1) {
            FATAL_ERROR("Parent process was reaped by init(1)\n");
            return 1;
    }
    /* Do what pkexec does */
    subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ());

    stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0);
    stdin_stream = g_data_input_stream_new(stdin_unix_stream);
    g_data_input_stream_set_newline_type(stdin_stream,
                                         G_DATA_STREAM_NEWLINE_TYPE_LF);
    g_clear_object(&stdin_unix_stream);
    g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL,
                                        stdin_read_complete, NULL);

    g_main_loop_run(loop);

    if (polkit_cancellable)
        g_clear_object(&polkit_cancellable);
    g_object_unref(stdin_stream);
    g_object_unref(authority);
    g_object_unref(subject);
    g_main_loop_unref(loop);

    return exit_status;
}
GSignondPipeStream *
gsignond_pipe_stream_new (
        gint in_fd,
        gint out_fd,
        gboolean close_fds)
{
    GSignondPipeStream *stream = GSIGNOND_PIPE_STREAM (g_object_new (
            GSIGNOND_TYPE_PIPE_STREAM, NULL));
    if (stream) {
        stream->priv->input_stream = G_INPUT_STREAM (
                g_unix_input_stream_new (in_fd, close_fds));
        stream->priv->output_stream = G_OUTPUT_STREAM (
                g_unix_output_stream_new (out_fd, close_fds));
    }
    return stream;
}
Example #15
0
/**
 * gegl_gio_open_input_stream:
 * @uri: (allow none) URI to open. @uri is preferred over @path if both are set
 * @path: (allow none) path to open. 
 * @out_file: (out) (transfer full): return location for GFile, if stream is for a file
 *
 * Return value: (transfer full): A new #GInputStream, free with g_object_unref()
 *
 * Note: currently private API
 */
GInputStream *
gegl_gio_open_input_stream(const gchar *uri, const gchar *path, GFile **out_file, GError **err)
{
  GFile *infile = NULL;
  GInputStream *fis = NULL;
  g_return_val_if_fail(uri || path, NULL);
  g_return_val_if_fail(out_file, NULL);

  if (path && g_strcmp0(path, "-") == 0)
    {
      const gboolean close_fd = FALSE;
      infile = NULL;
#ifdef G_OS_WIN32
      fis = g_win32_input_stream_new (GetStdHandle (STD_INPUT_HANDLE), close_fd);
#else
      fis = g_unix_input_stream_new(STDIN_FILENO, close_fd);
#endif
    }
  else if (uri && strlen(uri) > 0)
    {
      if (gegl_gio_uri_is_datauri(uri))
        {
          fis = input_stream_datauri(uri);
        }
      else
        {
          infile = g_file_new_for_uri(uri);
        }
    }
  else if (path && strlen(path) > 0)
    {
      infile = g_file_new_for_path(path);
    }
  else {
    return NULL;
  }

  if (infile)
    {
      g_assert(!fis);
      fis = G_INPUT_STREAM(g_file_read(infile, NULL, err));
      *out_file = infile;
    }

  return fis;
}
Example #16
0
static GBytes *
read_gpg_data (GCancellable *cancellable,
               GError **error)
{
  g_autoptr(GInputStream) source_stream = NULL;
  g_autoptr(GOutputStream) mem_stream = NULL;
  guint n_keyrings = 0;
  g_autoptr(GPtrArray) streams = NULL;

  if (opt_gpg_file != NULL)
    n_keyrings = g_strv_length (opt_gpg_file);

  guint ii;

  streams = g_ptr_array_new_with_free_func (g_object_unref);

  for (ii = 0; ii < n_keyrings; ii++)
    {
      GInputStream *input_stream = NULL;

      if (strcmp (opt_gpg_file[ii], "-") == 0)
        {
          input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
        }
      else
        {
          g_autoptr(GFile) file = g_file_new_for_path (opt_gpg_file[ii]);
          input_stream = G_INPUT_STREAM(g_file_read (file, cancellable, error));

          if (input_stream == NULL)
            return NULL;
        }

      /* Takes ownership. */
      g_ptr_array_add (streams, input_stream);
    }

  /* Chain together all the --keyring options as one long stream. */
  source_stream = (GInputStream *) xdg_app_chain_input_stream_new (streams);

  mem_stream = g_memory_output_stream_new_resizable ();
  if (g_output_stream_splice (mem_stream, source_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0)
    return NULL;

  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem_stream));
}
Example #17
0
static GIOStream *
my_io_stream_new_for_fds (gint fd_in, gint fd_out)
{
  GIOStream *stream;
  GInputStream *input_stream;
  GOutputStream *real_output_stream;
  GOutputStream *output_stream;

  input_stream = g_unix_input_stream_new (fd_in, TRUE);
  real_output_stream = g_unix_output_stream_new (fd_out, TRUE);
  output_stream = g_object_new (MY_TYPE_SLOW_CLOSE_OUTPUT_STREAM,
                                "base-stream", real_output_stream,
                                NULL);
  stream = my_io_stream_new (input_stream, output_stream);
  g_object_unref (input_stream);
  g_object_unref (output_stream);
  g_object_unref (real_output_stream);
  return stream;
}
Example #18
0
GamepadDevice::GamepadDevice(int fd, Nix::Gamepad* gamepad)
    : m_fileDescriptor(fd)
    , m_nixGamepad(gamepad)
    , m_inputStream(0)
    , m_source(0)
{
    char deviceId[Nix::Gamepad::idLengthCap];
    if (ioctl(m_fileDescriptor, JSIOCGNAME(sizeof(deviceId)), deviceId) < 0)
        return;

    uint8_t numberOfAxes;
    uint8_t numberOfButtons;
    if (ioctl(m_fileDescriptor, JSIOCGAXES, &numberOfAxes) < 0 || ioctl(m_fileDescriptor, JSIOCGBUTTONS, &numberOfButtons) < 0)
        return;

    memset(m_nixGamepad->id, 0, Nix::Gamepad::idLengthCap);

    gsize bytesWritten, bytesRead;
    GError* error = 0;
    gchar* deviceIdUTF16 = g_convert(deviceId, -1, "UTF-16", "ASCII", &bytesRead, &bytesWritten, &error);

    if (!error) {
        memcpy(m_nixGamepad->id, deviceIdUTF16, bytesWritten);
        g_free(deviceIdUTF16);
    } else
        g_error_free(error);

    m_nixGamepad->connected = false;
    m_nixGamepad->timestamp = 0;
    m_nixGamepad->axesLength = std::min<unsigned>(numberOfAxes, Nix::Gamepad::axesLengthCap);
    m_nixGamepad->buttonsLength = std::min<unsigned>(numberOfButtons, Nix::Gamepad::buttonsLengthCap);

    unsigned i, total;
    for (i = 0, total = m_nixGamepad->axesLength; i < total; i++)
        m_nixGamepad->axes[i] = 0;
    for (i = 0, total = m_nixGamepad->buttonsLength; i < total; i++)
        m_nixGamepad->buttons[i] = 0;

    m_inputStream = g_unix_input_stream_new(m_fileDescriptor, FALSE);
    m_source = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(m_inputStream), 0);
    g_source_set_callback(m_source, reinterpret_cast<GSourceFunc>(readCallback), this, 0);
    g_source_attach(m_source, 0);
}
int main(int argc, char *argv[])
{
  gint ret, fds[2];
  GInputStream *input;
  GOutputStream *output;

  g_type_init();
  ret = pipe(fds);

  if (ret < 0)
    {
      g_error("pipe() failed, ret = %d", ret);
		  exit(EXIT_FAILURE);
    }

  input = g_unix_input_stream_new(fds[0], TRUE);
  output = g_unix_output_stream_new(fds[1], TRUE);

  receiver = sockmux_receiver_new(input, SOCKMUX_PROTOCOL_MAGIC);
  if (receiver == NULL)
    {
      g_error("sockmux_receiver_new() failed");
		  exit(EXIT_FAILURE);
    }

  sender = sockmux_sender_new(output, SOCKMUX_PROTOCOL_MAGIC);
  if (sender == NULL)
    {
      g_error("sockmux_sender_new() failed");
		  exit(EXIT_FAILURE);
    }

  g_signal_connect(receiver, "protocol-error",
                   G_CALLBACK(receiver_protocol_error), NULL);

  loop = g_main_loop_new(NULL, FALSE);
  checksum = g_checksum_new(G_CHECKSUM_SHA1);
  trigger();
  g_main_loop_run(loop);

  return EXIT_SUCCESS;
}
gboolean gvir_sandbox_console_attach_stdio(GVirSandboxConsole *console_,
                                           GError **error)
{
    GInputStream *localStdin = g_unix_input_stream_new(STDIN_FILENO, FALSE);
    GOutputStream *localStdout = g_unix_output_stream_new(STDOUT_FILENO, FALSE);
    GOutputStream *localStderr = g_unix_output_stream_new(STDERR_FILENO, FALSE);
    gboolean ret;

    ret = gvir_sandbox_console_attach(console_,
                                      G_UNIX_INPUT_STREAM(localStdin),
                                      G_UNIX_OUTPUT_STREAM(localStdout),
                                      G_UNIX_OUTPUT_STREAM(localStderr),
                                      error);

    g_object_unref(localStdin);
    g_object_unref(localStdout);
    g_object_unref(localStderr);

    return ret;
}
static GBytes *
read_gpg_data (GCancellable *cancellable,
               GError      **error)
{
  g_autoptr(GInputStream) source_stream = NULL;
  guint n_keyrings = 0;
  g_autoptr(GPtrArray) streams = NULL;

  if (opt_gpg_file != NULL)
    n_keyrings = g_strv_length (opt_gpg_file);

  guint ii;

  streams = g_ptr_array_new_with_free_func (g_object_unref);

  for (ii = 0; ii < n_keyrings; ii++)
    {
      GInputStream *input_stream = NULL;

      if (strcmp (opt_gpg_file[ii], "-") == 0)
        {
          input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
        }
      else
        {
          g_autoptr(GFile) file = g_file_new_for_commandline_arg (opt_gpg_file[ii]);
          input_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error));

          if (input_stream == NULL)
            return NULL;
        }

      /* Takes ownership. */
      g_ptr_array_add (streams, input_stream);
    }

  /* Chain together all the --keyring options as one long stream. */
  source_stream = (GInputStream *) flatpak_chain_input_stream_new (streams);

  return flatpak_read_stream (source_stream, FALSE, error);
}
static gboolean gvir_sandbox_console_open_remote(GVirSandboxConsoleRaw *console,
                                                 GError **error)
{
    GVirSandboxConsoleRawPrivate *priv = console->priv;
    GVirConnection *conn = NULL;
    GVirDomain *dom = NULL;
    gchar *devname = NULL;
    gboolean ret = FALSE;
    GVirConfigDomain *conf = NULL;
    GList *devices = NULL, *tmp;

    g_object_get(console,
                 "connection", &conn,
                 "domain", &dom,
                 "devname", &devname,
                 NULL);

    if (!gvir_sandbox_console_get_direct(GVIR_SANDBOX_CONSOLE(console))) {
        priv->console = gvir_connection_get_stream(conn, 0);

        if (!gvir_domain_open_console(dom, priv->console,
                                      devname, 0, error)) {
            g_object_unref(priv->console);
            priv->console = NULL;
            goto cleanup;
        }
    } else {
        const gchar *pty = NULL;

        if (!(conf = gvir_domain_get_config(dom, 0, error)))
            goto cleanup;

        if (!(devices = gvir_config_domain_get_devices(conf))) {
            g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s",
                        _("No devices found for domain"));
            goto cleanup;
        }

        tmp = devices;
        while (tmp && !pty) {
            GVirConfigDomainDevice *dev = tmp->data;
            const gchar *alias = gvir_config_domain_device_get_alias(dev);

            if (alias && g_str_equal(alias, devname) &&
                GVIR_CONFIG_IS_DOMAIN_CHARDEV(dev)) {
                GVirConfigDomainChardev *cdev = GVIR_CONFIG_DOMAIN_CHARDEV(dev);
                GVirConfigDomainChardevSource *csrc =
                    gvir_config_domain_chardev_get_source(cdev);

                if (GVIR_CONFIG_IS_DOMAIN_CHARDEV_SOURCE_PTY(csrc)) {
                    GVirConfigDomainChardevSourcePty *csrcpty =
                        GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE_PTY(csrc);

                    pty = gvir_config_domain_chardev_source_pty_get_path(csrcpty);
                    break;
                }

            }

            tmp = tmp->next;
        }

        if (!pty) {
            g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0,
                        _("No device %s found for domain"), devname);
            goto cleanup;
        }

        if ((priv->consolePty = open(pty, O_NOCTTY|O_RDWR)) < 0) {
            g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0,
                        _("Unable to open console %s"), pty);
            goto cleanup;
        }

        priv->consoleInput = G_UNIX_INPUT_STREAM(g_unix_input_stream_new(priv->consolePty, FALSE));
        priv->consoleOutput = G_UNIX_OUTPUT_STREAM(g_unix_output_stream_new(priv->consolePty, FALSE));
    }

    ret = TRUE;

 cleanup:
    if (conf)
        g_object_unref(conf);
    if (conn)
        g_object_unref(conn);
    if (dom)
        g_object_unref(dom);
    g_free(devname);

    return ret;
}
Example #23
0
int main (int argc, char **argv)
{
  GMainLoop *loop = NULL;
  GstElement *pipeline = NULL;
  GstBus *bus = NULL;
  GstElement *conf = NULL;
  FsParticipant *part = NULL;
  GError *error = NULL;
  GInputStream *istream = NULL;
  gchar *send_socket, *recv_socket;
  TestSession *ses;

  gst_init (&argc, &argv);

  if (argc != 3)
  {
    g_print ("Usage: %s <send socket> <recv_socket>\n", argv[0]);
    return 1;
  }

  send_socket = argv[1];
  recv_socket = argv[2];

  if (unlink (send_socket) < 0 && errno != ENOENT)
  {
    g_print ("Could not delete send or recv sockets");
    return 2;
  }

  g_print ("Press ENTER when the other side is ready\n");

  loop = g_main_loop_new (NULL, FALSE);

  pipeline = gst_pipeline_new (NULL);

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, async_bus_cb, pipeline);
  gst_object_unref (bus);

  conf = gst_element_factory_make ("fsrtpconference", NULL);
  g_assert (conf);

  part = fs_conference_new_participant (FS_CONFERENCE (conf), &error);
  print_error (error);
  g_assert (part);

  g_assert (gst_bin_add (GST_BIN (pipeline), conf));

  istream = g_unix_input_stream_new (0, FALSE);

  ses = add_audio_session (pipeline, FS_CONFERENCE (conf), 1, part, send_socket,
      recv_socket);

  g_input_stream_skip_async (istream, 1, G_PRIORITY_DEFAULT, NULL, skipped_cb,
      ses);

  g_assert (gst_element_set_state (pipeline, GST_STATE_PLAYING) !=
      GST_STATE_CHANGE_FAILURE);
  g_main_loop_run (loop);

  g_assert (gst_element_set_state (pipeline, GST_STATE_NULL) !=
      GST_STATE_CHANGE_FAILURE);

  g_object_unref (part);
  g_object_unref (istream);

  free_session (ses);

  gst_object_unref (pipeline);
  g_main_loop_unref (loop);

  return 0;
}
static void
tp_file_start_transfer (EmpathyTpFile *self)
{
  gint fd, domain, res = 0;
  GError *error = NULL;
  struct sockaddr *my_addr = NULL;
  size_t my_size = 0;

  if (self->priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_UNIX)
    {
      domain = AF_UNIX;
    }
  else if (self->priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_IPV4)
    {
      domain = AF_INET;
    }
  else
    {
      error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
          EMPATHY_FT_ERROR_NOT_SUPPORTED, _("Socket type not supported"));

      DEBUG ("Socket not supported, closing channel");

      ft_operation_close_with_error (self, error);
      g_clear_error (&error);

      return;
    }

  fd = socket (domain, SOCK_STREAM, 0);

  if (fd < 0)
    {
      int code = errno;

      error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
          EMPATHY_FT_ERROR_SOCKET, g_strerror (code));

      DEBUG ("Failed to create socket, closing channel");

      ft_operation_close_with_error (self, error);
      g_clear_error (&error);

      return;
    }

  if (self->priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_UNIX)
    {
      struct sockaddr_un addr;

      memset (&addr, 0, sizeof (addr));
      addr.sun_family = domain;
      strncpy (addr.sun_path, self->priv->socket_address->data,
          self->priv->socket_address->len);

      my_addr = (struct sockaddr *) &addr;
      my_size = sizeof (addr);
    }
  else if (self->priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_IPV4)
    {
      struct sockaddr_in addr;

      memset (&addr, 0, sizeof (addr));
      addr.sin_family = domain;
      inet_pton (AF_INET, self->priv->socket_address->data, &addr.sin_addr);
      addr.sin_port = htons (self->priv->port);

      my_addr = (struct sockaddr *) &addr;
      my_size = sizeof (addr);
    }

  res = connect (fd, my_addr, my_size);

  if (res < 0)
    {
      int code = errno;

      error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
          EMPATHY_FT_ERROR_SOCKET, g_strerror (code));

      DEBUG ("Failed to connect socket, closing channel");

      ft_operation_close_with_error (self, error);
      close (fd);
      g_clear_error (&error);

      return;
    }

  DEBUG ("Start the transfer");

  self->priv->start_time = empathy_time_get_current ();

  /* notify we're starting a transfer */
  if (self->priv->progress_callback != NULL)
    self->priv->progress_callback (self, 0, self->priv->progress_user_data);

  if (self->priv->incoming)
    {
      GInputStream *socket_stream;

      socket_stream = g_unix_input_stream_new (fd, TRUE);

      g_output_stream_splice_async (self->priv->out_stream, socket_stream,
          G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
          G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
          G_PRIORITY_DEFAULT, self->priv->cancellable,
          splice_stream_ready_cb, self);

      g_object_unref (socket_stream);
    }
  else
    {
      GOutputStream *socket_stream;

      socket_stream = g_unix_output_stream_new (fd, TRUE);

      g_output_stream_splice_async (socket_stream, self->priv->in_stream,
          G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
          G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
          G_PRIORITY_DEFAULT, self->priv->cancellable,
          splice_stream_ready_cb, self);

      g_object_unref (socket_stream);
    }
}
static gboolean
show_one_part (OstreeRepo                    *self,
               gboolean                       swap_endian,
               const char                    *from,
               const char                    *to,
               GVariant                      *meta_entries,
               guint                          i,
               guint64                       *total_size_ref,
               guint64                       *total_usize_ref,
               GCancellable                  *cancellable,
               GError                      **error)
{
  gboolean ret = FALSE;
  guint32 version;
  guint64 size, usize;
  g_autoptr(GVariant) objects = NULL;
  g_autoptr(GInputStream) part_in = NULL;
  g_autoptr(GVariant) part = NULL;
  g_autofree char *part_path = _ostree_get_relative_static_delta_part_path (from, to, i);
  gint part_fd = -1;

  g_variant_get_child (meta_entries, i, "(u@aytt@ay)", &version, NULL, &size, &usize, &objects);
  size = maybe_swap_endian_u64 (swap_endian, size);
  usize = maybe_swap_endian_u64 (swap_endian, usize);
  *total_size_ref += size;
  *total_usize_ref += usize;
  g_print ("PartMeta%u: nobjects=%u size=%" G_GUINT64_FORMAT " usize=%" G_GUINT64_FORMAT "\n",
           i, (guint)(g_variant_get_size (objects) / OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN), size, usize);

  part_fd = openat (self->repo_dir_fd, part_path, O_RDONLY | O_CLOEXEC);
  if (part_fd < 0)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }

  part_in = g_unix_input_stream_new (part_fd, FALSE);
  
  if (!_ostree_static_delta_part_open (part_in, NULL, 
                                       OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM,
                                       NULL,
                                       &part,
                                       cancellable, error))
    goto out;

  { g_autoptr(GVariant) modes = NULL;
    g_autoptr(GVariant) xattrs = NULL;
    g_autoptr(GVariant) blob = NULL;
    g_autoptr(GVariant) ops = NULL;
    OstreeDeltaExecuteStats stats = { { 0, }, };

    g_variant_get (part, "(@a(uuu)@aa(ayay)@ay@ay)",
                   &modes, &xattrs, &blob, &ops);

    g_print ("PartPayload%u: nmodes=%" G_GUINT64_FORMAT
             " nxattrs=%" G_GUINT64_FORMAT
             " blobsize=%" G_GUINT64_FORMAT
             " opsize=%" G_GUINT64_FORMAT
             "\n",
             i,
             (guint64)g_variant_n_children (modes),
             (guint64)g_variant_n_children (xattrs),
             (guint64)g_variant_n_children (blob),
             (guint64)g_variant_n_children (ops));

    if (!_ostree_static_delta_part_execute (self, objects,
                                            part, TRUE,
                                            &stats, cancellable, error))
      goto out;

    { const guint *n_ops = stats.n_ops_executed;
      g_print ("PartPayloadOps%u: openspliceclose=%u open=%u write=%u setread=%u "
               "unsetread=%u close=%u bspatch=%u\n",
               i, n_ops[0], n_ops[1], n_ops[2], n_ops[3], n_ops[4], n_ops[5], n_ops[6]);
    }
  }
    
  ret = TRUE;
 out:
  return ret;
}
/**
 * ostree_repo_static_delta_execute_offline:
 * @self: Repo
 * @dir_or_file: Path to a directory containing static delta data, or directly to the superblock
 * @skip_validation: If %TRUE, assume data integrity
 * @cancellable: Cancellable
 * @error: Error
 *
 * Given a directory representing an already-downloaded static delta
 * on disk, apply it, generating a new commit.  The directory must be
 * named with the form "FROM-TO", where both are checksums, and it
 * must contain a file named "superblock", along with at least one part.
 */
gboolean
ostree_repo_static_delta_execute_offline (OstreeRepo                    *self,
                                          GFile                         *dir_or_file,
                                          gboolean                       skip_validation,
                                          GCancellable                  *cancellable,
                                          GError                      **error)
{
  gboolean ret = FALSE;
  guint i, n;
  const char *dir_or_file_path = NULL;
  glnx_fd_close int meta_fd = -1;
  glnx_fd_close int dfd = -1;
  g_autoptr(GVariant) meta = NULL;
  g_autoptr(GVariant) headers = NULL;
  g_autoptr(GVariant) metadata = NULL;
  g_autoptr(GVariant) fallback = NULL;
  g_autofree char *to_checksum = NULL;
  g_autofree char *from_checksum = NULL;
  g_autofree char *basename = NULL;

  dir_or_file_path = gs_file_get_path_cached (dir_or_file);

  /* First, try opening it as a directory */
  dfd = glnx_opendirat_with_errno (AT_FDCWD, dir_or_file_path, TRUE);
  if (dfd < 0)
    {
      if (errno != ENOTDIR)
        {
          glnx_set_error_from_errno (error);
          goto out;
        }
      else
        {
          g_autofree char *dir = dirname (g_strdup (dir_or_file_path));
          basename = g_path_get_basename (dir_or_file_path);

          if (!glnx_opendirat (AT_FDCWD, dir, TRUE, &dfd, error))
            goto out;
        }
    }
  else
    basename = g_strdup ("superblock");

  meta_fd = openat (dfd, basename, O_RDONLY | O_CLOEXEC);
  if (meta_fd < 0)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }
  
  if (!ot_util_variant_map_fd (meta_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT),
                               FALSE, &meta, error))
    goto out;

  /* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */

  metadata = g_variant_get_child_value (meta, 0);

  /* Write the to-commit object */
  {
    g_autoptr(GVariant) to_csum_v = NULL;
    g_autoptr(GVariant) from_csum_v = NULL;
    g_autoptr(GVariant) to_commit = NULL;
    gboolean have_to_commit;
    gboolean have_from_commit;

    to_csum_v = g_variant_get_child_value (meta, 3);
    if (!ostree_validate_structureof_csum_v (to_csum_v, error))
      goto out;
    to_checksum = ostree_checksum_from_bytes_v (to_csum_v);

    from_csum_v = g_variant_get_child_value (meta, 2);
    if (g_variant_n_children (from_csum_v) > 0)
      {
        if (!ostree_validate_structureof_csum_v (from_csum_v, error))
          goto out;
        from_checksum = ostree_checksum_from_bytes_v (from_csum_v);

        if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, from_checksum,
                                     &have_from_commit, cancellable, error))
          goto out;

        if (!have_from_commit)
          {
            g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                         "Commit %s, which is the delta source, is not in repository", from_checksum);
            goto out;
          }
      }

    if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum,
                                 &have_to_commit, cancellable, error))
      goto out;
    
    if (!have_to_commit)
      {
        g_autofree char *detached_path = _ostree_get_relative_static_delta_path (from_checksum, to_checksum, "commitmeta");
        g_autoptr(GVariant) detached_data = NULL;

        detached_data = g_variant_lookup_value (metadata, detached_path, G_VARIANT_TYPE("a{sv}"));
        if (detached_data && !ostree_repo_write_commit_detached_metadata (self,
                                                                          to_checksum,
                                                                          detached_data,
                                                                          cancellable,
                                                                          error))
          goto out;

        to_commit = g_variant_get_child_value (meta, 4);
        if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT,
                                         to_checksum, to_commit, NULL,
                                         cancellable, error))
          goto out;
      }
  }

  fallback = g_variant_get_child_value (meta, 7);
  if (g_variant_n_children (fallback) > 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Cannot execute delta offline: contains nonempty http fallback entries");
      goto out;
    }

  headers = g_variant_get_child_value (meta, 6);
  n = g_variant_n_children (headers);
  for (i = 0; i < n; i++)
    {
      guint32 version;
      guint64 size;
      guint64 usize;
      const guchar *csum;
      char checksum[OSTREE_SHA256_STRING_LEN+1];
      gboolean have_all;
      g_autoptr(GInputStream) part_in = NULL;
      g_autoptr(GVariant) inline_part_data = NULL;
      g_autoptr(GVariant) header = NULL;
      g_autoptr(GVariant) csum_v = NULL;
      g_autoptr(GVariant) objects = NULL;
      g_autoptr(GVariant) part = NULL;
      g_autofree char *deltapart_path = NULL;
      OstreeStaticDeltaOpenFlags delta_open_flags = 
        skip_validation ? OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM : 0;

      header = g_variant_get_child_value (headers, i);
      g_variant_get (header, "(u@aytt@ay)", &version, &csum_v, &size, &usize, &objects);

      if (version > OSTREE_DELTAPART_VERSION)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Delta part has too new version %u", version);
          goto out;
        }

      if (!_ostree_repo_static_delta_part_have_all_objects (self, objects, &have_all,
                                                            cancellable, error))
        goto out;

      /* If we already have these objects, don't bother executing the
       * static delta.
       */
      if (have_all)
        continue;

      csum = ostree_checksum_bytes_peek_validate (csum_v, error);
      if (!csum)
        goto out;
      ostree_checksum_inplace_from_bytes (csum, checksum);

      deltapart_path =
        _ostree_get_relative_static_delta_part_path (from_checksum, to_checksum, i);

      inline_part_data = g_variant_lookup_value (metadata, deltapart_path, G_VARIANT_TYPE("(yay)"));
      if (inline_part_data)
        {
          g_autoptr(GBytes) inline_part_bytes = g_variant_get_data_as_bytes (inline_part_data);
          part_in = g_memory_input_stream_new_from_bytes (inline_part_bytes);

          /* For inline parts, we don't checksum, because it's
           * included with the metadata, so we're not trying to
           * protect against MITM or such.  Non-security related
           * checksums should be done at the underlying storage layer.
           */
          delta_open_flags |= OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM;

          if (!_ostree_static_delta_part_open (part_in, inline_part_bytes, 
                                               delta_open_flags,
                                               NULL,
                                               &part,
                                               cancellable, error))
            goto out;
        }
      else
        {
          g_autofree char *relpath = g_strdup_printf ("%u", i); /* TODO avoid malloc here */
          glnx_fd_close int part_fd = openat (dfd, relpath, O_RDONLY | O_CLOEXEC);
          if (part_fd < 0)
            {
              glnx_set_error_from_errno (error);
              g_prefix_error (error, "Opening deltapart '%s': ", deltapart_path);
              goto out;
            }

          part_in = g_unix_input_stream_new (part_fd, FALSE);

          if (!_ostree_static_delta_part_open (part_in, NULL, 
                                               delta_open_flags,
                                               checksum,
                                               &part,
                                               cancellable, error))
            goto out;
        }

      if (!_ostree_static_delta_part_execute (self, objects, part, skip_validation,
                                              NULL, cancellable, error))
        {
          g_prefix_error (error, "Executing delta part %i: ", i);
          goto out;
        }
    }

  ret = TRUE;
 out:
  return ret;
}
Example #27
0
gboolean
builder_host_spawnv (GFile                *dir,
                     char                **output,
                     GError              **error,
                     const gchar * const  *argv)
{
  guint32 client_pid;
  GVariantBuilder *fd_builder = g_variant_builder_new (G_VARIANT_TYPE("a{uh}"));
  GVariantBuilder *env_builder = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
  g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new ();
  gint stdout_handle, stdin_handle, stderr_handle;
  g_autoptr(GDBusConnection) connection = NULL;
  g_autoptr(GVariant) ret = NULL;
  g_autoptr(GMainLoop) loop = NULL;
  g_auto(GStrv) env_vars = NULL;
  guint subscription;
  HostCommandCallData data = { NULL };
  guint sigterm_id = 0, sigint_id = 0;
  g_autofree gchar *commandline = NULL;
  g_autoptr(GOutputStream) out = NULL;
  int pipefd[2];
  int i;

  commandline = flatpak_quote_argv ((const char **) argv);
  g_debug ("Running '%s' on host", commandline);

  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
  if (connection == NULL)
    return FALSE;

  loop = g_main_loop_new (NULL, FALSE);
  data.connection = connection;
  data.loop = loop;
  data.refs = 1;

  subscription = g_dbus_connection_signal_subscribe (connection,
                                                     NULL,
                                                     "org.freedesktop.Flatpak.Development",
                                                     "HostCommandExited",
                                                     "/org/freedesktop/Flatpak/Development",
                                                     NULL,
                                                     G_DBUS_SIGNAL_FLAGS_NONE,
                                                     host_command_exited_cb,
                                                     &data, NULL);

  stdin_handle = g_unix_fd_list_append (fd_list, 0, error);
  if (stdin_handle == -1)
    return FALSE;

  if (output)
    {
      g_autoptr(GInputStream) in = NULL;

      if (pipe2 (pipefd, O_CLOEXEC) != 0)
        {
          glnx_set_error_from_errno (error);
          return FALSE;
        }

      data.refs++;
      in = g_unix_input_stream_new (pipefd[0], TRUE);
      out = g_memory_output_stream_new_resizable ();
      g_output_stream_splice_async (out,
                                    in,
                                    G_OUTPUT_STREAM_SPLICE_NONE,
                                    0,
                                    NULL,
                                    output_spliced_cb,
                                    &data);
      stdout_handle = g_unix_fd_list_append (fd_list, pipefd[1], error);
      close (pipefd[1]);
      if (stdout_handle == -1)
        return FALSE;
    }
  else
    {
      stdout_handle = g_unix_fd_list_append (fd_list, 1, error);
      if (stdout_handle == -1)
        return FALSE;
    }

  stderr_handle = g_unix_fd_list_append (fd_list, 2, error);
  if (stderr_handle == -1)
    return FALSE;

  g_variant_builder_add (fd_builder, "{uh}", 0, stdin_handle);
  g_variant_builder_add (fd_builder, "{uh}", 1, stdout_handle);
  g_variant_builder_add (fd_builder, "{uh}", 2, stderr_handle);

  env_vars = g_listenv ();
  for (i = 0; env_vars[i] != NULL; i++)
    {
      const char *env_var = env_vars[i];
      g_variant_builder_add (env_builder, "{ss}", env_var, g_getenv (env_var));
    }

  sigterm_id = g_unix_signal_add (SIGTERM, sigterm_handler, &data);
  sigint_id = g_unix_signal_add (SIGINT, sigint_handler, &data);

  ret = g_dbus_connection_call_with_unix_fd_list_sync (connection,
                                                       "org.freedesktop.Flatpak",
                                                       "/org/freedesktop/Flatpak/Development",
                                                       "org.freedesktop.Flatpak.Development",
                                                       "HostCommand",
                                                       g_variant_new ("(^ay^aay@a{uh}@a{ss}u)",
                                                                      dir ? flatpak_file_get_path_cached (dir) : "",
                                                                      argv,
                                                                      g_variant_builder_end (fd_builder),
                                                                      g_variant_builder_end (env_builder),
                                                                      FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV),
                                                       G_VARIANT_TYPE ("(u)"),
                                                       G_DBUS_CALL_FLAGS_NONE, -1,
                                                       fd_list, NULL,
                                                       NULL, error);

  if (ret == NULL)
    return FALSE;


  g_variant_get (ret, "(u)", &client_pid);
  data.client_pid = client_pid;

  g_main_loop_run (loop);

  g_source_remove (sigterm_id);
  g_source_remove (sigint_id);
  g_dbus_connection_signal_unsubscribe (connection, subscription);

  if (!g_spawn_check_exit_status (data.exit_status, 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;
}
Example #28
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;
}
Example #29
0
void
_gdk_wayland_display_convert_selection (GdkDisplay *display,
					GdkWindow  *requestor,
					GdkAtom     selection,
					GdkAtom     target,
					guint32     time)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
  SelectionBuffer *buffer_data;

  if (!wayland_selection->offer)
    {
      GdkEvent *event;

      event = gdk_event_new (GDK_SELECTION_NOTIFY);
      event->selection.window = g_object_ref (requestor);
      event->selection.send_event = FALSE;
      event->selection.selection = selection;
      event->selection.target = target;
      event->selection.property = GDK_NONE;
      event->selection.time = GDK_CURRENT_TIME;
      event->selection.requestor = g_object_ref (requestor);

      gdk_event_put (event);
      gdk_event_free (event);
      return;
    }

  wl_data_offer_accept (wayland_selection->offer,
                        _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)),
                        gdk_atom_name (target));

  buffer_data = g_hash_table_lookup (wayland_selection->selection_buffers,
                                     target);

  if (buffer_data)
    selection_buffer_add_requestor (buffer_data, requestor);
  else
    {
      GInputStream *stream = NULL;
      int pipe_fd[2], natoms = 0;
      GdkAtom *atoms = NULL;

      if (target == gdk_atom_intern_static_string ("TARGETS"))
        {
          gint i = 0;
          GList *l;

          natoms = g_list_length (wayland_selection->targets);
          atoms = g_new0 (GdkAtom, natoms);

          for (l = wayland_selection->targets; l; l = l->next)
            atoms[i++] = l->data;
        }
      else
        {
          g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL);
          wl_data_offer_receive (wayland_selection->offer,
                                 gdk_atom_name (target),
                                 pipe_fd[1]);
          stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
          close (pipe_fd[1]);
        }

      buffer_data = selection_buffer_new (stream, selection, target);
      selection_buffer_add_requestor (buffer_data, requestor);

      if (stream)
        g_object_unref (stream);

      if (atoms)
        {
          /* Store directly the local atoms */
          selection_buffer_append_data (buffer_data, atoms, natoms * sizeof (GdkAtom));
          g_free (atoms);
        }

      g_hash_table_insert (wayland_selection->selection_buffers,
                           GDK_ATOM_TO_POINTER (target),
                           buffer_data);
    }

  if (!buffer_data->stream)
    selection_buffer_notify (buffer_data);
}
Example #30
0
static void
_j4status_io_add_stream(J4statusIOContext *self, const gchar *stream_desc)
{
    J4statusIOStream *stream;
    if ( g_strcmp0(stream_desc, "std") == 0 )
    {
        GOutputStream *out;
        GInputStream *in;
#ifdef G_OS_UNIX
        out = g_unix_output_stream_new(1, FALSE);
        in = g_unix_input_stream_new(0, FALSE);
#else /* ! G_OS_UNIX */
        return;
#endif /* ! G_OS_UNIX */

        stream = _j4status_io_stream_new(self);

        stream->out = g_data_output_stream_new(out);
        stream->in = g_data_input_stream_new(in);
        g_object_unref(out);
        g_object_unref(in);

        _j4status_io_stream_put_header(stream, self->header);
        g_data_input_stream_read_line_async(stream->in, G_PRIORITY_DEFAULT, NULL, _j4status_io_stream_read_callback, stream);

        goto end;
    }

    GSocketAddress *address = NULL;

    if ( g_str_has_prefix(stream_desc, "tcp:") )
    {
        const gchar *uri = stream_desc + strlen("tcp:");
        gchar *port_str = g_utf8_strrchr(uri, -1, ':');
        if ( port_str == NULL )
            /* No port, illegal stream description */
            return;

        *port_str = '\0';
        ++port_str;

        guint64 port;
        port = g_ascii_strtoull(port_str, NULL, 10);
        if ( port > 65535 )
            return;

        GInetAddress *inet_address;
        inet_address = g_inet_address_new_from_string(uri);

        address = g_inet_socket_address_new(inet_address, port);
    }

#ifdef G_OS_UNIX
    if ( g_str_has_prefix(stream_desc, "unix:") )
    {
        const gchar *path = stream_desc + strlen("unix:");

        address = g_unix_socket_address_new(path);
    }
#endif /* G_OS_UNIX */

    if ( address == NULL )
        return;

    stream = _j4status_io_stream_new(self);
    stream->address = address;

    _j4status_io_stream_connect(stream);

end:
    self->streams = g_list_prepend(self->streams, stream);
}