static gssize ekg_gnutls_pull(gnutls_transport_ptr_t connptr, gpointer buf, gsize len) { struct ekg_gnutls_connection *conn = connptr; GBufferedInputStream *s = G_BUFFERED_INPUT_STREAM(conn->connection->instream); gsize avail_bytes = g_buffered_input_stream_get_available(s); /* XXX: EOF? */ g_assert(len > 0); if (avail_bytes == 0) { if (conn->connection_error) return 0; /* EOF */ gnutls_transport_set_errno(conn->session, EAGAIN); return -1; } else { GError *err = NULL; gssize ret = g_input_stream_read( G_INPUT_STREAM(s), buf, MIN(avail_bytes, len), NULL, &err); if (ret == -1) { debug_error("ekg_gnutls_pull() failed: %s\n", err->message); g_error_free(err); } return ret; } g_assert_not_reached(); }
static double * parse_data_file(GDataInputStream *in, int *rows_ret, int *cols_ret, GError **err_ret) { GError *err = NULL; int result_used = 0; int result_allocated = 256; double *result = g_new(double, result_allocated); gchar *line; int rows = 0; int cols = 0; while ((line = g_data_input_stream_read_line(in, NULL, NULL, &err))) { gchar **words = g_strsplit_set(line, " \t", 0); gboolean is_empty = ! words[0]; if (is_empty || words[0][0] == '#') goto next_line; int n = 0; while (words[n]) ++n; if (cols == 0) { cols = n; } else if (n < cols && g_buffered_input_stream_get_available(G_BUFFERED_INPUT_STREAM(in)) == 0) { g_set_error(&err, JVQPLOT_ERROR, JVQPLOT_ERROR_INCOMPLETE, "incomplete input"); goto next_line; } else if (cols != n) { g_set_error(&err, JVQPLOT_ERROR, JVQPLOT_ERROR_CORRUPTED, "invalid data (malformed matrix)"); goto next_line; } /* if there is only one column, prepend the index */ if (cols == 1) { if (result_used >= result_allocated) { result_allocated *= 2; result = g_renew(double, result, result_allocated); } result[result_used++] = rows+1; } int i; for (i=0; i<cols; ++i) { char *endptr; double x = strtod(words[i], &endptr); if (*endptr) { g_set_error(&err, JVQPLOT_ERROR, JVQPLOT_ERROR_CORRUPTED, "invalid data (malformed number)"); goto next_line; } if (result_used >= result_allocated) { result_allocated *= 2; result = g_renew(double, result, result_allocated); } result[result_used++] = x; }
static void setup_async_read(struct ekg_connection *c) { g_buffered_input_stream_fill_async( G_BUFFERED_INPUT_STREAM(c->instream), -1, /* fill the buffer */ G_PRIORITY_DEFAULT, c->cancellable, done_async_read, c); }
/** * news_parser_parse_async: * @parser: (in): A #NewsParser. * @stream: (in): A #GInputStream. * @cancellable: (in): A #GCancellable to to cancel the task. * @callback: (in): A callback to perform when the operation completes. * @user_data: (in): User data for @callback. * * Requests that @parser parse the feed contained in @stream asynchronously. * When the operation completes, @callback will be executed from the * main loop. @callback is responsible for calling news_parser_parse_finish() * to retrieve the result. * * Returns: None. */ void news_parser_parse_async (NewsParser *parser, GInputStream *stream, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { NewsParserPrivate *priv; GInputStream *buffered; ENTRY; g_return_if_fail(NEWS_IS_PARSER(parser)); g_return_if_fail(G_IS_INPUT_STREAM(stream)); g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); g_return_if_fail(callback != NULL); g_return_if_fail(parser->priv->simple == NULL); priv = parser->priv; priv->simple = g_simple_async_result_new(G_OBJECT(parser), callback, user_data, news_parser_parse_async); if (cancellable) { priv->cancellable = g_object_ref(cancellable); } buffered = g_buffered_input_stream_new_sized(stream, 1024); g_buffered_input_stream_fill_async(G_BUFFERED_INPUT_STREAM(buffered), BUFFER_FILL_SIZE, G_PRIORITY_DEFAULT, priv->cancellable, news_parser_buffered_fill_cb, g_object_ref(parser)); g_object_unref(buffered); EXIT; }
/** * g_vfs_ftp_connection_enable_tls: * @conn: a connection without an active data connection * @server_identity: address of the server used to verify the certificate * @cb: callback called if there's a verification error * @user_data: user data passed to @cb * @cancellable: cancellable to interrupt wait * @error: %NULL or location to take a potential error * * Tries to enable TLS on the given @connection. If setting up TLS fails, * %FALSE will be returned and @error will be set. When this function fails, * you need to check if the connection is still usable. It might have been * closed. * * Returns: %TRUE on success, %FALSE otherwise. **/ gboolean g_vfs_ftp_connection_enable_tls (GVfsFtpConnection * conn, GSocketConnectable *server_identity, CertificateCallback cb, gpointer user_data, GCancellable * cancellable, GError ** error) { GIOStream *secure; g_return_val_if_fail (conn != NULL, FALSE); g_return_val_if_fail (conn->data == NULL, FALSE); g_return_val_if_fail (!conn->waiting_for_reply, FALSE); g_return_val_if_fail (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (conn->commands_in)) == 0, FALSE); secure = g_tls_client_connection_new (conn->commands, server_identity, error); if (secure == NULL) return FALSE; g_object_unref (conn->commands); conn->commands = secure; create_input_stream (conn); g_signal_connect (secure, "accept-certificate", G_CALLBACK (cb), user_data); if (!g_tls_connection_handshake (G_TLS_CONNECTION (secure), cancellable, error)) { /* Close here to be sure it won't get used anymore */ g_io_stream_close (secure, cancellable, NULL); return FALSE; } return TRUE; }
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 void done_async_read(GObject *obj, GAsyncResult *res, gpointer user_data) { struct ekg_connection *c = user_data; GError *err = NULL; gssize rsize; GBufferedInputStream *instr = G_BUFFERED_INPUT_STREAM(obj); rsize = g_buffered_input_stream_fill_finish(instr, res, &err); if (rsize <= 0) { if (rsize == -1) /* error */ debug_error("done_async_read(), read failed: %s\n", err ? err->message : NULL); else { /* EOF */ #if NEED_SLAVERY if (c->master) /* let the master handle it */ return; #endif debug_function("done_async_read(), EOF\n"); if (g_buffered_input_stream_get_available(instr) > 0) c->callback(c->instream, c->priv_data); err = g_error_new_literal( EKG_CONNECTION_ERROR, EKG_CONNECTION_ERROR_EOF, "Connection terminated"); } c->failure_callback(c->instream, err, c->priv_data); ekg_connection_remove(c); g_error_free(err); return; } debug_function("done_async_read(): read %d bytes\n", rsize); c->callback(c->instream, c->priv_data); setup_async_read(c); }
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; }
char * g_data_input_stream_read_upto (GDataInputStream *stream, const gchar *stop_chars, gssize stop_chars_len, gsize *length, GCancellable *cancellable, GError **error) { GBufferedInputStream *bstream; gsize checked; gssize found_pos; gssize res; char *data_until; g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL); if (stop_chars_len < 0) stop_chars_len = strlen (stop_chars); bstream = G_BUFFERED_INPUT_STREAM (stream); checked = 0; while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1) { if (g_buffered_input_stream_get_available (bstream) == g_buffered_input_stream_get_buffer_size (bstream)) g_buffered_input_stream_set_buffer_size (bstream, 2 * g_buffered_input_stream_get_buffer_size (bstream)); res = g_buffered_input_stream_fill (bstream, -1, cancellable, error); if (res < 0) return NULL; if (res == 0) { /* End of stream */ if (g_buffered_input_stream_get_available (bstream) == 0) { if (length) *length = 0; return NULL; } else { found_pos = checked; break; } } } data_until = g_malloc (found_pos + 1); res = g_input_stream_read (G_INPUT_STREAM (stream), data_until, found_pos, NULL, NULL); if (length) *length = (gsize)found_pos; g_warn_if_fail (res == found_pos); data_until[found_pos] = 0; return data_until; }