Commit ce836121 authored by Alexander Larsson's avatar Alexander Larsson

Import all the highlevel socket classes from gnio

parent 2597e3ad
......@@ -130,6 +130,7 @@ appinfo_sources += gdesktopappinfo.c gdesktopappinfo.h
platform_libadd += libasyncns/libasyncns.la xdgmime/libxdgmime.la
platform_deps += libasyncns/libasyncns.la xdgmime/libxdgmime.la
unix_sources = \
gunixconnection.c \
gunixfdmessage.c \
gunixmount.c \
gunixmount.h \
......@@ -150,6 +151,7 @@ unix_sources = \
giounixincludedir=$(includedir)/gio-unix-2.0/gio
giounixinclude_HEADERS = \
gdesktopappinfo.h \
gunixconnection.h \
gunixmounts.h \
gunixfdmessage.h \
gunixinputstream.h \
......@@ -235,11 +237,21 @@ libgio_2_0_la_SOURCES = \
gseekable.c \
gsimpleasyncresult.c \
gsocket.c \
gsocketcontrolmessage.c \
gsocketaddress.c \
gsocketaddressenumerator.c \
gsocketclient.c \
gsocketconnectable.c \
gsocketconnection.c \
gsocketcontrolmessage.c \
gsocketinputstream.c \
gsocketinputstream.h \
gsocketlistener.c \
gsocketoutputstream.c \
gsocketoutputstream.h \
gsocketservice.c \
gsrvtarget.c \
gtcpconnection.c \
gthreadedsocketservice.c\
gthemedicon.c \
gthreadedresolver.c \
gthreadedresolver.h \
......@@ -353,11 +365,17 @@ gio_headers = \
gseekable.h \
gsimpleasyncresult.h \
gsocket.h \
gsocketcontrolmessage.h \
gsocketaddress.h \
gsocketaddressenumerator.h \
gsocketclient.h \
gsocketconnectable.h \
gsocketconnection.h \
gsocketcontrolmessage.h \
gsocketlistener.h \
gsocketservice.h \
gsrvtarget.h \
gtcpconnection.h \
gthreadedsocketservice.h\
gthemedicon.h \
gvfs.h \
gvolume.h \
......
......@@ -2,3 +2,4 @@ VOID:STRING,STRING,STRING,FLAGS
VOID:STRING,BOXED
VOID:BOOLEAN,POINTER
VOID:OBJECT,OBJECT,ENUM
BOOLEAN:OBJECT,OBJECT
......@@ -74,10 +74,16 @@
#include <gio/gseekable.h>
#include <gio/gsimpleasyncresult.h>
#include <gio/gsocket.h>
#include <gio/gsocketcontrolmessage.h>
#include <gio/gsocketaddress.h>
#include <gio/gsocketaddressenumerator.h>
#include <gio/gsocketclient.h>
#include <gio/gsocketconnectable.h>
#include <gio/gsocketconnection.h>
#include <gio/gsocketcontrolmessage.h>
#include <gio/gsocketlistener.h>
#include <gio/gsocketservice.h>
#include <gio/gtcpconnection.h>
#include <gio/gthreadedsocketservice.h>
#include <gio/gsrvtarget.h>
#include <gio/gthemedicon.h>
#include <gio/gvfs.h>
......
......@@ -1110,6 +1110,88 @@ g_socket_control_message_serialize
#endif
#endif
#if IN_HEADER(__G_SOCKET_CLIENT_H__)
#if IN_FILE(__G_SOCKET_CLIENT_C__)
g_socket_client_get_type G_GNUC_CONST
g_socket_client_connect
g_socket_client_connect_async
g_socket_client_connect_finish
g_socket_client_connect_to_host
g_socket_client_connect_to_host_async
g_socket_client_connect_to_host_finish
g_socket_client_get_family
g_socket_client_get_local_address
g_socket_client_get_protocol
g_socket_client_get_socket_type
g_socket_client_new
g_socket_client_set_family
g_socket_client_set_local_address
g_socket_client_set_protocol
g_socket_client_set_socket_type
#endif
#endif
#if IN_HEADER(__G_SOCKET_CONNECTION_H__)
#if IN_FILE(__G_SOCKET_CONNECTION_C__)
g_socket_connection_get_type G_GNUC_CONST
g_socket_connection_factory_create_connection
g_socket_connection_factory_lookup_type
g_socket_connection_factory_register_type
g_socket_connection_get_local_address
g_socket_connection_get_remote_address
g_socket_connection_get_socket
#endif
#endif
#if IN_HEADER(__G_SOCKET_LISTENER_H__)
#if IN_FILE(__G_SOCKET_LISTENER_C__)
g_socket_listener_get_type G_GNUC_CONST
g_socket_listener_accept
g_socket_listener_accept_async
g_socket_listener_accept_finish
g_socket_listener_accept_socket
g_socket_listener_accept_socket_async
g_socket_listener_accept_socket_finish
g_socket_listener_add_address
g_socket_listener_add_inet_port
g_socket_listener_add_socket
g_socket_listener_close
g_socket_listener_new
g_socket_listener_set_backlog
#endif
#endif
#if IN_HEADER(__G_SOCKET_SERVICE_H__)
#if IN_FILE(__G_SOCKET_SERVICE_C__)
g_socket_service_get_type G_GNUC_CONST
g_socket_service_is_active
g_socket_service_new
g_socket_service_start
g_socket_service_stop
#endif
#endif
#if IN_HEADER(__G_THREADED_SOCKET_SERVICE_H__)
#if IN_FILE(__G_THREADED_SOCKET_SERVICE_C__)
g_threaded_socket_service_get_type G_GNUC_CONST
g_threaded_socket_service_new
#endif
#endif
#if IN_HEADER(__G_TCP_CONNECTION_H__)
#if IN_FILE(__G_TCP_CONNECTION_C__)
g_tcp_connection_get_type G_GNUC_CONST
#endif
#endif
#if IN_HEADER(__G_UNIX_CONNECTION_H__)
#if IN_FILE(__G_UNIX_CONNECTION_C__)
g_unix_connection_get_type G_GNUC_CONST
g_unix_connection_receive_fd
g_unix_connection_send_fd
#endif
#endif
#if IN_HEADER(__G_UNIX_FD_MESSAGE_H__)
#if IN_FILE(__G_UNIX_FD_MESSAGE_C__)
g_unix_fd_message_get_type G_GNUC_CONST
......
......@@ -126,10 +126,60 @@ typedef struct _GSocket GSocket;
* received over #GSocket.
**/
typedef struct _GSocketControlMessage GSocketControlMessage;
/**
* GSocketClient:
*
* A helper class for network clients to make connections.
*
* Since: 2.22
**/
typedef struct _GSocketClient GSocketClient;
/**
* GSocketConnection:
*
* A socket connection GIOStream object for connection-oriented sockets.
*
* Since: 2.22
**/
typedef struct _GSocketConnection GSocketConnection;
/**
* GSocketClient:
*
* A helper class for network servers to listen for and accept connections.
*
* Since: 2.22
**/
typedef struct _GSocketListener GSocketListener;
/**
* GSocketService:
*
* A helper class for handling accepting incomming connections in the
* glib mainloop.
*
* Since: 2.22
**/
typedef struct _GSocketService GSocketService;
typedef struct _GSocketAddress GSocketAddress;
typedef struct _GSocketAddressEnumerator GSocketAddressEnumerator;
typedef struct _GSocketConnectable GSocketConnectable;
typedef struct _GSrvTarget GSrvTarget;
/**
* GTcpConnection:
*
* A #GSocketConnection for TCP/IP connections.
*
* Since: 2.22
**/
typedef struct _GTcpConnection GTcpConnection;
/**
* GThreadedSocketService:
*
* A helper class for handling accepting incomming connections in the
* glib mainloop and handling them in a thread.
*
* Since: 2.22
**/
typedef struct _GThreadedSocketService GThreadedSocketService;
typedef struct _GThemedIcon GThemedIcon;
typedef struct _GVfs GVfs; /* Dummy typedef */
......
This diff is collapsed.
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright © 2008, 2009 Codethink Limited
* Copyright © 2009 Red Hat, Inc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
* Alexander Larsson <alexl@redhat.com>
*/
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
#error "Only <gio/gio.h> can be included directly."
#endif
#ifndef __G_SOCKET_CLIENT_H__
#define __G_SOCKET_CLIENT_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_SOCKET_CLIENT (g_socket_client_get_type ())
#define G_SOCKET_CLIENT(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_SOCKET_CLIENT, GSocketClient))
#define G_SOCKET_CLIENT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
G_TYPE_SOCKET_CLIENT, GSocketClientClass))
#define G_IS_SOCKET_CLIENT(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_SOCKET_CLIENT))
#define G_IS_SOCKET_CLIENT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
G_TYPE_SOCKET_CLIENT))
#define G_SOCKET_CLIENT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
G_TYPE_SOCKET_CLIENT, GSocketClientClass))
typedef struct _GSocketClientPrivate GSocketClientPrivate;
typedef struct _GSocketClientClass GSocketClientClass;
struct _GSocketClientClass
{
GObjectClass parent_class;
/* Padding for future expansion */
void (*_g_reserved1) (void);
void (*_g_reserved2) (void);
void (*_g_reserved3) (void);
void (*_g_reserved4) (void);
void (*_g_reserved5) (void);
};
struct _GSocketClient
{
GObject parent_instance;
GSocketClientPrivate *priv;
};
GType g_socket_client_get_type (void) G_GNUC_CONST;
GSocketClient *g_socket_client_new (void);
GSocketFamily g_socket_client_get_family (GSocketClient *client);
void g_socket_client_set_family (GSocketClient *client,
GSocketFamily family);
GSocketType g_socket_client_get_socket_type (GSocketClient *client);
void g_socket_client_set_socket_type (GSocketClient *client,
GSocketType type);
const char *g_socket_client_get_protocol (GSocketClient *client);
void g_socket_client_set_protocol (GSocketClient *client,
const char *protocol);
GSocketAddress *g_socket_client_get_local_address (GSocketClient *client);
void g_socket_client_set_local_address (GSocketClient *client,
GSocketAddress *address);
GSocketConnection * g_socket_client_connect (GSocketClient *client,
GSocketConnectable *connectable,
GCancellable *cancellable,
GError **error);
GSocketConnection * g_socket_client_connect_to_host (GSocketClient *client,
const char *hostname,
int port,
GCancellable *cancellable,
GError **error);
void g_socket_client_connect_async (GSocketClient *client,
GSocketConnectable *connectable,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSocketConnection * g_socket_client_connect_finish (GSocketClient *client,
GAsyncResult *result,
GError **error);
void g_socket_client_connect_to_host_async (GSocketClient *client,
const char *hostname,
int port,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSocketConnection * g_socket_client_connect_to_host_finish (GSocketClient *client,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __G_SOCKET_CLIENT_H___ */
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
* © 2008 codethink
* Copyright © 2009 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors: Christian Kellner <gicmo@gnome.org>
* Samuel Cormier-Iijima <sciyoshi@gmail.com>
* Ryan Lortie <desrt@desrt.ca>
* Alexander Larsson <alexl@redhat.com>
*/
#include "config.h"
#include "gsocketconnection.h"
#include "gsocketoutputstream.h"
#include "gsocketinputstream.h"
#include <gio/giostream.h>
#include <gio/gsimpleasyncresult.h>
#include "gunixconnection.h"
#include "gtcpconnection.h"
#include "glibintl.h"
#include "gioalias.h"
/**
* SECTION:gsocketconnection
* @short_description: High-level socket connection stream
* @include: gio/gio.h
* @see_also: #GIOStream, #GSocketClient, #GSocketListener
*
* #GSocketConnection is a #GIOStream for a connected socket. They
* can be created either by #GSocketClient when connecting to a host,
* or by #GSocketListener when accepting a new client.
*
* The type of the #GSocketConnection object returned from these calls depends
* on the type of the underlying socket that is in use. For instance, for a
* TCP/IP connection it will be a #GTcpConnection.
*
* Chosing what type of object to construct is done with the socket connection
* factory, and it is possible for 3rd parties to register custom socket connection
* types for specific combination of socket family/type/protocol using
* g_socket_connection_factory_register_type().
*
* Since: 2.22
**/
G_DEFINE_TYPE (GSocketConnection,
g_socket_connection, G_TYPE_IO_STREAM);
enum
{
PROP_NONE,
PROP_SOCKET,
};
struct _GSocketConnectionPrivate
{
GSocket *socket;
GInputStream *input_stream;
GOutputStream *output_stream;
};
static gboolean g_socket_connection_close (GIOStream *stream,
GCancellable *cancellable,
GError **error);
static void g_socket_connection_close_async (GIOStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
static gboolean g_socket_connection_close_finish (GIOStream *stream,
GAsyncResult *result,
GError **error);
static GInputStream *
g_socket_connection_get_input_stream (GIOStream *io_stream)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
if (connection->priv->input_stream == NULL)
connection->priv->input_stream = (GInputStream *)
_g_socket_input_stream_new (connection->priv->socket);
return connection->priv->input_stream;
}
static GOutputStream *
g_socket_connection_get_output_stream (GIOStream *io_stream)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
if (connection->priv->output_stream == NULL)
connection->priv->output_stream = (GOutputStream *)
_g_socket_output_stream_new (connection->priv->socket);
return connection->priv->output_stream;
}
GSocket *
g_socket_connection_get_socket (GSocketConnection *connection)
{
g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL);
return connection->priv->socket;
}
/**
* g_socket_connection_get_local_address:
* @connection: a #GSocketConnection.
* @error: #GError for error reporting, or %NULL to ignore.
*
* Try to get the local address of a socket connection.
*
* Returns: a #GSocketAddress or %NULL on error.
*
* Since: 2.22
**/
GSocketAddress *
g_socket_connection_get_local_address (GSocketConnection *connection,
GError **error)
{
return g_socket_get_local_address (connection->priv->socket, error);
}
/**
* g_socket_connection_get_remote_address:
* @connection: a #GSocketConnection.
* @error: #GError for error reporting, or %NULL to ignore.
*
* Try to get the remove address of a socket connection.
*
* Returns: a #GSocketAddress or %NULL on error.
*
* Since: 2.22
**/
GSocketAddress *
g_socket_connection_get_remote_address (GSocketConnection *connection,
GError **error)
{
return g_socket_get_remote_address (connection->priv->socket, error);
}
static void
g_socket_connection_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (object);
switch (prop_id)
{
case PROP_SOCKET:
g_value_set_object (value, connection->priv->socket);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
g_socket_connection_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (object);
switch (prop_id)
{
case PROP_SOCKET:
connection->priv->socket = G_SOCKET (g_value_dup_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
g_socket_connection_constructed (GObject *object)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (object);
g_assert (connection->priv->socket != NULL);
}
static void
g_socket_connection_finalize (GObject *object)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (object);
if (connection->priv->input_stream)
g_object_unref (connection->priv->input_stream);
if (connection->priv->output_stream)
g_object_unref (connection->priv->output_stream);
g_object_unref (connection->priv->socket);
G_OBJECT_CLASS (g_socket_connection_parent_class)
->finalize (object);
}
static void
g_socket_connection_class_init (GSocketConnectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
g_type_class_add_private (klass, sizeof (GSocketConnectionPrivate));
gobject_class->set_property = g_socket_connection_set_property;
gobject_class->get_property = g_socket_connection_get_property;
gobject_class->constructed = g_socket_connection_constructed;
gobject_class->finalize = g_socket_connection_finalize;
stream_class->get_input_stream = g_socket_connection_get_input_stream;
stream_class->get_output_stream = g_socket_connection_get_output_stream;
stream_class->close_fn = g_socket_connection_close;
stream_class->close_async = g_socket_connection_close_async;
stream_class->close_finish = g_socket_connection_close_finish;
g_object_class_install_property (gobject_class, PROP_SOCKET,
g_param_spec_object ("socket",
P_("Socket"),
P_("The underlying GSocket"),
G_TYPE_SOCKET, G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
g_socket_connection_init (GSocketConnection *connection)
{
connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection,
G_TYPE_SOCKET_CONNECTION,
GSocketConnectionPrivate);
}
static gboolean
g_socket_connection_close (GIOStream *stream,
GCancellable *cancellable,
GError **error)
{
GSocketConnection *connection = G_SOCKET_CONNECTION (stream);
if (connection->priv->output_stream)
g_output_stream_close (connection->priv->output_stream,
cancellable, NULL);
if (connection->priv->input_stream)
g_input_stream_close (connection->priv->input_stream,
cancellable, NULL);
return g_socket_close (connection->priv->socket, error);
}
static void
g_socket_connection_close_async (GIOStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
GError *error;
/* socket close is not blocked, just do it! */
error = NULL;
if (!g_io_stream_close (stream, cancellable, &error))
{
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback, user_data,
error);
g_error_free (error);
return;
}
res = g_simple_async_result_new (G_OBJECT (stream),
callback,
user_data,
g_socket_connection_close_async);
g_simple_async_result_complete_in_idle (res);
g_object_unref (res);
}
static gboolean
g_socket_connection_close_finish (GIOStream *stream,
GAsyncResult *result,
GError **error)
{
return TRUE;
}
typedef struct {
GSocketFamily socket_family;
GSocketType socket_type;
int protocol;
GType implementation;
} ConnectionFactory;
static guint
connection_factory_hash (gconstpointer key)
{
const ConnectionFactory *factory = key;
guint h;
h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8);
/* This is likely to be small, so spread over whole
hash space to get some distribution */
h = h ^ (h << 8) ^ (h << 16) ^ (h << 24);
return h;
}
static gboolean
connection_factory_equal (gconstpointer _a,
gconstpointer _b)
{
const ConnectionFactory *a = _a;
const ConnectionFactory *b = _b;
if (a->socket_family != b->socket_family)
return FALSE;
if (a->socket_type != b->socket_type)
return FALSE;
if (a->protocol != b->protocol)
return FALSE;
return TRUE;
}
static GHashTable *connection_factories = NULL;
G_LOCK_DEFINE_STATIC(connection_factories);
/**
* g_socket_connection_factory_register_type:
* @g_type: a #GType, inheriting from G_SOCKET_CONNECTION
* @family: a #GSocketFamily.
* @type: a #GSocketType
* @protocol: a protocol id
*
* Looks up the #GType to be used when creating socket connections on
* sockets with the specified @family,@type and @protocol_id.
*
* If no type is registered, the #GSocketConnection base type is returned.
*
* Returns: a #GType
* Since: 2.22
**/
void
g_socket_connection_factory_register_type (GType g_type,
GSocketFamily family,
GSocketType type,
gint protocol)
{
ConnectionFactory *factory;
g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION));
G_LOCK (connection_factories);
if (connection_factories == NULL)
connection_factories = g_hash_table_new_full (connection_factory_hash,
connection_factory_equal,
(GDestroyNotify)g_free,
NULL);
factory = g_new0 (ConnectionFactory, 1);
factory->socket_family = family;
factory->socket_type = type;
factory->protocol = protocol;
factory->implementation = g_type;
g_hash_table_insert (connection_factories,
factory, factory);
G_UNLOCK (connection_factories);
}
static void
init_builtin_types (void)
{
volatile GType a_type;
#ifndef G_OS_WIN32
a_type = g_unix_connection_get_type ();
#endif
a_type = g_tcp_connection_get_type ();
}