After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 648551 - [PATCH]Able to pass-in o pre-constructed listen socket to soup_server_new
[PATCH]Able to pass-in o pre-constructed listen socket to soup_server_new
Status: RESOLVED DUPLICATE of bug 621138
Product: libsoup
Classification: Core
Component: API
unspecified
Other Linux
: Normal normal
: ---
Assigned To: libsoup-maint@gnome.bugs
libsoup-maint@gnome.bugs
Depends on:
Blocks:
 
 
Reported: 2011-04-24 12:18 UTC by kikidong
Modified: 2012-01-10 16:19 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description kikidong 2011-04-24 12:18:51 UTC
From 77eb437d5bcb745e75d14627f3d24085f60682a2 Mon Sep 17 00:00:00 2001
From: microcai <microcai@fedoraproject.org>
Date: Sun, 24 Apr 2011 20:10:58 +0800
Subject: [PATCH] This make libsoup based app systemd socket activation
 capable. First, construt soupsocket, then manully call it
 with soup_socket_listen_fd(), then pass soupsocket to
 soup_server_new.

This is maybe a suggestion, you guys may have better idea/API.
But the idea is simple, make libsoup based application able to
do systemd socket activation, of Xinetd activation.
---
 libsoup/soup-server.c |   33 +++++++++++++++++++++++++--------
 libsoup/soup-server.h |    1 +
 libsoup/soup-socket.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index d56efd1..1829f45 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -130,6 +130,7 @@ enum {
 	PROP_ASYNC_CONTEXT,
 	PROP_RAW_PATHS,
 	PROP_SERVER_HEADER,
+	PROP_LISTEN_SOCKET,
 
 	LAST_PROP
 };
@@ -446,6 +447,14 @@ soup_server_class_init (SoupServerClass *server_class)
 				     "Server header",
 				     NULL,
 				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class, PROP_LISTEN_SOCKET,
+		g_param_spec_object (SOUP_SERVER_LISTEN_SOCKET,
+				     "Listen socket",
+				     "Listen socket",
+				     SOUP_TYPE_SOCKET,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 }
 
 static GObject *
@@ -478,14 +487,16 @@ constructor (GType                  type,
 		}
 	}
 
-	priv->listen_sock =
-		soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->interface,
-				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
-				 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
-				 NULL);
-	if (!soup_socket_listen (priv->listen_sock)) {
-		g_object_unref (server);
-		return NULL;
+	if(!priv->listen_sock){
+		priv->listen_sock =
+			soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->interface,
+					 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
+					 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
+					 NULL);
+		if (!soup_socket_listen (priv->listen_sock)) {
+			g_object_unref (server);
+			return NULL;
+		}
 	}
 
 	/* Re-resolve the interface address, in particular in case
@@ -548,6 +559,9 @@ set_property (GObject *object, guint prop_id,
 		} else
 			priv->server_header = g_strdup (header);
 		break;
+	case PROP_LISTEN_SOCKET:
+		priv->listen_sock = g_value_get_object(value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -582,6 +596,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_SERVER_HEADER:
 		g_value_set_string (value, priv->server_header);
 		break;
+	case PROP_LISTEN_SOCKET:
+		g_value_set_object(value,priv->listen_sock);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
diff --git a/libsoup/soup-server.h b/libsoup/soup-server.h
index 4ea17ad..3f630da 100644
--- a/libsoup/soup-server.h
+++ b/libsoup/soup-server.h
@@ -63,6 +63,7 @@ typedef void (*SoupServerCallback) (SoupServer        *server,
 #define SOUP_SERVER_ASYNC_CONTEXT "async-context"
 #define SOUP_SERVER_RAW_PATHS     "raw-paths"
 #define SOUP_SERVER_SERVER_HEADER "server-header"
+#define SOUP_SERVER_LISTEN_SOCKET "listen-socket"
 
 SoupServer        *soup_server_new            (const char            *optname1,
 					       ...) G_GNUC_NULL_TERMINATED;
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 8d11841..ffbc883 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -854,6 +854,55 @@ soup_socket_listen (SoupSocket *sock)
 	return FALSE;
 }
 
+
+/**
+ * soup_socket_listen_fd:
+ * @sock: a server #SoupSocket (which must not already be connected or
+ * listening)
+ * @fd: a native socket fd, that is already listen on an address
+ *
+ * Makes @sock start listening on the passing fd
+ *
+ **/
+void
+soup_socket_listen_fd (SoupSocket *sock,int fd)
+
+{
+	SoupSocketPrivate *priv;
+
+	g_return_if_fail (SOUP_IS_SOCKET (sock));
+	priv = SOUP_SOCKET_GET_PRIVATE (sock);
+	g_return_if_fail (priv->gsock == NULL);
+
+	priv->is_server = TRUE;
+
+	/* @local_addr may have its port set to 0. So we intentionally
+	 * don't store it in priv->local_addr, so that if the
+	 * caller calls soup_socket_get_local_address() later, we'll
+	 * have to make a new addr by calling getsockname(), which
+	 * will have the right port number.
+	 */
+
+	priv->gsock = g_socket_new_from_fd(fd,NULL);
+
+	if (!priv->gsock)
+		goto cant_listen;
+
+	finish_socket_setup (priv);
+
+	/* Force local_addr to be re-resolved now */
+	g_object_unref (priv->local_addr);
+	priv->local_addr = NULL;
+
+	priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
+						    listen_watch, sock,
+						    NULL);
+	return ;
+
+ cant_listen:
+	if (priv->conn)
+		disconnect_internal (sock);
+}
 static void
 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
 				      gpointer sock)
-- 
1.7.5.rc1
Comment 1 Simon McVittie 2012-01-10 16:19:09 UTC
It looks as though this was requested already in Bug #621138.

*** This bug has been marked as a duplicate of bug 621138 ***