コード例 #1
0
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);
}
コード例 #2
0
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);
    }
}
コード例 #3
0
ファイル: glib-compat.c プロジェクト: cooljeanius/gcab
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;
}
コード例 #4
0
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;
}
コード例 #5
0
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;
}