nkeynes@998 | 1 | /**
|
nkeynes@1021 | 2 | * $Id$
|
nkeynes@998 | 3 | *
|
nkeynes@998 | 4 | * Glib-based networking support functions. Currently this is just for activity callbacks.
|
nkeynes@998 | 5 | *
|
nkeynes@998 | 6 | * Copyright (c) 2009 Nathan Keynes.
|
nkeynes@998 | 7 | *
|
nkeynes@998 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@998 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@998 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@998 | 11 | * (at your option) any later version.
|
nkeynes@998 | 12 | *
|
nkeynes@998 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@998 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@998 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@998 | 16 | * GNU General Public License for more details.
|
nkeynes@998 | 17 | */
|
nkeynes@998 | 18 |
|
nkeynes@998 | 19 | #include <assert.h>
|
nkeynes@998 | 20 | #include <glib.h>
|
nkeynes@998 | 21 | #include <stdlib.h>
|
nkeynes@998 | 22 | #include "netutil.h"
|
nkeynes@998 | 23 |
|
nkeynes@998 | 24 | struct net_glib_cbinfo {
|
nkeynes@998 | 25 | net_callback_t callback;
|
nkeynes@998 | 26 | void * cbdata;
|
nkeynes@998 | 27 | void (*cbdealloc)(void *);
|
nkeynes@998 | 28 | };
|
nkeynes@998 | 29 |
|
nkeynes@998 | 30 | static gboolean net_glib_callback( GIOChannel *source, GIOCondition cond, gpointer data )
|
nkeynes@998 | 31 | {
|
nkeynes@998 | 32 | struct net_glib_cbinfo *cbinfo = (struct net_glib_cbinfo *)data;
|
nkeynes@998 | 33 | return cbinfo->callback( g_io_channel_unix_get_fd(source), cbinfo->cbdata);
|
nkeynes@998 | 34 | }
|
nkeynes@998 | 35 |
|
nkeynes@998 | 36 | static void net_glib_release( void *data )
|
nkeynes@998 | 37 | {
|
nkeynes@998 | 38 | struct net_glib_cbinfo *cbinfo = (struct net_glib_cbinfo *)data;
|
nkeynes@998 | 39 | if( cbinfo->cbdealloc ) {
|
nkeynes@998 | 40 | cbinfo->cbdealloc( cbinfo->cbdata );
|
nkeynes@998 | 41 | }
|
nkeynes@998 | 42 | free(cbinfo);
|
nkeynes@998 | 43 | }
|
nkeynes@998 | 44 |
|
nkeynes@998 | 45 | /**
|
nkeynes@998 | 46 | * Register a TCP server socket listener on an already open (and listening)
|
nkeynes@998 | 47 | * socket. The socket must not have been previously registered.
|
nkeynes@998 | 48 | * @return TRUE on success, FALSE on failure.
|
nkeynes@998 | 49 | *
|
nkeynes@998 | 50 | * Defined in netutil.h
|
nkeynes@998 | 51 | */
|
nkeynes@998 | 52 | gboolean net_register_tcp_listener( int fd, net_callback_t callback, void *data, void (*dealloc)(void*) )
|
nkeynes@998 | 53 | {
|
nkeynes@998 | 54 | struct net_glib_cbinfo *cbinfo = malloc( sizeof(struct net_glib_cbinfo) );
|
nkeynes@998 | 55 | assert(cbinfo != NULL);
|
nkeynes@998 | 56 |
|
nkeynes@998 | 57 | cbinfo->callback = callback;
|
nkeynes@998 | 58 | cbinfo->cbdata = data;
|
nkeynes@998 | 59 | cbinfo->cbdealloc = dealloc;
|
nkeynes@998 | 60 |
|
nkeynes@998 | 61 | /**
|
nkeynes@998 | 62 | * Note magic here: the watch creates an event source which holds a
|
nkeynes@998 | 63 | * reference to the channel. We unref the channel so that the channel then
|
nkeynes@998 | 64 | * is automatically released when the event source goes away.
|
nkeynes@998 | 65 | */
|
nkeynes@998 | 66 | GIOChannel *chan = g_io_channel_unix_new(fd);
|
nkeynes@998 | 67 | g_io_channel_set_encoding( chan, NULL, NULL );
|
nkeynes@998 | 68 | g_io_channel_set_buffered(chan, FALSE);
|
nkeynes@998 | 69 | g_io_add_watch_full( chan, 0, G_IO_IN, net_glib_callback, cbinfo, net_glib_release );
|
nkeynes@998 | 70 | g_io_channel_unref( chan );
|
nkeynes@998 | 71 | return TRUE;
|
nkeynes@998 | 72 | }
|