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; }
/** * 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; }
static gboolean convert_var_to_tmpfiles_d (int src_rootfs_dfd, int dest_rootfs_dfd, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GString) prefix = g_string_new ("/var"); glnx_fd_close int tmpfiles_fd = -1; /* Append to an existing one for package layering */ if ((tmpfiles_fd = TEMP_FAILURE_RETRY (openat (dest_rootfs_dfd, "usr/lib/tmpfiles.d/rpm-ostree-autovar.conf", O_WRONLY | O_CREAT | O_APPEND | O_NOCTTY, 0644))) == -1) { glnx_set_error_from_errno (error); goto out; } { glnx_unref_object GOutputStream *tmpfiles_out = g_unix_output_stream_new (tmpfiles_fd, FALSE); if (!tmpfiles_out) goto out; if (!convert_var_to_tmpfiles_d_recurse (tmpfiles_out, src_rootfs_dfd, prefix, cancellable, error)) goto out; if (!g_output_stream_close (tmpfiles_out, cancellable, error)) goto out; } ret = TRUE; out: return ret; }
/** * gs_file_create: * @file: Path to non-existent file * @mode: Unix access permissions * @out_stream: (out) (transfer full) (allow-none): Newly created output, or %NULL * @cancellable: a #GCancellable * @error: a #GError * * Like g_file_create(), except this function allows specifying the * access mode. This allows atomically creating private files. */ gboolean gs_file_create (GFile *file, int mode, GOutputStream **out_stream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int fd; GOutputStream *ret_stream = NULL; fd = open_nointr (gs_file_get_path_cached (file), O_WRONLY | O_CREAT | O_EXCL, mode); if (fd < 0) { gs_set_prefix_error_from_errno (error, errno, "open"); goto out; } if (fchmod (fd, mode) < 0) { close (fd); gs_set_prefix_error_from_errno (error, errno, "fchmod"); goto out; } ret_stream = g_unix_output_stream_new (fd, TRUE); ret = TRUE; gs_transfer_out_value (out_stream, &ret_stream); out: g_clear_object (&ret_stream); return ret; }
static void uri_resolved (YelpUri *uri, gchar *orig) { GOutputStream *stream = g_unix_output_stream_new (1, FALSE); print_uri (orig, uri, stream); g_object_unref (uri); g_main_loop_quit (loop); }
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; }
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; }
static gboolean handle_userdata_script (MinCloudAgentApp *self, GInputStream *instream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gs_free char *tmppath = g_strdup ("/var/tmp/userdata-script.XXXXXX"); gs_unref_object GOutputStream *outstream = NULL; int fd; fd = g_mkstemp_full (tmppath, O_WRONLY, 0700); if (fd == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create temporary userdata script: %s", g_strerror (errsv)); goto out; } outstream = g_unix_output_stream_new (fd, TRUE); if (0 > g_output_stream_splice ((GOutputStream*)outstream, instream, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET | G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, self->cancellable, error)) goto out; gs_log_structured_print_id_v (MCA_USERDATA_EXECUTING_ID, "Executing user data script"); if (!gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_NULL, cancellable, error, tmppath, NULL)) { gs_log_structured_print_id_v (MCA_USERDATA_FAILED_ID, "User data script failed"); goto out; } gs_log_structured_print_id_v (MCA_USERDATA_SUCCESS_ID, "User data script suceeded"); if (!g_file_replace_contents (self->userdata_done_stamp, "done\n", 5, NULL, FALSE, 0, NULL, cancellable, error)) goto out; ret = TRUE; out: (void) unlink (tmppath); return ret; }
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 AsyncWriteData * async_write_data_new (GdkWaylandSelection *selection) { AsyncWriteData *write_data; write_data = g_slice_new0 (AsyncWriteData); write_data->selection = selection; write_data->stream = g_unix_output_stream_new (selection->stored_selection.fd, TRUE); return write_data; }
gboolean gimp_config_dump (GObject *gimp, GimpConfigDumpFormat format) { GOutputStream *output; GimpConfigWriter *writer; GimpConfig *rc; g_return_val_if_fail (G_IS_OBJECT (gimp), FALSE); rc = g_object_new (GIMP_TYPE_RC, "gimp", gimp, NULL); #ifdef G_OS_WIN32 output = g_win32_output_stream_new ((gpointer) 1, FALSE); #else output = g_unix_output_stream_new (1, FALSE); #endif writer = gimp_config_writer_new_stream (output, NULL, NULL); switch (format) { case GIMP_CONFIG_DUMP_NONE: break; case GIMP_CONFIG_DUMP_GIMPRC: gimp_config_writer_comment (writer, "Dump of the GIMP default configuration"); gimp_config_writer_linefeed (writer); gimp_config_serialize_properties (rc, writer); gimp_config_writer_linefeed (writer); break; case GIMP_CONFIG_DUMP_GIMPRC_SYSTEM: dump_gimprc_system (rc, writer, output); break; case GIMP_CONFIG_DUMP_GIMPRC_MANPAGE: dump_gimprc_manpage (rc, writer, output); break; } gimp_config_writer_finish (writer, NULL, NULL); g_object_unref (output); g_object_unref (rc); return TRUE; }
/** * gs_console_get_stderr: * * Returns: (transfer none): The singleton stream connected to standard error */ GOutputStream * gs_console_get_stderr (void) { #ifdef G_OS_UNIX static gsize instance = 0; if (g_once_init_enter (&instance)) g_once_init_leave (&instance, (gsize) g_unix_output_stream_new (2, FALSE)); return (GOutputStream*) instance; #else g_error ("not implemented"); #endif }
gboolean gvir_sandbox_console_attach_stderr(GVirSandboxConsole *console_, GError **error) { GOutputStream *localStderr = g_unix_output_stream_new(STDERR_FILENO, FALSE); gboolean ret; ret = gvir_sandbox_console_attach(console_, NULL, NULL, G_UNIX_OUTPUT_STREAM(localStderr), error); g_object_unref(localStderr); return ret; }
/** * gs_file_open_in_tmpdir_at: * @tmpdir_fd: Directory to place temporary file * @mode: Default mode (will be affected by umask) * @out_name: (out) (transfer full): Newly created file name * @out_stream: (out) (transfer full) (allow-none): Newly created output stream * @cancellable: * @error: * * Like g_file_open_tmp(), except the file will be created in the * provided @tmpdir, and allows specification of the Unix @mode, which * means private files may be created. Return values will be stored * in @out_name, and optionally @out_stream. */ gboolean gs_file_open_in_tmpdir_at (int tmpdir_fd, int mode, char **out_name, GOutputStream **out_stream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const int max_attempts = 128; int i; char *tmp_name = NULL; int fd; /* 128 attempts seems reasonable... */ for (i = 0; i < max_attempts; i++) { g_free (tmp_name); tmp_name = gs_fileutil_gen_tmp_name (NULL, NULL); do fd = openat (tmpdir_fd, tmp_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode); while (fd == -1 && errno == EINTR); if (fd < 0 && errno != EEXIST) { gs_set_prefix_error_from_errno (error, errno, "openat"); goto out; } else if (fd != -1) break; } if (i == max_attempts) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Exhausted attempts to open temporary file"); goto out; } ret = TRUE; gs_transfer_out_value (out_name, &tmp_name); if (out_stream) *out_stream = g_unix_output_stream_new (fd, TRUE); else (void) close (fd); out: g_free (tmp_name); return ret; }
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; }
gboolean ostree_builtin_cat (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; int i; const char *rev; gs_unref_object GOutputStream *stdout_stream = NULL; gs_unref_object GFile *root = NULL; gs_unref_object GFile *f = NULL; context = g_option_context_new ("COMMIT PATH... - Concatenate contents of files"); if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc <= 2) { ot_util_usage_error (context, "A COMMIT and at least one PATH argument are required", error); goto out; } rev = argv[1]; if (!ostree_repo_read_commit (repo, rev, &root, NULL, NULL, error)) goto out; stdout_stream = g_unix_output_stream_new (1, FALSE); for (i = 2; i < argc; i++) { g_clear_object (&f); f = g_file_resolve_relative_path (root, argv[i]); if (!cat_one_file (f, stdout_stream, cancellable, error)) goto out; } ret = TRUE; out: if (context) g_option_context_free (context); return ret; }
/** * gimp_config_writer_new_fd: * @fd: * * Return value: a new #GimpConfigWriter or %NULL in case of an error * * Since: GIMP 2.4 **/ GimpConfigWriter * gimp_config_writer_new_fd (gint fd) { GimpConfigWriter *writer; g_return_val_if_fail (fd > 0, NULL); writer = g_slice_new0 (GimpConfigWriter); #ifdef G_OS_WIN32 writer->output = g_win32_output_stream_new ((gpointer) fd, FALSE); #else writer->output = g_unix_output_stream_new (fd, FALSE); #endif writer->buffer = g_string_new (NULL); return writer; }
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; }
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; }
void set_user_icon_data (ActUser *user, GdkPixbuf *pixbuf) { gchar *path; gint fd; GOutputStream *stream; GError *error; path = g_build_filename (g_get_tmp_dir (), "gnome-control-center-user-icon-XXXXXX", NULL); fd = g_mkstemp (path); if (fd == -1) { g_warning ("failed to create temporary file for image data"); g_free (path); return; } stream = g_unix_output_stream_new (fd, TRUE); error = NULL; if (!gdk_pixbuf_save_to_stream (pixbuf, stream, "png", NULL, &error, NULL)) { g_warning ("failed to save image: %s", error->message); g_error_free (error); g_object_unref (stream); return; } g_object_unref (stream); act_user_set_icon_file (user, path); /* if we ever make the dbus call async, the g_remove call needs * to wait for its completion */ g_remove (path); g_free (path); }
static void extract_content_child_process (PopplerDocument *document, gsize n_bytes, int fd[2]) { GString *str; gint64 size; GOutputStream *output_stream; GDataOutputStream *dataout_stream; /* This is the child extracting the content, hopefully in time */ output_stream = g_unix_output_stream_new (fd[1], FALSE); dataout_stream = g_data_output_stream_new (output_stream); str = extract_content_text (document, n_bytes); size = (gint64) str->len; /* Write the results to the pipe */ if (g_data_output_stream_put_int64 (dataout_stream, size, NULL, NULL)) { g_output_stream_write_all (output_stream, str->str, str->len, NULL, NULL, NULL); } g_debug ("Child: Content extraction now finished in child process, " "written %" G_GSIZE_FORMAT " bytes to parent process", size); g_string_free (str, TRUE); g_object_unref (dataout_stream); g_object_unref (output_stream); close (fd[1]); exit (0); }
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; }
gboolean _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GString *output = g_string_new (""); gs_unref_object GOutputStream *out_stream = NULL; gs_unref_ptrarray GPtrArray *loader_configs = NULL; guint i; gsize bytes_written; gboolean is_efi; /* So... yeah. Just going to hardcode these. */ static const char hardcoded_video[] = "load_video\n" "set gfxpayload=keep\n"; static const char hardcoded_insmods[] = "insmod gzio\n"; const char *grub2_boot_device_id = g_getenv ("GRUB2_BOOT_DEVICE_ID"); const char *grub2_prepare_root_cache = g_getenv ("GRUB2_PREPARE_ROOT_CACHE"); /* We must have been called via the wrapper script */ g_assert (grub2_boot_device_id != NULL); g_assert (grub2_prepare_root_cache != NULL); /* Passed from the parent */ is_efi = g_getenv ("_OSTREE_GRUB2_IS_EFI") != NULL; out_stream = g_unix_output_stream_new (target_fd, FALSE); if (!_ostree_sysroot_read_boot_loader_configs (sysroot, bootversion, &loader_configs, cancellable, error)) goto out; for (i = 0; i < loader_configs->len; i++) { OstreeBootconfigParser *config = loader_configs->pdata[i]; const char *title; const char *options; const char *kernel; const char *initrd; char *quoted_title = NULL; char *uuid = NULL; char *quoted_uuid = NULL; title = ostree_bootconfig_parser_get (config, "title"); if (!title) title = "(Untitled)"; kernel = ostree_bootconfig_parser_get (config, "linux"); quoted_title = g_shell_quote (title); uuid = g_strdup_printf ("ostree-%u-%s", (guint)i, grub2_boot_device_id); quoted_uuid = g_shell_quote (uuid); g_string_append_printf (output, "menuentry %s --class gnu-linux --class gnu --class os --unrestricted %s {\n", quoted_title, quoted_uuid); g_free (uuid); g_free (quoted_title); g_free (quoted_uuid); /* Hardcoded sections */ g_string_append (output, hardcoded_video); g_string_append (output, hardcoded_insmods); g_string_append (output, grub2_prepare_root_cache); g_string_append_c (output, '\n'); if (!kernel) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No \"linux\" key in bootloader config"); goto out; } if (is_efi) g_string_append (output, "linuxefi "); else g_string_append (output, "linux16 "); g_string_append (output, kernel); options = ostree_bootconfig_parser_get (config, "options"); if (options) { g_string_append_c (output, ' '); g_string_append (output, options); } g_string_append_c (output, '\n'); initrd = ostree_bootconfig_parser_get (config, "initrd"); if (initrd) { if (is_efi) g_string_append (output, "initrdefi "); else g_string_append (output, "initrd16 "); g_string_append (output, initrd); g_string_append_c (output, '\n'); } g_string_append (output, "}\n"); } if (!g_output_stream_write_all (out_stream, output->str, output->len, &bytes_written, cancellable, error)) goto out; ret = TRUE; out: if (output) g_string_free (output, TRUE); return ret; }
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); }
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); } }
gboolean _ostree_static_delta_part_open (GInputStream *part_in, GBytes *inline_part_bytes, OstreeStaticDeltaOpenFlags flags, const char *expected_checksum, GVariant **out_part, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0; const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0; gsize bytes_read; guint8 comptype; g_autoptr(GChecksum) checksum = NULL; g_autoptr(GInputStream) checksum_in = NULL; g_autoptr(GVariant) ret_part = NULL; GInputStream *source_in; /* We either take a fd or a GBytes reference */ g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE); g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE); if (!skip_checksum) { checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum); source_in = checksum_in; } else { source_in = part_in; } { guint8 buf[1]; /* First byte is compression type */ if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read, cancellable, error)) { g_prefix_error (error, "Reading initial compression flag byte: "); goto out; } comptype = buf[0]; } switch (comptype) { case 0: if (!inline_part_bytes) { int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in); /* No compression, no checksums - a fast path */ if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } else { g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1, g_bytes_get_size (inline_part_bytes) - 1); ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), content_bytes, trusted); g_variant_ref_sink (ret_part); } if (!skip_checksum) g_checksum_update (checksum, g_variant_get_data (ret_part), g_variant_get_size (ret_part)); break; case 'x': { g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX"); g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new (); g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp); g_autoptr(GOutputStream) unpacked_out = NULL; glnx_fd_close int unpacked_fd = -1; gssize n_bytes_written; unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640); if (unpacked_fd < 0) { glnx_set_error_from_errno (error); goto out; } /* Now make it autocleanup on process exit - in the future, we * should consider caching unpacked deltas as well. */ if (unlink (tmppath) < 0) { glnx_set_error_from_errno (error); goto out; } unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE); n_bytes_written = g_output_stream_splice (unpacked_out, convin, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error); if (n_bytes_written < 0) goto out; if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0), trusted, &ret_part, error)) goto out; } break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid compression type '%u'", comptype); goto out; } if (checksum) { const char *actual_checksum = g_checksum_get_string (checksum); g_assert (expected_checksum != NULL); if (strcmp (actual_checksum, expected_checksum) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Checksum mismatch in static delta part; expected=%s actual=%s", expected_checksum, actual_checksum); goto out; } } ret = TRUE; *out_part = g_steal_pointer (&ret_part); out: return ret; }
/* * This function creates a file under a temporary name, then rename()s * it into place. This implements union-like behavior. */ static gboolean checkout_file_unioning_from_input_at (OstreeRepo *repo, OstreeRepoCheckoutAtOptions *options, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, int destination_dfd, const char *destination_name, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) { if (!_ostree_make_temporary_symlink_at (destination_dfd, g_file_info_get_symlink_target (file_info), &temp_filename, cancellable, error)) goto out; if (xattrs) { if (!glnx_dfd_name_set_all_xattrs (destination_dfd, temp_filename, xattrs, cancellable, error)) goto out; } if (G_UNLIKELY (renameat (destination_dfd, temp_filename, destination_dfd, destination_name) == -1)) { glnx_set_error_from_errno (error); goto out; } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { glnx_fd_close int temp_fd = -1; g_autoptr(GOutputStream) temp_out = NULL; guint32 file_mode; file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); /* Don't make setuid files on checkout when we're doing --user */ if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER) file_mode &= ~(S_ISUID|S_ISGID); if (!glnx_open_tmpfile_linkable_at (destination_dfd, ".", O_WRONLY | O_CLOEXEC, &temp_fd, &temp_filename, error)) goto out; temp_out = g_unix_output_stream_new (temp_fd, FALSE); if (!write_regular_file_content (repo, options, temp_out, file_info, xattrs, input, cancellable, error)) goto out; if (!glnx_link_tmpfile_at (destination_dfd, GLNX_LINK_TMPFILE_REPLACE, temp_fd, temp_filename, destination_dfd, destination_name, error)) goto out; } else g_assert_not_reached (); ret = TRUE; out: return ret; }
static gboolean run (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; const char *dirpath; OtTrivialHttpd appstruct = { 0, }; OtTrivialHttpd *app = &appstruct; glnx_unref_object SoupServer *server = NULL; g_autoptr(GFileMonitor) dirmon = NULL; context = g_option_context_new ("[DIR] - Simple webserver"); g_option_context_add_main_entries (context, options, NULL); app->root_dfd = -1; if (!g_option_context_parse (context, &argc, &argv, error)) goto out; if (argc > 1) dirpath = argv[1]; else dirpath = "."; if (!glnx_opendirat (AT_FDCWD, dirpath, TRUE, &app->root_dfd, error)) goto out; if (!(opt_random_500s_percentage >= 0 && opt_random_500s_percentage <= 99)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid --random-500s=%u", opt_random_500s_percentage); goto out; } if (opt_log) { GOutputStream *stream = NULL; if (g_strcmp0 (opt_log, "-") == 0) { if (opt_daemonize) { ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error); goto out; } stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE)); } else { g_autoptr(GFile) log_file = NULL; GFileOutputStream* log_stream; log_file = g_file_new_for_path (opt_log); log_stream = g_file_create (log_file, G_FILE_CREATE_PRIVATE, cancellable, error); if (!log_stream) goto out; stream = G_OUTPUT_STREAM (log_stream); } app->log = stream; } #if SOUP_CHECK_VERSION(2, 48, 0) server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); if (!soup_server_listen_all (server, opt_port, 0, error)) goto out; #else server = soup_server_new (SOUP_SERVER_PORT, opt_port, SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); #endif soup_server_add_handler (server, NULL, httpd_callback, app, NULL); if (opt_port_file) { g_autofree char *portstr = NULL; #if SOUP_CHECK_VERSION(2, 48, 0) GSList *listeners = soup_server_get_listeners (server); g_autoptr(GSocket) listener = NULL; g_autoptr(GSocketAddress) addr = NULL; g_assert (listeners); listener = g_object_ref (listeners->data); g_slist_free (listeners); listeners = NULL; addr = g_socket_get_local_address (listener, error); if (!addr) goto out; g_assert (G_IS_INET_SOCKET_ADDRESS (addr)); portstr = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress*)addr)); #else portstr = g_strdup_printf ("%u\n", soup_server_get_port (server)); #endif if (g_strcmp0 ("-", opt_port_file) == 0) { fputs (portstr, stdout); // not g_print - this must go to stdout, not a handler fflush (stdout); } else if (!g_file_set_contents (opt_port_file, portstr, strlen (portstr), error)) goto out; } #if !SOUP_CHECK_VERSION(2, 48, 0) soup_server_run_async (server); #endif if (opt_daemonize) { pid_t pid = fork(); if (pid == -1) { int errsv = errno; g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), g_strerror (errsv)); goto out; } else if (pid > 0) { ret = TRUE; goto out; } /* Child, continue */ if (setsid () < 0) err (1, "setsid"); /* Daemonising: close stdout/stderr so $() et al work on us */ if (freopen("/dev/null", "r", stdin) == NULL) err (1, "freopen"); if (freopen("/dev/null", "w", stdout) == NULL) err (1, "freopen"); if (freopen("/dev/null", "w", stderr) == NULL) err (1, "freopen"); } else { /* Since we're used for testing purposes, let's just do this by * default. This ensures we exit when our parent does. */ if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0) { if (errno != ENOSYS) { glnx_set_error_from_errno (error); goto out; } } } app->running = TRUE; if (opt_autoexit) { gboolean is_symlink = FALSE; g_autoptr(GFile) root = NULL; g_autoptr(GFileInfo) info = NULL; root = g_file_new_for_path (dirpath); info = g_file_query_info (root, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!info) goto out; is_symlink = g_file_info_get_is_symlink (info); if (is_symlink) dirmon = g_file_monitor_file (root, 0, cancellable, error); else dirmon = g_file_monitor_directory (root, 0, cancellable, error); if (!dirmon) goto out; g_signal_connect (dirmon, "changed", G_CALLBACK (on_dir_changed), app); } httpd_log (app, "serving at root %s\n", dirpath); while (app->running) g_main_context_iteration (NULL, TRUE); ret = TRUE; out: if (app->root_dfd != -1) (void) close (app->root_dfd); g_clear_object (&app->log); return ret; }
static gboolean checkout_file_from_input_at (OstreeRepo *self, OstreeRepoCheckoutOptions *options, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, int destination_dfd, const char *destination_name, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int res; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) { do res = symlinkat (g_file_info_get_symlink_target (file_info), destination_dfd, destination_name); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { glnx_set_error_from_errno (error); goto out; } if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) { if (G_UNLIKELY (fchownat (destination_dfd, destination_name, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), g_file_info_get_attribute_uint32 (file_info, "unix::gid"), AT_SYMLINK_NOFOLLOW) == -1)) { glnx_set_error_from_errno (error); goto out; } if (xattrs) { if (!glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name, xattrs, cancellable, error)) goto out; } } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { g_autoptr(GOutputStream) temp_out = NULL; int fd; guint32 file_mode; file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); /* Don't make setuid files on checkout when we're doing --user */ if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER) file_mode &= ~(S_ISUID|S_ISGID); do fd = openat (destination_dfd, destination_name, O_WRONLY | O_CREAT | O_EXCL, file_mode); while (G_UNLIKELY (fd == -1 && errno == EINTR)); if (fd == -1) { glnx_set_error_from_errno (error); goto out; } temp_out = g_unix_output_stream_new (fd, TRUE); fd = -1; /* Transfer ownership */ if (!write_regular_file_content (self, options, temp_out, file_info, xattrs, input, cancellable, error)) goto out; } else g_assert_not_reached (); ret = TRUE; out: return ret; }
static gboolean checkout_object_for_uncompressed_cache (OstreeRepo *self, const char *loose_path, GFileInfo *src_info, GInputStream *content, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; g_autoptr(GOutputStream) temp_out = NULL; glnx_fd_close int fd = -1; int res; guint32 file_mode; /* Don't make setuid files in uncompressed cache */ file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode"); file_mode &= ~(S_ISUID|S_ISGID); if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY | O_CLOEXEC, &fd, &temp_filename, error)) goto out; temp_out = g_unix_output_stream_new (fd, FALSE); if (g_output_stream_splice (temp_out, content, 0, cancellable, error) < 0) goto out; if (!g_output_stream_flush (temp_out, cancellable, error)) goto out; if (!self->disable_fsync) { do res = fsync (fd); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } if (!g_output_stream_close (temp_out, cancellable, error)) goto out; if (fchmod (fd, file_mode) < 0) { glnx_set_error_from_errno (error); goto out; } if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd, loose_path, cancellable, error)) goto out; if (!glnx_link_tmpfile_at (self->tmp_dir_fd, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST, fd, temp_filename, self->uncompressed_objects_dir_fd, loose_path, error)) goto out; ret = TRUE; out: return ret; }