From 7cfe8e8d82c0b40be2e24b71ba0e6f6f5dc8ed9d Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Wed, 27 Feb 2008 17:56:24 -0500 Subject: [PATCH] Change to using enums for g_socket_new --- gnio/gnioerror.h | 1 + gnio/gsocket.c | 75 +++++++++++++++++++++++++++++++++++++++++----- gnio/gsocket.h | 16 +++++++++- test/test-client.c | 4 +-- test/test-server.c | 34 ++++++++++++++++++--- 5 files changed, 115 insertions(+), 15 deletions(-) diff --git a/gnio/gnioerror.h b/gnio/gnioerror.h index 77fb069..e74a52d 100644 --- a/gnio/gnioerror.h +++ b/gnio/gnioerror.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS #define G_IO_ERROR_RESOLVER_NOT_FOUND 31 #define G_IO_ERROR_RESOLVER_NO_DATA 32 +#define G_IO_ERROR_ADDRESS_IN_USE 33 G_END_DECLS diff --git a/gnio/gsocket.c b/gnio/gsocket.c index eeb848e..f9410bf 100644 --- a/gnio/gsocket.c +++ b/gnio/gsocket.c @@ -158,16 +158,74 @@ g_socket_init (GSocket *socket) } GSocket * -g_socket_new (gint domain, gint type, gint protocol) +g_socket_new (GSocketDomain domain, GSocketType type, const gchar *protocol, GError **error) { - gint sock; + static GStaticMutex getprotobyname_mutex = G_STATIC_MUTEX_INIT; + gint fd, native_domain, native_type, native_protocol; - sock = socket(domain, type, protocol); + switch (domain) + { + case G_SOCKET_DOMAIN_INET: + native_domain = PF_INET; + break; - if (sock < 0) - return NULL; + case G_SOCKET_DOMAIN_INET6: + native_domain = PF_INET6; + break; + + case G_SOCKET_DOMAIN_UNIX: + native_domain = PF_UNIX; + break; + + default: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported socket domain"); + return NULL; + } + + switch (type) + { + case G_SOCKET_TYPE_STREAM: + native_type = SOCK_STREAM; + break; + + case G_SOCKET_TYPE_DATAGRAM: + native_type = SOCK_DGRAM; + break; + + case G_SOCKET_TYPE_SEQPACKET: + native_type = SOCK_SEQPACKET; + break; - return G_SOCKET (g_object_new (G_TYPE_SOCKET, "fd", sock, NULL)); + default: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported socket type"); + return NULL; + } + + if (protocol == NULL) + native_protocol = 0; + else + { + struct protoent *ent; + g_static_mutex_lock (&getprotobyname_mutex); + if (!(ent = getprotobyname (protocol))) + { + g_static_mutex_unlock (&getprotobyname_mutex); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported socket protocol"); + return NULL; + } + native_protocol = ent->p_proto; + g_static_mutex_unlock (&getprotobyname_mutex); + } + + fd = socket(native_domain, native_type, native_protocol); + + if (fd < 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "unable to create socket: %s", g_strerror (errno)); + return NULL; + } + + return G_SOCKET (g_object_new (G_TYPE_SOCKET, "fd", fd, NULL)); } GSocket * @@ -222,7 +280,7 @@ g_socket_get_peer_address (GSocket *socket, if (getpeername (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0) { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get peer address"); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get peer address: %s", g_strerror (errno)); return NULL; } @@ -253,7 +311,7 @@ g_socket_bind (GSocket *socket, if (bind (socket->priv->fd, (struct sockaddr *) addr, g_socket_address_native_size (address)) < 0) { - // TODO: set error + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error binding to address: %s", g_strerror (errno)); return FALSE; } @@ -321,6 +379,7 @@ accept_callback (AcceptData *data, g_simple_async_result_set_op_res_gpointer (result, g_socket_new_from_fd (ret), g_object_unref); } + g_simple_async_result_complete (result); g_object_unref (result); diff --git a/gnio/gsocket.h b/gnio/gsocket.h index 63295e1..0affe7c 100644 --- a/gnio/gsocket.h +++ b/gnio/gsocket.h @@ -55,9 +55,23 @@ struct _GSocketClass GObjectClass parent_class; }; +typedef enum +{ + G_SOCKET_DOMAIN_INET, + G_SOCKET_DOMAIN_INET6, + G_SOCKET_DOMAIN_UNIX +} GSocketDomain; + +typedef enum +{ + G_SOCKET_TYPE_STREAM, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_TYPE_SEQPACKET +} GSocketType; + GType g_socket_get_type (void) G_GNUC_CONST; -GSocket * g_socket_new (gint domain, gint type, gint protocol); +GSocket * g_socket_new (GSocketDomain domain, GSocketType type, const gchar *protocol, GError **error); GSocket * g_socket_new_from_fd (gint fd); diff --git a/test/test-client.c b/test/test-client.c index 13a0b63..ea6e8cb 100644 --- a/test/test-client.c +++ b/test/test-client.c @@ -14,7 +14,7 @@ accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) GError *error = NULL; if (!g_socket_connect_finish (socket, result, &error)) { - g_warning ("error connecting: %s", error->message); + g_warning (error->message); return; } @@ -31,7 +31,7 @@ int main (int argc, char *argv[]) loop = g_main_loop_new (NULL, FALSE); - socket = g_socket_new (AF_INET, SOCK_STREAM, 0); + socket = g_socket_new (G_SOCKET_DOMAIN_INET, G_SOCKET_TYPE_STREAM, NULL, NULL); g_printf ("connecting to 127.0.0.1:31882...\n"); diff --git a/test/test-server.c b/test/test-server.c index d6d9e46..dd51b02 100644 --- a/test/test-server.c +++ b/test/test-server.c @@ -8,6 +8,20 @@ GMainLoop *loop; +void accept_callback (GSocket *socket, GAsyncResult *result, gpointer data); + +gboolean +accept_source (gpointer data) +{ + GSocket *socket = G_SOCKET (data); + + g_print ("in source\n"); + + g_socket_accept_async (socket, NULL, (GAsyncReadyCallback) accept_callback, NULL); + + return FALSE; +} + void accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) { @@ -15,16 +29,27 @@ accept_callback (GSocket *socket, GAsyncResult *result, gpointer data) GSocketAddress *address; GError *error = NULL; + g_print ("in callback\n"); + new_socket = g_socket_accept_finish (socket, result, &error); - address = g_socket_get_peer_address (new_socket, NULL); + if (!new_socket) + g_error (error->message); + + address = g_socket_get_peer_address (new_socket, &error); + + if (!address) + g_error (error->message); g_printf ("got a new connection from %s:%d\n", g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))), g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address))); + + g_idle_add (accept_source, (gpointer) socket); } int main (int argc, char *argv[]) { GSocket *socket; + GError *error = NULL; g_thread_init (NULL); @@ -32,15 +57,16 @@ int main (int argc, char *argv[]) loop = g_main_loop_new (NULL, FALSE); - socket = g_socket_new (AF_INET, SOCK_STREAM, 0); + socket = g_socket_new (G_SOCKET_DOMAIN_INET, G_SOCKET_TYPE_STREAM, NULL, NULL); - g_socket_bind (socket, G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet4_address_from_string ("127.0.0.1")), 31882)), NULL); + if (!g_socket_bind (socket, G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet4_address_from_string ("127.0.0.1")), 31882)), &error)) + g_error (error->message); g_socket_listen (socket, 10); g_printf ("listening on port 31882...\n"); - g_socket_accept_async (socket, NULL, (GAsyncReadyCallback) accept_callback, NULL); + g_idle_add (accept_source, (gpointer) socket); g_main_loop_run (loop); -- 2.20.1