[gnio] Add protocol argument to GSocket



commit f12fff986dfa6a40bbdedad968c92155e6ee8c6f
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Apr 28 12:47:18 2009 +0200

    Add protocol argument to GSocket
    
    This is useful e.g. to create a SCTP socket, but most users can pass NULL.
---
 configure.ac        |    2 +-
 gio/gsocket.c       |   53 ++++++++++++++++++++++++++++++++++++++++++++++++--
 gio/gsocket.h       |    3 +-
 gio/gsocketclient.c |    2 +-
 gio/gtcplistener.c  |    8 ++++--
 gio/gunixlistener.c |    3 +-
 6 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/configure.ac b/configure.ac
index aaa134d..af7e877 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ AC_CHECK_FUNC(g_socket_connectable_enumerate,,
               AC_MSG_ERROR([gnio requires a new glib (git://git.gnome.org/glib)]))
 LIBS="$gnio_saved_libs"
 
-
+AC_CHECK_FUNCS(getprotobyname_r)
 
 AC_ARG_ENABLE(vala,
               AS_HELP_STRING([--enable-vala],
diff --git a/gio/gsocket.c b/gio/gsocket.c
index d227c5f..0b9ea72 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -53,6 +53,7 @@ enum
   PROP_0,
   PROP_DOMAIN,
   PROP_TYPE,
+  PROP_PROTOCOL,
   PROP_FD,
   PROP_BLOCKING,
   PROP_LISTEN_BACKLOG,
@@ -66,6 +67,7 @@ struct _GSocketPrivate
 {
   GSocketFamily   family;
   GSocketType     type;
+  char           *protocol;
   gint            fd;
   gboolean        blocking;
   gint            listen_backlog;
@@ -245,10 +247,13 @@ g_socket_details_from_fd (GSocket *socket)
 static gint
 g_socket_create_socket (GSocketFamily   family,
                         GSocketType     type,
+			const char     *protocol_name,
                         GError        **error)
 {
   gint native_type;
   gint fd;
+  gint protocol;
+  struct protoent *protoent;
 
   switch (type)
     {
@@ -268,7 +273,31 @@ g_socket_create_socket (GSocketFamily   family,
       g_assert_not_reached ();
     }
 
-  fd = socket (family, native_type, 0);
+  protocol = 0;
+  if (protocol_name)
+    {
+#ifdef HAVE_GETPROTOBYNAME_R
+      char buffer[1024];
+      struct protoent my_protoent;
+
+      protoent = NULL;
+      getprotobyname_r (protocol_name,
+			&my_protoent, buffer, sizeof (buffer),
+			&protoent);
+#else
+      protoent = getprotobyname (protocol_name);
+#endif
+      if (protoent == NULL)
+	{
+	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		       "unable to create socket: Protocol %s not supported",
+		       protocol_name);
+	  return -1;
+	}
+      protocol = protoent->p_proto;
+    }
+
+  fd = socket (family, native_type, protocol);
 
   if (fd < 0)
     {
@@ -294,6 +323,7 @@ g_socket_constructed (GObject *object)
     /* create the fd from socket->priv info */
     socket->priv->fd = g_socket_create_socket (socket->priv->family,
                                                socket->priv->type,
+                                               socket->priv->protocol,
                                                &socket->priv->construct_error);
 }
 
@@ -315,6 +345,10 @@ g_socket_get_property (GObject    *object,
         g_value_set_enum (value, socket->priv->type);
         break;
 
+      case PROP_PROTOCOL:
+        g_value_set_string (value, socket->priv->protocol);
+        break;
+
       case PROP_FD:
         g_value_set_int (value, socket->priv->fd);
         break;
@@ -366,6 +400,10 @@ g_socket_set_property (GObject      *object,
         socket->priv->type = g_value_get_enum (value);
         break;
 
+      case PROP_PROTOCOL:
+        socket->priv->protocol = g_value_dup_string (value);
+        break;
+
       case PROP_FD:
         socket->priv->fd = g_value_get_int (value);
         break;
@@ -459,6 +497,13 @@ g_socket_class_init (GSocketClass *klass)
                                                       G_SOCKET_TYPE_STREAM,
                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_PROTOCOL,
+                                   g_param_spec_string ("protocol",
+							"socket protocol",
+							"the protocol to use, or NULL",
+							NULL,
+							G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property (gobject_class, PROP_FD,
                                    g_param_spec_int ("fd",
                                                      "file descriptor",
@@ -528,9 +573,11 @@ g_socket_init (GSocket *socket)
 }
 
 GSocket *
-g_socket_new (GSocketFamily family, GSocketType type)
+g_socket_new (GSocketFamily family,
+	      GSocketType type,
+	      const char *protocol)
 {
-  return G_SOCKET (g_object_new (G_TYPE_SOCKET, "family", family, "type", type, NULL));
+  return G_SOCKET (g_object_new (G_TYPE_SOCKET, "family", family, "type", type, "protocol", protocol, NULL));
 }
 
 GSocket *
diff --git a/gio/gsocket.h b/gio/gsocket.h
index cdb9697..4b27bb5 100644
--- a/gio/gsocket.h
+++ b/gio/gsocket.h
@@ -76,7 +76,8 @@ typedef struct
 
 GType                  g_socket_get_type                (void);
 GSocket *              g_socket_new                     (GSocketFamily            family,
-							 GSocketType              type);
+							 GSocketType              type,
+							 const char              *protocol);
 GSocket *              g_socket_new_from_fd             (gint                     fd);
 GSocketAddress *       g_socket_get_local_address       (GSocket                 *socket,
 							 GError                 **error);
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index c93d218..230c2d8 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -36,7 +36,7 @@ g_socket_client_real_socket_factory (GSocketClient  *client,
                                      GSocketAddress *address)
 {
   return g_socket_new (g_socket_address_get_family (address),
-                       G_SOCKET_TYPE_STREAM);
+                       G_SOCKET_TYPE_STREAM, NULL);
 }
 
 static void
diff --git a/gio/gtcplistener.c b/gio/gtcplistener.c
index 2e25e6a..334b3f7 100644
--- a/gio/gtcplistener.c
+++ b/gio/gtcplistener.c
@@ -55,7 +55,7 @@ g_tcp_listener_socket_factory (GSocketListener  *listener,
       GSocketFamily family;
 
       family = g_inet_address_get_family (tcp_listener->priv->address);
-      socket = g_socket_new (family, G_SOCKET_TYPE_STREAM);
+      socket = g_socket_new (family, G_SOCKET_TYPE_STREAM, NULL);
       address = g_object_ref (tcp_listener->priv->address);
 
       if (family == G_SOCKET_FAMILY_IPV6)
@@ -66,7 +66,8 @@ g_tcp_listener_socket_factory (GSocketListener  *listener,
     {
       /* try to get a hybrid ipv6/ipv4 socket first */
       socket = g_socket_new (G_SOCKET_FAMILY_IPV6,
-                             G_SOCKET_TYPE_STREAM);
+                             G_SOCKET_TYPE_STREAM,
+			     NULL);
 
       if (socket)
         /* we can do ipv6, so bind to :: */
@@ -76,7 +77,8 @@ g_tcp_listener_socket_factory (GSocketListener  *listener,
         /* no ipv6. bind to 0.0.0.0 */
         {
           socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
-                                 G_SOCKET_TYPE_STREAM);
+                                 G_SOCKET_TYPE_STREAM,
+				 NULL);
           address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
         }
     }
diff --git a/gio/gunixlistener.c b/gio/gunixlistener.c
index 7f415e1..0fc89e5 100644
--- a/gio/gunixlistener.c
+++ b/gio/gunixlistener.c
@@ -46,7 +46,8 @@ g_unix_listener_socket_factory (GSocketListener  *listener,
   GSocket *socket;
 
   socket = g_socket_new (G_SOCKET_FAMILY_UNIX,
-                         G_SOCKET_TYPE_STREAM);
+                         G_SOCKET_TYPE_STREAM,
+			 NULL);
   sockaddr = g_unix_socket_address_new (unix_listener->priv->path);
 
   /* XXX fix */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]