Converting InetAddresses to native struct in*_addr and SocketAddresses to struct...
authorSamuel Cormier-Iijima <sciyoshi@gmail.com>
Sun, 17 Feb 2008 14:39:29 +0000 (09:39 -0500)
committerSamuel Cormier-Iijima <sciyoshi@gmail.com>
Sun, 17 Feb 2008 14:39:29 +0000 (09:39 -0500)
gnio/ginetaddress.h
gnio/ginetsocketaddress.c
gnio/gsocket.c
gnio/gsocket.h
gnio/gsocketaddress.c
gnio/gsocketaddress.h
test/Makefile.am
test/test-server.c [new file with mode: 0644]

index 305ded2..6f01c7b 100644 (file)
@@ -65,6 +65,10 @@ GType           g_inet_address_get_type        (void) G_GNUC_CONST;
 
 gchar *         g_inet_address_to_string       (GInetAddress *address);
 
+gsize           g_inet_address_sockaddr_size   (GInetAddress *address);
+
+gboolean        g_inet_address_to_sockaddr     (GInetAddress *address, gpointer dest);
+
 gboolean        g_inet_address_is_any          (GInetAddress *address);
 
 gboolean        g_inet_address_is_linklocal    (GInetAddress *address);
index 6b2d7b1..5913aee 100644 (file)
 
 #include <config.h>
 #include <glib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 
 #include "ginetsocketaddress.h"
+#include "ginetaddress.h"
+#include "ginet4address.h"
+#include "ginet6address.h"
 
 G_DEFINE_TYPE (GInetSocketAddress, g_inet_socket_address, G_TYPE_SOCKET_ADDRESS);
 
@@ -94,10 +100,55 @@ g_inet_socket_address_set_property (GObject *object, guint prop_id, const GValue
     }
 }
 
+static gssize
+g_inet_socket_address_native_size (GSocketAddress *address)
+{
+  GInetSocketAddress *addr;
+
+  g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+  addr = G_INET_SOCKET_ADDRESS (address);
+
+  if (G_IS_INET4_ADDRESS (addr->priv->address))
+    return sizeof (struct sockaddr_in);
+  else if (G_IS_INET6_ADDRESS (addr->priv->address))
+    return sizeof (struct sockaddr_in6);
+  else
+    return -1;
+}
+
+static gboolean
+g_inet_socket_address_to_native (GSocketAddress *address, gpointer dest)
+{
+  GInetSocketAddress *addr;
+
+  g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+  addr = G_INET_SOCKET_ADDRESS (address);
+
+  if (G_IS_INET4_ADDRESS (addr->priv->address))
+    {
+      struct sockaddr_in *sock = (struct sockaddr_in *) dest;
+
+      sock->sin_family = AF_INET;
+      sock->sin_port = addr->priv->port;
+      memcpy (&(sock->sin_addr.s_addr), g_inet4_address_to_bytes (G_INET4_ADDRESS (addr->priv->address)), sizeof (sock->sin_addr));
+      memset (sock->sin_zero, 0, sizeof (sock->sin_zero));
+      return TRUE;
+    }
+  else if (G_IS_INET6_ADDRESS (addr->priv->address))
+    {
+      return FALSE;
+    }
+  else
+    return FALSE;
+}
+
 static void
 g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (GInetSocketAddressPrivate));
 
@@ -106,6 +157,9 @@ g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
   gobject_class->set_property = g_inet_socket_address_set_property;
   gobject_class->get_property = g_inet_socket_address_get_property;
 
+  gsocketaddress_class->to_native = g_inet_socket_address_to_native;
+  gsocketaddress_class->native_size = g_inet_socket_address_native_size;
+
   g_object_class_install_property (gobject_class, PROP_ADDRESS,
                                    g_param_spec_object ("address",
                                                         "address",
@@ -129,6 +183,9 @@ g_inet_socket_address_init (GInetSocketAddress *address)
   address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
                                                G_TYPE_INET_SOCKET_ADDRESS,
                                                GInetSocketAddressPrivate);
+
+  address->priv->address = NULL;
+  address->priv->port = 0;
 }
 
 
index c0a8a1a..42b6394 100644 (file)
 # include <netinet/in.h>
 # include <arpa/inet.h>
 # include <netdb.h>
+# include <fcntl.h>
 #else
-# include <winsock2.h>
-# include <winerror.h>
-# include <ws2tcpip.h>
-# undef HAVE_GETADDRINFO
-# define HAVE_GETHOSTBYNAME_THREADSAFE 1
+
 #endif
 #include <errno.h>
 
@@ -53,12 +50,33 @@ struct _GSocketPrivate
   int fd;
 };
 
+static void
+g_socket_finalize (GObject *object)
+{
+  GSocket *socket G_GNUC_UNUSED = G_SOCKET (object);
+
+  if (G_OBJECT_CLASS (g_socket_parent_class)->finalize)
+    (*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object);
+}
+
+static void
+g_socket_dispose (GObject *object)
+{
+  GSocket *socket G_GNUC_UNUSED = G_SOCKET (object);;
+
+  if (G_OBJECT_CLASS (g_socket_parent_class)->dispose)
+    (*G_OBJECT_CLASS (g_socket_parent_class)->dispose) (object);
+}
+
 static void
 g_socket_class_init (GSocketClass *klass)
 {
   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (GSocketPrivate));
+
+  gobject_class->finalize = g_socket_finalize;
+  gobject_class->dispose = g_socket_dispose;
 }
 
 static void
@@ -73,6 +91,28 @@ g_socket_new ()
   return G_SOCKET (g_object_new (G_TYPE_SOCKET, NULL));
 }
 
+GSocket *
+g_socket_new_from_fd (gint fd)
+{
+  return G_SOCKET (g_object_new (G_TYPE_SOCKET, NULL));
+}
+
+void
+g_socket_set_blocking (GSocket *socket, gboolean blocking)
+{
+  glong arg;
+
+  g_return_if_fail (G_IS_SOCKET (socket));
+
+  if ((arg = fcntl (socket->priv->fd, F_GETFL, NULL)) < 0)
+    g_warning ("Error getting socket status flags: %s", g_strerror (errno));
+
+  arg = blocking ? arg | O_NONBLOCK : arg & ~O_NONBLOCK;
+
+  if (fcntl (socket->priv->fd, F_SETFL, arg) < 0)
+    g_warning ("Error setting socket status flags: %s", g_strerror (errno));
+}
+
 void
 g_socket_listen (GSocket *socket, gint backlog)
 {
@@ -80,3 +120,41 @@ g_socket_listen (GSocket *socket, gint backlog)
 
   listen (socket->priv->fd, backlog);
 }
+
+gboolean
+g_socket_connect (GSocket         *socket,
+                  GSocketAddress  *address,
+                  GCancellable    *cancellable,
+                  GError         **error)
+{
+  g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
+/*
+  if (connect () < 0)
+    {
+      if (errno == EINPROGRESS)
+        g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING, "connection in progress");
+      else
+        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error connecting: %s", g_strerror (errno));
+      return FALSE;
+    }
+*/
+  return TRUE;
+}
+
+void
+g_socket_connect_async (GSocket             *socket,
+                        GSocketAddress      *address,
+                        GCancellable        *cancellable,
+                        GAsyncReadyCallback *callback,
+                        gpointer             user_data)
+{
+
+}
+
+gboolean
+g_socket_connect_finish (GSocket       *socket,
+                         GAsyncResult  *result,
+                         GError       **error)
+{
+
+}
index 4143d3e..7a0a568 100644 (file)
@@ -59,13 +59,19 @@ GType          g_socket_get_type         (void) G_GNUC_CONST;
 
 GSocket *      g_socket_new              (void);
 
+GSocket *      g_socket_new_from_fd      (gint fd);
+
+void           g_socket_set_blocking     (GSocket  *socket,
+                                          gboolean  blocking);
+
 gboolean       g_socket_bind             (GSocket         *socket,
                                           GSocketAddress  *address,
                                           GError         **error);
 
-void           g_socket_connect          (GSocket        *socket,
-                                          GSocketAddress *address,
-                                          GCancellable   *cancellable);
+gboolean       g_socket_connect          (GSocket         *socket,
+                                          GSocketAddress  *address,
+                                          GCancellable    *cancellable,
+                                          GError         **error);
 
 void           g_socket_connect_async    (GSocket             *socket,
                                           GSocketAddress      *address,
@@ -73,7 +79,7 @@ void           g_socket_connect_async    (GSocket             *socket,
                                           GAsyncReadyCallback *callback,
                                           gpointer             user_data);
 
-void           g_socket_connect_finish   (GSocket       *socket,
+gboolean       g_socket_connect_finish   (GSocket       *socket,
                                           GAsyncResult  *result,
                                           GError       **error);
 
index 88b4700..0f904cc 100644 (file)
@@ -39,3 +39,19 @@ g_socket_address_init (GSocketAddress *address)
 {
 
 }
+
+gssize
+g_socket_address_native_size (GSocketAddress *address)
+{
+  g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), -1);
+
+  return G_SOCKET_ADDRESS_GET_CLASS (address)->native_size (address);
+}
+
+gboolean
+g_socket_address_to_native (GSocketAddress *address, gpointer dest)
+{
+  g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
+
+  return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest);
+}
index 72fdcce..985ae5f 100644 (file)
@@ -46,9 +46,17 @@ struct _GSocketAddress
 struct _GSocketAddressClass
 {
   GObjectClass parent_class;
+
+  gssize (*native_size) (GSocketAddress *address);
+
+  gboolean (*to_native) (GSocketAddress *address, gpointer dest);
 };
 
-GType          g_socket_address_get_type (void) G_GNUC_CONST;
+GType          g_socket_address_get_type    (void) G_GNUC_CONST;
+
+gboolean       g_socket_address_to_native   (GSocketAddress *address, gpointer dest);
+
+gssize         g_socket_address_native_size (GSocketAddress *address);
 
 G_END_DECLS
 
index 637039b..8366f20 100644 (file)
@@ -11,6 +11,7 @@ AM_LDFLAGS =                           \
 
 noinst_PROGRAMS = \
        test-stuff \
+       test-server \
        $(NULL)
 
 EXTRA_DIST = 
diff --git a/test/test-server.c b/test/test-server.c
new file mode 100644 (file)
index 0000000..0bbdb0e
--- /dev/null
@@ -0,0 +1,26 @@
+#include <gio/gio.h>
+#include <gnio/gsocket.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+
+GMainLoop *loop;
+
+int main (int argc, char *argv[])
+{
+       GSocket *socket;
+       GError *error = NULL;
+
+       g_thread_init (NULL);
+
+       g_type_init ();
+
+       loop = g_main_loop_new (NULL, FALSE);
+
+       socket = g_socket_new ();
+
+       g_socket_set_blocking (socket, FALSE);
+
+       g_main_loop_run (loop);
+
+       return 0;
+}