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)
|