/** * gsf_input_stdio_new_FILE : * @filename : The filename corresponding to @file. * @file : an existing stdio <type>FILE</type> * * @keep_open : Should @file be closed when the wrapper is closed * * Assumes ownership of @file when succeeding. If @keep_open is true, * ownership reverts to caller when the GsfObject is closed. * * Returns: a new GsfInput wrapper for @file. Note that if the file is not * seekable, this function will make a local copy of the entire file. **/ GsfInput * gsf_input_stdio_new_FILE (char const *filename, FILE *file, gboolean keep_open) { GsfInputStdio *stdio; struct stat st; gsf_off_t size; g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (file != NULL, NULL); if (fstat (fileno (file), &st) < 0 || !S_ISREG (st.st_mode)) { return make_local_copy (file, filename, NULL); } size = st.st_size; stdio = g_object_new (GSF_INPUT_STDIO_TYPE, NULL); if (G_UNLIKELY (NULL == stdio)) return NULL; stdio->file = file; stdio->keep_open = keep_open; stdio->filename = g_strdup (filename); gsf_input_set_size (GSF_INPUT (stdio), size); gsf_input_set_name_from_filename (GSF_INPUT (stdio), filename); return GSF_INPUT (stdio); }
/** * gsf_input_gio_new: * @file: * @err: (allow-none): place to store a #GError if anything goes wrong * * Returns: A new #GsfInputGio or %NULL */ GsfInput * gsf_input_gio_new (GFile *file, GError **err) { GsfInputGio *input; GInputStream *stream; gsf_off_t filesize; g_return_val_if_fail (file != NULL, NULL); stream = (GInputStream *)g_file_read (file, NULL, err); if (stream == NULL) return NULL; if (1) { /* see https://bugzilla.gnome.org/show_bug.cgi?id=724970 */ return make_local_copy (file, stream); } if (!can_seek (stream)) return make_local_copy (file, stream); { GFileInfo *info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, NULL, NULL); if (!info) return make_local_copy (file, stream); filesize = g_file_info_get_size (info); g_object_unref (info); } input = g_object_new (GSF_INPUT_GIO_TYPE, NULL); gsf_input_set_size (GSF_INPUT (input), filesize); g_object_ref (file); input->stream = stream; input->file = file; input->buf = NULL; input->buf_size = 0; set_name_from_file (GSF_INPUT (input), file); return GSF_INPUT (input); }
/** * gsf_input_gio_new: * @file: * @err: optionally NULL. * * Returns: A new #GsfInputGio or NULL */ GsfInput * gsf_input_gio_new (GFile *file, GError **err) { GsfInputGio *input; GInputStream *stream; gsf_off_t filesize; g_return_val_if_fail (file != NULL, NULL); stream = (GInputStream *)g_file_read (file, NULL, err); if (stream == NULL) return NULL; if (!can_seek (stream)) return make_local_copy (file, stream); { GFileInfo *info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, NULL, NULL); if (!info) return make_local_copy (file, stream); filesize = g_file_info_get_size (info); g_object_unref (info); } input = g_object_new (GSF_INPUT_GIO_TYPE, NULL); if (G_UNLIKELY (NULL == input)) { g_input_stream_close (stream, NULL, NULL); g_object_unref (stream); return NULL; } gsf_input_set_size (GSF_INPUT (input), filesize); g_object_ref (file); input->stream = stream; input->file = file; input->buf = NULL; input->buf_size = 0; set_name_from_file (GSF_INPUT (input), file); return GSF_INPUT (input); }
/* coverity[ -tainted_string_sink_content : arg-0 ] */ GsfInput * gsf_input_stdio_new (char const *filename, GError **err) { GsfInputStdio *input; struct stat st; FILE *file; gsf_off_t size; g_return_val_if_fail (filename != NULL, NULL); file = g_fopen (filename, "rb"); if (file == NULL) { if (err) { int save_errno = errno; char *utf8name = g_filename_display_name (filename); g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (save_errno), "%s: %s", utf8name, g_strerror (save_errno)); g_free (utf8name); } return NULL; } if (fstat (fileno (file), &st) < 0 || !S_ISREG (st.st_mode)) { GsfInput *res = make_local_copy (file, filename, err); fclose (file); return res; } size = st.st_size; input = (GsfInputStdio *)g_object_new (GSF_INPUT_STDIO_TYPE, NULL); if (G_UNLIKELY (NULL == input)) { fclose (file); return NULL; } input->file = file; input->filename = g_strdup (filename); input->buf = NULL; input->buf_size = 0; input->keep_open = FALSE; gsf_input_set_size (GSF_INPUT (input), size); gsf_input_set_name_from_filename (GSF_INPUT (input), filename); return GSF_INPUT (input); }
PARROT_CAN_RETURN_NULL static PMC * make_local_copy(PARROT_INTERP, ARGIN(Parrot_Interp from), ARGIN(PMC *arg)) { ASSERT_ARGS(make_local_copy) PMC *ret_val; STRING * const _sub = interp->vtables[enum_class_Sub]->whoami; STRING * const _multi_sub = interp->vtables[enum_class_MultiSub]->whoami; if (PMC_IS_NULL(arg)) { ret_val = PMCNULL; } else if (PObj_is_PMC_shared_TEST(arg)) { ret_val = arg; } else if (VTABLE_isa(from, arg, _multi_sub)) { INTVAL i = 0; const INTVAL n = VTABLE_elements(from, arg); ret_val = Parrot_pmc_new(interp, enum_class_MultiSub); for (i = 0; i < n; ++i) { PMC *const orig = VTABLE_get_pmc_keyed_int(from, arg, i); PMC *const copy = make_local_copy(interp, from, orig); VTABLE_push_pmc(interp, ret_val, copy); } } else if (VTABLE_isa(from, arg, _sub)) { /* this is a workaround for cloning subroutines not actually * working as one might expect mainly because the segment is * not correctly copied */ Parrot_Sub_attributes *ret_val_sub, *arg_sub; ret_val = Parrot_clone(interp, arg); PMC_get_sub(interp, ret_val, ret_val_sub); PMC_get_sub(interp, arg, arg_sub); ret_val_sub->seg = arg_sub->seg; /* Skip vtable overrides and methods. */ if (ret_val_sub->vtable_index == -1 && !(ret_val_sub->comp_flags & SUB_COMP_FLAG_METHOD)) { Parrot_ns_store_sub(interp, ret_val); } } else { ret_val = Parrot_clone(interp, arg); } return ret_val; }