LCOV - code coverage report
Current view: top level - glib - giochannel.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 52.1 % 853 444
Test Date: 2025-01-07 05:22:06 Functions: 79.5 % 39 31
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GLIB - Library of useful routines for C programming
       2                 :             :  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       3                 :             :  *
       4                 :             :  * giochannel.c: IO Channel abstraction
       5                 :             :  * Copyright 1998 Owen Taylor
       6                 :             :  *
       7                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       8                 :             :  *
       9                 :             :  * This library is free software; you can redistribute it and/or
      10                 :             :  * modify it under the terms of the GNU Lesser General Public
      11                 :             :  * License as published by the Free Software Foundation; either
      12                 :             :  * version 2.1 of the License, or (at your option) any later version.
      13                 :             :  *
      14                 :             :  * This library is distributed in the hope that it will be useful,
      15                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :             :  * Lesser General Public License for more details.
      18                 :             :  *
      19                 :             :  * You should have received a copy of the GNU Lesser General Public
      20                 :             :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      21                 :             :  */
      22                 :             : 
      23                 :             : /*
      24                 :             :  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      25                 :             :  * file for a list of people on the GLib Team.  See the ChangeLog
      26                 :             :  * files for a list of changes.  These files are distributed with
      27                 :             :  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
      28                 :             :  */
      29                 :             : 
      30                 :             : /* 
      31                 :             :  * MT safe
      32                 :             :  */
      33                 :             : 
      34                 :             : #include "config.h"
      35                 :             : 
      36                 :             : #include <string.h>
      37                 :             : #include <errno.h>
      38                 :             : 
      39                 :             : #include "giochannel.h"
      40                 :             : 
      41                 :             : #include "gstrfuncs.h"
      42                 :             : #include "gtestutils.h"
      43                 :             : #include "glibintl.h"
      44                 :             : 
      45                 :             : 
      46                 :             : /**
      47                 :             :  * GIOChannel:
      48                 :             :  *
      49                 :             :  * The `GIOChannel` data type aims to provide a portable method for
      50                 :             :  * using file descriptors, pipes, and sockets, and integrating them
      51                 :             :  * into the main event loop (see [struct@GLib.MainContext]). Currently,
      52                 :             :  * full support is available on UNIX platforms; support for Windows
      53                 :             :  * is only partially complete.
      54                 :             :  *
      55                 :             :  * To create a new `GIOChannel` on UNIX systems use
      56                 :             :  * [ctor@GLib.IOChannel.unix_new]. This works for plain file descriptors,
      57                 :             :  * pipes and sockets. Alternatively, a channel can be created for a
      58                 :             :  * file in a system independent manner using [ctor@GLib.IOChannel.new_file].
      59                 :             :  *
      60                 :             :  * Once a `GIOChannel` has been created, it can be used in a generic
      61                 :             :  * manner with the functions [method@GLib.IOChannel.read_chars],
      62                 :             :  * [method@GLib.IOChannel.write_chars], [method@GLib.IOChannel.seek_position],
      63                 :             :  * and [method@GLib.IOChannel.shutdown].
      64                 :             :  *
      65                 :             :  * To add a `GIOChannel` to the main event loop, use [func@GLib.io_add_watch] or
      66                 :             :  * [func@GLib.io_add_watch_full]. Here you specify which events you are
      67                 :             :  * interested in on the `GIOChannel`, and provide a function to be called
      68                 :             :  * whenever these events occur.
      69                 :             :  *
      70                 :             :  * `GIOChannel` instances are created with an initial reference count of 1.
      71                 :             :  * [method@GLib.IOChannel.ref] and [method@GLib.IOChannel.unref] can be used to
      72                 :             :  * increment or decrement the reference count respectively. When the
      73                 :             :  * reference count falls to 0, the `GIOChannel` is freed. (Though it
      74                 :             :  * isn’t closed automatically, unless it was created using
      75                 :             :  * [ctor@GLib.IOChannel.new_file].) Using [func@GLib.io_add_watch] or
      76                 :             :  * [func@GLib.io_add_watch_full] increments a channel’s reference count.
      77                 :             :  *
      78                 :             :  * The new functions [method@GLib.IOChannel.read_chars],
      79                 :             :  * [method@GLib.IOChannel.read_line], [method@GLib.IOChannel.read_line_string],
      80                 :             :  * [method@GLib.IOChannel.read_to_end], [method@GLib.IOChannel.write_chars],
      81                 :             :  * [method@GLib.IOChannel.seek_position], and [method@GLib.IOChannel.flush]
      82                 :             :  * should not be mixed with the deprecated functions
      83                 :             :  * [method@GLib.IOChannel.read], [method@GLib.IOChannel.write], and
      84                 :             :  * [method@GLib.IOChannel.seek] on the same channel.
      85                 :             :  **/
      86                 :             : 
      87                 :             : /**
      88                 :             :  * GIOFuncs:
      89                 :             :  * @io_read: reads raw bytes from the channel.  This is called from
      90                 :             :  *           various functions such as g_io_channel_read_chars() to
      91                 :             :  *           read raw bytes from the channel.  Encoding and buffering
      92                 :             :  *           issues are dealt with at a higher level.
      93                 :             :  * @io_write: writes raw bytes to the channel.  This is called from
      94                 :             :  *            various functions such as g_io_channel_write_chars() to
      95                 :             :  *            write raw bytes to the channel.  Encoding and buffering
      96                 :             :  *            issues are dealt with at a higher level.
      97                 :             :  * @io_seek: (optional): seeks the channel.  This is called from
      98                 :             :  *           g_io_channel_seek() on channels that support it.
      99                 :             :  * @io_close: closes the channel.  This is called from
     100                 :             :  *            g_io_channel_close() after flushing the buffers.
     101                 :             :  * @io_create_watch: creates a watch on the channel.  This call
     102                 :             :  *                   corresponds directly to g_io_create_watch().
     103                 :             :  * @io_free: called from g_io_channel_unref() when the channel needs to
     104                 :             :  *           be freed.  This function must free the memory associated
     105                 :             :  *           with the channel, including freeing the #GIOChannel
     106                 :             :  *           structure itself.  The channel buffers have been flushed
     107                 :             :  *           and possibly @io_close has been called by the time this
     108                 :             :  *           function is called.
     109                 :             :  * @io_set_flags: sets the #GIOFlags on the channel.  This is called
     110                 :             :  *                from g_io_channel_set_flags() with all flags except
     111                 :             :  *                for %G_IO_FLAG_APPEND and %G_IO_FLAG_NONBLOCK masked
     112                 :             :  *                out.
     113                 :             :  * @io_get_flags: gets the #GIOFlags for the channel.  This function
     114                 :             :  *                need only return the %G_IO_FLAG_APPEND and
     115                 :             :  *                %G_IO_FLAG_NONBLOCK flags; g_io_channel_get_flags()
     116                 :             :  *                automatically adds the others as appropriate.
     117                 :             :  *
     118                 :             :  * A table of functions used to handle different types of #GIOChannel
     119                 :             :  * in a generic way.
     120                 :             :  **/
     121                 :             : 
     122                 :             : /**
     123                 :             :  * GIOStatus:
     124                 :             :  * @G_IO_STATUS_ERROR: An error occurred.
     125                 :             :  * @G_IO_STATUS_NORMAL: Success.
     126                 :             :  * @G_IO_STATUS_EOF: End of file.
     127                 :             :  * @G_IO_STATUS_AGAIN: Resource temporarily unavailable.
     128                 :             :  *
     129                 :             :  * Statuses returned by most of the #GIOFuncs functions.
     130                 :             :  **/
     131                 :             : 
     132                 :             : /**
     133                 :             :  * GIOError:
     134                 :             :  * @G_IO_ERROR_NONE: no error
     135                 :             :  * @G_IO_ERROR_AGAIN: an EAGAIN error occurred
     136                 :             :  * @G_IO_ERROR_INVAL: an EINVAL error occurred
     137                 :             :  * @G_IO_ERROR_UNKNOWN: another error occurred
     138                 :             :  *
     139                 :             :  * #GIOError is only used by the deprecated functions
     140                 :             :  * g_io_channel_read(), g_io_channel_write(), and g_io_channel_seek().
     141                 :             :  **/
     142                 :             : 
     143                 :             : #define G_IO_NICE_BUF_SIZE      1024
     144                 :             : 
     145                 :             : /* This needs to be as wide as the largest character in any possible encoding */
     146                 :             : #define MAX_CHAR_SIZE           10
     147                 :             : 
     148                 :             : /* Some simplifying macros, which reduce the need to worry whether the
     149                 :             :  * buffers have been allocated. These also make USE_BUF () an lvalue,
     150                 :             :  * which is used in g_io_channel_read_to_end ().
     151                 :             :  */
     152                 :             : #define USE_BUF(channel)        ((channel)->encoding ? (channel)->encoded_read_buf \
     153                 :             :                                  : (channel)->read_buf)
     154                 :             : #define BUF_LEN(string)         ((string) ? (string)->len : 0)
     155                 :             : 
     156                 :             : static GIOError         g_io_error_get_from_g_error     (GIOStatus    status,
     157                 :             :                                                          GError      *err);
     158                 :             : static void             g_io_channel_purge              (GIOChannel  *channel);
     159                 :             : static GIOStatus        g_io_channel_fill_buffer        (GIOChannel  *channel,
     160                 :             :                                                          GError     **err);
     161                 :             : static GIOStatus        g_io_channel_read_line_backend  (GIOChannel  *channel,
     162                 :             :                                                          gsize       *length,
     163                 :             :                                                          gsize       *terminator_pos,
     164                 :             :                                                          GError     **error);
     165                 :             : 
     166                 :             : /**
     167                 :             :  * g_io_channel_init:
     168                 :             :  * @channel: a #GIOChannel
     169                 :             :  *
     170                 :             :  * Initializes a #GIOChannel struct. 
     171                 :             :  *
     172                 :             :  * This is called by each of the above functions when creating a 
     173                 :             :  * #GIOChannel, and so is not often needed by the application 
     174                 :             :  * programmer (unless you are creating a new type of #GIOChannel).
     175                 :             :  */
     176                 :             : void
     177                 :        1041 : g_io_channel_init (GIOChannel *channel)
     178                 :             : {
     179                 :        1041 :   channel->ref_count = 1;
     180                 :        1041 :   channel->encoding = g_strdup ("UTF-8");
     181                 :        1041 :   channel->line_term = NULL;
     182                 :        1041 :   channel->line_term_len = 0;
     183                 :        1041 :   channel->buf_size = G_IO_NICE_BUF_SIZE;
     184                 :        1041 :   channel->read_cd = (GIConv) -1;
     185                 :        1041 :   channel->write_cd = (GIConv) -1;
     186                 :        1041 :   channel->read_buf = NULL; /* Lazy allocate buffers */
     187                 :        1041 :   channel->encoded_read_buf = NULL;
     188                 :        1041 :   channel->write_buf = NULL;
     189                 :        1041 :   channel->partial_write_buf[0] = '\0';
     190                 :        1041 :   channel->use_buffer = TRUE;
     191                 :        1041 :   channel->do_encode = FALSE;
     192                 :        1041 :   channel->close_on_unref = FALSE;
     193                 :        1041 : }
     194                 :             : 
     195                 :             : /**
     196                 :             :  * g_io_channel_ref:
     197                 :             :  * @channel: a #GIOChannel
     198                 :             :  *
     199                 :             :  * Increments the reference count of a #GIOChannel.
     200                 :             :  *
     201                 :             :  * Returns: the @channel that was passed in (since 2.6)
     202                 :             :  */
     203                 :             : GIOChannel *
     204                 :         777 : g_io_channel_ref (GIOChannel *channel)
     205                 :             : {
     206                 :         777 :   g_return_val_if_fail (channel != NULL, NULL);
     207                 :             : 
     208                 :         777 :   g_atomic_int_inc (&channel->ref_count);
     209                 :             : 
     210                 :         777 :   return channel;
     211                 :             : }
     212                 :             : 
     213                 :             : /**
     214                 :             :  * g_io_channel_unref:
     215                 :             :  * @channel: a #GIOChannel
     216                 :             :  *
     217                 :             :  * Decrements the reference count of a #GIOChannel.
     218                 :             :  */
     219                 :             : void 
     220                 :        1785 : g_io_channel_unref (GIOChannel *channel)
     221                 :             : {
     222                 :             :   gboolean is_zero;
     223                 :             : 
     224                 :        1785 :   g_return_if_fail (channel != NULL);
     225                 :             : 
     226                 :        1785 :   is_zero = g_atomic_int_dec_and_test (&channel->ref_count);
     227                 :             : 
     228                 :        1785 :   if (G_UNLIKELY (is_zero))
     229                 :             :     {
     230                 :        1008 :       if (channel->close_on_unref)
     231                 :         723 :         g_io_channel_shutdown (channel, TRUE, NULL);
     232                 :             :       else
     233                 :         285 :         g_io_channel_purge (channel);
     234                 :        1008 :       g_free (channel->encoding);
     235                 :        1008 :       if (channel->read_cd != (GIConv) -1)
     236                 :           1 :         g_iconv_close (channel->read_cd);
     237                 :        1008 :       if (channel->write_cd != (GIConv) -1)
     238                 :           0 :         g_iconv_close (channel->write_cd);
     239                 :        1008 :       g_free (channel->line_term);
     240                 :        1008 :       if (channel->read_buf)
     241                 :         220 :         g_string_free (channel->read_buf, TRUE);
     242                 :        1008 :       if (channel->write_buf)
     243                 :          35 :         g_string_free (channel->write_buf, TRUE);
     244                 :        1008 :       if (channel->encoded_read_buf)
     245                 :         161 :         g_string_free (channel->encoded_read_buf, TRUE);
     246                 :        1008 :       channel->funcs->io_free (channel);
     247                 :             :     }
     248                 :             : }
     249                 :             : 
     250                 :             : static GIOError
     251                 :         417 : g_io_error_get_from_g_error (GIOStatus  status,
     252                 :             :                              GError    *err)
     253                 :             : {
     254                 :         417 :   switch (status)
     255                 :             :     {
     256                 :         417 :       case G_IO_STATUS_NORMAL:
     257                 :             :       case G_IO_STATUS_EOF:
     258                 :         417 :         return G_IO_ERROR_NONE;
     259                 :           0 :       case G_IO_STATUS_AGAIN:
     260                 :           0 :         return G_IO_ERROR_AGAIN;
     261                 :           0 :       case G_IO_STATUS_ERROR:
     262                 :           0 :         g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN);
     263                 :             :         
     264                 :           0 :         if (err->domain != G_IO_CHANNEL_ERROR)
     265                 :           0 :           return G_IO_ERROR_UNKNOWN;
     266                 :           0 :         switch (err->code)
     267                 :             :           {
     268                 :           0 :             case G_IO_CHANNEL_ERROR_INVAL:
     269                 :           0 :               return G_IO_ERROR_INVAL;
     270                 :           0 :             default:
     271                 :           0 :               return G_IO_ERROR_UNKNOWN;
     272                 :             :           }
     273                 :           0 :       default:
     274                 :             :         g_assert_not_reached ();
     275                 :             :     }
     276                 :             : }
     277                 :             : 
     278                 :             : /**
     279                 :             :  * g_io_channel_read:
     280                 :             :  * @channel: a #GIOChannel
     281                 :             :  * @buf: a buffer to read the data into (which should be at least 
     282                 :             :  *       count bytes long)
     283                 :             :  * @count: the number of bytes to read from the #GIOChannel
     284                 :             :  * @bytes_read: returns the number of bytes actually read
     285                 :             :  * 
     286                 :             :  * Reads data from a #GIOChannel. 
     287                 :             :  * 
     288                 :             :  * Returns: %G_IO_ERROR_NONE if the operation was successful. 
     289                 :             :  *
     290                 :             :  * Deprecated:2.2: Use g_io_channel_read_chars() instead.
     291                 :             :  **/
     292                 :             : GIOError 
     293                 :         417 : g_io_channel_read (GIOChannel *channel, 
     294                 :             :                    gchar      *buf, 
     295                 :             :                    gsize       count,
     296                 :             :                    gsize      *bytes_read)
     297                 :             : {
     298                 :         417 :   GError *err = NULL;
     299                 :             :   GIOError error;
     300                 :             :   GIOStatus status;
     301                 :             : 
     302                 :         417 :   g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
     303                 :         417 :   g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN);
     304                 :             : 
     305                 :         417 :   if (count == 0)
     306                 :             :     {
     307                 :           0 :       if (bytes_read)
     308                 :           0 :         *bytes_read = 0;
     309                 :           0 :       return G_IO_ERROR_NONE;
     310                 :             :     }
     311                 :             : 
     312                 :         417 :   g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN);
     313                 :             : 
     314                 :         417 :   status = channel->funcs->io_read (channel, buf, count, bytes_read, &err);
     315                 :             : 
     316                 :         417 :   error = g_io_error_get_from_g_error (status, err);
     317                 :             : 
     318                 :         417 :   if (err)
     319                 :           0 :     g_error_free (err);
     320                 :             : 
     321                 :         417 :   return error;
     322                 :             : }
     323                 :             : 
     324                 :             : /**
     325                 :             :  * g_io_channel_write:
     326                 :             :  * @channel:  a #GIOChannel
     327                 :             :  * @buf: the buffer containing the data to write
     328                 :             :  * @count: the number of bytes to write
     329                 :             :  * @bytes_written: the number of bytes actually written
     330                 :             :  * 
     331                 :             :  * Writes data to a #GIOChannel. 
     332                 :             :  * 
     333                 :             :  * Returns:  %G_IO_ERROR_NONE if the operation was successful.
     334                 :             :  *
     335                 :             :  * Deprecated:2.2: Use g_io_channel_write_chars() instead.
     336                 :             :  **/
     337                 :             : GIOError 
     338                 :           0 : g_io_channel_write (GIOChannel  *channel, 
     339                 :             :                     const gchar *buf, 
     340                 :             :                     gsize        count,
     341                 :             :                     gsize       *bytes_written)
     342                 :             : {
     343                 :           0 :   GError *err = NULL;
     344                 :             :   GIOError error;
     345                 :             :   GIOStatus status;
     346                 :             : 
     347                 :           0 :   g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
     348                 :           0 :   g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN);
     349                 :             : 
     350                 :           0 :   status = channel->funcs->io_write (channel, buf, count, bytes_written, &err);
     351                 :             : 
     352                 :           0 :   error = g_io_error_get_from_g_error (status, err);
     353                 :             : 
     354                 :           0 :   if (err)
     355                 :           0 :     g_error_free (err);
     356                 :             : 
     357                 :           0 :   return error;
     358                 :             : }
     359                 :             : 
     360                 :             : /**
     361                 :             :  * g_io_channel_seek:
     362                 :             :  * @channel: a #GIOChannel
     363                 :             :  * @offset: an offset, in bytes, which is added to the position specified 
     364                 :             :  *          by @type
     365                 :             :  * @type: the position in the file, which can be %G_SEEK_CUR (the current
     366                 :             :  *        position), %G_SEEK_SET (the start of the file), or %G_SEEK_END 
     367                 :             :  *        (the end of the file)
     368                 :             :  * 
     369                 :             :  * Sets the current position in the #GIOChannel, similar to the standard 
     370                 :             :  * library function fseek(). 
     371                 :             :  * 
     372                 :             :  * Returns: %G_IO_ERROR_NONE if the operation was successful.
     373                 :             :  *
     374                 :             :  * Deprecated:2.2: Use g_io_channel_seek_position() instead.
     375                 :             :  **/
     376                 :             : GIOError 
     377                 :           0 : g_io_channel_seek (GIOChannel *channel,
     378                 :             :                    gint64      offset, 
     379                 :             :                    GSeekType   type)
     380                 :             : {
     381                 :           0 :   GError *err = NULL;
     382                 :             :   GIOError error;
     383                 :             :   GIOStatus status;
     384                 :             : 
     385                 :           0 :   g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
     386                 :           0 :   g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN);
     387                 :             : 
     388                 :           0 :   switch (type)
     389                 :             :     {
     390                 :           0 :       case G_SEEK_CUR:
     391                 :             :       case G_SEEK_SET:
     392                 :             :       case G_SEEK_END:
     393                 :           0 :         break;
     394                 :           0 :       default:
     395                 :           0 :         g_warning ("g_io_channel_seek: unknown seek type");
     396                 :           0 :         return G_IO_ERROR_UNKNOWN;
     397                 :             :     }
     398                 :             : 
     399                 :           0 :   status = channel->funcs->io_seek (channel, offset, type, &err);
     400                 :             : 
     401                 :           0 :   error = g_io_error_get_from_g_error (status, err);
     402                 :             : 
     403                 :           0 :   if (err)
     404                 :           0 :     g_error_free (err);
     405                 :             : 
     406                 :           0 :   return error;
     407                 :             : }
     408                 :             : 
     409                 :             : /* The function g_io_channel_new_file() is prototyped in both
     410                 :             :  * giounix.c and giowin32.c, so we stick its documentation here.
     411                 :             :  */
     412                 :             : 
     413                 :             : /**
     414                 :             :  * g_io_channel_new_file:
     415                 :             :  * @filename: (type filename): A string containing the name of a file
     416                 :             :  * @mode: One of "r", "w", "a", "r+", "w+", "a+". These have
     417                 :             :  *        the same meaning as in fopen()
     418                 :             :  * @error: A location to return an error of type %G_FILE_ERROR
     419                 :             :  *
     420                 :             :  * Open a file @filename as a #GIOChannel using mode @mode. This
     421                 :             :  * channel will be closed when the last reference to it is dropped,
     422                 :             :  * so there is no need to call g_io_channel_close() (though doing
     423                 :             :  * so will not cause problems, as long as no attempt is made to
     424                 :             :  * access the channel after it is closed).
     425                 :             :  *
     426                 :             :  * Returns: A #GIOChannel on success, %NULL on failure.
     427                 :             :  **/
     428                 :             : 
     429                 :             : /**
     430                 :             :  * g_io_channel_close:
     431                 :             :  * @channel: A #GIOChannel
     432                 :             :  * 
     433                 :             :  * Close an IO channel. Any pending data to be written will be
     434                 :             :  * flushed, ignoring errors. The channel will not be freed until the
     435                 :             :  * last reference is dropped using g_io_channel_unref(). 
     436                 :             :  *
     437                 :             :  * Deprecated:2.2: Use g_io_channel_shutdown() instead.
     438                 :             :  **/
     439                 :             : void
     440                 :           0 : g_io_channel_close (GIOChannel *channel)
     441                 :             : {
     442                 :           0 :   GError *err = NULL;
     443                 :             :   
     444                 :           0 :   g_return_if_fail (channel != NULL);
     445                 :             : 
     446                 :           0 :   g_io_channel_purge (channel);
     447                 :             : 
     448                 :           0 :   channel->funcs->io_close (channel, &err);
     449                 :             : 
     450                 :           0 :   if (err)
     451                 :             :     { /* No way to return the error */
     452                 :           0 :       g_warning ("Error closing channel: %s", err->message);
     453                 :           0 :       g_error_free (err);
     454                 :             :     }
     455                 :             :   
     456                 :           0 :   channel->close_on_unref = FALSE; /* Because we already did */
     457                 :           0 :   channel->is_readable = FALSE;
     458                 :           0 :   channel->is_writeable = FALSE;
     459                 :           0 :   channel->is_seekable = FALSE;
     460                 :             : }
     461                 :             : 
     462                 :             : /**
     463                 :             :  * g_io_channel_shutdown:
     464                 :             :  * @channel: a #GIOChannel
     465                 :             :  * @flush: if %TRUE, flush pending
     466                 :             :  * @err: location to store a #GIOChannelError
     467                 :             :  * 
     468                 :             :  * Close an IO channel. Any pending data to be written will be
     469                 :             :  * flushed if @flush is %TRUE. The channel will not be freed until the
     470                 :             :  * last reference is dropped using g_io_channel_unref().
     471                 :             :  *
     472                 :             :  * Returns: the status of the operation.
     473                 :             :  **/
     474                 :             : GIOStatus
     475                 :         839 : g_io_channel_shutdown (GIOChannel  *channel,
     476                 :             :                        gboolean     flush,
     477                 :             :                        GError     **err)
     478                 :             : {
     479                 :             :   GIOStatus status, result;
     480                 :         839 :   GError *tmperr = NULL;
     481                 :             :   
     482                 :         839 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
     483                 :         839 :   g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR);
     484                 :             : 
     485                 :         839 :   if (channel->write_buf && channel->write_buf->len > 0)
     486                 :             :     {
     487                 :           1 :       if (flush)
     488                 :             :         {
     489                 :             :           GIOFlags flags;
     490                 :             :       
     491                 :             :           /* Set the channel to blocking, to avoid a busy loop
     492                 :             :            */
     493                 :           1 :           flags = g_io_channel_get_flags (channel);
     494                 :             :           /* Ignore any errors here, they're irrelevant */
     495                 :           1 :           g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
     496                 :             : 
     497                 :           1 :           result = g_io_channel_flush (channel, &tmperr);
     498                 :             :         }
     499                 :             :       else
     500                 :           0 :         result = G_IO_STATUS_NORMAL;
     501                 :             : 
     502                 :           1 :       g_string_truncate(channel->write_buf, 0);
     503                 :             :     }
     504                 :             :   else
     505                 :         838 :     result = G_IO_STATUS_NORMAL;
     506                 :             : 
     507                 :         839 :   if (channel->partial_write_buf[0] != '\0')
     508                 :             :     {
     509                 :           0 :       if (flush)
     510                 :           0 :         g_warning ("Partial character at end of write buffer not flushed.");
     511                 :           0 :       channel->partial_write_buf[0] = '\0';
     512                 :             :     }
     513                 :             : 
     514                 :         839 :   status = channel->funcs->io_close (channel, err);
     515                 :             : 
     516                 :         839 :   channel->close_on_unref = FALSE; /* Because we already did */
     517                 :         839 :   channel->is_readable = FALSE;
     518                 :         839 :   channel->is_writeable = FALSE;
     519                 :         839 :   channel->is_seekable = FALSE;
     520                 :             : 
     521                 :         839 :   if (status != G_IO_STATUS_NORMAL)
     522                 :             :     {
     523                 :           0 :       g_clear_error (&tmperr);
     524                 :           0 :       return status;
     525                 :             :     }
     526                 :         839 :   else if (result != G_IO_STATUS_NORMAL)
     527                 :             :     {
     528                 :           0 :       g_propagate_error (err, tmperr);
     529                 :           0 :       return result;
     530                 :             :     }
     531                 :             :   else
     532                 :         839 :     return G_IO_STATUS_NORMAL;
     533                 :             : }
     534                 :             : 
     535                 :             : /* This function is used for the final flush on close or unref */
     536                 :             : static void
     537                 :         285 : g_io_channel_purge (GIOChannel *channel)
     538                 :             : {
     539                 :         285 :   GError *err = NULL;
     540                 :             :   GIOStatus status G_GNUC_UNUSED;
     541                 :             : 
     542                 :         285 :   g_return_if_fail (channel != NULL);
     543                 :             : 
     544                 :         285 :   if (channel->write_buf && channel->write_buf->len > 0)
     545                 :             :     {
     546                 :             :       GIOFlags flags;
     547                 :             : 
     548                 :             :       /* Set the channel to blocking, to avoid a busy loop
     549                 :             :        */
     550                 :          33 :       flags = g_io_channel_get_flags (channel);
     551                 :          33 :       g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
     552                 :             : 
     553                 :          33 :       status = g_io_channel_flush (channel, &err);
     554                 :             : 
     555                 :          33 :       if (err)
     556                 :             :         { /* No way to return the error */
     557                 :           0 :           g_warning ("Error flushing string: %s", err->message);
     558                 :           0 :           g_error_free (err);
     559                 :             :         }
     560                 :             :     }
     561                 :             : 
     562                 :             :   /* Flush these in case anyone tries to close without unrefing */
     563                 :             : 
     564                 :         285 :   if (channel->read_buf)
     565                 :         217 :     g_string_truncate (channel->read_buf, 0);
     566                 :         285 :   if (channel->write_buf)
     567                 :          33 :     g_string_truncate (channel->write_buf, 0);
     568                 :         285 :   if (channel->encoding)
     569                 :             :     {
     570                 :         168 :       if (channel->encoded_read_buf)
     571                 :         159 :         g_string_truncate (channel->encoded_read_buf, 0);
     572                 :             : 
     573                 :         168 :       if (channel->partial_write_buf[0] != '\0')
     574                 :             :         {
     575                 :           0 :           g_warning ("Partial character at end of write buffer not flushed.");
     576                 :           0 :           channel->partial_write_buf[0] = '\0';
     577                 :             :         }
     578                 :             :     }
     579                 :             : }
     580                 :             : 
     581                 :             : /**
     582                 :             :  * g_io_create_watch:
     583                 :             :  * @channel: a #GIOChannel to watch
     584                 :             :  * @condition: conditions to watch for
     585                 :             :  *
     586                 :             :  * Creates a #GSource that's dispatched when @condition is met for the 
     587                 :             :  * given @channel. For example, if condition is %G_IO_IN, the source will
     588                 :             :  * be dispatched when there's data available for reading.
     589                 :             :  *
     590                 :             :  * The callback function invoked by the #GSource should be added with
     591                 :             :  * g_source_set_callback(), but it has type #GIOFunc (not #GSourceFunc).
     592                 :             :  *
     593                 :             :  * g_io_add_watch() is a simpler interface to this same functionality, for 
     594                 :             :  * the case where you want to add the source to the default main loop context 
     595                 :             :  * at the default priority.
     596                 :             :  *
     597                 :             :  * On Windows, polling a #GSource created to watch a channel for a socket
     598                 :             :  * puts the socket in non-blocking mode. This is a side-effect of the
     599                 :             :  * implementation and unavoidable.
     600                 :             :  *
     601                 :             :  * Returns: a new #GSource
     602                 :             :  */
     603                 :             : GSource *
     604                 :         776 : g_io_create_watch (GIOChannel   *channel,
     605                 :             :                    GIOCondition  condition)
     606                 :             : {
     607                 :         776 :   g_return_val_if_fail (channel != NULL, NULL);
     608                 :             : 
     609                 :         776 :   return channel->funcs->io_create_watch (channel, condition);
     610                 :             : }
     611                 :             : 
     612                 :             : /**
     613                 :             :  * g_io_add_watch_full: (rename-to g_io_add_watch)
     614                 :             :  * @channel: a #GIOChannel
     615                 :             :  * @priority: the priority of the #GIOChannel source
     616                 :             :  * @condition: the condition to watch for
     617                 :             :  * @func: the function to call when the condition is satisfied
     618                 :             :  * @user_data: user data to pass to @func
     619                 :             :  * @notify: the function to call when the source is removed
     620                 :             :  *
     621                 :             :  * Adds the #GIOChannel into the default main loop context
     622                 :             :  * with the given priority.
     623                 :             :  *
     624                 :             :  * This internally creates a main loop source using g_io_create_watch()
     625                 :             :  * and attaches it to the main loop context with g_source_attach().
     626                 :             :  * You can do these steps manually if you need greater control.
     627                 :             :  *
     628                 :             :  * Returns: the event source id
     629                 :             :  */
     630                 :             : guint 
     631                 :          11 : g_io_add_watch_full (GIOChannel    *channel,
     632                 :             :                      gint           priority,
     633                 :             :                      GIOCondition   condition,
     634                 :             :                      GIOFunc        func,
     635                 :             :                      gpointer       user_data,
     636                 :             :                      GDestroyNotify notify)
     637                 :             : {
     638                 :             :   GSource *source;
     639                 :             :   guint id;
     640                 :             :   
     641                 :          11 :   g_return_val_if_fail (channel != NULL, 0);
     642                 :             : 
     643                 :          11 :   source = g_io_create_watch (channel, condition);
     644                 :             : 
     645                 :          11 :   if (priority != G_PRIORITY_DEFAULT)
     646                 :           1 :     g_source_set_priority (source, priority);
     647                 :          11 :   g_source_set_callback (source, (GSourceFunc)func, user_data, notify);
     648                 :             : 
     649                 :          11 :   id = g_source_attach (source, NULL);
     650                 :          11 :   g_source_unref (source);
     651                 :             : 
     652                 :          11 :   return id;
     653                 :             : }
     654                 :             : 
     655                 :             : /**
     656                 :             :  * g_io_add_watch:
     657                 :             :  * @channel: a #GIOChannel
     658                 :             :  * @condition: the condition to watch for
     659                 :             :  * @func: the function to call when the condition is satisfied
     660                 :             :  * @user_data: user data to pass to @func
     661                 :             :  *
     662                 :             :  * Adds the #GIOChannel into the default main loop context
     663                 :             :  * with the default priority.
     664                 :             :  *
     665                 :             :  * Returns: the event source id
     666                 :             :  */
     667                 :             : /**
     668                 :             :  * GIOFunc:
     669                 :             :  * @source: the #GIOChannel event source
     670                 :             :  * @condition: the condition which has been satisfied
     671                 :             :  * @data: user data set in g_io_add_watch() or g_io_add_watch_full()
     672                 :             :  *
     673                 :             :  * Specifies the type of function passed to g_io_add_watch() or
     674                 :             :  * g_io_add_watch_full(), which is called when the requested condition
     675                 :             :  * on a #GIOChannel is satisfied.
     676                 :             :  *
     677                 :             :  * Returns: the function should return %FALSE if the event source
     678                 :             :  *          should be removed
     679                 :             :  **/
     680                 :             : /**
     681                 :             :  * GIOCondition:
     682                 :             :  * @G_IO_IN: There is data to read.
     683                 :             :  * @G_IO_OUT: Data can be written (without blocking).
     684                 :             :  * @G_IO_PRI: There is urgent data to read.
     685                 :             :  * @G_IO_ERR: Error condition.
     686                 :             :  * @G_IO_HUP: Hung up (the connection has been broken, usually for
     687                 :             :  *            pipes and sockets).
     688                 :             :  * @G_IO_NVAL: Invalid request. The file descriptor is not open.
     689                 :             :  *
     690                 :             :  * A bitwise combination representing a condition to watch for on an
     691                 :             :  * event source.
     692                 :             :  **/
     693                 :             : guint 
     694                 :           4 : g_io_add_watch (GIOChannel   *channel,
     695                 :             :                 GIOCondition  condition,
     696                 :             :                 GIOFunc       func,
     697                 :             :                 gpointer      user_data)
     698                 :             : {
     699                 :           4 :   return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL);
     700                 :             : }
     701                 :             : 
     702                 :             : /**
     703                 :             :  * g_io_channel_get_buffer_condition:
     704                 :             :  * @channel: A #GIOChannel
     705                 :             :  *
     706                 :             :  * This function returns a #GIOCondition depending on whether there
     707                 :             :  * is data to be read/space to write data in the internal buffers in 
     708                 :             :  * the #GIOChannel. Only the flags %G_IO_IN and %G_IO_OUT may be set.
     709                 :             :  *
     710                 :             :  * Returns: A #GIOCondition
     711                 :             :  **/
     712                 :             : GIOCondition
     713                 :       13602 : g_io_channel_get_buffer_condition (GIOChannel *channel)
     714                 :             : {
     715                 :       13602 :   GIOCondition condition = 0;
     716                 :             : 
     717                 :       13602 :   if (channel->encoding)
     718                 :             :     {
     719                 :        2723 :       if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0))
     720                 :           0 :         condition |= G_IO_IN; /* Only return if we have full characters */
     721                 :             :     }
     722                 :             :   else
     723                 :             :     {
     724                 :       10879 :       if (channel->read_buf && (channel->read_buf->len > 0))
     725                 :           0 :         condition |= G_IO_IN;
     726                 :             :     }
     727                 :             : 
     728                 :       13602 :   if (channel->write_buf && (channel->write_buf->len < channel->buf_size))
     729                 :           0 :     condition |= G_IO_OUT;
     730                 :             : 
     731                 :       13602 :   return condition;
     732                 :             : }
     733                 :             : 
     734                 :             : /**
     735                 :             :  * g_io_channel_error_from_errno:
     736                 :             :  * @en: an `errno` error number, e.g. `EINVAL`
     737                 :             :  *
     738                 :             :  * Converts an `errno` error number to a #GIOChannelError.
     739                 :             :  *
     740                 :             :  * Returns: a #GIOChannelError error number, e.g. 
     741                 :             :  *      %G_IO_CHANNEL_ERROR_INVAL.
     742                 :             :  **/
     743                 :             : GIOChannelError
     744                 :           0 : g_io_channel_error_from_errno (gint en)
     745                 :             : {
     746                 :             : #ifdef EAGAIN
     747                 :           0 :   g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED);
     748                 :             : #endif
     749                 :             : 
     750                 :           0 :   switch (en)
     751                 :             :     {
     752                 :             : #ifdef EBADF
     753                 :           0 :     case EBADF:
     754                 :           0 :       g_warning ("Invalid file descriptor.");
     755                 :           0 :       return G_IO_CHANNEL_ERROR_FAILED;
     756                 :             : #endif
     757                 :             : 
     758                 :             : #ifdef EFAULT
     759                 :           0 :     case EFAULT:
     760                 :           0 :       g_warning ("Buffer outside valid address space.");
     761                 :           0 :       return G_IO_CHANNEL_ERROR_FAILED;
     762                 :             : #endif
     763                 :             : 
     764                 :             : #ifdef EFBIG
     765                 :           0 :     case EFBIG:
     766                 :           0 :       return G_IO_CHANNEL_ERROR_FBIG;
     767                 :             : #endif
     768                 :             : 
     769                 :             : #ifdef EINTR
     770                 :             :     /* In general, we should catch EINTR before we get here,
     771                 :             :      * but close() is allowed to return EINTR by POSIX, so
     772                 :             :      * we need to catch it here; EINTR from close() is
     773                 :             :      * unrecoverable, because it's undefined whether
     774                 :             :      * the fd was actually closed or not, so we just return
     775                 :             :      * a generic error code.
     776                 :             :      */
     777                 :           0 :     case EINTR:
     778                 :           0 :       return G_IO_CHANNEL_ERROR_FAILED;
     779                 :             : #endif
     780                 :             : 
     781                 :             : #ifdef EINVAL
     782                 :           0 :     case EINVAL:
     783                 :           0 :       return G_IO_CHANNEL_ERROR_INVAL;
     784                 :             : #endif
     785                 :             : 
     786                 :             : #ifdef EIO
     787                 :           0 :     case EIO:
     788                 :           0 :       return G_IO_CHANNEL_ERROR_IO;
     789                 :             : #endif
     790                 :             : 
     791                 :             : #ifdef EISDIR
     792                 :           0 :     case EISDIR:
     793                 :           0 :       return G_IO_CHANNEL_ERROR_ISDIR;
     794                 :             : #endif
     795                 :             : 
     796                 :             : #ifdef ENOSPC
     797                 :           0 :     case ENOSPC:
     798                 :           0 :       return G_IO_CHANNEL_ERROR_NOSPC;
     799                 :             : #endif
     800                 :             : 
     801                 :             : #ifdef ENXIO
     802                 :           0 :     case ENXIO:
     803                 :           0 :       return G_IO_CHANNEL_ERROR_NXIO;
     804                 :             : #endif
     805                 :             : 
     806                 :             : #ifdef EOVERFLOW
     807                 :             : #if EOVERFLOW != EFBIG
     808                 :           0 :     case EOVERFLOW:
     809                 :           0 :       return G_IO_CHANNEL_ERROR_OVERFLOW;
     810                 :             : #endif
     811                 :             : #endif
     812                 :             : 
     813                 :             : #ifdef EPIPE
     814                 :           0 :     case EPIPE:
     815                 :           0 :       return G_IO_CHANNEL_ERROR_PIPE;
     816                 :             : #endif
     817                 :             : 
     818                 :           0 :     default:
     819                 :           0 :       return G_IO_CHANNEL_ERROR_FAILED;
     820                 :             :     }
     821                 :             : }
     822                 :             : 
     823                 :             : /**
     824                 :             :  * g_io_channel_set_buffer_size:
     825                 :             :  * @channel: a #GIOChannel
     826                 :             :  * @size: the size of the buffer, or 0 to let GLib pick a good size
     827                 :             :  *
     828                 :             :  * Sets the buffer size.
     829                 :             :  **/  
     830                 :             : void
     831                 :           2 : g_io_channel_set_buffer_size (GIOChannel *channel,
     832                 :             :                               gsize       size)
     833                 :             : {
     834                 :           2 :   g_return_if_fail (channel != NULL);
     835                 :             : 
     836                 :           2 :   if (size == 0)
     837                 :           0 :     size = G_IO_NICE_BUF_SIZE;
     838                 :             : 
     839                 :           2 :   if (size < MAX_CHAR_SIZE)
     840                 :           0 :     size = MAX_CHAR_SIZE;
     841                 :             : 
     842                 :           2 :   channel->buf_size = size;
     843                 :             : }
     844                 :             : 
     845                 :             : /**
     846                 :             :  * g_io_channel_get_buffer_size:
     847                 :             :  * @channel: a #GIOChannel
     848                 :             :  *
     849                 :             :  * Gets the buffer size.
     850                 :             :  *
     851                 :             :  * Returns: the size of the buffer.
     852                 :             :  **/  
     853                 :             : gsize
     854                 :           1 : g_io_channel_get_buffer_size (GIOChannel *channel)
     855                 :             : {
     856                 :           1 :   g_return_val_if_fail (channel != NULL, 0);
     857                 :             : 
     858                 :           1 :   return channel->buf_size;
     859                 :             : }
     860                 :             : 
     861                 :             : /**
     862                 :             :  * g_io_channel_set_line_term:
     863                 :             :  * @channel: a #GIOChannel
     864                 :             :  * @line_term: (nullable): The line termination string. Use %NULL for
     865                 :             :  *             autodetect.  Autodetection breaks on "\n", "\r\n", "\r", "\0",
     866                 :             :  *             and the Unicode paragraph separator. Autodetection should not be
     867                 :             :  *             used for anything other than file-based channels.
     868                 :             :  * @length: The length of the termination string. If -1 is passed, the
     869                 :             :  *          string is assumed to be nul-terminated. This option allows
     870                 :             :  *          termination strings with embedded nuls.
     871                 :             :  *
     872                 :             :  * This sets the string that #GIOChannel uses to determine
     873                 :             :  * where in the file a line break occurs.
     874                 :             :  **/
     875                 :             : void
     876                 :           2 : g_io_channel_set_line_term (GIOChannel  *channel,
     877                 :             :                             const gchar *line_term,
     878                 :             :                             gint         length)
     879                 :             : {
     880                 :           2 :   g_return_if_fail (channel != NULL);
     881                 :           2 :   g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
     882                 :             : 
     883                 :           2 :   g_free (channel->line_term);
     884                 :             : 
     885                 :           2 :   if (line_term == NULL)
     886                 :             :     {
     887                 :           0 :       channel->line_term = NULL;
     888                 :           0 :       channel->line_term_len = 0;
     889                 :             :     }
     890                 :           2 :   else if (length >= 0)
     891                 :             :     {
     892                 :             :       /* We store the value nul-terminated even if the input is not */
     893                 :           1 :       channel->line_term = g_malloc0 (length + 1);
     894                 :           1 :       memcpy (channel->line_term, line_term, length);
     895                 :           1 :       channel->line_term_len = (guint) length;
     896                 :             :     }
     897                 :             :   else
     898                 :             :     {
     899                 :             :       /* We’re constrained by line_term_len being a guint here */
     900                 :           1 :       gsize length_size = strlen (line_term);
     901                 :           1 :       g_return_if_fail (length_size <= G_MAXUINT);
     902                 :           1 :       channel->line_term = g_strdup (line_term);
     903                 :           1 :       channel->line_term_len = (guint) length_size;
     904                 :             :     }
     905                 :             : }
     906                 :             : 
     907                 :             : /**
     908                 :             :  * g_io_channel_get_line_term:
     909                 :             :  * @channel: a #GIOChannel
     910                 :             :  * @length: (out) (optional): a location to return the length of the line terminator
     911                 :             :  *
     912                 :             :  * This returns the string that #GIOChannel uses to determine
     913                 :             :  * where in the file a line break occurs. A value of %NULL
     914                 :             :  * indicates autodetection. Since 2.84, the return value is always
     915                 :             :  * nul-terminated.
     916                 :             :  *
     917                 :             :  * Returns: The line termination string. This value
     918                 :             :  *   is owned by GLib and must not be freed.
     919                 :             :  **/
     920                 :             : const gchar *
     921                 :           3 : g_io_channel_get_line_term (GIOChannel *channel,
     922                 :             :                             gint       *length)
     923                 :             : {
     924                 :           3 :   g_return_val_if_fail (channel != NULL, NULL);
     925                 :             : 
     926                 :           3 :   if (length)
     927                 :           2 :     *length = channel->line_term_len;
     928                 :             : 
     929                 :           3 :   return channel->line_term;
     930                 :             : }
     931                 :             : 
     932                 :             : /**
     933                 :             :  * g_io_channel_set_flags:
     934                 :             :  * @channel: a #GIOChannel
     935                 :             :  * @flags: the flags to set on the IO channel
     936                 :             :  * @error: A location to return an error of type #GIOChannelError
     937                 :             :  *
     938                 :             :  * Sets the (writeable) flags in @channel to (@flags & %G_IO_FLAG_SET_MASK).
     939                 :             :  *
     940                 :             :  * Returns: the status of the operation. 
     941                 :             :  **/
     942                 :             : /**
     943                 :             :  * GIOFlags:
     944                 :             :  * @G_IO_FLAG_NONE: no special flags set. Since: 2.74
     945                 :             :  * @G_IO_FLAG_APPEND: turns on append mode, corresponds to %O_APPEND
     946                 :             :  *     (see the documentation of the UNIX open() syscall)
     947                 :             :  * @G_IO_FLAG_NONBLOCK: turns on nonblocking mode, corresponds to
     948                 :             :  *     %O_NONBLOCK/%O_NDELAY (see the documentation of the UNIX open()
     949                 :             :  *     syscall)
     950                 :             :  * @G_IO_FLAG_IS_READABLE: indicates that the io channel is readable.
     951                 :             :  *     This flag cannot be changed.
     952                 :             :  * @G_IO_FLAG_IS_WRITABLE: indicates that the io channel is writable.
     953                 :             :  *     This flag cannot be changed.
     954                 :             :  * @G_IO_FLAG_IS_WRITEABLE: a misspelled version of @G_IO_FLAG_IS_WRITABLE
     955                 :             :  *     that existed before the spelling was fixed in GLib 2.30. It is kept
     956                 :             :  *     here for compatibility reasons. Deprecated since 2.30
     957                 :             :  * @G_IO_FLAG_IS_SEEKABLE: indicates that the io channel is seekable,
     958                 :             :  *     i.e. that g_io_channel_seek_position() can be used on it.
     959                 :             :  *     This flag cannot be changed.
     960                 :             :  * @G_IO_FLAG_MASK: the mask that specifies all the valid flags.
     961                 :             :  * @G_IO_FLAG_GET_MASK: the mask of the flags that are returned from
     962                 :             :  *     g_io_channel_get_flags()
     963                 :             :  * @G_IO_FLAG_SET_MASK: the mask of the flags that the user can modify
     964                 :             :  *     with g_io_channel_set_flags()
     965                 :             :  *
     966                 :             :  * Specifies properties of a #GIOChannel. Some of the flags can only be
     967                 :             :  * read with g_io_channel_get_flags(), but not changed with
     968                 :             :  * g_io_channel_set_flags().
     969                 :             :  */
     970                 :             : GIOStatus
     971                 :          40 : g_io_channel_set_flags (GIOChannel  *channel,
     972                 :             :                         GIOFlags     flags,
     973                 :             :                         GError     **error)
     974                 :             : {
     975                 :          40 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
     976                 :          40 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
     977                 :             :                         G_IO_STATUS_ERROR);
     978                 :             : 
     979                 :          40 :   return (*channel->funcs->io_set_flags) (channel,
     980                 :          40 :                                           flags & G_IO_FLAG_SET_MASK,
     981                 :             :                                           error);
     982                 :             : }
     983                 :             : 
     984                 :             : /**
     985                 :             :  * g_io_channel_get_flags:
     986                 :             :  * @channel: a #GIOChannel
     987                 :             :  *
     988                 :             :  * Gets the current flags for a #GIOChannel, including read-only
     989                 :             :  * flags such as %G_IO_FLAG_IS_READABLE.
     990                 :             :  *
     991                 :             :  * The values of the flags %G_IO_FLAG_IS_READABLE and %G_IO_FLAG_IS_WRITABLE
     992                 :             :  * are cached for internal use by the channel when it is created.
     993                 :             :  * If they should change at some later point (e.g. partial shutdown
     994                 :             :  * of a socket with the UNIX shutdown() function), the user
     995                 :             :  * should immediately call g_io_channel_get_flags() to update
     996                 :             :  * the internal values of these flags.
     997                 :             :  *
     998                 :             :  * Returns: the flags which are set on the channel
     999                 :             :  **/
    1000                 :             : GIOFlags
    1001                 :          34 : g_io_channel_get_flags (GIOChannel *channel)
    1002                 :             : {
    1003                 :             :   GIOFlags flags;
    1004                 :             : 
    1005                 :          34 :   g_return_val_if_fail (channel != NULL, 0);
    1006                 :             : 
    1007                 :          34 :   flags = (* channel->funcs->io_get_flags) (channel);
    1008                 :             : 
    1009                 :             :   /* Cross implementation code */
    1010                 :             : 
    1011                 :          34 :   if (channel->is_seekable)
    1012                 :           8 :     flags |= G_IO_FLAG_IS_SEEKABLE;
    1013                 :          34 :   if (channel->is_readable)
    1014                 :           2 :     flags |= G_IO_FLAG_IS_READABLE;
    1015                 :          34 :   if (channel->is_writeable)
    1016                 :          34 :     flags |= G_IO_FLAG_IS_WRITABLE;
    1017                 :             : 
    1018                 :          34 :   return flags;
    1019                 :             : }
    1020                 :             : 
    1021                 :             : /**
    1022                 :             :  * g_io_channel_set_close_on_unref:
    1023                 :             :  * @channel: a #GIOChannel
    1024                 :             :  * @do_close: Whether to close the channel on the final unref of
    1025                 :             :  *            the GIOChannel data structure.
    1026                 :             :  *
    1027                 :             :  * Whether to close the channel on the final unref of the #GIOChannel
    1028                 :             :  * data structure. The default value of this is %TRUE for channels
    1029                 :             :  * created by g_io_channel_new_file (), and %FALSE for all other channels.
    1030                 :             :  *
    1031                 :             :  * Setting this flag to %TRUE for a channel you have already closed
    1032                 :             :  * can cause problems when the final reference to the #GIOChannel is dropped.
    1033                 :             :  **/
    1034                 :             : void
    1035                 :         805 : g_io_channel_set_close_on_unref (GIOChannel *channel,
    1036                 :             :                                  gboolean    do_close)
    1037                 :             : {
    1038                 :         805 :   g_return_if_fail (channel != NULL);
    1039                 :             : 
    1040                 :         805 :   channel->close_on_unref = do_close;
    1041                 :             : }
    1042                 :             : 
    1043                 :             : /**
    1044                 :             :  * g_io_channel_get_close_on_unref:
    1045                 :             :  * @channel: a #GIOChannel.
    1046                 :             :  *
    1047                 :             :  * Returns whether the file/socket/whatever associated with @channel
    1048                 :             :  * will be closed when @channel receives its final unref and is
    1049                 :             :  * destroyed. The default value of this is %TRUE for channels created
    1050                 :             :  * by g_io_channel_new_file (), and %FALSE for all other channels.
    1051                 :             :  *
    1052                 :             :  * Returns: %TRUE if the channel will be closed, %FALSE otherwise.
    1053                 :             :  **/
    1054                 :             : gboolean
    1055                 :           1 : g_io_channel_get_close_on_unref (GIOChannel *channel)
    1056                 :             : {
    1057                 :           1 :   g_return_val_if_fail (channel != NULL, FALSE);
    1058                 :             : 
    1059                 :           1 :   return channel->close_on_unref;
    1060                 :             : }
    1061                 :             : 
    1062                 :             : /**
    1063                 :             :  * g_io_channel_seek_position:
    1064                 :             :  * @channel: a #GIOChannel
    1065                 :             :  * @offset: The offset in bytes from the position specified by @type
    1066                 :             :  * @type: a #GSeekType. The type %G_SEEK_CUR is only allowed in those
    1067                 :             :  *                      cases where a call to g_io_channel_set_encoding ()
    1068                 :             :  *                      is allowed. See the documentation for
    1069                 :             :  *                      g_io_channel_set_encoding () for details.
    1070                 :             :  * @error: A location to return an error of type #GIOChannelError
    1071                 :             :  *
    1072                 :             :  * Replacement for g_io_channel_seek() with the new API.
    1073                 :             :  *
    1074                 :             :  * Returns: the status of the operation.
    1075                 :             :  **/
    1076                 :             : /**
    1077                 :             :  * GSeekType:
    1078                 :             :  * @G_SEEK_CUR: the current position in the file.
    1079                 :             :  * @G_SEEK_SET: the start of the file.
    1080                 :             :  * @G_SEEK_END: the end of the file.
    1081                 :             :  *
    1082                 :             :  * An enumeration specifying the base position for a
    1083                 :             :  * g_io_channel_seek_position() operation.
    1084                 :             :  **/
    1085                 :             : GIOStatus
    1086                 :           0 : g_io_channel_seek_position (GIOChannel  *channel,
    1087                 :             :                             gint64       offset,
    1088                 :             :                             GSeekType    type,
    1089                 :             :                             GError     **error)
    1090                 :             : {
    1091                 :             :   GIOStatus status;
    1092                 :             : 
    1093                 :             :   /* For files, only one of the read and write buffers can contain data.
    1094                 :             :    * For sockets, both can contain data.
    1095                 :             :    */
    1096                 :             : 
    1097                 :           0 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    1098                 :           0 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    1099                 :             :                         G_IO_STATUS_ERROR);
    1100                 :           0 :   g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR);
    1101                 :             : 
    1102                 :           0 :   switch (type)
    1103                 :             :     {
    1104                 :           0 :       case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */
    1105                 :           0 :         if (channel->use_buffer)
    1106                 :             :           {
    1107                 :           0 :             if (channel->do_encode && channel->encoded_read_buf
    1108                 :           0 :                 && channel->encoded_read_buf->len > 0)
    1109                 :             :               {
    1110                 :           0 :                 g_warning ("Seek type G_SEEK_CUR not allowed for this"
    1111                 :             :                   " channel's encoding.");
    1112                 :           0 :                 return G_IO_STATUS_ERROR;
    1113                 :             :               }
    1114                 :           0 :           if (channel->read_buf)
    1115                 :           0 :             offset -= channel->read_buf->len;
    1116                 :           0 :           if (channel->encoded_read_buf)
    1117                 :             :             {
    1118                 :           0 :               g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
    1119                 :             : 
    1120                 :             :               /* If there's anything here, it's because the encoding is UTF-8,
    1121                 :             :                * so we can just subtract the buffer length, the same as for
    1122                 :             :                * the unencoded data.
    1123                 :             :                */
    1124                 :             : 
    1125                 :           0 :               offset -= channel->encoded_read_buf->len;
    1126                 :             :             }
    1127                 :             :           }
    1128                 :           0 :         break;
    1129                 :           0 :       case G_SEEK_SET:
    1130                 :             :       case G_SEEK_END:
    1131                 :           0 :         break;
    1132                 :           0 :       default:
    1133                 :           0 :         g_warning ("g_io_channel_seek_position: unknown seek type");
    1134                 :           0 :         return G_IO_STATUS_ERROR;
    1135                 :             :     }
    1136                 :             : 
    1137                 :           0 :   if (channel->use_buffer)
    1138                 :             :     {
    1139                 :           0 :       status = g_io_channel_flush (channel, error);
    1140                 :           0 :       if (status != G_IO_STATUS_NORMAL)
    1141                 :           0 :         return status;
    1142                 :             :     }
    1143                 :             : 
    1144                 :           0 :   status = channel->funcs->io_seek (channel, offset, type, error);
    1145                 :             : 
    1146                 :           0 :   if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer))
    1147                 :             :     {
    1148                 :           0 :       if (channel->read_buf)
    1149                 :           0 :         g_string_truncate (channel->read_buf, 0);
    1150                 :             : 
    1151                 :             :       /* Conversion state no longer matches position in file */
    1152                 :           0 :       if (channel->read_cd != (GIConv) -1)
    1153                 :           0 :         g_iconv (channel->read_cd, NULL, NULL, NULL, NULL);
    1154                 :           0 :       if (channel->write_cd != (GIConv) -1)
    1155                 :           0 :         g_iconv (channel->write_cd, NULL, NULL, NULL, NULL);
    1156                 :             : 
    1157                 :           0 :       if (channel->encoded_read_buf)
    1158                 :             :         {
    1159                 :           0 :           g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
    1160                 :           0 :           g_string_truncate (channel->encoded_read_buf, 0);
    1161                 :             :         }
    1162                 :             : 
    1163                 :           0 :       if (channel->partial_write_buf[0] != '\0')
    1164                 :             :         {
    1165                 :           0 :           g_warning ("Partial character at end of write buffer not flushed.");
    1166                 :           0 :           channel->partial_write_buf[0] = '\0';
    1167                 :             :         }
    1168                 :             :     }
    1169                 :             : 
    1170                 :           0 :   return status;
    1171                 :             : }
    1172                 :             : 
    1173                 :             : /**
    1174                 :             :  * g_io_channel_flush:
    1175                 :             :  * @channel: a #GIOChannel
    1176                 :             :  * @error: location to store an error of type #GIOChannelError
    1177                 :             :  *
    1178                 :             :  * Flushes the write buffer for the GIOChannel.
    1179                 :             :  *
    1180                 :             :  * Returns: the status of the operation: One of
    1181                 :             :  *   %G_IO_STATUS_NORMAL, %G_IO_STATUS_AGAIN, or
    1182                 :             :  *   %G_IO_STATUS_ERROR.
    1183                 :             :  **/
    1184                 :             : GIOStatus
    1185                 :         204 : g_io_channel_flush (GIOChannel  *channel,
    1186                 :             :                     GError     **error)
    1187                 :             : {
    1188                 :             :   GIOStatus status;
    1189                 :         204 :   gsize this_time = 1, bytes_written = 0;
    1190                 :             : 
    1191                 :         204 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    1192                 :         204 :   g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
    1193                 :             : 
    1194                 :         204 :   if (channel->write_buf == NULL || channel->write_buf->len == 0)
    1195                 :           0 :     return G_IO_STATUS_NORMAL;
    1196                 :             : 
    1197                 :             :   do
    1198                 :             :     {
    1199                 :         204 :       g_assert (this_time > 0);
    1200                 :             : 
    1201                 :         204 :       status = channel->funcs->io_write (channel,
    1202                 :         204 :                                          channel->write_buf->str + bytes_written,
    1203                 :         204 :                                          channel->write_buf->len - bytes_written,
    1204                 :             :                                          &this_time, error);
    1205                 :         204 :       bytes_written += this_time;
    1206                 :             :     }
    1207                 :         204 :   while ((bytes_written < channel->write_buf->len)
    1208                 :         204 :          && (status == G_IO_STATUS_NORMAL));
    1209                 :             : 
    1210                 :         204 :   g_string_erase (channel->write_buf, 0, bytes_written);
    1211                 :             : 
    1212                 :         204 :   return status;
    1213                 :             : }
    1214                 :             : 
    1215                 :             : /**
    1216                 :             :  * g_io_channel_set_buffered:
    1217                 :             :  * @channel: a #GIOChannel
    1218                 :             :  * @buffered: whether to set the channel buffered or unbuffered
    1219                 :             :  *
    1220                 :             :  * The buffering state can only be set if the channel's encoding
    1221                 :             :  * is %NULL. For any other encoding, the channel must be buffered.
    1222                 :             :  *
    1223                 :             :  * A buffered channel can only be set unbuffered if the channel's
    1224                 :             :  * internal buffers have been flushed. Newly created channels or
    1225                 :             :  * channels which have returned %G_IO_STATUS_EOF
    1226                 :             :  * not require such a flush. For write-only channels, a call to
    1227                 :             :  * g_io_channel_flush () is sufficient. For all other channels,
    1228                 :             :  * the buffers may be flushed by a call to g_io_channel_seek_position ().
    1229                 :             :  * This includes the possibility of seeking with seek type %G_SEEK_CUR
    1230                 :             :  * and an offset of zero. Note that this means that socket-based
    1231                 :             :  * channels cannot be set unbuffered once they have had data
    1232                 :             :  * read from them.
    1233                 :             :  *
    1234                 :             :  * On unbuffered channels, it is safe to mix read and write
    1235                 :             :  * calls from the new and old APIs, if this is necessary for
    1236                 :             :  * maintaining old code.
    1237                 :             :  *
    1238                 :             :  * The default state of the channel is buffered.
    1239                 :             :  **/
    1240                 :             : void
    1241                 :         721 : g_io_channel_set_buffered (GIOChannel *channel,
    1242                 :             :                            gboolean    buffered)
    1243                 :             : {
    1244                 :         721 :   g_return_if_fail (channel != NULL);
    1245                 :             : 
    1246                 :         721 :   if (channel->encoding != NULL)
    1247                 :             :     {
    1248                 :           0 :       g_warning ("Need to have NULL encoding to set the buffering state of the "
    1249                 :             :                  "channel.");
    1250                 :           0 :       return;
    1251                 :             :     }
    1252                 :             : 
    1253                 :         721 :   g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0);
    1254                 :         721 :   g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0);
    1255                 :             : 
    1256                 :         721 :   channel->use_buffer = buffered;
    1257                 :             : }
    1258                 :             : 
    1259                 :             : /**
    1260                 :             :  * g_io_channel_get_buffered:
    1261                 :             :  * @channel: a #GIOChannel
    1262                 :             :  *
    1263                 :             :  * Returns whether @channel is buffered.
    1264                 :             :  *
    1265                 :             :  * Return Value: %TRUE if the @channel is buffered. 
    1266                 :             :  **/
    1267                 :             : gboolean
    1268                 :           1 : g_io_channel_get_buffered (GIOChannel *channel)
    1269                 :             : {
    1270                 :           1 :   g_return_val_if_fail (channel != NULL, FALSE);
    1271                 :             : 
    1272                 :           1 :   return channel->use_buffer;
    1273                 :             : }
    1274                 :             : 
    1275                 :             : /**
    1276                 :             :  * g_io_channel_set_encoding:
    1277                 :             :  * @channel: a #GIOChannel
    1278                 :             :  * @encoding: (nullable): the encoding type
    1279                 :             :  * @error: location to store an error of type #GConvertError
    1280                 :             :  *
    1281                 :             :  * Sets the encoding for the input/output of the channel. 
    1282                 :             :  * The internal encoding is always UTF-8. The default encoding 
    1283                 :             :  * for the external file is UTF-8.
    1284                 :             :  *
    1285                 :             :  * The encoding %NULL is safe to use with binary data.
    1286                 :             :  *
    1287                 :             :  * The encoding can only be set if one of the following conditions
    1288                 :             :  * is true:
    1289                 :             :  * 
    1290                 :             :  * - The channel was just created, and has not been written to or read from yet.
    1291                 :             :  *
    1292                 :             :  * - The channel is write-only.
    1293                 :             :  *
    1294                 :             :  * - The channel is a file, and the file pointer was just repositioned
    1295                 :             :  *   by a call to g_io_channel_seek_position(). (This flushes all the
    1296                 :             :  *   internal buffers.)
    1297                 :             :  *
    1298                 :             :  * - The current encoding is %NULL or UTF-8.
    1299                 :             :  *
    1300                 :             :  * - One of the (new API) read functions has just returned %G_IO_STATUS_EOF
    1301                 :             :  *   (or, in the case of g_io_channel_read_to_end(), %G_IO_STATUS_NORMAL).
    1302                 :             :  * 
    1303                 :             :  * -  One of the functions g_io_channel_read_chars() or 
    1304                 :             :  *    g_io_channel_read_unichar() has returned %G_IO_STATUS_AGAIN or 
    1305                 :             :  *    %G_IO_STATUS_ERROR. This may be useful in the case of 
    1306                 :             :  *    %G_CONVERT_ERROR_ILLEGAL_SEQUENCE.
    1307                 :             :  *    Returning one of these statuses from g_io_channel_read_line(),
    1308                 :             :  *    g_io_channel_read_line_string(), or g_io_channel_read_to_end()
    1309                 :             :  *    does not guarantee that the encoding can be changed.
    1310                 :             :  *
    1311                 :             :  * Channels which do not meet one of the above conditions cannot call
    1312                 :             :  * g_io_channel_seek_position() with an offset of %G_SEEK_CUR, and, if 
    1313                 :             :  * they are "seekable", cannot call g_io_channel_write_chars() after 
    1314                 :             :  * calling one of the API "read" functions.
    1315                 :             :  *
    1316                 :             :  * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set
    1317                 :             :  */
    1318                 :             : GIOStatus
    1319                 :         840 : g_io_channel_set_encoding (GIOChannel   *channel,
    1320                 :             :                            const gchar  *encoding,
    1321                 :             :                            GError      **error)
    1322                 :             : {
    1323                 :             :   GIConv read_cd, write_cd;
    1324                 :             : #ifndef G_DISABLE_ASSERT
    1325                 :             :   gboolean did_encode;
    1326                 :             : #endif
    1327                 :             : 
    1328                 :         840 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    1329                 :         840 :   g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
    1330                 :             : 
    1331                 :             :   /* Make sure the encoded buffers are empty */
    1332                 :             : 
    1333                 :         840 :   g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf ||
    1334                 :             :                         channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR);
    1335                 :             : 
    1336                 :         840 :   if (!channel->use_buffer)
    1337                 :             :     {
    1338                 :           0 :       g_warning ("Need to set the channel buffered before setting the encoding.");
    1339                 :           0 :       g_warning ("Assuming this is what you meant and acting accordingly.");
    1340                 :             : 
    1341                 :           0 :       channel->use_buffer = TRUE;
    1342                 :             :     }
    1343                 :             : 
    1344                 :         840 :   if (channel->partial_write_buf[0] != '\0')
    1345                 :             :     {
    1346                 :           0 :       g_warning ("Partial character at end of write buffer not flushed.");
    1347                 :           0 :       channel->partial_write_buf[0] = '\0';
    1348                 :             :     }
    1349                 :             : 
    1350                 :             : #ifndef G_DISABLE_ASSERT
    1351                 :         840 :   did_encode = channel->do_encode;
    1352                 :             : #endif
    1353                 :             : 
    1354                 :         840 :   if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0)
    1355                 :             :     {
    1356                 :         839 :       channel->do_encode = FALSE;
    1357                 :         839 :       read_cd = write_cd = (GIConv) -1;
    1358                 :             :     }
    1359                 :             :   else
    1360                 :             :     {
    1361                 :           1 :       gint err = 0;
    1362                 :           1 :       const gchar *from_enc = NULL, *to_enc = NULL;
    1363                 :             : 
    1364                 :           1 :       if (channel->is_readable)
    1365                 :             :         {
    1366                 :           1 :           read_cd = g_iconv_open ("UTF-8", encoding);
    1367                 :             : 
    1368                 :           1 :           if (read_cd == (GIConv) -1)
    1369                 :             :             {
    1370                 :           0 :               err = errno;
    1371                 :           0 :               from_enc = encoding;
    1372                 :           0 :               to_enc = "UTF-8";
    1373                 :             :             }
    1374                 :             :         }
    1375                 :             :       else
    1376                 :           0 :         read_cd = (GIConv) -1;
    1377                 :             : 
    1378                 :           1 :       if (channel->is_writeable && err == 0)
    1379                 :             :         {
    1380                 :           0 :           write_cd = g_iconv_open (encoding, "UTF-8");
    1381                 :             : 
    1382                 :           0 :           if (write_cd == (GIConv) -1)
    1383                 :             :             {
    1384                 :           0 :               err = errno;
    1385                 :           0 :               from_enc = "UTF-8";
    1386                 :           0 :               to_enc = encoding;
    1387                 :             :             }
    1388                 :             :         }
    1389                 :             :       else
    1390                 :           1 :         write_cd = (GIConv) -1;
    1391                 :             : 
    1392                 :           1 :       if (err != 0)
    1393                 :             :         {
    1394                 :           0 :           g_assert (from_enc);
    1395                 :           0 :           g_assert (to_enc);
    1396                 :             : 
    1397                 :           0 :           if (err == EINVAL)
    1398                 :           0 :             g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
    1399                 :             :                          _("Conversion from character set “%s” to “%s” is not supported"),
    1400                 :             :                          from_enc, to_enc);
    1401                 :             :           else
    1402                 :           0 :             g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
    1403                 :             :                          _("Could not open converter from “%s” to “%s”: %s"),
    1404                 :             :                          from_enc, to_enc, g_strerror (err));
    1405                 :             : 
    1406                 :           0 :           if (read_cd != (GIConv) -1)
    1407                 :           0 :             g_iconv_close (read_cd);
    1408                 :           0 :           if (write_cd != (GIConv) -1)
    1409                 :           0 :             g_iconv_close (write_cd);
    1410                 :             : 
    1411                 :           0 :           return G_IO_STATUS_ERROR;
    1412                 :             :         }
    1413                 :             : 
    1414                 :           1 :       channel->do_encode = TRUE;
    1415                 :             :     }
    1416                 :             : 
    1417                 :             :   /* The encoding is ok, so set the fields in channel */
    1418                 :             : 
    1419                 :         840 :   if (channel->read_cd != (GIConv) -1)
    1420                 :           0 :     g_iconv_close (channel->read_cd);
    1421                 :         840 :   if (channel->write_cd != (GIConv) -1)
    1422                 :           0 :     g_iconv_close (channel->write_cd);
    1423                 :             : 
    1424                 :         840 :   if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0)
    1425                 :             :     {
    1426                 :           0 :       g_assert (!did_encode); /* Encoding UTF-8, NULL doesn't use encoded_read_buf */
    1427                 :             : 
    1428                 :             :       /* This is just validated UTF-8, so we can copy it back into read_buf
    1429                 :             :        * so it can be encoded in whatever the new encoding is.
    1430                 :             :        */
    1431                 :             : 
    1432                 :           0 :       g_string_prepend_len (channel->read_buf, channel->encoded_read_buf->str,
    1433                 :           0 :                             channel->encoded_read_buf->len);
    1434                 :           0 :       g_string_truncate (channel->encoded_read_buf, 0);
    1435                 :             :     }
    1436                 :             : 
    1437                 :         840 :   channel->read_cd = read_cd;
    1438                 :         840 :   channel->write_cd = write_cd;
    1439                 :             : 
    1440                 :         840 :   g_free (channel->encoding);
    1441                 :         840 :   channel->encoding = g_strdup (encoding);
    1442                 :             : 
    1443                 :         840 :   return G_IO_STATUS_NORMAL;
    1444                 :             : }
    1445                 :             : 
    1446                 :             : /**
    1447                 :             :  * g_io_channel_get_encoding:
    1448                 :             :  * @channel: a #GIOChannel
    1449                 :             :  *
    1450                 :             :  * Gets the encoding for the input/output of the channel. 
    1451                 :             :  * The internal encoding is always UTF-8. The encoding %NULL 
    1452                 :             :  * makes the channel safe for binary data.
    1453                 :             :  *
    1454                 :             :  * Returns: A string containing the encoding, this string is
    1455                 :             :  *   owned by GLib and must not be freed.
    1456                 :             :  **/
    1457                 :             : const gchar *
    1458                 :           1 : g_io_channel_get_encoding (GIOChannel *channel)
    1459                 :             : {
    1460                 :           1 :   g_return_val_if_fail (channel != NULL, NULL);
    1461                 :             : 
    1462                 :           1 :   return channel->encoding;
    1463                 :             : }
    1464                 :             : 
    1465                 :             : static GIOStatus
    1466                 :        3724 : g_io_channel_fill_buffer (GIOChannel  *channel,
    1467                 :             :                           GError     **err)
    1468                 :             : {
    1469                 :             :   gsize read_size, cur_len, oldlen;
    1470                 :             :   GIOStatus status;
    1471                 :             : 
    1472                 :        3724 :   if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0)
    1473                 :             :     {
    1474                 :           0 :       status = g_io_channel_flush (channel, err);
    1475                 :           0 :       if (status != G_IO_STATUS_NORMAL)
    1476                 :           0 :         return status;
    1477                 :             :     }
    1478                 :        3724 :   if (channel->is_seekable && channel->partial_write_buf[0] != '\0')
    1479                 :             :     {
    1480                 :           0 :       g_warning ("Partial character at end of write buffer not flushed.");
    1481                 :           0 :       channel->partial_write_buf[0] = '\0';
    1482                 :             :     }
    1483                 :             : 
    1484                 :        3724 :   if (!channel->read_buf)
    1485                 :         220 :     channel->read_buf = g_string_sized_new (channel->buf_size);
    1486                 :             : 
    1487                 :        3724 :   cur_len = channel->read_buf->len;
    1488                 :             : 
    1489                 :        3724 :   g_string_set_size (channel->read_buf, channel->read_buf->len + channel->buf_size);
    1490                 :             : 
    1491                 :        3724 :   status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len,
    1492                 :             :                                     channel->buf_size, &read_size, err);
    1493                 :             : 
    1494                 :        3724 :   g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0));
    1495                 :             : 
    1496                 :        3724 :   g_string_truncate (channel->read_buf, read_size + cur_len);
    1497                 :             : 
    1498                 :        3724 :   if ((status != G_IO_STATUS_NORMAL) &&
    1499                 :         176 :       ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0)))
    1500                 :         143 :     return status;
    1501                 :             : 
    1502                 :        3581 :   g_assert (channel->read_buf->len > 0);
    1503                 :             : 
    1504                 :        3581 :   if (channel->encoded_read_buf)
    1505                 :        2875 :     oldlen = channel->encoded_read_buf->len;
    1506                 :             :   else
    1507                 :             :     {
    1508                 :         706 :       oldlen = 0;
    1509                 :         706 :       if (channel->encoding)
    1510                 :         161 :         channel->encoded_read_buf = g_string_sized_new (channel->buf_size);
    1511                 :             :     }
    1512                 :             : 
    1513                 :        3581 :   if (channel->do_encode)
    1514                 :             :     {
    1515                 :             :       gsize errnum, inbytes_left, outbytes_left;
    1516                 :             :       gchar *inbuf, *outbuf;
    1517                 :             :       int errval;
    1518                 :             : 
    1519                 :           1 :       g_assert (channel->encoded_read_buf);
    1520                 :             : 
    1521                 :           1 : reencode:
    1522                 :             : 
    1523                 :           1 :       inbytes_left = channel->read_buf->len;
    1524                 :           1 :       outbytes_left = MAX (channel->read_buf->len,
    1525                 :             :                            channel->encoded_read_buf->allocated_len
    1526                 :             :                            - channel->encoded_read_buf->len - 1); /* 1 for NULL */
    1527                 :           1 :       outbytes_left = MAX (outbytes_left, 6);
    1528                 :             : 
    1529                 :           1 :       inbuf = channel->read_buf->str;
    1530                 :           1 :       g_string_set_size (channel->encoded_read_buf,
    1531                 :           1 :                          channel->encoded_read_buf->len + outbytes_left);
    1532                 :           1 :       outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len
    1533                 :           1 :                - outbytes_left;
    1534                 :             : 
    1535                 :           1 :       errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left,
    1536                 :             :                         &outbuf, &outbytes_left);
    1537                 :           1 :       errval = errno;
    1538                 :             : 
    1539                 :           1 :       g_assert (inbuf + inbytes_left == channel->read_buf->str
    1540                 :             :                 + channel->read_buf->len);
    1541                 :           1 :       g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str
    1542                 :             :                 + channel->encoded_read_buf->len);
    1543                 :             : 
    1544                 :           1 :       g_string_erase (channel->read_buf, 0,
    1545                 :           1 :                       channel->read_buf->len - inbytes_left);
    1546                 :           1 :       g_string_truncate (channel->encoded_read_buf,
    1547                 :             :                          channel->encoded_read_buf->len - outbytes_left);
    1548                 :             : 
    1549                 :           1 :       if (errnum == (gsize) -1)
    1550                 :             :         {
    1551                 :           0 :           switch (errval)
    1552                 :             :             {
    1553                 :           0 :               case EINVAL:
    1554                 :           0 :                 if ((oldlen == channel->encoded_read_buf->len)
    1555                 :           0 :                   && (status == G_IO_STATUS_EOF))
    1556                 :           0 :                   status = G_IO_STATUS_EOF;
    1557                 :             :                 else
    1558                 :           0 :                   status = G_IO_STATUS_NORMAL;
    1559                 :           0 :                 break;
    1560                 :           0 :               case E2BIG:
    1561                 :             :                 /* Buffer size at least 6, wrote at least on character */
    1562                 :           0 :                 g_assert (inbuf != channel->read_buf->str);
    1563                 :           0 :                 goto reencode;
    1564                 :           0 :               case EILSEQ:
    1565                 :           0 :                 if (oldlen < channel->encoded_read_buf->len)
    1566                 :           0 :                   status = G_IO_STATUS_NORMAL;
    1567                 :             :                 else
    1568                 :             :                   {
    1569                 :           0 :                     g_set_error_literal (err, G_CONVERT_ERROR,
    1570                 :             :                       G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
    1571                 :             :                       _("Invalid byte sequence in conversion input"));
    1572                 :           0 :                     return G_IO_STATUS_ERROR;
    1573                 :             :                   }
    1574                 :           0 :                 break;
    1575                 :           0 :               default:
    1576                 :           0 :                 g_assert (errval != EBADF); /* The converter should be open */
    1577                 :           0 :                 g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
    1578                 :             :                   _("Error during conversion: %s"), g_strerror (errval));
    1579                 :           0 :                 return G_IO_STATUS_ERROR;
    1580                 :             :             }
    1581                 :             :         }
    1582                 :           1 :       g_assert ((status != G_IO_STATUS_NORMAL)
    1583                 :             :                || (channel->encoded_read_buf->len > 0));
    1584                 :             :     }
    1585                 :        3580 :   else if (channel->encoding) /* UTF-8 */
    1586                 :             :     {
    1587                 :             :       gchar *nextchar, *lastchar;
    1588                 :             : 
    1589                 :        3035 :       g_assert (channel->encoded_read_buf);
    1590                 :             : 
    1591                 :        3035 :       nextchar = channel->read_buf->str;
    1592                 :        3035 :       lastchar = channel->read_buf->str + channel->read_buf->len;
    1593                 :             : 
    1594                 :     2393992 :       while (nextchar < lastchar)
    1595                 :             :         {
    1596                 :             :           gunichar val_char;
    1597                 :             : 
    1598                 :     2390957 :           val_char = g_utf8_get_char_validated (nextchar, lastchar - nextchar);
    1599                 :             : 
    1600                 :     2390957 :           switch (val_char)
    1601                 :             :             {
    1602                 :         394 :               case -2:
    1603                 :             :                 /* stop, leave partial character in buffer */
    1604                 :         394 :                 lastchar = nextchar;
    1605                 :         394 :                 break;
    1606                 :           0 :               case -1:
    1607                 :           0 :                 if (oldlen < channel->encoded_read_buf->len)
    1608                 :           0 :                   status = G_IO_STATUS_NORMAL;
    1609                 :             :                 else
    1610                 :             :                   {
    1611                 :           0 :                     g_set_error_literal (err, G_CONVERT_ERROR,
    1612                 :             :                       G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
    1613                 :             :                       _("Invalid byte sequence in conversion input"));
    1614                 :           0 :                     status = G_IO_STATUS_ERROR;
    1615                 :             :                   }
    1616                 :           0 :                 lastchar = nextchar;
    1617                 :           0 :                 break;
    1618                 :     2390563 :               default:
    1619                 :     2390563 :                 nextchar = g_utf8_next_char (nextchar);
    1620                 :     2390563 :                 break;
    1621                 :             :             }
    1622                 :             :         }
    1623                 :             : 
    1624                 :        3035 :       if (lastchar > channel->read_buf->str)
    1625                 :             :         {
    1626                 :        3035 :           gint copy_len = lastchar - channel->read_buf->str;
    1627                 :             : 
    1628                 :        3035 :           g_string_append_len (channel->encoded_read_buf, channel->read_buf->str,
    1629                 :             :                                copy_len);
    1630                 :        3035 :           g_string_erase (channel->read_buf, 0, copy_len);
    1631                 :             :         }
    1632                 :             :     }
    1633                 :             : 
    1634                 :        3581 :   return status;
    1635                 :             : }
    1636                 :             : 
    1637                 :             : /**
    1638                 :             :  * g_io_channel_read_line:
    1639                 :             :  * @channel: a #GIOChannel
    1640                 :             :  * @str_return: (out): The line read from the #GIOChannel, including the
    1641                 :             :  *              line terminator. This data should be freed with g_free()
    1642                 :             :  *              when no longer needed. This is a nul-terminated string. 
    1643                 :             :  *              If a @length of zero is returned, this will be %NULL instead.
    1644                 :             :  * @length: (out) (optional): location to store length of the read data, or %NULL
    1645                 :             :  * @terminator_pos: (out) (optional): location to store position of line terminator, or %NULL
    1646                 :             :  * @error: A location to return an error of type #GConvertError
    1647                 :             :  *         or #GIOChannelError
    1648                 :             :  *
    1649                 :             :  * Reads a line, including the terminating character(s),
    1650                 :             :  * from a #GIOChannel into a newly-allocated string.
    1651                 :             :  * @str_return will contain allocated memory if the return
    1652                 :             :  * is %G_IO_STATUS_NORMAL.
    1653                 :             :  *
    1654                 :             :  * Returns: the status of the operation.
    1655                 :             :  **/
    1656                 :             : GIOStatus
    1657                 :         259 : g_io_channel_read_line (GIOChannel  *channel,
    1658                 :             :                         gchar      **str_return,
    1659                 :             :                         gsize       *length,
    1660                 :             :                         gsize       *terminator_pos,
    1661                 :             :                         GError     **error)
    1662                 :             : {
    1663                 :             :   GIOStatus status;
    1664                 :             :   gsize got_length;
    1665                 :             :   
    1666                 :         259 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    1667                 :         259 :   g_return_val_if_fail (str_return != NULL, G_IO_STATUS_ERROR);
    1668                 :         259 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    1669                 :             :                         G_IO_STATUS_ERROR);
    1670                 :         259 :   g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
    1671                 :             : 
    1672                 :         259 :   status = g_io_channel_read_line_backend (channel, &got_length, terminator_pos, error);
    1673                 :             : 
    1674                 :         259 :   if (length && status != G_IO_STATUS_ERROR)
    1675                 :           1 :     *length = got_length;
    1676                 :             : 
    1677                 :         259 :   if (status == G_IO_STATUS_NORMAL)
    1678                 :             :     {
    1679                 :             :       gchar *line;
    1680                 :             : 
    1681                 :             :       /* Copy the read bytes (including any embedded nuls) and nul-terminate.
    1682                 :             :        * `USE_BUF (channel)->str` is guaranteed to be nul-terminated as it’s a
    1683                 :             :        * #GString, so it’s safe to call g_memdup2() with +1 length to allocate
    1684                 :             :        * a nul-terminator. */
    1685                 :         259 :       g_assert (USE_BUF (channel));
    1686                 :         259 :       line = g_memdup2 (USE_BUF (channel)->str, got_length + 1);
    1687                 :         259 :       line[got_length] = '\0';
    1688                 :         259 :       *str_return = g_steal_pointer (&line);
    1689                 :         259 :       g_string_erase (USE_BUF (channel), 0, got_length);
    1690                 :             :     }
    1691                 :             :   else
    1692                 :           0 :     *str_return = NULL;
    1693                 :             :   
    1694                 :         259 :   return status;
    1695                 :             : }
    1696                 :             : 
    1697                 :             : /**
    1698                 :             :  * g_io_channel_read_line_string:
    1699                 :             :  * @channel: a #GIOChannel
    1700                 :             :  * @buffer: a #GString into which the line will be written.
    1701                 :             :  *          If @buffer already contains data, the old data will
    1702                 :             :  *          be overwritten.
    1703                 :             :  * @terminator_pos: (nullable): location to store position of line terminator, or %NULL
    1704                 :             :  * @error: a location to store an error of type #GConvertError
    1705                 :             :  *         or #GIOChannelError
    1706                 :             :  *
    1707                 :             :  * Reads a line from a #GIOChannel, using a #GString as a buffer.
    1708                 :             :  *
    1709                 :             :  * Returns: the status of the operation.
    1710                 :             :  **/
    1711                 :             : GIOStatus
    1712                 :       20033 : g_io_channel_read_line_string (GIOChannel  *channel,
    1713                 :             :                                GString     *buffer,
    1714                 :             :                                gsize       *terminator_pos,
    1715                 :             :                                GError     **error)
    1716                 :             : {
    1717                 :             :   gsize length;
    1718                 :             :   GIOStatus status;
    1719                 :             : 
    1720                 :       20033 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    1721                 :       20033 :   g_return_val_if_fail (buffer != NULL, G_IO_STATUS_ERROR);
    1722                 :       20033 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    1723                 :             :                         G_IO_STATUS_ERROR);
    1724                 :       20033 :   g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
    1725                 :             : 
    1726                 :       20033 :   if (buffer->len > 0)
    1727                 :             :     g_string_truncate (buffer, 0); /* clear out the buffer */
    1728                 :             : 
    1729                 :       20033 :   status = g_io_channel_read_line_backend (channel, &length, terminator_pos, error);
    1730                 :             : 
    1731                 :       20033 :   if (status == G_IO_STATUS_NORMAL)
    1732                 :             :     {
    1733                 :       20031 :       g_assert (USE_BUF (channel));
    1734                 :       20031 :       g_string_append_len (buffer, USE_BUF (channel)->str, length);
    1735                 :       20031 :       g_string_erase (USE_BUF (channel), 0, length);
    1736                 :             :     }
    1737                 :             : 
    1738                 :       20033 :   return status;
    1739                 :             : }
    1740                 :             : 
    1741                 :             : 
    1742                 :             : static GIOStatus
    1743                 :       20292 : g_io_channel_read_line_backend (GIOChannel  *channel,
    1744                 :             :                                 gsize       *length,
    1745                 :             :                                 gsize       *terminator_pos,
    1746                 :             :                                 GError     **error)
    1747                 :             : {
    1748                 :             :   GIOStatus status;
    1749                 :             :   gsize checked_to, line_term_len, line_length, got_term_len;
    1750                 :       20292 :   gboolean first_time = TRUE;
    1751                 :             : 
    1752                 :       20292 :   if (!channel->use_buffer)
    1753                 :             :     {
    1754                 :             :       /* Can't do a raw read in read_line */
    1755                 :           0 :       g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
    1756                 :             :                            _("Can’t do a raw read in g_io_channel_read_line_string"));
    1757                 :           0 :       return G_IO_STATUS_ERROR;
    1758                 :             :     }
    1759                 :             : 
    1760                 :       20292 :   status = G_IO_STATUS_NORMAL;
    1761                 :             : 
    1762                 :       20292 :   if (channel->line_term)
    1763                 :           1 :     line_term_len = channel->line_term_len;
    1764                 :             :   else
    1765                 :       20291 :     line_term_len = 3;
    1766                 :             :     /* This value used for setting checked_to, it's the longest of the four
    1767                 :             :      * we autodetect for.
    1768                 :             :      */
    1769                 :             : 
    1770                 :       20292 :   checked_to = 0;
    1771                 :             : 
    1772                 :             :   while (TRUE)
    1773                 :        2711 :     {
    1774                 :             :       gchar *nextchar, *lastchar;
    1775                 :             :       GString *use_buf;
    1776                 :             : 
    1777                 :       23003 :       if (!first_time || (BUF_LEN (USE_BUF (channel)) == 0))
    1778                 :             :         {
    1779                 :        2996 : read_again:
    1780                 :        2996 :           status = g_io_channel_fill_buffer (channel, error);
    1781                 :        2996 :           switch (status)
    1782                 :             :             {
    1783                 :        2994 :               case G_IO_STATUS_NORMAL:
    1784                 :        2994 :                 if (BUF_LEN (USE_BUF (channel)) == 0)
    1785                 :             :                   /* Can happen when using conversion and only read
    1786                 :             :                    * part of a character
    1787                 :             :                    */
    1788                 :             :                   {
    1789                 :           0 :                     first_time = FALSE;
    1790                 :           0 :                     continue;
    1791                 :             :                   }
    1792                 :        2994 :                 break;
    1793                 :           2 :               case G_IO_STATUS_EOF:
    1794                 :           2 :                 if (BUF_LEN (USE_BUF (channel)) == 0)
    1795                 :             :                   {
    1796                 :           2 :                     if (length)
    1797                 :           2 :                       *length = 0;
    1798                 :             : 
    1799                 :           2 :                     if (channel->encoding && channel->read_buf->len != 0)
    1800                 :             :                       {
    1801                 :           0 :                         g_set_error_literal (error, G_CONVERT_ERROR,
    1802                 :             :                                              G_CONVERT_ERROR_PARTIAL_INPUT,
    1803                 :             :                                              _("Leftover unconverted data in "
    1804                 :             :                                                "read buffer"));
    1805                 :           0 :                         return G_IO_STATUS_ERROR;
    1806                 :             :                       }
    1807                 :             :                     else
    1808                 :           2 :                       return G_IO_STATUS_EOF;
    1809                 :             :                   }
    1810                 :           0 :                 break;
    1811                 :           0 :               default:
    1812                 :           0 :                 if (length)
    1813                 :           0 :                   *length = 0;
    1814                 :           0 :                 return status;
    1815                 :             :             }
    1816                 :             :         }
    1817                 :             : 
    1818                 :       23001 :       g_assert (BUF_LEN (USE_BUF (channel)) != 0);
    1819                 :             : 
    1820                 :       23001 :       use_buf = USE_BUF (channel); /* The buffer has been created by this point */
    1821                 :             : 
    1822                 :       23001 :       first_time = FALSE;
    1823                 :             : 
    1824                 :       23001 :       lastchar = use_buf->str + use_buf->len;
    1825                 :             : 
    1826                 :     2398264 :       for (nextchar = use_buf->str + checked_to; nextchar < lastchar;
    1827                 :     2375263 :            channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++)
    1828                 :             :         {
    1829                 :     2395553 :           if (channel->line_term)
    1830                 :             :             {
    1831                 :           8 :               if (memcmp (channel->line_term, nextchar, line_term_len) == 0)
    1832                 :             :                 {
    1833                 :           1 :                   line_length = nextchar - use_buf->str;
    1834                 :           1 :                   got_term_len = line_term_len;
    1835                 :           1 :                   goto done;
    1836                 :             :                 }
    1837                 :             :             }
    1838                 :             :           else /* auto detect */
    1839                 :             :             {
    1840                 :     2395545 :               switch (*nextchar)
    1841                 :             :                 {
    1842                 :       20289 :                   case '\n': /* unix */
    1843                 :       20289 :                     line_length = nextchar - use_buf->str;
    1844                 :       20289 :                     got_term_len = 1;
    1845                 :       20289 :                     goto done;
    1846                 :           0 :                   case '\r': /* Warning: do not use with sockets */
    1847                 :           0 :                     line_length = nextchar - use_buf->str;
    1848                 :           0 :                     if ((nextchar == lastchar - 1) && (status != G_IO_STATUS_EOF)
    1849                 :           0 :                        && (lastchar == use_buf->str + use_buf->len))
    1850                 :           0 :                       goto read_again; /* Try to read more data */
    1851                 :           0 :                     if ((nextchar < lastchar - 1) && (*(nextchar + 1) == '\n')) /* dos */
    1852                 :           0 :                       got_term_len = 2;
    1853                 :             :                     else /* mac */
    1854                 :           0 :                       got_term_len = 1;
    1855                 :           0 :                     goto done;
    1856                 :       47032 :                   case '\xe2': /* Unicode paragraph separator */
    1857                 :       47032 :                     if (strncmp ("\xe2\x80\xa9", nextchar, 3) == 0)
    1858                 :             :                       {
    1859                 :           0 :                         line_length = nextchar - use_buf->str;
    1860                 :           0 :                         got_term_len = 3;
    1861                 :           0 :                         goto done;
    1862                 :             :                       }
    1863                 :       47032 :                     break;
    1864                 :           0 :                   case '\0': /* Embedded null in input */
    1865                 :           0 :                     line_length = nextchar - use_buf->str;
    1866                 :           0 :                     got_term_len = 1;
    1867                 :           0 :                     goto done;
    1868                 :     2328224 :                   default: /* no match */
    1869                 :     2328224 :                     break;
    1870                 :             :                 }
    1871                 :             :             }
    1872                 :             :         }
    1873                 :             : 
    1874                 :             :       /* If encoding != NULL, valid UTF-8, didn't overshoot */
    1875                 :        2711 :       g_assert (nextchar == lastchar);
    1876                 :             : 
    1877                 :             :       /* Check for EOF */
    1878                 :             : 
    1879                 :        2711 :       if (status == G_IO_STATUS_EOF)
    1880                 :             :         {
    1881                 :           0 :           if (channel->encoding && channel->read_buf->len > 0)
    1882                 :             :             {
    1883                 :           0 :               g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
    1884                 :             :                                    _("Channel terminates in a partial character"));
    1885                 :           0 :               return G_IO_STATUS_ERROR;
    1886                 :             :             }
    1887                 :           0 :           line_length = use_buf->len;
    1888                 :           0 :           got_term_len = 0;
    1889                 :           0 :           break;
    1890                 :             :         }
    1891                 :             : 
    1892                 :        2711 :       if (use_buf->len > line_term_len - 1)
    1893                 :        2662 :         checked_to = use_buf->len - (line_term_len - 1);
    1894                 :             :       else
    1895                 :          49 :         checked_to = 0;
    1896                 :             :     }
    1897                 :             : 
    1898                 :       20290 : done:
    1899                 :             : 
    1900                 :       20290 :   if (terminator_pos)
    1901                 :       20112 :     *terminator_pos = line_length;
    1902                 :             : 
    1903                 :       20290 :   if (length)
    1904                 :       20290 :     *length = line_length + got_term_len;
    1905                 :             : 
    1906                 :       20290 :   return G_IO_STATUS_NORMAL;
    1907                 :             : }
    1908                 :             : 
    1909                 :             : /**
    1910                 :             :  * g_io_channel_read_to_end:
    1911                 :             :  * @channel: a #GIOChannel
    1912                 :             :  * @str_return:  (out) (array length=length) (element-type guint8): Location to
    1913                 :             :  *              store a pointer to a string holding the remaining data in the
    1914                 :             :  *              #GIOChannel. This data should be freed with g_free() when no
    1915                 :             :  *              longer needed. This data is terminated by an extra nul
    1916                 :             :  *              character, but there may be other nuls in the intervening data.
    1917                 :             :  * @length: (out): location to store length of the data
    1918                 :             :  * @error: location to return an error of type #GConvertError
    1919                 :             :  *         or #GIOChannelError
    1920                 :             :  *
    1921                 :             :  * Reads all the remaining data from the file.
    1922                 :             :  *
    1923                 :             :  * Returns: %G_IO_STATUS_NORMAL on success. 
    1924                 :             :  *     This function never returns %G_IO_STATUS_EOF.
    1925                 :             :  **/
    1926                 :             : GIOStatus
    1927                 :           0 : g_io_channel_read_to_end (GIOChannel  *channel,
    1928                 :             :                           gchar      **str_return,
    1929                 :             :                           gsize       *length,
    1930                 :             :                           GError     **error)
    1931                 :             : {
    1932                 :             :   GIOStatus status;
    1933                 :             :     
    1934                 :           0 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    1935                 :           0 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    1936                 :             :     G_IO_STATUS_ERROR);
    1937                 :           0 :   g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
    1938                 :             : 
    1939                 :           0 :   if (str_return)
    1940                 :           0 :     *str_return = NULL;
    1941                 :           0 :   if (length)
    1942                 :           0 :     *length = 0;
    1943                 :             : 
    1944                 :           0 :   if (!channel->use_buffer)
    1945                 :             :     {
    1946                 :           0 :       g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
    1947                 :             :                            _("Can’t do a raw read in g_io_channel_read_to_end"));
    1948                 :           0 :       return G_IO_STATUS_ERROR;
    1949                 :             :     }
    1950                 :             : 
    1951                 :             :   do
    1952                 :           0 :     status = g_io_channel_fill_buffer (channel, error);
    1953                 :           0 :   while (status == G_IO_STATUS_NORMAL);
    1954                 :             : 
    1955                 :           0 :   if (status != G_IO_STATUS_EOF)
    1956                 :           0 :     return status;
    1957                 :             : 
    1958                 :           0 :   if (channel->encoding && channel->read_buf->len > 0)
    1959                 :             :     {
    1960                 :           0 :       g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
    1961                 :             :                            _("Channel terminates in a partial character"));
    1962                 :           0 :       return G_IO_STATUS_ERROR;
    1963                 :             :     }
    1964                 :             : 
    1965                 :           0 :   if (USE_BUF (channel) == NULL)
    1966                 :             :     {
    1967                 :             :       /* length is already set to zero */
    1968                 :           0 :       if (str_return)
    1969                 :           0 :         *str_return = g_strdup ("");
    1970                 :             :     }
    1971                 :             :   else
    1972                 :             :     {
    1973                 :           0 :       if (length)
    1974                 :           0 :         *length = USE_BUF (channel)->len;
    1975                 :             : 
    1976                 :           0 :       if (str_return)
    1977                 :           0 :         *str_return = g_string_free (USE_BUF (channel), FALSE);
    1978                 :             :       else
    1979                 :           0 :         g_string_free (USE_BUF (channel), TRUE);
    1980                 :             : 
    1981                 :           0 :       if (channel->encoding)
    1982                 :           0 :         channel->encoded_read_buf = NULL;
    1983                 :             :       else
    1984                 :           0 :         channel->read_buf = NULL;
    1985                 :             :     }
    1986                 :             : 
    1987                 :           0 :   return G_IO_STATUS_NORMAL;
    1988                 :             : }
    1989                 :             : 
    1990                 :             : /**
    1991                 :             :  * g_io_channel_read_chars:
    1992                 :             :  * @channel: a #GIOChannel
    1993                 :             :  * @buf: (out caller-allocates) (array length=count) (element-type guint8):
    1994                 :             :  *     a buffer to read data into
    1995                 :             :  * @count: (in): the size of the buffer. Note that the buffer may not be
    1996                 :             :  *     completely filled even if there is data in the buffer if the
    1997                 :             :  *     remaining data is not a complete character.
    1998                 :             :  * @bytes_read: (out) (optional): The number of bytes read. This may be
    1999                 :             :  *     zero even on success if count < 6 and the channel's encoding
    2000                 :             :  *     is non-%NULL. This indicates that the next UTF-8 character is
    2001                 :             :  *     too wide for the buffer.
    2002                 :             :  * @error: a location to return an error of type #GConvertError
    2003                 :             :  *     or #GIOChannelError.
    2004                 :             :  *
    2005                 :             :  * Replacement for g_io_channel_read() with the new API.
    2006                 :             :  *
    2007                 :             :  * Returns: the status of the operation.
    2008                 :             :  */
    2009                 :             : GIOStatus
    2010                 :        1422 : g_io_channel_read_chars (GIOChannel  *channel,
    2011                 :             :                          gchar       *buf,
    2012                 :             :                          gsize        count,
    2013                 :             :                          gsize       *bytes_read,
    2014                 :             :                          GError     **error)
    2015                 :             : {
    2016                 :             :   GIOStatus status;
    2017                 :             :   gsize got_bytes;
    2018                 :             : 
    2019                 :        1422 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    2020                 :        1422 :   g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
    2021                 :        1422 :   g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
    2022                 :             : 
    2023                 :        1422 :   if (count == 0)
    2024                 :             :     {
    2025                 :           0 :       if (bytes_read)
    2026                 :           0 :         *bytes_read = 0;
    2027                 :           0 :       return G_IO_STATUS_NORMAL;
    2028                 :             :     }
    2029                 :        1422 :   g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);
    2030                 :             : 
    2031                 :        1422 :   if (!channel->use_buffer)
    2032                 :             :     {
    2033                 :             :       gsize tmp_bytes;
    2034                 :             : 
    2035                 :        1173 :       g_assert (!channel->read_buf || channel->read_buf->len == 0);
    2036                 :             : 
    2037                 :        1173 :       status = channel->funcs->io_read (channel, buf, count, &tmp_bytes, error);
    2038                 :             : 
    2039                 :        1173 :       if (bytes_read)
    2040                 :        1173 :         *bytes_read = tmp_bytes;
    2041                 :             : 
    2042                 :        1173 :       return status;
    2043                 :             :     }
    2044                 :             : 
    2045                 :         249 :   status = G_IO_STATUS_NORMAL;
    2046                 :             : 
    2047                 :         977 :   while (BUF_LEN (USE_BUF (channel)) < count && status == G_IO_STATUS_NORMAL)
    2048                 :         728 :     status = g_io_channel_fill_buffer (channel, error);
    2049                 :             : 
    2050                 :             :   /* Only return an error if we have no data */
    2051                 :             : 
    2052                 :         249 :   if (BUF_LEN (USE_BUF (channel)) == 0)
    2053                 :             :     {
    2054                 :          98 :       g_assert (status != G_IO_STATUS_NORMAL);
    2055                 :             : 
    2056                 :          98 :       if (status == G_IO_STATUS_EOF && channel->encoding
    2057                 :          40 :           && BUF_LEN (channel->read_buf) > 0)
    2058                 :             :         {
    2059                 :           0 :           g_set_error_literal (error, G_CONVERT_ERROR,
    2060                 :             :                                G_CONVERT_ERROR_PARTIAL_INPUT,
    2061                 :             :                                _("Leftover unconverted data in read buffer"));
    2062                 :           0 :           status = G_IO_STATUS_ERROR;
    2063                 :             :         }
    2064                 :             : 
    2065                 :          98 :       if (bytes_read)
    2066                 :          98 :         *bytes_read = 0;
    2067                 :             : 
    2068                 :          98 :       return status;
    2069                 :             :     }
    2070                 :             : 
    2071                 :         151 :   if (status == G_IO_STATUS_ERROR)
    2072                 :           0 :     g_clear_error (error);
    2073                 :             : 
    2074                 :         151 :   got_bytes = MIN (count, BUF_LEN (USE_BUF (channel)));
    2075                 :             : 
    2076                 :         151 :   g_assert (got_bytes > 0);
    2077                 :             : 
    2078                 :         151 :   if (channel->encoding)
    2079                 :             :     /* Don't validate for NULL encoding, binary safe */
    2080                 :             :     {
    2081                 :             :       gchar *nextchar, *prevchar;
    2082                 :             : 
    2083                 :          43 :       g_assert (USE_BUF (channel) == channel->encoded_read_buf);
    2084                 :             : 
    2085                 :          43 :       nextchar = channel->encoded_read_buf->str;
    2086                 :             : 
    2087                 :             :       do
    2088                 :             :         {
    2089                 :         380 :           prevchar = nextchar;
    2090                 :         380 :           nextchar = g_utf8_next_char (nextchar);
    2091                 :         380 :           g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */
    2092                 :             :         }
    2093                 :         380 :       while (nextchar < channel->encoded_read_buf->str + got_bytes);
    2094                 :             : 
    2095                 :          43 :       if (nextchar > channel->encoded_read_buf->str + got_bytes)
    2096                 :           0 :         got_bytes = prevchar - channel->encoded_read_buf->str;
    2097                 :             : 
    2098                 :          43 :       g_assert (got_bytes > 0 || count < 6);
    2099                 :             :     }
    2100                 :             : 
    2101                 :         151 :   memcpy (buf, USE_BUF (channel)->str, got_bytes);
    2102                 :         151 :   g_string_erase (USE_BUF (channel), 0, got_bytes);
    2103                 :             : 
    2104                 :         151 :   if (bytes_read)
    2105                 :         151 :     *bytes_read = got_bytes;
    2106                 :             : 
    2107                 :         151 :   return G_IO_STATUS_NORMAL;
    2108                 :             : }
    2109                 :             : 
    2110                 :             : /**
    2111                 :             :  * g_io_channel_read_unichar:
    2112                 :             :  * @channel: a #GIOChannel
    2113                 :             :  * @thechar: (out): a location to return a character
    2114                 :             :  * @error: a location to return an error of type #GConvertError
    2115                 :             :  *         or #GIOChannelError
    2116                 :             :  *
    2117                 :             :  * Reads a Unicode character from @channel.
    2118                 :             :  * This function cannot be called on a channel with %NULL encoding.
    2119                 :             :  *
    2120                 :             :  * Returns: a #GIOStatus
    2121                 :             :  **/
    2122                 :             : GIOStatus
    2123                 :           0 : g_io_channel_read_unichar (GIOChannel  *channel,
    2124                 :             :                            gunichar    *thechar,
    2125                 :             :                            GError     **error)
    2126                 :             : {
    2127                 :           0 :   GIOStatus status = G_IO_STATUS_NORMAL;
    2128                 :             : 
    2129                 :           0 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    2130                 :           0 :   g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);
    2131                 :           0 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    2132                 :             :                         G_IO_STATUS_ERROR);
    2133                 :           0 :   g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
    2134                 :             : 
    2135                 :           0 :   while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL)
    2136                 :           0 :     status = g_io_channel_fill_buffer (channel, error);
    2137                 :             : 
    2138                 :             :   /* Only return an error if we have no data */
    2139                 :             : 
    2140                 :           0 :   if (BUF_LEN (USE_BUF (channel)) == 0)
    2141                 :             :     {
    2142                 :           0 :       g_assert (status != G_IO_STATUS_NORMAL);
    2143                 :             : 
    2144                 :           0 :       if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0)
    2145                 :             :         {
    2146                 :           0 :           g_set_error_literal (error, G_CONVERT_ERROR,
    2147                 :             :                                G_CONVERT_ERROR_PARTIAL_INPUT,
    2148                 :             :                                _("Leftover unconverted data in read buffer"));
    2149                 :           0 :           status = G_IO_STATUS_ERROR;
    2150                 :             :         }
    2151                 :             : 
    2152                 :           0 :       if (thechar)
    2153                 :           0 :         *thechar = (gunichar) -1;
    2154                 :             : 
    2155                 :           0 :       return status;
    2156                 :             :     }
    2157                 :             : 
    2158                 :           0 :   if (status == G_IO_STATUS_ERROR)
    2159                 :           0 :     g_clear_error (error);
    2160                 :             : 
    2161                 :           0 :   if (thechar)
    2162                 :           0 :     *thechar = g_utf8_get_char (channel->encoded_read_buf->str);
    2163                 :             : 
    2164                 :           0 :   g_string_erase (channel->encoded_read_buf, 0,
    2165                 :           0 :                   g_utf8_next_char (channel->encoded_read_buf->str)
    2166                 :             :                   - channel->encoded_read_buf->str);
    2167                 :             : 
    2168                 :           0 :   return G_IO_STATUS_NORMAL;
    2169                 :             : }
    2170                 :             : 
    2171                 :             : /**
    2172                 :             :  * g_io_channel_write_chars:
    2173                 :             :  * @channel: a #GIOChannel
    2174                 :             :  * @buf: (array) (element-type guint8): a buffer to write data from
    2175                 :             :  * @count: the size of the buffer. If -1, the buffer
    2176                 :             :  *         is taken to be a nul-terminated string.
    2177                 :             :  * @bytes_written: (out): The number of bytes written. This can be nonzero
    2178                 :             :  *                 even if the return value is not %G_IO_STATUS_NORMAL.
    2179                 :             :  *                 If the return value is %G_IO_STATUS_NORMAL and the
    2180                 :             :  *                 channel is blocking, this will always be equal
    2181                 :             :  *                 to @count if @count >= 0.
    2182                 :             :  * @error: a location to return an error of type #GConvertError
    2183                 :             :  *         or #GIOChannelError
    2184                 :             :  *
    2185                 :             :  * Replacement for g_io_channel_write() with the new API.
    2186                 :             :  *
    2187                 :             :  * On seekable channels with encodings other than %NULL or UTF-8, generic
    2188                 :             :  * mixing of reading and writing is not allowed. A call to g_io_channel_write_chars ()
    2189                 :             :  * may only be made on a channel from which data has been read in the
    2190                 :             :  * cases described in the documentation for g_io_channel_set_encoding ().
    2191                 :             :  *
    2192                 :             :  * Returns: the status of the operation.
    2193                 :             :  **/
    2194                 :             : GIOStatus
    2195                 :        2326 : g_io_channel_write_chars (GIOChannel   *channel,
    2196                 :             :                           const gchar  *buf,
    2197                 :             :                           gssize        count,
    2198                 :             :                           gsize        *bytes_written,
    2199                 :             :                           GError      **error)
    2200                 :             : {
    2201                 :             :   gsize count_unsigned;
    2202                 :             :   GIOStatus status;
    2203                 :        2326 :   gsize wrote_bytes = 0;
    2204                 :             : 
    2205                 :        2326 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    2206                 :        2326 :   g_return_val_if_fail (buf != NULL || count == 0, G_IO_STATUS_ERROR);
    2207                 :        2326 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    2208                 :             :                         G_IO_STATUS_ERROR);
    2209                 :        2326 :   g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
    2210                 :             : 
    2211                 :        2326 :   if (count < 0)
    2212                 :         169 :     count_unsigned = strlen (buf);
    2213                 :             :   else
    2214                 :        2157 :     count_unsigned = count;
    2215                 :             : 
    2216                 :        2326 :   if (count_unsigned == 0)
    2217                 :             :     {
    2218                 :           0 :       if (bytes_written)
    2219                 :           0 :         *bytes_written = 0;
    2220                 :           0 :       return G_IO_STATUS_NORMAL;
    2221                 :             :     }
    2222                 :             : 
    2223                 :        2326 :   g_assert (count_unsigned > 0);
    2224                 :             : 
    2225                 :             :   /* Raw write case */
    2226                 :             : 
    2227                 :        2326 :   if (!channel->use_buffer)
    2228                 :             :     {
    2229                 :             :       gsize tmp_bytes;
    2230                 :             :       
    2231                 :           0 :       g_assert (!channel->write_buf || channel->write_buf->len == 0);
    2232                 :           0 :       g_assert (channel->partial_write_buf[0] == '\0');
    2233                 :             :       
    2234                 :           0 :       status = channel->funcs->io_write (channel, buf, count_unsigned,
    2235                 :             :                                          &tmp_bytes, error);
    2236                 :             : 
    2237                 :           0 :       if (bytes_written)
    2238                 :           0 :         *bytes_written = tmp_bytes;
    2239                 :             : 
    2240                 :           0 :       return status;
    2241                 :             :     }
    2242                 :             : 
    2243                 :             :   /* General case */
    2244                 :             : 
    2245                 :        2326 :   if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0)
    2246                 :        2056 :     || (BUF_LEN (channel->encoded_read_buf) > 0)))
    2247                 :             :     {
    2248                 :           0 :       if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0)
    2249                 :             :         {
    2250                 :           0 :           g_warning ("Mixed reading and writing not allowed on encoded files");
    2251                 :           0 :           return G_IO_STATUS_ERROR;
    2252                 :             :         }
    2253                 :           0 :       status = g_io_channel_seek_position (channel, 0, G_SEEK_CUR, error);
    2254                 :           0 :       if (status != G_IO_STATUS_NORMAL)
    2255                 :             :         {
    2256                 :           0 :           if (bytes_written)
    2257                 :           0 :             *bytes_written = 0;
    2258                 :           0 :           return status;
    2259                 :             :         }
    2260                 :             :     }
    2261                 :             : 
    2262                 :        2326 :   if (!channel->write_buf)
    2263                 :          64 :     channel->write_buf = g_string_sized_new (channel->buf_size);
    2264                 :             : 
    2265                 :        4652 :   while (wrote_bytes < count_unsigned)
    2266                 :             :     {
    2267                 :             :       gsize space_in_buf;
    2268                 :             : 
    2269                 :             :       /* If the buffer is full, try a write immediately. In
    2270                 :             :        * the nonblocking case, this prevents the user from
    2271                 :             :        * writing just a little bit to the buffer every time
    2272                 :             :        * and never receiving an EAGAIN.
    2273                 :             :        */
    2274                 :             : 
    2275                 :        2326 :       if (channel->write_buf->len >= channel->buf_size - MAX_CHAR_SIZE)
    2276                 :             :         {
    2277                 :          77 :           gsize did_write = 0, this_time;
    2278                 :             : 
    2279                 :             :           do
    2280                 :             :             {
    2281                 :          77 :               status = channel->funcs->io_write (channel, channel->write_buf->str
    2282                 :          77 :                                                  + did_write, channel->write_buf->len
    2283                 :             :                                                  - did_write, &this_time, error);
    2284                 :          77 :               did_write += this_time;
    2285                 :             :             }
    2286                 :          77 :           while (status == G_IO_STATUS_NORMAL &&
    2287                 :          77 :                  did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE));
    2288                 :             : 
    2289                 :          77 :           g_string_erase (channel->write_buf, 0, did_write);
    2290                 :             : 
    2291                 :          77 :           if (status != G_IO_STATUS_NORMAL)
    2292                 :             :             {
    2293                 :           0 :               if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0)
    2294                 :           0 :                 status = G_IO_STATUS_NORMAL;
    2295                 :           0 :               if (bytes_written)
    2296                 :           0 :                 *bytes_written = wrote_bytes;
    2297                 :           0 :               return status;
    2298                 :             :             }
    2299                 :             :         }
    2300                 :             : 
    2301                 :        2326 :       space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1)
    2302                 :        2326 :                      - channel->write_buf->len; /* 1 for NULL */
    2303                 :             : 
    2304                 :             :       /* This is only true because g_io_channel_set_buffer_size ()
    2305                 :             :        * ensures that channel->buf_size >= MAX_CHAR_SIZE.
    2306                 :             :        */
    2307                 :        2326 :       g_assert (space_in_buf >= MAX_CHAR_SIZE);
    2308                 :             : 
    2309                 :        2326 :       if (!channel->encoding)
    2310                 :             :         {
    2311                 :        2152 :           gsize write_this = MIN (space_in_buf, count_unsigned - wrote_bytes);
    2312                 :             : 
    2313                 :             :           /* g_string_append_len() takes a gssize, so don’t overflow it*/
    2314                 :        2152 :           if (write_this > G_MAXSSIZE)
    2315                 :           0 :             write_this = G_MAXSSIZE;
    2316                 :             : 
    2317                 :        2152 :           g_string_append_len (channel->write_buf, buf, write_this);
    2318                 :        2152 :           buf += write_this;
    2319                 :        2152 :           wrote_bytes += write_this;
    2320                 :             :         }
    2321                 :             :       else
    2322                 :             :         {
    2323                 :             :           const gchar *from_buf;
    2324                 :             :           gsize from_buf_len, from_buf_old_len, left_len;
    2325                 :             :           gsize err;
    2326                 :             :           gint errnum;
    2327                 :             : 
    2328                 :         174 :           if (channel->partial_write_buf[0] != '\0')
    2329                 :             :             {
    2330                 :           0 :               g_assert (wrote_bytes == 0);
    2331                 :             : 
    2332                 :           0 :               from_buf = channel->partial_write_buf;
    2333                 :           0 :               from_buf_old_len = strlen (channel->partial_write_buf);
    2334                 :           0 :               g_assert (from_buf_old_len > 0);
    2335                 :           0 :               from_buf_len = MIN (6, from_buf_old_len + count_unsigned);
    2336                 :             : 
    2337                 :           0 :               memcpy (channel->partial_write_buf + from_buf_old_len, buf,
    2338                 :             :                       from_buf_len - from_buf_old_len);
    2339                 :             :             }
    2340                 :             :           else
    2341                 :             :             {
    2342                 :         174 :               from_buf = buf;
    2343                 :         174 :               from_buf_len = count_unsigned - wrote_bytes;
    2344                 :         174 :               from_buf_old_len = 0;
    2345                 :             :             }
    2346                 :             : 
    2347                 :         174 : reconvert:
    2348                 :             : 
    2349                 :         174 :           if (!channel->do_encode) /* UTF-8 encoding */
    2350                 :             :             {
    2351                 :             :               const gchar *badchar;
    2352                 :         174 :               gsize try_len = MIN (from_buf_len, space_in_buf);
    2353                 :             : 
    2354                 :             :               /* UTF-8, just validate, emulate g_iconv */
    2355                 :             : 
    2356                 :         174 :               if (!g_utf8_validate_len (from_buf, try_len, &badchar))
    2357                 :             :                 {
    2358                 :             :                   gunichar try_char;
    2359                 :           0 :                   gsize incomplete_len = from_buf + try_len - badchar;
    2360                 :             : 
    2361                 :           0 :                   left_len = from_buf + from_buf_len - badchar;
    2362                 :             : 
    2363                 :           0 :                   try_char = g_utf8_get_char_validated (badchar, incomplete_len);
    2364                 :             : 
    2365                 :           0 :                   switch (try_char)
    2366                 :             :                     {
    2367                 :           0 :                       case -2:
    2368                 :           0 :                         g_assert (incomplete_len < 6);
    2369                 :           0 :                         if (try_len == from_buf_len)
    2370                 :             :                           {
    2371                 :           0 :                             errnum = EINVAL;
    2372                 :           0 :                             err = (gsize) -1;
    2373                 :             :                           }
    2374                 :             :                         else
    2375                 :             :                           {
    2376                 :           0 :                             errnum = 0;
    2377                 :           0 :                             err = (gsize) 0;
    2378                 :             :                           }
    2379                 :           0 :                         break;
    2380                 :           0 :                       case -1:
    2381                 :           0 :                         g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars().");
    2382                 :             :                         /* FIXME bail here? */
    2383                 :           0 :                         errnum = EILSEQ;
    2384                 :           0 :                         err = (gsize) -1;
    2385                 :           0 :                         break;
    2386                 :           0 :                       default:
    2387                 :             :                         g_assert_not_reached ();
    2388                 :             :                         err = (gsize) -1;
    2389                 :             :                         errnum = 0; /* Don't confuse the compiler */
    2390                 :             :                     }
    2391                 :             :                 }
    2392                 :             :               else
    2393                 :             :                 {
    2394                 :         174 :                   err = (gsize) 0;
    2395                 :         174 :                   errnum = 0;
    2396                 :         174 :                   left_len = from_buf_len - try_len;
    2397                 :             :                 }
    2398                 :             : 
    2399                 :         174 :               g_string_append_len (channel->write_buf, from_buf,
    2400                 :             :                                    from_buf_len - left_len);
    2401                 :         174 :               from_buf += from_buf_len - left_len;
    2402                 :             :             }
    2403                 :             :           else
    2404                 :             :             {
    2405                 :             :                gchar *outbuf;
    2406                 :             : 
    2407                 :           0 :                left_len = from_buf_len;
    2408                 :           0 :                g_string_set_size (channel->write_buf, channel->write_buf->len
    2409                 :             :                                   + space_in_buf);
    2410                 :           0 :                outbuf = channel->write_buf->str + channel->write_buf->len
    2411                 :           0 :                         - space_in_buf;
    2412                 :           0 :                err = g_iconv (channel->write_cd, (gchar **) &from_buf, &left_len,
    2413                 :             :                               &outbuf, &space_in_buf);
    2414                 :           0 :                errnum = errno;
    2415                 :           0 :                g_string_truncate (channel->write_buf, channel->write_buf->len
    2416                 :             :                                   - space_in_buf);
    2417                 :             :             }
    2418                 :             : 
    2419                 :         174 :           if (err == (gsize) -1)
    2420                 :             :             {
    2421                 :           0 :               switch (errnum)
    2422                 :             :                 {
    2423                 :           0 :                   case EINVAL:
    2424                 :           0 :                     g_assert (left_len < 6);
    2425                 :             : 
    2426                 :           0 :                     if (from_buf_old_len == 0)
    2427                 :             :                       {
    2428                 :             :                         /* Not from partial_write_buf */
    2429                 :             : 
    2430                 :           0 :                         memcpy (channel->partial_write_buf, from_buf, left_len);
    2431                 :           0 :                         channel->partial_write_buf[left_len] = '\0';
    2432                 :           0 :                         if (bytes_written)
    2433                 :           0 :                           *bytes_written = count_unsigned;
    2434                 :           0 :                         return G_IO_STATUS_NORMAL;
    2435                 :             :                       }
    2436                 :             : 
    2437                 :             :                     /* Working in partial_write_buf */
    2438                 :             : 
    2439                 :           0 :                     if (left_len == from_buf_len)
    2440                 :             :                       {
    2441                 :             :                         /* Didn't convert anything, must still have
    2442                 :             :                          * less than a full character
    2443                 :             :                          */
    2444                 :             : 
    2445                 :           0 :                         g_assert (count_unsigned == from_buf_len - from_buf_old_len);
    2446                 :             : 
    2447                 :           0 :                         channel->partial_write_buf[from_buf_len] = '\0';
    2448                 :             : 
    2449                 :           0 :                         if (bytes_written)
    2450                 :           0 :                           *bytes_written = count_unsigned;
    2451                 :             : 
    2452                 :           0 :                         return G_IO_STATUS_NORMAL;
    2453                 :             :                       }
    2454                 :             : 
    2455                 :           0 :                     g_assert (from_buf_len - left_len >= from_buf_old_len);
    2456                 :             : 
    2457                 :             :                     /* We converted all the old data. This is fine */
    2458                 :             : 
    2459                 :           0 :                     break;
    2460                 :           0 :                   case E2BIG:
    2461                 :           0 :                     if (from_buf_len == left_len)
    2462                 :             :                       {
    2463                 :             :                         /* Nothing was written, add enough space for
    2464                 :             :                          * at least one character.
    2465                 :             :                          */
    2466                 :           0 :                         space_in_buf += MAX_CHAR_SIZE;
    2467                 :           0 :                         goto reconvert;
    2468                 :             :                       }
    2469                 :           0 :                     break;
    2470                 :           0 :                   case EILSEQ:
    2471                 :           0 :                     g_set_error_literal (error, G_CONVERT_ERROR,
    2472                 :             :                       G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
    2473                 :             :                       _("Invalid byte sequence in conversion input"));
    2474                 :           0 :                     if (from_buf_old_len > 0 && from_buf_len == left_len)
    2475                 :           0 :                       g_warning ("Illegal sequence due to partial character "
    2476                 :             :                                  "at the end of a previous write.");
    2477                 :             :                     else
    2478                 :             :                       {
    2479                 :           0 :                         g_assert (from_buf_len >= left_len + from_buf_old_len);
    2480                 :           0 :                         wrote_bytes += from_buf_len - left_len - from_buf_old_len;
    2481                 :             :                       }
    2482                 :           0 :                     if (bytes_written)
    2483                 :           0 :                       *bytes_written = wrote_bytes;
    2484                 :           0 :                     channel->partial_write_buf[0] = '\0';
    2485                 :           0 :                     return G_IO_STATUS_ERROR;
    2486                 :           0 :                   default:
    2487                 :           0 :                     g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
    2488                 :             :                       _("Error during conversion: %s"), g_strerror (errnum));
    2489                 :           0 :                     if (from_buf_len >= left_len + from_buf_old_len)
    2490                 :           0 :                       wrote_bytes += from_buf_len - left_len - from_buf_old_len;
    2491                 :           0 :                     if (bytes_written)
    2492                 :           0 :                       *bytes_written = wrote_bytes;
    2493                 :           0 :                     channel->partial_write_buf[0] = '\0';
    2494                 :           0 :                     return G_IO_STATUS_ERROR;
    2495                 :             :                 }
    2496                 :             :             }
    2497                 :             : 
    2498                 :         174 :           g_assert (from_buf_len - left_len >= from_buf_old_len);
    2499                 :             : 
    2500                 :         174 :           wrote_bytes += from_buf_len - left_len - from_buf_old_len;
    2501                 :             : 
    2502                 :         174 :           if (from_buf_old_len > 0)
    2503                 :             :             {
    2504                 :             :               /* We were working in partial_write_buf */
    2505                 :             : 
    2506                 :           0 :               buf += from_buf_len - left_len - from_buf_old_len;
    2507                 :           0 :               channel->partial_write_buf[0] = '\0';
    2508                 :             :             }
    2509                 :             :           else
    2510                 :         174 :             buf = from_buf;
    2511                 :             :         }
    2512                 :             :     }
    2513                 :             : 
    2514                 :        2326 :   if (bytes_written)
    2515                 :         113 :     *bytes_written = count_unsigned;
    2516                 :             : 
    2517                 :        2326 :   return G_IO_STATUS_NORMAL;
    2518                 :             : }
    2519                 :             : 
    2520                 :             : /**
    2521                 :             :  * g_io_channel_write_unichar:
    2522                 :             :  * @channel: a #GIOChannel
    2523                 :             :  * @thechar: a character
    2524                 :             :  * @error: location to return an error of type #GConvertError
    2525                 :             :  *         or #GIOChannelError
    2526                 :             :  *
    2527                 :             :  * Writes a Unicode character to @channel.
    2528                 :             :  * This function cannot be called on a channel with %NULL encoding.
    2529                 :             :  *
    2530                 :             :  * Returns: a #GIOStatus
    2531                 :             :  **/
    2532                 :             : GIOStatus
    2533                 :           0 : g_io_channel_write_unichar (GIOChannel  *channel,
    2534                 :             :                             gunichar     thechar,
    2535                 :             :                             GError     **error)
    2536                 :             : {
    2537                 :             :   GIOStatus status;
    2538                 :             :   gchar static_buf[6];
    2539                 :             :   gsize char_len, wrote_len;
    2540                 :             : 
    2541                 :           0 :   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
    2542                 :           0 :   g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);
    2543                 :           0 :   g_return_val_if_fail ((error == NULL) || (*error == NULL),
    2544                 :             :                         G_IO_STATUS_ERROR);
    2545                 :           0 :   g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
    2546                 :             : 
    2547                 :           0 :   char_len = g_unichar_to_utf8 (thechar, static_buf);
    2548                 :             : 
    2549                 :           0 :   if (channel->partial_write_buf[0] != '\0')
    2550                 :             :     {
    2551                 :           0 :       g_warning ("Partial character written before writing unichar.");
    2552                 :           0 :       channel->partial_write_buf[0] = '\0';
    2553                 :             :     }
    2554                 :             : 
    2555                 :           0 :   status = g_io_channel_write_chars (channel, static_buf,
    2556                 :             :                                      char_len, &wrote_len, error);
    2557                 :             : 
    2558                 :             :   /* We validate UTF-8, so we can't get a partial write */
    2559                 :             : 
    2560                 :           0 :   g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL);
    2561                 :             : 
    2562                 :           0 :   return status;
    2563                 :             : }
    2564                 :             : 
    2565                 :             : /**
    2566                 :             :  * G_IO_CHANNEL_ERROR:
    2567                 :             :  *
    2568                 :             :  * Error domain for #GIOChannel operations. Errors in this domain will
    2569                 :             :  * be from the #GIOChannelError enumeration. See #GError for
    2570                 :             :  * information on error domains.
    2571                 :             :  **/
    2572                 :             : /**
    2573                 :             :  * GIOChannelError:
    2574                 :             :  * @G_IO_CHANNEL_ERROR_FBIG: File too large.
    2575                 :             :  * @G_IO_CHANNEL_ERROR_INVAL: Invalid argument.
    2576                 :             :  * @G_IO_CHANNEL_ERROR_IO: IO error.
    2577                 :             :  * @G_IO_CHANNEL_ERROR_ISDIR: File is a directory.
    2578                 :             :  * @G_IO_CHANNEL_ERROR_NOSPC: No space left on device.
    2579                 :             :  * @G_IO_CHANNEL_ERROR_NXIO: No such device or address.
    2580                 :             :  * @G_IO_CHANNEL_ERROR_OVERFLOW: Value too large for defined datatype.
    2581                 :             :  * @G_IO_CHANNEL_ERROR_PIPE: Broken pipe.
    2582                 :             :  * @G_IO_CHANNEL_ERROR_FAILED: Some other error.
    2583                 :             :  *
    2584                 :             :  * Error codes returned by #GIOChannel operations.
    2585                 :             :  **/
    2586                 :             : 
    2587                 :           1 : G_DEFINE_QUARK (g-io-channel-error-quark, g_io_channel_error)
        

Generated by: LCOV version 2.0-1