static VALUE rg_peek_buffer(VALUE self) { gsize size; const void *buffer; buffer = g_buffered_input_stream_peek_buffer(_SELF(self), &size); return CSTR2RVAL_TAINTED(buffer, size); }
static void client_fill_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { BroadwayClient *client = user_data; gssize res; res = g_buffered_input_stream_fill_finish (client->in, result, NULL); if (res > 0) { guint32 size; gsize count, remaining; guint8 *buffer; buffer = (guint8 *)g_buffered_input_stream_peek_buffer (client->in, &count); remaining = count; while (remaining >= sizeof (guint32)) { memcpy (&size, buffer, sizeof (guint32)); if (size <= remaining) { client_handle_request (client, (BroadwayRequest *)buffer); remaining -= size; buffer += size; } } /* This is guaranteed not to block */ g_input_stream_skip (G_INPUT_STREAM (client->in), count - remaining, NULL, NULL); g_buffered_input_stream_fill_async (client->in, 4*1024, 0, NULL, client_fill_cb, client); } else { client_disconnected (client); } }
static gssize scan_for_chars (GDataInputStream *stream, gsize *checked_out, const char *stop_chars, gssize stop_chars_len) { GBufferedInputStream *bstream; const char *buffer; gsize start, end, peeked; int i; gsize available, checked; const char *stop_char; const char *stop_end; bstream = G_BUFFERED_INPUT_STREAM (stream); stop_end = stop_chars + stop_chars_len; checked = *checked_out; start = checked; buffer = (const char *)g_buffered_input_stream_peek_buffer (bstream, &available) + start; end = available; peeked = end - start; for (i = 0; checked < available && i < peeked; i++) { for (stop_char = stop_chars; stop_char != stop_end; stop_char++) { if (buffer[i] == *stop_char) return (start + i); } } checked = end; *checked_out = checked; return -1; }
static gboolean sysroot_stdout_ready_cb (GPollableInputStream *pollable_stream, StdoutClosure *closure) { glnx_unref_object RpmostreedSysroot *sysroot = NULL; glnx_unref_object RpmostreedTransaction *transaction = NULL; GMemoryInputStream *memory_stream; GBufferedInputStream *buffered_stream; char buffer[1024]; gconstpointer stream_buffer; gsize stream_buffer_size; gsize total_bytes_read = 0; gboolean have_line = FALSE; GError *local_error = NULL; sysroot = g_weak_ref_get (&closure->sysroot); if (sysroot != NULL) transaction = rpmostreed_transaction_monitor_ref_active_transaction (sysroot->transaction_monitor); /* XXX Would very much like g_buffered_input_stream_fill_nonblocking(). * Much of this function is a clumsy and inefficient attempt to * achieve the same thing. * * See: https://bugzilla.gnome.org/726797 */ buffered_stream = G_BUFFERED_INPUT_STREAM (closure->data_stream); memory_stream = (GMemoryInputStream *) g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (buffered_stream)); while (local_error == NULL) { gssize n_read; n_read = g_pollable_input_stream_read_nonblocking (pollable_stream, buffer, sizeof (buffer), NULL, &local_error); if (n_read > 0) { /* XXX Gotta use GBytes so the data gets copied. */ g_autoptr(GBytes) bytes = g_bytes_new (buffer, n_read); g_memory_input_stream_add_bytes (memory_stream, bytes); total_bytes_read += n_read; } } if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) goto out; g_clear_error (&local_error); read_another_line: /* Fill the buffered stream with the data we just put in the * memory stream, then peek at the buffer to see if it's safe * to call g_data_input_stream_read_line() without blocking. * * XXX Oye, there's gotta be an easier way to do this... */ /* This should never fail since it's just reading from memory. */ g_buffered_input_stream_fill (buffered_stream, total_bytes_read, NULL, NULL); stream_buffer = g_buffered_input_stream_peek_buffer (buffered_stream, &stream_buffer_size); have_line = (memchr (stream_buffer, '\n', stream_buffer_size) != NULL); if (have_line) { g_autofree char *line = NULL; gsize length; line = g_data_input_stream_read_line (closure->data_stream, &length, NULL, &local_error); if (local_error != NULL) goto out; /* If there's an active transaction, forward the line to the * transaction's owner through the "Message" signal. Otherwise * dump it to the non-redirected standard output stream. */ if (transaction != NULL) { rpmostree_transaction_emit_message (RPMOSTREE_TRANSACTION (transaction), line); } else { /* This is essentially puts(), don't care about errors. */ g_output_stream_write_all (closure->real_stdout, line, length, NULL, NULL, NULL); g_output_stream_write_all (closure->real_stdout, "\n", 1, NULL, NULL, NULL); } goto read_another_line; } out: if (local_error != NULL) { g_warning ("Failed to read stdout pipe: %s", local_error->message); g_clear_error (&local_error); } return G_SOURCE_CONTINUE; }
static gboolean log_load (GIOSchedulerJob *io_job, GCancellable *cancellable, gpointer user_data) { /* this runs in a separate i/o thread */ LoadJob *job = user_data; LogviewLog *log = job->log; GFile *f = log->priv->file; GFileInfo *info; GInputStream *is; const char *peeked_buffer; const char * parse_data[2]; GSList *days; const char *content_type; GFileType type; GError *err = NULL; GTimeVal timeval; gboolean is_archive, can_read; info = g_file_query_info (f, G_FILE_ATTRIBUTE_ACCESS_CAN_READ "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_TIME_MODIFIED ",", 0, NULL, &err); if (err) { if (err->code == G_IO_ERROR_PERMISSION_DENIED) { /* TODO: PolicyKit integration */ } goto out; } can_read = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ); if (!can_read) { /* TODO: PolicyKit integration */ err = g_error_new_literal (LOGVIEW_ERROR_QUARK, LOGVIEW_ERROR_PERMISSION_DENIED, _("You don't have enough permissions to read the file.")); g_object_unref (info); goto out; } type = g_file_info_get_file_type (info); content_type = g_file_info_get_content_type (info); is_archive = g_content_type_equals (content_type, "application/x-gzip"); if (type != (G_FILE_TYPE_REGULAR || G_FILE_TYPE_SYMBOLIC_LINK) || (!g_content_type_is_a (content_type, "text/plain") && !is_archive)) { err = g_error_new_literal (LOGVIEW_ERROR_QUARK, LOGVIEW_ERROR_NOT_A_LOG, _("The file is not a regular file or is not a text file.")); g_object_unref (info); goto out; } log->priv->file_size = g_file_info_get_size (info); g_file_info_get_modification_time (info, &timeval); log->priv->file_time = timeval.tv_sec; log->priv->display_name = g_strdup (g_file_info_get_display_name (info)); g_object_unref (info); /* initialize the stream */ is = G_INPUT_STREAM (g_file_read (f, NULL, &err)); if (err) { if (err->code == G_IO_ERROR_PERMISSION_DENIED) { /* TODO: PolicyKit integration */ } goto out; } if (is_archive) { #ifdef HAVE_ZLIB GZHandle *gz; gboolean res; guchar * buffer; gsize bytes_read; GInputStream *real_is; time_t mtime; /* seconds */ /* this also skips the header from |is| */ res = read_gzip_header (is, &mtime); if (!res) { g_object_unref (is); err = create_zlib_error (); goto out; } log->priv->file_time = mtime; gz = gz_handle_new (f, is); res = gz_handle_init (gz); if (!res) { g_object_unref (is); gz_handle_free (gz); err = create_zlib_error (); goto out; } real_is = g_memory_input_stream_new (); do { buffer = g_malloc (1024); res = gz_handle_read (gz, buffer, 1024, &bytes_read); g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (real_is), buffer, bytes_read, g_free); } while (res == TRUE && bytes_read > 0); if (!res) { gz_handle_free (gz); g_object_unref (real_is); g_object_unref (is); err = create_zlib_error (); goto out; } g_object_unref (is); is = real_is; gz_handle_free (gz); #else /* HAVE_ZLIB */ g_object_unref (is); err = g_error_new_literal (LOGVIEW_ERROR_QUARK, LOGVIEW_ERROR_NOT_SUPPORTED, _("This version of System Log does not support GZipped logs.")); goto out; #endif /* HAVE_ZLIB */ } log->priv->stream = g_data_input_stream_new (is); /* sniff into the stream for a timestamped line */ g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (log->priv->stream), (gssize) g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (log->priv->stream)), NULL, &err); if (err == NULL) { peeked_buffer = g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (log->priv->stream), NULL); parse_data[0] = peeked_buffer; parse_data[1] = NULL; if ((days = log_read_dates (parse_data, time (NULL))) != NULL) { log->priv->has_days = TRUE; g_slist_foreach (days, (GFunc) logview_utils_day_free, NULL); g_slist_free (days); } else { log->priv->has_days = FALSE; } } else { log->priv->has_days = FALSE; g_clear_error (&err); } g_object_unref (is); out: if (err) { job->err = err; } g_io_scheduler_job_send_to_mainloop_async (io_job, log_load_done, job, NULL); return FALSE; }