Change to using enums for g_socket_new
authorSamuel Cormier-Iijima <sciyoshi@gmail.com>
Wed, 27 Feb 2008 22:56:24 +0000 (17:56 -0500)
committerSamuel Cormier-Iijima <sciyoshi@gmail.com>
Wed, 27 Feb 2008 22:56:24 +0000 (17:56 -0500)
gnio/gnioerror.h
gnio/gsocket.c
gnio/gsocket.h
test/test-client.c
test/test-server.c

index 77fb069..e74a52d 100644 (file)
@@ -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
 
index eeb848e..f9410bf 100644 (file)
@@ -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);
index 63295e1..0affe7c 100644 (file)
@@ -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);
 
index 13a0b63..ea6e8cb 100644 (file)
@@ -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");
 
index d6d9e46..dd51b02 100644 (file)
@@ -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);