giochannel.c 78.4 KB
Newer Older
1
2
3
4
5
6
7
/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * giochannel.c: IO Channel abstraction
 * Copyright 1998 Owen Taylor
 *
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
10
11
12
13
14
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
19
20
21
22
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

23
/*
24
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
25
26
27
28
29
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

30
31
32
33
/* 
 * MT safe
 */

34
35
#include "config.h"

36
37
#include <string.h>
#include <errno.h>
38
39

#ifdef HAVE_UNISTD_H
40
#include <unistd.h>
41
#endif
42

43
44
45
46
#undef G_DISABLE_DEPRECATED

#include "glib.h"

47
48
#include "giochannel.h"

49
50
#include "glibintl.h"

51
52
#include "galias.h"

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
 * SECTION: iochannels
 * @title: IO Channels
 * @short_description: portable support for using files, pipes and
 *                     sockets
 * @see_also: <para> <variablelist> <varlistentry>
 *            <term>gtk_input_add_full(), gtk_input_remove(),
 *            gdk_input_add(), gdk_input_add_full(),
 *            gdk_input_remove()</term> <listitem><para> Convenience
 *            functions for creating #GIOChannel instances and adding
 *            them to the <link linkend="glib-The-Main-Event-Loop">main
 *            event loop</link>. </para></listitem> </varlistentry>
 *            </variablelist> </para>
 *
 * The #GIOChannel data type aims to provide a portable method for
 * using file descriptors, pipes, and sockets, and integrating them
 * into the <link linkend="glib-The-Main-Event-Loop">main event
 * loop</link>. Currently full support is available on UNIX platforms,
 * support for Windows is only partially complete.
 *
 * To create a new #GIOChannel on UNIX systems use
 * g_io_channel_unix_new(). This works for plain file descriptors,
 * pipes and sockets. Alternatively, a channel can be created for a
 * file in a system independent manner using g_io_channel_new_file().
 *
 * Once a #GIOChannel has been created, it can be used in a generic
 * manner with the functions g_io_channel_read_chars(),
 * g_io_channel_write_chars(), g_io_channel_seek_position(), and
 * g_io_channel_shutdown().
 *
 * To add a #GIOChannel to the <link
 * linkend="glib-The-Main-Event-Loop">main event loop</link> use
 * g_io_add_watch() or g_io_add_watch_full(). Here you specify which
 * events you are interested in on the #GIOChannel, and provide a
 * function to be called whenever these events occur.
 *
 * #GIOChannel instances are created with an initial reference count of
 * 1. g_io_channel_ref() and g_io_channel_unref() can be used to
 * increment or decrement the reference count respectively. When the
 * reference count falls to 0, the #GIOChannel is freed. (Though it
 * isn't closed automatically, unless it was created using
 * g_io_channel_new_from_file().) Using g_io_add_watch() or
 * g_io_add_watch_full() increments a channel's reference count.
 *
 * The new functions g_io_channel_read_chars(),
 * g_io_channel_read_line(), g_io_channel_read_line_string(),
 * g_io_channel_read_to_end(), g_io_channel_write_chars(),
 * g_io_channel_seek_position(), and g_io_channel_flush() should not be
 * mixed with the deprecated functions g_io_channel_read(),
 * g_io_channel_write(), and g_io_channel_seek() on the same channel.
 **/

/**
 * GIOChannel:
 *
 * A data structure representing an IO Channel. The fields should be
 * considered private and should only be accessed with the following
 * functions.
 **/

/**
 * GIOFuncs:
 * @io_read: reads raw bytes from the channel.  This is called from
 *           various functions such as g_io_channel_read_chars() to
 *           read raw bytes from the channel.  Encoding and buffering
 *           issues are dealt with at a higher level.
 * @io_write: writes raw bytes to the channel.  This is called from
 *            various functions such as g_io_channel_write_chars() to
 *            write raw bytes to the channel.  Encoding and buffering
 *            issues are dealt with at a higher level.
 * @io_seek: (optional) seeks the channel.  This is called from
 *           g_io_channel_seek() on channels that support it.
 * @io_close: closes the channel.  This is called from
 *            g_io_channel_close() after flushing the buffers.
 * @io_create_watch: creates a watch on the channel.  This call
 *                   corresponds directly to g_io_create_watch().
 * @io_free: called from g_io_channel_unref() when the channel needs to
 *           be freed.  This function must free the memory associated
 *           with the channel, including freeing the #GIOChannel
 *           structure itself.  The channel buffers have been flushed
 *           and possibly @io_close has been called by the time this
 *           function is called.
 * @io_set_flags: sets the #GIOFlags on the channel.  This is called
 *                from g_io_channel_set_flags() with all flags except
 *                for %G_IO_FLAG_APPEND and %G_IO_FLAG_NONBLOCK masked
 *                out.
 * @io_get_flags: gets the #GIOFlags for the channel.  This function
 *                need only return the %G_IO_FLAG_APPEND and
 *                %G_IO_FLAG_NONBLOCK flags; g_io_channel_get_flags()
 *                automatically adds the others as appropriate.
 *
 * A table of functions used to handle different types of #GIOChannel
 * in a generic way.
 **/

/**
 * GIOStatus:
 * @G_IO_STATUS_ERROR: An error occurred.
 * @G_IO_STATUS_NORMAL: Success.
 * @G_IO_STATUS_EOF: End of file.
 * @G_IO_STATUS_AGAIN: Resource temporarily unavailable.
 *
 * Stati returned by most of the #GIOFuncs functions.
 **/

/**
 * GIOError:
 * @G_IO_ERROR_NONE: no error
 * @G_IO_ERROR_AGAIN: an EAGAIN error occurred
 * @G_IO_ERROR_INVAL: an EINVAL error occurred
 * @G_IO_ERROR_UNKNOWN: another error occurred
 *
 * #GIOError is only used by the deprecated functions
 * g_io_channel_read(), g_io_channel_write(), and g_io_channel_seek().
 **/

169
170
#define G_IO_NICE_BUF_SIZE	1024

171
172
173
174
175
176
177
178
179
180
181
/* This needs to be as wide as the largest character in any possible encoding */
#define MAX_CHAR_SIZE		10

/* Some simplifying macros, which reduce the need to worry whether the
 * buffers have been allocated. These also make USE_BUF () an lvalue,
 * which is used in g_io_channel_read_to_end ().
 */
#define USE_BUF(channel)	((channel)->encoding ? (channel)->encoded_read_buf \
				 : (channel)->read_buf)
#define BUF_LEN(string)		((string) ? (string)->len : 0)

182
static GIOError		g_io_error_get_from_g_error	(GIOStatus    status,
183
184
185
186
							 GError      *err);
static void		g_io_channel_purge		(GIOChannel  *channel);
static GIOStatus	g_io_channel_fill_buffer	(GIOChannel  *channel,
							 GError     **err);
187
188
189
190
static GIOStatus	g_io_channel_read_line_backend	(GIOChannel  *channel,
							 gsize       *length,
							 gsize       *terminator_pos,
							 GError     **error);
191

Matthias Clasen's avatar
Matthias Clasen committed
192
193
194
195
196
197
198
199
200
201
/**
 * g_io_channel_init:
 * @channel: a #GIOChannel
 *
 * Initializes a #GIOChannel struct. 
 *
 * This is called by each of the above functions when creating a 
 * #GIOChannel, and so is not often needed by the application 
 * programmer (unless you are creating a new type of #GIOChannel).
 */
202
203
void
g_io_channel_init (GIOChannel *channel)
204
{
205
  channel->ref_count = 1;
206
  channel->encoding = g_strdup ("UTF-8");
207
  channel->line_term = NULL;
208
  channel->line_term_len = 0;
209
  channel->buf_size = G_IO_NICE_BUF_SIZE;
210
211
212
213
214
215
  channel->read_cd = (GIConv) -1;
  channel->write_cd = (GIConv) -1;
  channel->read_buf = NULL; /* Lazy allocate buffers */
  channel->encoded_read_buf = NULL;
  channel->write_buf = NULL;
  channel->partial_write_buf[0] = '\0';
216
217
218
  channel->use_buffer = TRUE;
  channel->do_encode = FALSE;
  channel->close_on_unref = FALSE;
219
220
}

Matthias Clasen's avatar
Matthias Clasen committed
221
222
223
224
225
226
227
228
/**
 * g_io_channel_ref:
 * @channel: a #GIOChannel
 *
 * Increments the reference count of a #GIOChannel.
 *
 * Returns: the @channel that was passed in (since 2.6)
 */
229
GIOChannel *
230
231
g_io_channel_ref (GIOChannel *channel)
{
232
  g_return_val_if_fail (channel != NULL, NULL);
233

234
  g_atomic_int_inc (&channel->ref_count);
235
236

  return channel;
237
238
}

Matthias Clasen's avatar
Matthias Clasen committed
239
240
241
242
243
244
/**
 * g_io_channel_unref:
 * @channel: a #GIOChannel
 *
 * Decrements the reference count of a #GIOChannel.
 */
245
246
247
void 
g_io_channel_unref (GIOChannel *channel)
{
248
249
  gboolean is_zero;

250
251
  g_return_if_fail (channel != NULL);

252
253
254
  is_zero = g_atomic_int_dec_and_test (&channel->ref_count);

  if (G_UNLIKELY (is_zero))
255
256
    {
      if (channel->close_on_unref)
257
        g_io_channel_shutdown (channel, TRUE, NULL);
258
259
260
      else
        g_io_channel_purge (channel);
      g_free (channel->encoding);
261
262
263
264
      if (channel->read_cd != (GIConv) -1)
        g_iconv_close (channel->read_cd);
      if (channel->write_cd != (GIConv) -1)
        g_iconv_close (channel->write_cd);
Matthias Clasen's avatar
Matthias Clasen committed
265
      g_free (channel->line_term);
266
267
268
269
270
271
      if (channel->read_buf)
        g_string_free (channel->read_buf, TRUE);
      if (channel->write_buf)
        g_string_free (channel->write_buf, TRUE);
      if (channel->encoded_read_buf)
        g_string_free (channel->encoded_read_buf, TRUE);
272
273
      channel->funcs->io_free (channel);
    }
274
275
}

276
static GIOError
277
278
g_io_error_get_from_g_error (GIOStatus  status,
			     GError    *err)
279
280
281
282
283
284
285
286
287
{
  switch (status)
    {
      case G_IO_STATUS_NORMAL:
      case G_IO_STATUS_EOF:
        return G_IO_ERROR_NONE;
      case G_IO_STATUS_AGAIN:
        return G_IO_ERROR_AGAIN;
      case G_IO_STATUS_ERROR:
288
289
	g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN);
	
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
        if (err->domain != G_IO_CHANNEL_ERROR)
          return G_IO_ERROR_UNKNOWN;
        switch (err->code)
          {
            case G_IO_CHANNEL_ERROR_INVAL:
              return G_IO_ERROR_INVAL;
            default:
              return G_IO_ERROR_UNKNOWN;
          }
      default:
        g_assert_not_reached ();
    }
}

/**
 * g_io_channel_read:
306
307
308
309
310
 * @channel: a #GIOChannel
 * @buf: a buffer to read the data into (which should be at least 
 *       count bytes long)
 * @count: the number of bytes to read from the #GIOChannel
 * @bytes_read: returns the number of bytes actually read
311
 * 
312
 * Reads data from a #GIOChannel. 
313
314
 * 
 * Return value: %G_IO_ERROR_NONE if the operation was successful. 
315
 *
316
 * Deprecated:2.2: Use g_io_channel_read_chars() instead.
317
 **/
318
319
320
GIOError 
g_io_channel_read (GIOChannel *channel, 
		   gchar      *buf, 
321
322
		   gsize       count,
		   gsize      *bytes_read)
323
{
324
325
326
327
  GError *err = NULL;
  GIOError error;
  GIOStatus status;

328
  g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
329
330
  g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN);

331
332
333
334
  if (count == 0)
    {
      if (bytes_read)
        *bytes_read = 0;
335
      return G_IO_ERROR_NONE;
336
337
338
339
    }

  g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN);

340
  status = channel->funcs->io_read (channel, buf, count, bytes_read, &err);
341

342
343
344
345
346
347
  error = g_io_error_get_from_g_error (status, err);

  if (err)
    g_error_free (err);

  return error;
348
349
}

350
351
/**
 * g_io_channel_write:
352
353
354
355
 * @channel:  a #GIOChannel
 * @buf: the buffer containing the data to write
 * @count: the number of bytes to write
 * @bytes_written: the number of bytes actually written
356
 * 
357
 * Writes data to a #GIOChannel. 
358
359
 * 
 * Return value:  %G_IO_ERROR_NONE if the operation was successful.
360
 *
361
 * Deprecated:2.2: Use g_io_channel_write_chars() instead.
362
 **/
363
GIOError 
364
365
366
367
g_io_channel_write (GIOChannel  *channel, 
		    const gchar *buf, 
		    gsize        count,
		    gsize       *bytes_written)
368
{
369
370
371
372
  GError *err = NULL;
  GIOError error;
  GIOStatus status;

373
  g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
374
375
376
377
378
  g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN);

  status = channel->funcs->io_write (channel, buf, count, bytes_written, &err);

  error = g_io_error_get_from_g_error (status, err);
379

380
381
382
383
  if (err)
    g_error_free (err);

  return error;
384
385
}

386
387
/**
 * g_io_channel_seek:
388
389
390
 * @channel: a #GIOChannel
 * @offset: an offset, in bytes, which is added to the position specified 
 *          by @type
391
 * @type: the position in the file, which can be %G_SEEK_CUR (the current
392
393
 *        position), %G_SEEK_SET (the start of the file), or %G_SEEK_END 
 *        (the end of the file)
394
 * 
395
396
 * Sets the current position in the #GIOChannel, similar to the standard 
 * library function fseek(). 
397
398
 * 
 * Return value: %G_IO_ERROR_NONE if the operation was successful.
399
 *
400
 * Deprecated:2.2: Use g_io_channel_seek_position() instead.
401
 **/
402
GIOError 
403
404
405
g_io_channel_seek (GIOChannel *channel,
		   gint64      offset, 
		   GSeekType   type)
406
{
407
408
409
410
  GError *err = NULL;
  GIOError error;
  GIOStatus status;

411
  g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
412
  g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN);
413

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
  switch (type)
    {
      case G_SEEK_CUR:
      case G_SEEK_SET:
      case G_SEEK_END:
        break;
      default:
        g_warning ("g_io_channel_seek: unknown seek type");
        return G_IO_ERROR_UNKNOWN;
    }

  status = channel->funcs->io_seek (channel, offset, type, &err);

  error = g_io_error_get_from_g_error (status, err);

  if (err)
    g_error_free (err);

  return error;
433
}
434
435
436
437
438
439
440

/* The function g_io_channel_new_file() is prototyped in both
 * giounix.c and giowin32.c, so we stick its documentation here.
 */

/**
 * g_io_channel_new_file:
441
 * @filename: A string containing the name of a file
442
 * @mode: One of "r", "w", "a", "r+", "w+", "a+". These have
443
444
 *        the same meaning as in fopen()
 * @error: A location to return an error of type %G_FILE_ERROR
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
 *
 * Open a file @filename as a #GIOChannel using mode @mode. This
 * channel will be closed when the last reference to it is dropped,
 * so there is no need to call g_io_channel_close() (though doing
 * so will not cause problems, as long as no attempt is made to
 * access the channel after it is closed).
 *
 * Return value: A #GIOChannel on success, %NULL on failure.
 **/

/**
 * g_io_channel_close:
 * @channel: A #GIOChannel
 * 
 * Close an IO channel. Any pending data to be written will be
 * flushed, ignoring errors. The channel will not be freed until the
461
462
 * last reference is dropped using g_io_channel_unref(). 
 *
463
 * Deprecated:2.2: Use g_io_channel_shutdown() instead.
464
 **/
465
466
467
void
g_io_channel_close (GIOChannel *channel)
{
468
469
  GError *err = NULL;
  
470
471
  g_return_if_fail (channel != NULL);

472
473
474
475
476
477
478
479
480
481
482
  g_io_channel_purge (channel);

  channel->funcs->io_close (channel, &err);

  if (err)
    { /* No way to return the error */
      g_warning ("Error closing channel: %s", err->message);
      g_error_free (err);
    }
  
  channel->close_on_unref = FALSE; /* Because we already did */
483
484
485
  channel->is_readable = FALSE;
  channel->is_writeable = FALSE;
  channel->is_seekable = FALSE;
486
487
488
489
490
491
492
493
494
}

/**
 * g_io_channel_shutdown:
 * @channel: a #GIOChannel
 * @flush: if %TRUE, flush pending
 * @err: location to store a #GIOChannelError
 * 
 * Close an IO channel. Any pending data to be written will be
495
 * flushed if @flush is %TRUE. The channel will not be freed until the
496
 * last reference is dropped using g_io_channel_unref().
497
 *
498
 * Return value: the status of the operation.
499
500
 **/
GIOStatus
501
502
503
g_io_channel_shutdown (GIOChannel  *channel,
		       gboolean     flush,
		       GError     **err)
504
{
505
506
  GIOStatus status, result;
  GError *tmperr = NULL;
507
508
  
  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
509
  g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR);
510

511
  if (channel->write_buf && channel->write_buf->len > 0)
512
    {
513
514
515
      if (flush)
        {
          GIOFlags flags;
516
      
517
518
519
520
521
          /* Set the channel to blocking, to avoid a busy loop
           */
          flags = g_io_channel_get_flags (channel);
          /* Ignore any errors here, they're irrelevant */
          g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
522

523
          result = g_io_channel_flush (channel, &tmperr);
524
        }
525
526
527
528
      else
        result = G_IO_STATUS_NORMAL;

      g_string_truncate(channel->write_buf, 0);
529
    }
530
531
  else
    result = G_IO_STATUS_NORMAL;
532

533
534
535
536
537
538
539
  if (channel->partial_write_buf[0] != '\0')
    {
      if (flush)
        g_warning ("Partial character at end of write buffer not flushed.\n");
      channel->partial_write_buf[0] = '\0';
    }

540
  status = channel->funcs->io_close (channel, err);
541
542

  channel->close_on_unref = FALSE; /* Because we already did */
543
544
545
  channel->is_readable = FALSE;
  channel->is_writeable = FALSE;
  channel->is_seekable = FALSE;
546

547
548
549
550
551
552
553
554
555
556
557
558
  if (status != G_IO_STATUS_NORMAL)
    {
      g_clear_error (&tmperr);
      return status;
    }
  else if (result != G_IO_STATUS_NORMAL)
    {
      g_propagate_error (err, tmperr);
      return result;
    }
  else
    return G_IO_STATUS_NORMAL;
559
560
561
562
563
564
565
}

/* This function is used for the final flush on close or unref */
static void
g_io_channel_purge (GIOChannel *channel)
{
  GError *err = NULL;
566
  GIOStatus status;
567
568
569

  g_return_if_fail (channel != NULL);

570
  if (channel->write_buf && channel->write_buf->len > 0)
571
572
573
574
575
576
577
578
    {
      GIOFlags flags;
      
      /* Set the channel to blocking, to avoid a busy loop
       */
      flags = g_io_channel_get_flags (channel);
      g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);

579
      status = g_io_channel_flush (channel, &err);
580
581
582
583
584
585
586
587
588
589

      if (err)
	{ /* No way to return the error */
	  g_warning ("Error flushing string: %s", err->message);
	  g_error_free (err);
	}
    }

  /* Flush these in case anyone tries to close without unrefing */

590
591
592
593
  if (channel->read_buf)
    g_string_truncate (channel->read_buf, 0);
  if (channel->write_buf)
    g_string_truncate (channel->write_buf, 0);
594
  if (channel->encoding)
595
596
597
598
599
600
601
602
603
604
    {
      if (channel->encoded_read_buf)
        g_string_truncate (channel->encoded_read_buf, 0);

      if (channel->partial_write_buf[0] != '\0')
        {
          g_warning ("Partial character at end of write buffer not flushed.\n");
          channel->partial_write_buf[0] = '\0';
        }
    }
605
606
}

Matthias Clasen's avatar
Matthias Clasen committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
/**
 * g_io_create_watch:
 * @channel: a #GIOChannel to watch
 * @condition: conditions to watch for
 *
 * Creates a #GSource that's dispatched when @condition is met for the 
 * given @channel. For example, if condition is #G_IO_IN, the source will 
 * be dispatched when there's data available for reading.
 *
 * g_io_add_watch() is a simpler interface to this same functionality, for 
 * the case where you want to add the source to the default main loop context 
 * at the default priority.
 *
 * On Windows, polling a #GSource created to watch a channel for a socket
 * puts the socket in non-blocking mode. This is a side-effect of the
 * implementation and unavoidable.
 *
 * Returns: a new #GSource
 */
626
GSource *
627
628
g_io_create_watch (GIOChannel   *channel,
		   GIOCondition  condition)
629
630
631
632
633
634
{
  g_return_val_if_fail (channel != NULL, NULL);

  return channel->funcs->io_create_watch (channel, condition);
}

Matthias Clasen's avatar
Matthias Clasen committed
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
/**
 * g_io_add_watch_full:
 * @channel: a #GIOChannel
 * @priority: the priority of the #GIOChannel source
 * @condition: the condition to watch for
 * @func: the function to call when the condition is satisfied
 * @user_data: user data to pass to @func
 * @notify: the function to call when the source is removed
 *
 * Adds the #GIOChannel into the default main loop context
 * with the given priority.
 *
 * This internally creates a main loop source using g_io_create_watch()
 * and attaches it to the main loop context with g_source_attach().
 * You can do these steps manuallt if you need greater control.
 *
 * Returns: the event source id
 */
653
guint 
654
g_io_add_watch_full (GIOChannel    *channel,
655
656
657
658
659
660
		     gint           priority,
		     GIOCondition   condition,
		     GIOFunc        func,
		     gpointer       user_data,
		     GDestroyNotify notify)
{
661
  GSource *source;
662
  guint id;
663
  
664
665
  g_return_val_if_fail (channel != NULL, 0);

666
667
668
669
670
671
  source = g_io_create_watch (channel, condition);

  if (priority != G_PRIORITY_DEFAULT)
    g_source_set_priority (source, priority);
  g_source_set_callback (source, (GSourceFunc)func, user_data, notify);

672
673
674
675
  id = g_source_attach (source, NULL);
  g_source_unref (source);

  return id;
676
677
}

Matthias Clasen's avatar
Matthias Clasen committed
678
679
680
681
682
683
684
685
686
687
688
689
/**
 * g_io_add_watch:
 * @channel: a #GIOChannel
 * @condition: the condition to watch for
 * @func: the function to call when the condition is satisfied
 * @user_data: user data to pass to @func
 *
 * Adds the #GIOChannel into the default main loop context
 * with the default priority.
 *
 * Returns: the event source id
 */
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
/**
 * GIOFunc:
 * @source: the #GIOChannel event source
 * @condition: the condition which has been satisfied
 * @data: user data set in g_io_add_watch() or g_io_add_watch_full()
 * @Returns: the function should return %FALSE if the event source
 *           should be removed
 *
 * Specifies the type of function passed to g_io_add_watch() or
 * g_io_add_watch_full(), which is called when the requested condition
 * on a #GIOChannel is satisfied.
 **/
/**
 * GIOCondition:
 * @G_IO_IN: There is data to read.
 * @G_IO_OUT: Data can be written (without blocking).
 * @G_IO_PRI: There is urgent data to read.
 * @G_IO_ERR: Error condition.
 * @G_IO_HUP: Hung up (the connection has been broken, usually for
 *            pipes and sockets).
 * @G_IO_NVAL: Invalid request. The file descriptor is not open.
 *
 * A bitwise combination representing a condition to watch for on an
 * event source.
 **/
715
guint 
716
717
718
719
g_io_add_watch (GIOChannel   *channel,
		GIOCondition  condition,
		GIOFunc       func,
		gpointer      user_data)
720
{
721
  return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL);
722
}
723
724
725
726
727

/**
 * g_io_channel_get_buffer_condition:
 * @channel: A #GIOChannel
 *
728
 * This function returns a #GIOCondition depending on whether there
729
730
 * is data to be read/space to write data in the internal buffers in 
 * the #GIOChannel. Only the flags %G_IO_IN and %G_IO_OUT may be set.
731
732
733
734
735
736
 *
 * Return value: A #GIOCondition
 **/
GIOCondition
g_io_channel_get_buffer_condition (GIOChannel *channel)
{
737
738
  GIOCondition condition = 0;

739
740
741
742
743
744
745
746
747
748
  if (channel->encoding)
    {
      if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0))
        condition |= G_IO_IN; /* Only return if we have full characters */
    }
  else
    {
      if (channel->read_buf && (channel->read_buf->len > 0))
        condition |= G_IO_IN;
    }
749
750

  if (channel->write_buf && (channel->write_buf->len < channel->buf_size))
751
    condition |= G_IO_OUT;
752
753

  return condition;
754
755
756
}

/**
757
 * g_io_channel_error_from_errno:
758
 * @en: an <literal>errno</literal> error number, e.g. %EINVAL
759
 *
760
761
 * Converts an <literal>errno</literal> error number to a #GIOChannelError.
 *
762
763
 * Return value: a #GIOChannelError error number, e.g. 
 *      %G_IO_CHANNEL_ERROR_INVAL.
764
765
 **/
GIOChannelError
766
g_io_channel_error_from_errno (gint en)
767
768
769
770
771
772
773
774
775
{
#ifdef EAGAIN
  g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED);
#endif

  switch (en)
    {
#ifdef EBADF
    case EBADF:
776
777
      g_warning("Invalid file descriptor.\n");
      return G_IO_CHANNEL_ERROR_FAILED;
778
779
780
781
#endif

#ifdef EFAULT
    case EFAULT:
782
      g_warning("Buffer outside valid address space.\n");
783
784
785
786
787
788
      return G_IO_CHANNEL_ERROR_FAILED;
#endif

#ifdef EFBIG
    case EFBIG:
      return G_IO_CHANNEL_ERROR_FBIG;
789
790
#endif

791
792
793
794
795
796
797
798
799
800
801
802
#ifdef EINTR
    /* In general, we should catch EINTR before we get here,
     * but close() is allowed to return EINTR by POSIX, so
     * we need to catch it here; EINTR from close() is
     * unrecoverable, because it's undefined whether
     * the fd was actually closed or not, so we just return
     * a generic error code.
     */
    case EINTR:
      return G_IO_CHANNEL_ERROR_FAILED;
#endif

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
#ifdef EINVAL
    case EINVAL:
      return G_IO_CHANNEL_ERROR_INVAL;
#endif

#ifdef EIO
    case EIO:
      return G_IO_CHANNEL_ERROR_IO;
#endif

#ifdef EISDIR
    case EISDIR:
      return G_IO_CHANNEL_ERROR_ISDIR;
#endif

#ifdef ENOSPC
    case ENOSPC:
      return G_IO_CHANNEL_ERROR_NOSPC;
#endif

823
824
825
#ifdef ENXIO
    case ENXIO:
      return G_IO_CHANNEL_ERROR_NXIO;
826
#endif
827
828
829
830
831
832

#ifdef EOVERFLOW
    case EOVERFLOW:
      return G_IO_CHANNEL_ERROR_OVERFLOW;
#endif

833
834
835
836
837
838
839
840
841
842
843
844
845
#ifdef EPIPE
    case EPIPE:
      return G_IO_CHANNEL_ERROR_PIPE;
#endif

    default:
      return G_IO_CHANNEL_ERROR_FAILED;
    }
}

/**
 * g_io_channel_set_buffer_size:
 * @channel: a #GIOChannel
846
 * @size: the size of the buffer, or 0 to let GLib pick a good size
847
 *
Matthias Clasen's avatar
Matthias Clasen committed
848
 * Sets the buffer size.
849
850
 **/  
void
851
852
g_io_channel_set_buffer_size (GIOChannel *channel,
                              gsize       size)
853
854
855
856
857
858
{
  g_return_if_fail (channel != NULL);

  if (size == 0)
    size = G_IO_NICE_BUF_SIZE;

859
860
  if (size < MAX_CHAR_SIZE)
    size = MAX_CHAR_SIZE;
861

862
863
864
865
866
867
868
  channel->buf_size = size;
}

/**
 * g_io_channel_get_buffer_size:
 * @channel: a #GIOChannel
 *
Matthias Clasen's avatar
Matthias Clasen committed
869
 * Gets the buffer size.
870
871
872
873
 *
 * Return value: the size of the buffer.
 **/  
gsize
874
g_io_channel_get_buffer_size (GIOChannel *channel)
875
876
877
878
879
880
881
882
883
{
  g_return_val_if_fail (channel != NULL, 0);

  return channel->buf_size;
}

/**
 * g_io_channel_set_line_term:
 * @channel: a #GIOChannel
884
885
886
 * @line_term: The line termination string. Use %NULL for autodetect.
 *             Autodetection breaks on "\n", "\r\n", "\r", "\0", and
 *             the Unicode paragraph separator. Autodetection should
887
 *             not be used for anything other than file-based channels.
888
 * @length: The length of the termination string. If -1 is passed, the
Matthias Clasen's avatar
Matthias Clasen committed
889
 *          string is assumed to be nul-terminated. This option allows
890
 *          termination strings with embedded nuls.
891
892
893
894
895
896
 *
 * This sets the string that #GIOChannel uses to determine
 * where in the file a line break occurs.
 **/
void
g_io_channel_set_line_term (GIOChannel	*channel,
897
898
                            const gchar	*line_term,
			    gint         length)
899
900
{
  g_return_if_fail (channel != NULL);
901
  g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
902

903
904
905
906
907
  if (line_term == NULL)
    length = 0;
  else if (length < 0)
    length = strlen (line_term);

Matthias Clasen's avatar
Matthias Clasen committed
908
  g_free (channel->line_term);
909
910
  channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
  channel->line_term_len = length;
911
912
913
914
915
}

/**
 * g_io_channel_get_line_term:
 * @channel: a #GIOChannel
916
 * @length: a location to return the length of the line terminator
917
918
919
 *
 * This returns the string that #GIOChannel uses to determine
 * where in the file a line break occurs. A value of %NULL
920
 * indicates autodetection.
921
922
923
924
925
 *
 * Return value: The line termination string. This value
 *   is owned by GLib and must not be freed.
 **/
G_CONST_RETURN gchar*
926
927
g_io_channel_get_line_term (GIOChannel *channel,
			    gint       *length)
928
{
929
  g_return_val_if_fail (channel != NULL, NULL);
930

931
932
933
  if (length)
    *length = channel->line_term_len;

934
935
936
937
938
  return channel->line_term;
}

/**
 * g_io_channel_set_flags:
939
940
941
 * @channel: a #GIOChannel
 * @flags: the flags to set on the IO channel
 * @error: A location to return an error of type #GIOChannelError
942
 *
943
 * Sets the (writeable) flags in @channel to (@flags & %G_IO_CHANNEL_SET_MASK).
944
 *
945
 * Return value: the status of the operation. 
946
 **/
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
/**
 * GIOFlags:
 * @G_IO_FLAG_APPEND: turns on append mode, corresponds to %O_APPEND
 *                    (see the documentation of the UNIX open()
 *                    syscall).
 * @G_IO_FLAG_NONBLOCK: turns on nonblocking mode, corresponds to
 *                      %O_NONBLOCK/%O_NDELAY (see the documentation of
 *                      the UNIX open() syscall).
 * @G_IO_FLAG_IS_READABLE: indicates that the io channel is readable.
 *                         This flag can not be changed.
 * @G_IO_FLAG_IS_WRITEABLE: indicates that the io channel is writable.
 *                          This flag can not be changed.
 * @G_IO_FLAG_IS_SEEKABLE: indicates that the io channel is seekable,
 *                         i.e. that g_io_channel_seek_position() can
 *                         be used on it.  This flag can not be changed.
 * @G_IO_FLAG_MASK: the mask that specifies all the valid flags.
 * @G_IO_FLAG_GET_MASK: the mask of the flags that are returned from
 *                      g_io_channel_get_flags().
 * @G_IO_FLAG_SET_MASK: the mask of the flags that the user can modify
 *                      with g_io_channel_set_flags().
 *
 * Specifies properties of a #GIOChannel. Some of the flags can only be
 * read with g_io_channel_get_flags(), but not changed with
 * g_io_channel_set_flags().
 **/
972
GIOStatus
973
974
975
g_io_channel_set_flags (GIOChannel  *channel,
                        GIOFlags     flags,
                        GError     **error)
976
977
978
979
980
{
  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
  g_return_val_if_fail ((error == NULL) || (*error == NULL),
			G_IO_STATUS_ERROR);

981
  return (*channel->funcs->io_set_flags) (channel,
982
983
984
985
986
987
988
989
990
991
					  flags & G_IO_FLAG_SET_MASK,
					  error);
}

/**
 * g_io_channel_get_flags:
 * @channel: a #GIOChannel
 *
 * Gets the current flags for a #GIOChannel, including read-only
 * flags such as %G_IO_FLAG_IS_READABLE.
992
 *
993
994
995
 * The values of the flags %G_IO_FLAG_IS_READABLE and %G_IO_FLAG_IS_WRITEABLE
 * are cached for internal use by the channel when it is created.
 * If they should change at some later point (e.g. partial shutdown
996
 * of a socket with the UNIX shutdown() function), the user
997
 * should immediately call g_io_channel_get_flags() to update
998
999
 * the internal values of these flags.
 *
1000
 * Return value: the flags which are set on the channel
1001
1002
1003
1004
 **/
GIOFlags
g_io_channel_get_flags (GIOChannel *channel)
{
1005
1006
  GIOFlags flags;

1007
  g_return_val_if_fail (channel != NULL, 0);
1008

1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
  flags = (* channel->funcs->io_get_flags) (channel);

  /* Cross implementation code */

  if (channel->is_seekable)
    flags |= G_IO_FLAG_IS_SEEKABLE;
  if (channel->is_readable)
    flags |= G_IO_FLAG_IS_READABLE;
  if (channel->is_writeable)
    flags |= G_IO_FLAG_IS_WRITEABLE;

  return flags;
1021
1022
}

1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
/**
 * g_io_channel_set_close_on_unref:
 * @channel: a #GIOChannel
 * @do_close: Whether to close the channel on the final unref of
 *            the GIOChannel data structure. The default value of
 *            this is %TRUE for channels created by g_io_channel_new_file (),
 *            and %FALSE for all other channels.
 *
 * Setting this flag to %TRUE for a channel you have already closed
 * can cause problems.
 **/
void
g_io_channel_set_close_on_unref	(GIOChannel *channel,
				 gboolean    do_close)
{
  g_return_if_fail (channel != NULL);

  channel->close_on_unref = do_close;
}

/**
 * g_io_channel_get_close_on_unref:
1045
 * @channel: a #GIOChannel.
1046
 *
1047
1048
1049
1050
1051
1052
1053
 * Returns whether the file/socket/whatever associated with @channel
 * will be closed when @channel receives its final unref and is
 * destroyed. The default value of this is %TRUE for channels created
 * by g_io_channel_new_file (), and %FALSE for all other channels.
 *
 * Return value: Whether the channel will be closed on the final unref of
 *               the GIOChannel data structure.
1054
1055
1056
1057
1058
1059
1060
1061
1062
 **/
gboolean
g_io_channel_get_close_on_unref	(GIOChannel *channel)
{
  g_return_val_if_fail (channel != NULL, FALSE);

  return channel->close_on_unref;
}

1063
1064
1065
1066
/**
 * g_io_channel_seek_position:
 * @channel: a #GIOChannel
 * @offset: The offset in bytes from the position specified by @type
1067
1068
1069
1070
 * @type: a #GSeekType. The type %G_SEEK_CUR is only allowed in those
 *                      cases where a call to g_io_channel_set_encoding ()
 *                      is allowed. See the documentation for
 *                      g_io_channel_set_encoding () for details.
1071
1072
1073
1074
 * @error: A location to return an error of type #GIOChannelError
 *
 * Replacement for g_io_channel_seek() with the new API.
 *
1075
 * Return value: the status of the operation.
1076
 **/
1077
1078
1079
1080
1081
1082
1083
1084
1085
/**
 * GSeekType:
 * @G_SEEK_CUR: the current position in the file.
 * @G_SEEK_SET: the start of the file.
 * @G_SEEK_END: the end of the file.
 *
 * An enumeration specifying the base position for a
 * g_io_channel_seek_position() operation.
 **/
1086
GIOStatus
1087
1088
1089
1090
g_io_channel_seek_position (GIOChannel  *channel,
                            gint64       offset,
                            GSeekType    type,
                            GError     **error)
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
{
  GIOStatus status;

  /* For files, only one of the read and write buffers can contain data.
   * For sockets, both can contain data.
   */

  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
  g_return_val_if_fail ((error == NULL) || (*error == NULL),
			G_IO_STATUS_ERROR);
1101
  g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR);
1102
1103
1104
1105

  switch (type)
    {
      case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */
1106
        if (channel->use_buffer)
1107
          {
1108
1109
            if (channel->do_encode && channel->encoded_read_buf
                && channel->encoded_read_buf->len > 0)
1110
1111
1112
1113
1114
1115
1116
              {
                g_warning ("Seek type G_SEEK_CUR not allowed for this"
                  " channel's encoding.\n");
                return G_IO_STATUS_ERROR;
              }
          if (channel->read_buf)
            offset -= channel->read_buf->len;
1117
1118
          if (channel->encoded_read_buf)
            {
1119
              g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
1120
1121
1122
1123
1124
1125
1126
1127

              /* If there's anything here, it's because the encoding is UTF-8,
               * so we can just subtract the buffer length, the same as for
               * the unencoded data.
               */

              offset -= channel->encoded_read_buf->len;
            }
1128
          }
1129
        break;
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
      case G_SEEK_SET:
      case G_SEEK_END:
        break;
      default:
        g_warning ("g_io_channel_seek_position: unknown seek type");
        return G_IO_STATUS_ERROR;
    }

  if (channel->use_buffer)
    {
      status = g_io_channel_flush (channel, error);
      if (status != G_IO_STATUS_NORMAL)
        return status;
    }

  status = channel->funcs->io_seek (channel, offset, type, error);

  if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer))
    {
1149
1150
      if (channel->read_buf)
        g_string_truncate (channel->read_buf, 0);
1151
1152
1153
1154
1155
1156
1157
1158

      /* Conversion state no longer matches position in file */
      if (channel->read_cd != (GIConv) -1)
        g_iconv (channel->read_cd, NULL, NULL, NULL, NULL);
      if (channel->write_cd != (GIConv) -1)
        g_iconv (channel->write_cd, NULL, NULL, NULL, NULL);

      if (channel->encoded_read_buf)
1159
        {
1160
1161
          g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
          g_string_truncate (channel->encoded_read_buf, 0);
1162
        }
1163

1164
1165
1166
1167
      if (channel->partial_write_buf[0] != '\0')
        {
          g_warning ("Partial character at end of write buffer not flushed.\n");
          channel->partial_write_buf[0] = '\0';
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
        }
    }

  return status;
}

/**
 * g_io_channel_flush:
 * @channel: a #GIOChannel
 * @error: location to store an error of type #GIOChannelError
 *
Matthias Clasen's avatar
Matthias Clasen committed
1179
 * Flushes the write buffer for the GIOChannel.
1180
1181
 *
 * Return value: the status of the operation: One of
1182
1183
 *   #G_IO_STATUS_NORMAL, #G_IO_STATUS_AGAIN, or
 *   #G_IO_STATUS_ERROR.
1184
1185
1186
1187
1188
1189
 **/
GIOStatus
g_io_channel_flush (GIOChannel	*channel,
		    GError     **error)
{
  GIOStatus status;
1190
  gsize this_time = 1, bytes_written = 0;
1191
1192
1193
1194

  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
  g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);

1195
  if (channel->write_buf == NULL || channel->write_buf->len == 0)
1196
    return G_IO_STATUS_NORMAL;
1197
1198
1199

  do
    {
1200
1201
      g_assert (this_time > 0);

1202
      status = channel->funcs->io_write (channel,
1203
1204
1205
					 channel->write_buf->str + bytes_written,
					 channel->write_buf->len - bytes_written,
					 &this_time, error);
1206
1207
1208
      bytes_written += this_time;
    }
  while ((bytes_written < channel->write_buf->len)
1209
         && (status == G_IO_STATUS_NORMAL));
1210
1211
1212

  g_string_erase (channel->write_buf, 0, bytes_written);

1213
1214
  return status;
}
1215

1216
1217
1218
1219
1220
1221
1222
1223
/**
 * g_io_channel_set_buffered:
 * @channel: a #GIOChannel
 * @buffered: whether to set the channel buffered or unbuffered
 *
 * The buffering state can only be set if the channel's encoding
 * is %NULL. For any other encoding, the channel must be buffered.
 *
1224
1225
 * A buffered channel can only be set unbuffered if the channel's
 * internal buffers have been flushed. Newly created channels or
Matthias Clasen's avatar
Matthias Clasen committed
1226
 * channels which have returned %G_IO_STATUS_EOF
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
 * not require such a flush. For write-only channels, a call to
 * g_io_channel_flush () is sufficient. For all other channels,
 * the buffers may be flushed by a call to g_io_channel_seek_position ().
 * This includes the possibility of seeking with seek type %G_SEEK_CUR
 * and an offset of zero. Note that this means that socket-based
 * channels cannot be set unbuffered once they have had data
 * read from them.
 *
 * On unbuffered channels, it is safe to mix read and write
 * calls from the new and old APIs, if this is necessary for
 * maintaining old code.
 *
1239
1240
1241
 * The default state of the channel is buffered.
 **/
void
1242
1243
g_io_channel_set_buffered (GIOChannel *channel,
                           gboolean    buffered)
1244
1245
{
  g_return_if_fail (channel != NULL);
1246

1247
1248
1249
1250
1251
1252
  if (channel->encoding != NULL)
    {
      g_warning ("Need to have NULL encoding to set the buffering state of the "
                 "channel.\n");
      return;
    }
1253

1254
1255
1256
1257
1258
1259
1260
1261
  g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0);
  g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0);

  channel->use_buffer = buffered;
}

/**
 * g_io_channel_get_buffered:
1262
 * @channel: a #GIOChannel
1263
 *
1264
 * Returns whether @channel is buffered.
1265
 *
1266
 * Return Value: %TRUE if the @channel is buffered. 
1267
1268
 **/
gboolean
1269
g_io_channel_get_buffered (GIOChannel *channel)
1270
1271
1272
1273
{
  g_return_val_if_fail (channel != NULL, FALSE);

  return channel->use_buffer;
1274
1275
1276
1277
1278
1279
}

/**
 * g_io_channel_set_encoding:
 * @channel: a #GIOChannel
 * @encoding: the encoding type
1280
 * @error: location to store an error of type #GConvertError
1281
 *
1282
1283
1284
 * Sets the encoding for the input/output of the channel. 
 * The internal encoding is always UTF-8. The default encoding 
 * for the external file is UTF-8.
1285
 *
1286
 * The encoding %NULL is safe to use with binary data.
1287
 *
1288
1289
 * The encoding can only be set if one of the following conditions
 * is true:
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
 * <itemizedlist>
 * <listitem><para>
 *    The channel was just created, and has not been written to or read 
 *    from yet.
 * </para></listitem>
 * <listitem><para>
 *    The channel is write-only.
 * </para></listitem>
 * <listitem><para>
 *    The channel is a file, and the file pointer was just
1300
1301
 *    repositioned by a call to g_io_channel_seek_position().
 *    (This flushes all the internal buffers.)
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
 * </para></listitem>
 * <listitem><para>
 *    The current encoding is %NULL or UTF-8.
 * </para></listitem>
 * <listitem><para>
 *    One of the (new API) read functions has just returned %G_IO_STATUS_EOF
 *    (or, in the case of g_io_channel_read_to_end(), %G_IO_STATUS_NORMAL).
 * </para></listitem>
 * <listitem><para>
 *    One of the functions g_io_channel_read_chars() or 
 *    g_io_channel_read_unichar() has returned %G_IO_STATUS_AGAIN or 
 *    %G_IO_STATUS_ERROR. This may be useful in the case of 
 *    %G_CONVERT_ERROR_ILLEGAL_SEQUENCE.
 *    Returning one of these statuses from g_io_channel_read_line(),
 *    g_io_channel_read_line_string(), or g_io_channel_read_to_end()
 *    does <emphasis>not</emphasis> guarantee that the encoding can 
 *    be changed.
 * </para></listitem>
 * </itemizedlist>
1321
 * Channels which do not meet one of the above conditions cannot call
1322
1323
1324
 * g_io_channel_seek_position() with an offset of %G_SEEK_CUR, and, if 
 * they are "seekable", cannot call g_io_channel_write_chars() after 
 * calling one of the API "read" functions.
1325
 *
Matthias Clasen's avatar
Matthias Clasen committed
1326
 * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set.
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
 **/
GIOStatus
g_io_channel_set_encoding (GIOChannel	*channel,
                           const gchar	*encoding,
			   GError      **error)
{
  GIConv read_cd, write_cd;
  gboolean did_encode;

  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
  g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);

1339
  /* Make sure the encoded buffers are empty */
1340

1341
  g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf ||
1342
1343
			channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR);

1344
  if (!channel->use_buffer)
1345
    {
1346
1347
1348
      g_warning ("Need to set the channel buffered before setting the encoding.\n");
      g_warning ("Assuming this is what you meant and acting accordingly.\n");

1349
1350
      channel->use_buffer = TRUE;
    }
1351

1352
1353
1354
1355
1356
1357
  if (channel->partial_write_buf[0] != '\0')
    {
      g_warning ("Partial character at end of write buffer not flushed.\n");
      channel->partial_write_buf[0] = '\0';
    }

1358
1359
1360
  did_encode = channel->do_encode;

  if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0)
1361
1362
    {
      channel->do_encode = FALSE;
1363
      read_cd = write_cd = (GIConv) -1;
1364
1365
1366
    }
  else
    {
1367
1368
      gint err = 0;
      const gchar *from_enc = NULL, *to_enc = NULL;
1369

1370
      if (channel->is_readable)
1371
        {
1372
1373
1374
1375
1376
          read_cd = g_iconv_open ("UTF-8", encoding);

          if (read_cd == (GIConv) -1)
            {
              err = errno;
1377
1378
              from_enc = encoding;
              to_enc = "UTF-8";
1379
            }
1380
1381
        }
      else
1382
1383
1384
        read_cd = (GIConv) -1;

      if (channel->is_writeable && err == 0)
1385
1386
        {
          write_cd = g_iconv_open (encoding, "UTF-8");
1387