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; }
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 }
/** * 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; }
/** * 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; }
/** * 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); }
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; }
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"); }
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; }
/** * 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 }
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; }
/** * 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; }
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)); }
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; }
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; }
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; }
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; }
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; }
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); }
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); }