~ubuntu-branches/ubuntu/precise/gedit/precise

« back to all changes in this revision

Viewing changes to gedit/gedit-gio-document-saver.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-04-14 16:41:13 UTC
  • mfrom: (1.1.78 upstream)
  • Revision ID: james.westby@ubuntu.com-20100414164113-0xgl3u73pcs0ngbc
Tags: 2.30.0git20100413-0ubuntu1
* Updating to git snaptshot since 2.30.1 will be after lucid
* debian/patches/90_autoconf.patch:
  - new version update

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
        gboolean               tried_mount;
52
52
        gssize                 written;
53
53
        gssize                 read;
 
54
        GError                *error;
54
55
} AsyncData;
55
56
 
56
57
#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
132
133
        async = g_slice_new (AsyncData);
133
134
        async->saver = gvsaver;
134
135
        async->cancellable = g_object_ref (gvsaver->priv->cancellable);
 
136
 
135
137
        async->tried_mount = FALSE;
136
138
        async->written = 0;
137
139
        async->read = 0;
138
 
        
 
140
 
 
141
        async->error = NULL;
 
142
 
139
143
        return async;
140
144
}
141
145
 
143
147
async_data_free (AsyncData *async)
144
148
{
145
149
        g_object_unref (async->cancellable);
 
150
 
 
151
        if (async->error)
 
152
        {
 
153
                g_error_free (async->error);
 
154
        }
 
155
 
146
156
        g_slice_free (AsyncData, async);
147
157
}
148
158
 
187
197
              GError    *error)
188
198
{
189
199
        g_propagate_error (&async->saver->priv->error, error);
190
 
        
191
200
        remote_save_completed_or_failed (async->saver, async);
192
201
}
193
202
 
 
203
/* BEGIN NOTE:
 
204
 *
 
205
 * This fixes an issue in GOutputStream that applies the atomic replace
 
206
 * save strategy. The stream moves the written file to the original file
 
207
 * when the stream is closed. However, there is no way currently to tell
 
208
 * the stream that the save should be aborted (there could be a
 
209
 * conversion error). The patch explicitly closes the output stream
 
210
 * in all these cases with a GCancellable in the cancelled state, causing
 
211
 * the output stream to close, but not move the file. This makes use
 
212
 * of an implementation detail in the local gio file stream and should be
 
213
 * properly fixed by adding the appropriate API in gio. Until then, at least
 
214
 * we prevent data corruption for now.
 
215
 *
 
216
 * Relevant bug reports:
 
217
 *
 
218
 * Bug 615110 - write file ignore encoding errors (gedit)
 
219
 * https://bugzilla.gnome.org/show_bug.cgi?id=615110
 
220
 *
 
221
 * Bug 602412 - g_file_replace does not restore original file when there is
 
222
 *              errors while writing (glib/gio)
 
223
 * https://bugzilla.gnome.org/show_bug.cgi?id=602412
 
224
 */
 
225
static void
 
226
cancel_output_stream_ready_cb (GOutputStream *stream,
 
227
                               GAsyncResult  *result,
 
228
                               AsyncData     *async)
 
229
{
 
230
        GError *error;
 
231
 
 
232
        g_output_stream_close_finish (stream, result, NULL);
 
233
 
 
234
        /* check cancelled state manually */
 
235
        if (g_cancellable_is_cancelled (async->cancellable) || async->error == NULL)
 
236
        {
 
237
                async_data_free (async);
 
238
                return;
 
239
        }
 
240
 
 
241
        error = async->error;
 
242
        async->error = NULL;
 
243
 
 
244
        async_failed (async, error);
 
245
}
 
246
 
 
247
static void
 
248
cancel_output_stream (AsyncData *async)
 
249
{
 
250
        GCancellable *cancellable;
 
251
 
 
252
        gedit_debug_message (DEBUG_SAVER, "Cancel output stream");
 
253
 
 
254
        cancellable = g_cancellable_new ();
 
255
        g_cancellable_cancel (cancellable);
 
256
 
 
257
        g_output_stream_close_async (async->saver->priv->stream,
 
258
                                     G_PRIORITY_HIGH,
 
259
                                     cancellable,
 
260
                                     (GAsyncReadyCallback)cancel_output_stream_ready_cb,
 
261
                                     async);
 
262
 
 
263
        g_object_unref (cancellable);
 
264
}
 
265
 
 
266
static void
 
267
cancel_output_stream_and_fail (AsyncData *async,
 
268
                               GError    *error)
 
269
{
 
270
 
 
271
        gedit_debug_message (DEBUG_SAVER, "Cancel output stream and fail");
 
272
 
 
273
        g_propagate_error (&async->error, error);
 
274
        cancel_output_stream (async);
 
275
}
 
276
 
 
277
/*
 
278
 * END NOTE
 
279
 */
 
280
 
194
281
static void
195
282
remote_get_info_cb (GFile        *source,
196
283
                    GAsyncResult *res,
283
370
                                   async->cancellable, &error))
284
371
        {
285
372
                gedit_debug_message (DEBUG_SAVER, "Closing input stream error: %s", error->message);
286
 
                async_failed (async, error);
 
373
                cancel_output_stream_and_fail (async, error);
287
374
                return;
288
375
        }
289
376
 
314
401
        /* Check cancelled state manually */
315
402
        if (g_cancellable_is_cancelled (async->cancellable))
316
403
        {
317
 
                async_data_free (async);
 
404
                cancel_output_stream (async);
318
405
                return;
319
406
        }
320
407
 
325
412
        if (bytes_written == -1)
326
413
        {
327
414
                gedit_debug_message (DEBUG_SAVER, "Write error: %s", error->message);
328
 
                async_failed (async, error);
 
415
                cancel_output_stream_and_fail (async, error);
329
416
                return;
330
417
        }
331
418
 
389
476
 
390
477
        if (error != NULL)
391
478
        {
392
 
                async_failed (async, error);
 
479
                cancel_output_stream_and_fail (async, error);
393
480
                return;
394
481
        }
395
482