gimpconfigwriter.c 20.4 KB
Newer Older
1
/* LIBGIMP - The GIMP Library
2 3 4 5 6
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * GimpConfigWriter
 * Copyright (C) 2003  Sven Neumann <sven@gimp.org>
 *
7
 * This library is free software: you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 3 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library.  If not, see
19
 * <https://www.gnu.org/licenses/>.
20 21 22 23
 */

#include "config.h"

24
#include <string.h>
25

26
#include <gio/gio.h>
27 28

#ifdef G_OS_WIN32
29 30 31
#include <gio/gwin32outputstream.h>
#else
#include <gio/gunixoutputstream.h>
32 33
#endif

34 35
#include "libgimpbase/gimpbase.h"

36 37
#include "gimpconfigtypes.h"

38 39
#include "gimpconfigwriter.h"
#include "gimpconfig-iface.h"
40
#include "gimpconfig-error.h"
41
#include "gimpconfig-serialize.h"
42
#include "gimpconfig-utils.h"
43

44
#include "libgimp/libgimp-intl.h"
45 46


47 48 49 50 51 52 53 54 55 56
/**
 * SECTION: gimpconfigwriter
 * @title: GimpConfigWriter
 * @short_description: Functions for writing config info to a file for
 *                     libgimpconfig.
 *
 * Functions for writing config info to a file for libgimpconfig.
 **/


57 58
struct _GimpConfigWriter
{
59 60 61
  gint           ref_count;
  gboolean       finished;

62 63 64 65 66 67 68
  GOutputStream *output;
  GFile         *file;
  GError        *error;
  GString       *buffer;
  gboolean       comment;
  gint           depth;
  gint           marker;
69 70 71
};


72 73 74 75
G_DEFINE_BOXED_TYPE (GimpConfigWriter, gimp_config_writer,
                     gimp_config_writer_ref, gimp_config_writer_unref)


76 77 78 79
static inline void  gimp_config_writer_flush        (GimpConfigWriter  *writer);
static inline void  gimp_config_writer_newline      (GimpConfigWriter  *writer);
static gboolean     gimp_config_writer_close_output (GimpConfigWriter  *writer,
                                                     GError           **error);
80

81 82 83
static inline void
gimp_config_writer_flush (GimpConfigWriter *writer)
{
84 85
  GError *error = NULL;

86 87 88
  if (! writer->output)
    return;

89 90 91
  if (! g_output_stream_write_all (writer->output,
                                   writer->buffer->str,
                                   writer->buffer->len,
92
                                   NULL, NULL, &error))
93 94 95
    {
      g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
                   _("Error writing to '%s': %s"),
96 97 98
                   writer->file ?
                   gimp_file_get_utf8_name (writer->file) : "output stream",
                   error->message);
99 100
      g_clear_error (&error);
    }
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

  g_string_truncate (writer->buffer, 0);
}

static inline void
gimp_config_writer_newline (GimpConfigWriter *writer)
{
  gint i;

  g_string_append_c (writer->buffer, '\n');

  if (writer->comment)
    g_string_append_len (writer->buffer, "# ", 2);

  for (i = 0; i < writer->depth; i++)
    g_string_append_len (writer->buffer, "    ", 4);
}
118

119
/**
120
 * gimp_config_writer_new_from_file:
121 122 123 124 125 126 127 128 129 130
 * @file: a #GFile
 * @atomic: if %TRUE the file is written atomically
 * @header: text to include as comment at the top of the file
 * @error: return location for errors
 *
 * Creates a new #GimpConfigWriter and sets it up to write to
 * @file. If @atomic is %TRUE, a temporary file is used to avoid
 * possible race conditions. The temporary file is then moved to @file
 * when the writer is closed.
 *
131
 * Returns: (nullable): a new #GimpConfigWriter or %NULL in case of an error
132
 *
133
 * Since: 2.10
134 135
 **/
GimpConfigWriter *
136 137 138 139
gimp_config_writer_new_from_file (GFile        *file,
                                  gboolean      atomic,
                                  const gchar  *header,
                                  GError      **error)
140 141
{
  GimpConfigWriter *writer;
142
  GOutputStream    *output;
143
  GFile            *dir;
144 145

  g_return_val_if_fail (G_IS_FILE (file), NULL);
146
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
147

148 149 150 151 152 153 154 155 156 157 158 159 160 161
  dir = g_file_get_parent (file);
  if (dir && ! g_file_query_exists (dir, NULL))
    {
      if (! g_file_make_directory_with_parents (dir, NULL, error))
        g_prefix_error (error,
                        _("Could not create directory '%s' for '%s': "),
                        gimp_file_get_utf8_name (dir),
                        gimp_file_get_utf8_name (file));
    }
  g_object_unref (dir);

  if (error && *error)
    return NULL;

162 163
  if (atomic)
    {
164 165 166
      output = G_OUTPUT_STREAM (g_file_replace (file,
                                                NULL, FALSE, G_FILE_CREATE_NONE,
                                                NULL, error));
167
      if (! output)
168 169 170
        g_prefix_error (error,
                        _("Could not create temporary file for '%s': "),
                        gimp_file_get_utf8_name (file));
171 172 173
    }
  else
    {
174 175
      output = G_OUTPUT_STREAM (g_file_replace (file,
                                                NULL, FALSE,
176
                                                G_FILE_CREATE_REPLACE_DESTINATION,
177
                                                NULL, error));
178
    }
179

180
  if (! output)
181
    return NULL;
182

183 184
  writer = g_slice_new0 (GimpConfigWriter);

185 186 187 188
  writer->ref_count = 1;
  writer->output    = output;
  writer->file      = g_object_ref (file);
  writer->buffer    = g_string_new (NULL);
189 190 191 192 193 194

  if (header)
    {
      gimp_config_writer_comment (writer, header);
      gimp_config_writer_linefeed (writer);
    }
195 196 197 198

  return writer;
}

199
/**
200
 * gimp_config_writer_new_from_stream:
201 202 203 204 205 206 207
 * @output: a #GOutputStream
 * @header: text to include as comment at the top of the file
 * @error: return location for errors
 *
 * Creates a new #GimpConfigWriter and sets it up to write to
 * @output.
 *
208
 * Returns: (nullable): a new #GimpConfigWriter or %NULL in case of an error
209
 *
210
 * Since: 2.10
211 212
 **/
GimpConfigWriter *
213 214 215
gimp_config_writer_new_from_stream (GOutputStream  *output,
                                    const gchar    *header,
                                    GError        **error)
216 217 218 219 220 221 222 223
{
  GimpConfigWriter *writer;

  g_return_val_if_fail (G_IS_OUTPUT_STREAM (output), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  writer = g_slice_new0 (GimpConfigWriter);

224 225 226
  writer->ref_count = 1;
  writer->output    = g_object_ref (output);
  writer->buffer    = g_string_new (NULL);
227 228 229 230 231 232 233 234 235 236

  if (header)
    {
      gimp_config_writer_comment (writer, header);
      gimp_config_writer_linefeed (writer);
    }

  return writer;
}

237
/**
238
 * gimp_config_writer_new_from_fd:
239 240
 * @fd:
 *
241
 * Returns: (nullable): a new #GimpConfigWriter or %NULL in case of an error
242
 *
243
 * Since: 2.4
244
 **/
245
GimpConfigWriter *
246
gimp_config_writer_new_from_fd (gint fd)
247 248 249 250 251
{
  GimpConfigWriter *writer;

  g_return_val_if_fail (fd > 0, NULL);

252
  writer = g_slice_new0 (GimpConfigWriter);
253

254 255
  writer->ref_count = 1;

256
#ifdef G_OS_WIN32
257
  writer->output = g_win32_output_stream_new ((gpointer) fd, FALSE);
258 259 260 261
#else
  writer->output = g_unix_output_stream_new (fd, FALSE);
#endif

262 263 264 265 266
  writer->buffer = g_string_new (NULL);

  return writer;
}

267
/**
268
 * gimp_config_writer_new_from_string:
269 270
 * @string:
 *
271
 * Returns: (nullable): a new #GimpConfigWriter or %NULL in case of an error
272
 *
273
 * Since: 2.4
274
 **/
275
GimpConfigWriter *
276
gimp_config_writer_new_from_string (GString *string)
277 278 279 280 281
{
  GimpConfigWriter *writer;

  g_return_val_if_fail (string != NULL, NULL);

282
  writer = g_slice_new0 (GimpConfigWriter);
283

284 285
  writer->ref_count = 1;
  writer->buffer    = string;
286 287 288 289

  return writer;
}

290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
/**
 * gimp_config_writer_ref:
 * @writer: #GimpConfigWriter to ref
 *
 * Adds a reference to a #GimpConfigWriter.
 *
 * Returns: the same @writer.
 *
 * Since: 3.0
 */
GimpConfigWriter *
gimp_config_writer_ref (GimpConfigWriter *writer)
{
  g_return_val_if_fail (writer != NULL, NULL);

  writer->ref_count++;

  return writer;
}

/**
 * gimp_config_writer_unref:
 * @writer: #GimpConfigWriter to unref
 *
 * Unref a #GimpConfigWriter. If the reference count drops to zero, the
315
 * writer is freed.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
 *
 * Note that at least one of the references has to be dropped using
 * gimp_config_writer_finish().
 *
 * Since: 3.0
 */
void
gimp_config_writer_unref (GimpConfigWriter *writer)
{
  g_return_if_fail (writer != NULL);

  writer->ref_count--;

  if (writer->ref_count < 1)
    {
      if (! writer->finished)
        {
          GError *error = NULL;

          g_printerr ("%s: dropping last reference via unref(), you should "
                      "call gimp_config_writer_finish()\n", G_STRFUNC);

          if (! gimp_config_writer_finish (writer, NULL, &error))
            {
              g_printerr ("%s: error on finishing writer: %s\n",
                          G_STRFUNC, error->message);
            }
        }
      else
        {
          g_slice_free (GimpConfigWriter, writer);
        }
    }
}

351 352 353 354 355 356 357 358 359 360
/**
 * gimp_config_writer_comment_mode:
 * @writer: a #GimpConfigWriter
 * @enable: %TRUE to enable comment mode, %FALSE to disable it
 *
 * This function toggles whether the @writer should create commented
 * or uncommented output. This feature is used to generate the
 * system-wide installed gimprc that documents the default settings.
 *
 * Since comments have to start at the beginning of a line, this
361
 * function will insert a newline if necessary.
362
 *
363
 * Since: 2.4
364
 **/
365 366 367 368 369
void
gimp_config_writer_comment_mode (GimpConfigWriter *writer,
                                 gboolean          enable)
{
  g_return_if_fail (writer != NULL);
370
  g_return_if_fail (writer->finished == FALSE);
371 372 373 374 375 376

  if (writer->error)
    return;

  enable = (enable ? TRUE : FALSE);

377 378
  if (writer->comment == enable)
    return;
379 380

  writer->comment = enable;
381 382 383 384 385 386 387 388

  if (enable)
    {
     if (writer->buffer->len == 0)
       g_string_append_len (writer->buffer, "# ", 2);
     else
       gimp_config_writer_newline (writer);
    }
389 390 391
}


392 393 394 395 396
/**
 * gimp_config_writer_open:
 * @writer: a #GimpConfigWriter
 * @name: name of the element to open
 *
397
 * This function writes the opening parenthesis followed by @name.
398 399
 * It also increases the indentation level and sets a mark that
 * can be used by gimp_config_writer_revert().
400
 *
401
 * Since: 2.4
402
 **/
403 404
void
gimp_config_writer_open (GimpConfigWriter *writer,
Sven Neumann's avatar
Sven Neumann committed
405
                         const gchar      *name)
406 407
{
  g_return_if_fail (writer != NULL);
408
  g_return_if_fail (writer->finished == FALSE);
409
  g_return_if_fail (name != NULL);
410 411 412 413 414 415 416 417

  if (writer->error)
    return;

  /* store the current buffer length so we can revert to this state */
  writer->marker = writer->buffer->len;

  if (writer->depth > 0)
418
    gimp_config_writer_newline (writer);
419 420 421 422 423 424

  writer->depth++;

  g_string_append_printf (writer->buffer, "(%s", name);
}

425 426 427 428 429 430 431 432
/**
 * gimp_config_writer_print:
 * @writer: a #GimpConfigWriter
 * @string: a string to write
 * @len: number of bytes from @string or -1 if @string is NUL-terminated.
 *
 * Appends a space followed by @string to the @writer. Note that string
 * must not contain any special characters that might need to be escaped.
433
 *
434
 * Since: 2.4
435
 **/
436 437
void
gimp_config_writer_print (GimpConfigWriter  *writer,
Sven Neumann's avatar
Sven Neumann committed
438 439
                          const gchar       *string,
                          gint               len)
440 441
{
  g_return_if_fail (writer != NULL);
442
  g_return_if_fail (writer->finished == FALSE);
443 444 445 446 447 448 449 450
  g_return_if_fail (len == 0 || string != NULL);

  if (writer->error)
    return;

  if (len < 0)
    len = strlen (string);

451 452 453 454 455
  if (len)
    {
      g_string_append_c (writer->buffer, ' ');
      g_string_append_len (writer->buffer, string, len);
    }
456 457
}

458 459 460 461
/**
 * gimp_config_writer_printf:
 * @writer: a #GimpConfigWriter
 * @format: a format string as described for g_strdup_printf().
462
 * @...: list of arguments according to @format
463 464
 *
 * A printf-like function for #GimpConfigWriter.
465
 *
466
 * Since: 2.4
467
 **/
468 469
void
gimp_config_writer_printf (GimpConfigWriter *writer,
Sven Neumann's avatar
Sven Neumann committed
470 471
                           const gchar      *format,
                           ...)
472 473 474 475 476
{
  gchar   *buffer;
  va_list  args;

  g_return_if_fail (writer != NULL);
477
  g_return_if_fail (writer->finished == FALSE);
478 479 480 481 482 483 484 485 486
  g_return_if_fail (format != NULL);

  if (writer->error)
    return;

  va_start (args, format);
  buffer = g_strdup_vprintf (format, args);
  va_end (args);

487
  g_string_append_c (writer->buffer, ' ');
488 489 490 491 492
  g_string_append (writer->buffer, buffer);

  g_free (buffer);
}

493 494 495 496 497 498 499
/**
 * gimp_config_writer_string:
 * @writer: a #GimpConfigWriter
 * @string: a NUL-terminated string
 *
 * Writes a string value to @writer. The @string is quoted and special
 * characters are escaped.
500
 *
501
 * Since: 2.4
502
 **/
503
void
504 505
gimp_config_writer_string (GimpConfigWriter *writer,
                           const gchar      *string)
506 507
{
  g_return_if_fail (writer != NULL);
508
  g_return_if_fail (writer->finished == FALSE);
509 510 511 512

  if (writer->error)
    return;

513 514
  g_string_append_c (writer->buffer, ' ');
  gimp_config_string_append_escaped (writer->buffer, string);
515 516
}

517 518
/**
 * gimp_config_writer_identifier:
519 520
 * @writer:     a #GimpConfigWriter
 * @identifier: a NUL-terminated string
521 522 523
 *
 * Writes an identifier to @writer. The @string is *not* quoted and special
 * characters are *not* escaped.
524
 *
525
 * Since: 2.4
526 527 528 529 530 531
 **/
void
gimp_config_writer_identifier (GimpConfigWriter *writer,
                               const gchar      *identifier)
{
  g_return_if_fail (writer != NULL);
532
  g_return_if_fail (writer->finished == FALSE);
533 534 535 536 537 538 539 540
  g_return_if_fail (identifier != NULL);

  if (writer->error)
    return;

  g_string_append_printf (writer->buffer, " %s", identifier);
}

541 542 543 544 545 546 547

/**
 * gimp_config_writer_data:
 * @writer: a #GimpConfigWriter
 * @length:
 * @data:
 *
548
 * Since: 2.4
549
 **/
550 551 552 553 554 555 556 557
void
gimp_config_writer_data (GimpConfigWriter *writer,
                         gint              length,
                         const guint8     *data)
{
  gint i;

  g_return_if_fail (writer != NULL);
558
  g_return_if_fail (writer->finished == FALSE);
559 560
  g_return_if_fail (length >= 0);
  g_return_if_fail (data != NULL || length == 0);
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577

  if (writer->error)
    return;

  g_string_append (writer->buffer, " \"");

  for (i = 0; i < length; i++)
    {
      if (g_ascii_isalpha (data[i]))
        g_string_append_c (writer->buffer, data[i]);
      else
        g_string_append_printf (writer->buffer, "\\%o", data[i]);
    }

  g_string_append (writer->buffer, "\"");
}

578 579 580 581 582 583 584
/**
 * gimp_config_writer_revert:
 * @writer: a #GimpConfigWriter
 *
 * Reverts all changes to @writer that were done since the last call
 * to gimp_config_writer_open(). This can only work if you didn't call
 * gimp_config_writer_close() yet.
585
 *
586
 * Since: 2.4
587
 **/
588 589 590 591
void
gimp_config_writer_revert (GimpConfigWriter *writer)
{
  g_return_if_fail (writer != NULL);
592
  g_return_if_fail (writer->finished == FALSE);
593 594 595 596

  if (writer->error)
    return;

597 598 599
  g_return_if_fail (writer->depth > 0);
  g_return_if_fail (writer->marker != -1);

600 601 602
  g_string_truncate (writer->buffer, writer->marker);

  writer->depth--;
603
  writer->marker = -1;
604 605
}

606 607 608 609 610
/**
 * gimp_config_writer_close:
 * @writer: a #GimpConfigWriter
 *
 * Closes an element opened with gimp_config_writer_open().
611
 *
612
 * Since: 2.4
613
 **/
614 615 616 617
void
gimp_config_writer_close (GimpConfigWriter *writer)
{
  g_return_if_fail (writer != NULL);
618
  g_return_if_fail (writer->finished == FALSE);
619 620 621 622

  if (writer->error)
    return;

623 624
  g_return_if_fail (writer->depth > 0);

625 626 627 628 629 630
  g_string_append_c (writer->buffer, ')');

  if (--writer->depth == 0)
    {
      g_string_append_c (writer->buffer, '\n');

631
      gimp_config_writer_flush (writer);
632 633 634
    }
}

635 636 637 638 639 640
/**
 * gimp_config_writer_finish:
 * @writer: a #GimpConfigWriter
 * @footer: text to include as comment at the bottom of the file
 * @error: return location for possible errors
 *
641 642 643 644 645 646 647
 * This function finishes the work of @writer and unrefs it
 * afterwards.  It closes all open elements, appends an optional
 * comment and releases all resources allocated by @writer.
 *
 * Using any function except gimp_config_writer_ref() or
 * gimp_config_writer_unref() after this function is forbidden
 * and will trigger warnings.
648
 *
649
 * Returns: %TRUE if everything could be successfully written,
650
 *          %FALSE otherwise
651
 *
652
 * Since: 2.4
653
 **/
654 655
gboolean
gimp_config_writer_finish (GimpConfigWriter  *writer,
Sven Neumann's avatar
Sven Neumann committed
656 657
                           const gchar       *footer,
                           GError           **error)
658 659 660 661
{
  gboolean success = TRUE;

  g_return_val_if_fail (writer != NULL, FALSE);
662
  g_return_val_if_fail (writer->finished == FALSE, FALSE);
663 664 665 666 667 668 669 670 671
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (writer->depth < 0)
    {
      g_warning ("gimp_config_writer_finish: depth < 0 !!");
    }
  else
    {
      while (writer->depth)
Sven Neumann's avatar
Sven Neumann committed
672
        gimp_config_writer_close (writer);
673 674 675 676 677 678 679 680
    }

  if (footer)
    {
      gimp_config_writer_linefeed (writer);
      gimp_config_writer_comment (writer, footer);
    }

681
  if (writer->output)
682
    {
683
      success = gimp_config_writer_close_output (writer, error);
684

685
      g_clear_object (&writer->file);
686

687
      g_string_free (writer->buffer, TRUE);
688
      writer->buffer = NULL;
689
    }
690

691 692
  if (writer->error)
    {
693 694 695 696 697
      if (error && *error == NULL)
        g_propagate_error (error, writer->error);
      else
        g_clear_error (&writer->error);

698
      success = FALSE;
699 700
    }

701 702 703
  writer->finished = TRUE;

  gimp_config_writer_unref (writer);
704

705 706 707 708 709 710 711
  return success;
}

void
gimp_config_writer_linefeed (GimpConfigWriter *writer)
{
  g_return_if_fail (writer != NULL);
712
  g_return_if_fail (writer->finished == FALSE);
713

714 715 716
  if (writer->error)
    return;

717
  if (writer->output && writer->buffer->len == 0 && !writer->comment)
718
    {
719 720 721
      GError *error = NULL;

      if (! g_output_stream_write_all (writer->output, "\n", 1,
722
                                       NULL, NULL, &error))
723 724 725
        {
          g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
                       _("Error writing to '%s': %s"),
726 727 728
                       writer->file ?
                       gimp_file_get_utf8_name (writer->file) : "output stream",
                       error->message);
729 730
          g_clear_error (&error);
        }
731 732 733
    }
  else
    {
734
      gimp_config_writer_newline (writer);
735
    }
736 737
}

738 739 740 741 742 743 744 745
/**
 * gimp_config_writer_comment:
 * @writer: a #GimpConfigWriter
 * @comment: the comment to write (ASCII only)
 *
 * Appends the @comment to @str and inserts linebreaks and hash-marks to
 * format it as a comment. Note that this function does not handle non-ASCII
 * characters.
746
 *
747
 * Since: 2.4
748
 **/
749 750
void
gimp_config_writer_comment (GimpConfigWriter *writer,
Sven Neumann's avatar
Sven Neumann committed
751
                            const gchar      *comment)
752
{
753
  const gchar *s;
754
  gboolean     comment_mode;
755 756 757 758
  gint         i, len, space;

#define LINE_LENGTH 75

759
  g_return_if_fail (writer != NULL);
760
  g_return_if_fail (writer->finished == FALSE);
761 762 763 764

  if (writer->error)
    return;

765 766
  g_return_if_fail (writer->depth == 0);

767 768 769
  if (!comment)
    return;

770 771
  comment_mode = writer->comment;
  gimp_config_writer_comment_mode (writer, TRUE);
772

773
  len = strlen (comment);
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793

  while (len > 0)
    {
      for (s = comment, i = 0, space = 0;
           *s != '\n' && (i <= LINE_LENGTH || space == 0) && i < len;
           s++, i++)
        {
          if (g_ascii_isspace (*s))
            space = i;
        }

      if (i > LINE_LENGTH && space && *s != '\n')
        i = space;

      g_string_append_len (writer->buffer, comment, i);

      i++;

      comment += i;
      len     -= i;
794 795 796

      if (len > 0)
        gimp_config_writer_newline (writer);
797 798
    }

799 800
  gimp_config_writer_comment_mode (writer, comment_mode);
  gimp_config_writer_newline (writer);
801

802 803 804 805 806 807
  if (writer->depth == 0)
    gimp_config_writer_flush (writer);

#undef LINE_LENGTH
}

808
static gboolean
809 810
gimp_config_writer_close_output (GimpConfigWriter  *writer,
                                 GError           **error)
811
{
812 813
  g_return_val_if_fail (writer->output != NULL, FALSE);

814 815
  if (writer->error)
    {
816 817 818 819 820 821 822
      GCancellable *cancellable = g_cancellable_new ();

      /* Cancel the overwrite initiated by g_file_replace(). */
      g_cancellable_cancel (cancellable);
      g_output_stream_close (writer->output, cancellable, NULL);
      g_object_unref (cancellable);

823
      g_clear_object (&writer->output);
824

825
      return FALSE;
826 827
    }

828
  if (writer->file)
Sven Neumann's avatar
Sven Neumann committed
829
    {
830
      GError *my_error = NULL;
Sven Neumann's avatar
Sven Neumann committed
831

832 833 834 835 836 837 838
      if (! g_output_stream_close (writer->output, NULL, &my_error))
        {
          g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
                       _("Error writing '%s': %s"),
                       gimp_file_get_utf8_name (writer->file),
                       my_error->message);
          g_clear_error (&my_error);
839

840
          g_clear_object (&writer->output);
841 842 843

          return FALSE;
        }
844 845
    }

846
  g_clear_object (&writer->output);
847 848 849

  return TRUE;
}