Re: How to use GIOChannel to read an Unix socket
- From: silverburgh <silverburgh meryl gmail com>
- To: Chris Vine <chris cvine freeserve co uk>
- Cc: gtk-list gnome org
- Subject: Re: How to use GIOChannel to read an Unix socket
- Date: Tue, 26 Jan 2010 23:59:11 -0800
Chris,
I have updated my gio_read_socket per your advice.
But when the other end closes the socket (the GIOChannel* gio ties to
that socket),
I get a segmentation fault. I think some how when I call
gio_shutdown, it ends up calling gio_read_socket again, and it crashes
with a Segmentation fault.
My console output:
gio shutdown:
gio_read_socket
(GtkLauncher:5402): GLib-CRITICAL **: g_io_channel_read_line:
assertion `channel->is_readable' failed
Program received signal SIGSEGV, Segmentation fault.
0x08048aa4 in gio_read_socket (gio=0x8590f50, condition=G_IO_IN, data=0x0)
at main.c:230
230 g_error ("Error reading: %s\n", err->message);
static gboolean
gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data)
{
printf (" gio_read_socket \n");
GIOStatus ret;
GError *err = NULL;
gchar *msg;
gsize len;
if (condition & G_IO_HUP){
printf ("Read end of pipe died!\n");
return TRUE;
}
ret = g_io_channel_read_line (gio, &msg, &len, NULL, &err);
if (ret == G_IO_STATUS_ERROR)
g_error ("Error reading: %s\n", err->message);
else if (ret == G_IO_STATUS_EOF) {
printf ("gio shutdown: \n");
g_io_channel_shutdown(gio, true, &err);
} else {
printf ("Read %u bytes: %s\n", len, msg);
g_free (msg);
}
return TRUE;
}
Thank you for any more help.
On Sun, Jan 24, 2010 at 2:47 AM, Chris Vine <chris cvine freeserve co uk> wrote:
> On Sun, 24 Jan 2010 00:02:49 -0800
> silverburgh <silverburgh meryl gmail com> wrote:
>> Hi,
>>
>> I create a GIOChannel which wraps around a socket on linux:
>>
>> GIOChannel* channel = g_io_channel_unix_new(sock);
>> g_io_add_watch(channel, G_IO_IN,
>> gio_read_socket, NULL));
>> g_io_add_watch(channel, G_IO_HUP,
>> gio_close_socket, NULL));
>>
>> And my function gio_read_socket() does get called whenever there is
>> data available on the socket. And I am able to retrieve data using
>> g_io_channel_read_line ().
>> But when the other side of the socket get closed(). My function
>> g_io_channel_read_line() get called infinite number of times with the
>> number of data read = 0. Can you please tell me how can I fix my
>> problem? And my function gio_close_socket() which registered for
>> G_IO_HUP were never get called.
>>
>> static gboolean
>> gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer
>> data) {
>> printf (" gio_read_socket \n");
>> GIOStatus ret;
>> GError *err = NULL;
>> gchar *msg;
>> gsize len;
>>
>> ret = g_io_channel_read_line (gio, &msg, &len, NULL, &err);
>> if (ret == G_IO_STATUS_ERROR)
>> g_error ("Error reading: %s\n", err->message);
>>
>> printf ("Read %u bytes: %s\n", len, msg);
>> g_free (msg);
>> // Try to close the socket when nothing is there.
>> if (len == 0) {
>> close(g_io_channel_unix_get_fd(gio));
>> g_io_channel_close(gio);
>> }
>>
>> return TRUE;
>> }
>
> You need to check the return value of g_io_channel_read_line() for more
> than just an error - in particular for G_IO_STATUS_EOF. You also should
> not normally have a separate callback for a G_IO_HUP condition because
> POLL_HUP is not of itself a reliable indicator of end of file.
> (Instead bitwise-or it with G_IO_IN for a single handler.)
>
> See this for further details:
> http://www.greenend.org.uk/rjk/2001/06/poll.html
>
> Actually, you have attempted to fix your problem in a different way,
> by closing the socket when the read data length is 0, assuming that you
> are doing blocking reads. However, you need to free the GIOChannel
> object. The easiest way to do that is to call g_io_channel_unref() on
> the GIOChannel object immediately after you have called
> g_io_add_watch() on it. g_io_channel_*_new() returns a GIOChannel
> object with a reference count of one. g_io_add_watch() adds a further
> reference count - if you decrement it by 1, the callback will be
> disconnected and the relevant GSource object removed when the callback
> returns FALSE, which it should do when it detects end-of-file, or if
> you call g_source_remove() on the return value of g_io_add_watch().
> (Incidentally, you are also supposed to use g_io_channel_shutdown()
> rather than g_io_channel_close(), but that of itself is not sufficient
> to free the GIOCondition object and it is not necessary anyway in this
> usage.) I agree that the documentation on this isn't very good.
>
> Chris
>
>
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]