static gboolean soi_gdk_pixbuf_save (gchar const *buf, gsize count, GError **error, gpointer data) { GsfOutput *output = GSF_OUTPUT (data); gboolean ok = gsf_output_write (output, count, buf); if (!ok && error) *error = g_error_copy (gsf_output_error (output)); return ok; }
static int test (char *argv[]) { GsfInput *input; GsfOutput *output; GError *err = NULL; int rval = 0; input = gsf_input_stdio_new (argv[1], &err); if (input == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s\n", argv[1], err->message); g_error_free (err); return 1; } output = gsf_output_stdio_new (argv[2], &err); if (output == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s\n", argv[2], err->message); g_error_free (err); g_object_unref (G_OBJECT (input)); return 1; } if (gsf_input_copy (input, output) == FALSE) { rval = 1; err = (GError*) gsf_output_error (output); if (err != NULL) { g_warning ("'%s' error: %s\n", argv[2], err->message); } } g_object_unref (G_OBJECT (input)); gsf_output_close (output); g_object_unref (G_OBJECT (output)); return rval; }
static void go_plugin_file_saver_save (GOFileSaver const *fs, GOIOContext *io_context, GoView const *view, GsfOutput *output) { GOPluginFileSaver *pfs = GO_PLUGIN_FILE_SAVER (fs); GOPluginServiceFileSaver *service_file_saver = GO_PLUGIN_SERVICE_FILE_SAVER (pfs->service); GOErrorInfo *error = NULL; g_return_if_fail (GSF_IS_OUTPUT (output)); go_plugin_service_load (pfs->service, &error); if (error != NULL) { go_io_error_info_set (io_context, error); go_io_error_push (io_context, go_error_info_new_str ( _("Error while loading plugin for saving."))); if (!gsf_output_error (output)) gsf_output_set_error (output, 0, _("Failed to load plugin for saving")); return; } g_return_if_fail (service_file_saver->cbs.plugin_func_file_save != NULL); service_file_saver->cbs.plugin_func_file_save (fs, pfs->service, io_context, view, output); }
static gboolean gsf_output_stdio_close (GsfOutput *output) { GsfOutputStdio *stdio = GSF_OUTPUT_STDIO (output); gboolean res; char *backup_filename = NULL; GDateTime *modtime; if (stdio->file == NULL) return FALSE; if (gsf_output_error (output)) { res = TRUE; if (!stdio->keep_open && !close_file_helper (stdio, FALSE)) res = FALSE; if (!unlink_file_helper (stdio)) res = FALSE; return res; } if (stdio->keep_open) { gboolean res = (0 == fflush (stdio->file)); if (!res) gsf_output_set_error (output, errno, "Failed to flush."); stdio->file = NULL; return res; } res = close_file_helper (stdio, TRUE); /* short circuit our when dealing with raw FILE */ if (!stdio->real_filename) return res; if (!res) { unlink_file_helper (stdio); return FALSE; } /* Move the original file to a backup */ if (stdio->create_backup_copy) { gint result; backup_filename = g_strconcat (stdio->real_filename, ".bak", NULL); result = rename_wrapper (stdio->real_filename, backup_filename); if (result != 0) { char *utf8name = g_filename_display_name (backup_filename); gsf_output_set_error (output, errno, "Could not backup the original as %s.", utf8name); g_free (utf8name); g_unlink (stdio->temp_filename); res = FALSE; goto out; } } /* Move the temp file to the original file */ if (rename_wrapper (stdio->temp_filename, stdio->real_filename) != 0) { gint saved_errno = errno; if (backup_filename != NULL && rename_wrapper (backup_filename, stdio->real_filename) != 0) saved_errno = errno; res = gsf_output_set_error (output, saved_errno, "%s", g_strerror (saved_errno)); goto out; } modtime = gsf_output_get_modtime (output); if (modtime) { #ifdef UTIME_AVAILABLE struct utimbuf ut; ut.actime = time (NULL); ut.modtime = g_date_time_to_unix (modtime); /* Ignore errors */ /* utimes() provides better accuracy, but doesn't have gstdio version. gio seems to provide access. */ (void)utime (stdio->real_filename, &ut); #endif } /* Restore permissions. There is not much error checking we * can do here, I'm afraid. The final data is saved anyways. * Note the order: mode, uid+gid, gid, uid, mode. */ g_chmod (stdio->real_filename, stdio->st.st_mode); #ifdef HAVE_CHOWN if (chown_wrapper (stdio->real_filename, stdio->st.st_uid, stdio->st.st_gid)) { /* We cannot set both. Maybe we can set one. */ chown_wrapper (stdio->real_filename, -1, stdio->st.st_gid); chown_wrapper (stdio->real_filename, stdio->st.st_uid, -1); } g_chmod (stdio->real_filename, stdio->st.st_mode); #endif out: g_free (backup_filename); return res; }
static gboolean gsf_output_stdio_close (GsfOutput *output) { GsfOutputStdio *stdio = GSF_OUTPUT_STDIO (output); gboolean res; char *backup_filename = NULL; if (stdio->file == NULL) return FALSE; if (gsf_output_error (output)) { res = TRUE; if (!stdio->keep_open && !close_file_helper (stdio, FALSE)) res = FALSE; if (!unlink_file_helper (stdio)) res = FALSE; return res; } if (stdio->keep_open) { gboolean res = (0 == fflush (stdio->file)); if (!res) gsf_output_set_error (output, errno, "Failed to flush."); stdio->file = NULL; return res; } res = close_file_helper (stdio, TRUE); /* short circuit our when dealing with raw FILE */ if (!stdio->real_filename) return res; if (!res) { unlink_file_helper (stdio); return FALSE; } /* Move the original file to a backup */ if (stdio->create_backup_copy) { gint result; backup_filename = g_strconcat (stdio->real_filename, ".bak", NULL); result = rename_wrapper (stdio->real_filename, backup_filename); if (result != 0) { char *utf8name = g_filename_display_name (backup_filename); gsf_output_set_error (output, errno, "Could not backup the original as %s.", utf8name); g_free (utf8name); g_free (backup_filename); g_unlink (stdio->temp_filename); return FALSE; } } /* Move the temp file to the original file */ if (rename_wrapper (stdio->temp_filename, stdio->real_filename) != 0) { gint saved_errno = errno; if (backup_filename != NULL && rename_wrapper (backup_filename, stdio->real_filename) != 0) saved_errno = errno; res = gsf_output_set_error (output, saved_errno, "%s", g_strerror (saved_errno)); } else { /* Restore permissions. There is not much error checking we * can do here, I'm afraid. The final data is saved anyways. * Note the order: mode, uid+gid, gid, uid, mode. */ chmod_wrapper (stdio->real_filename, stdio->st.st_mode); #ifdef HAVE_CHOWN if (chown (stdio->real_filename, stdio->st.st_uid, stdio->st.st_gid)) { /* We cannot set both. Maybe we can set one. */ chown (stdio->real_filename, -1, stdio->st.st_gid); chown (stdio->real_filename, stdio->st.st_uid, -1); } chmod_wrapper (stdio->real_filename, stdio->st.st_mode); #endif } g_free (backup_filename); return res; }