[PATCH libxtrans v3.1] Enable systemd socket activation

Łukasz Stelmach l.stelmach at samsung.com
Fri Jul 12 08:17:20 PDT 2013


Receive file descriptors of open sockets from systemd instead of
creating them.

Signed-off-by: Łukasz Stelmach <l.stelmach at samsung.com>
Cc: Kyungmin Park <kyungmin.park at samsung.com>
Cc: MyungJoo Ham <myungjoo.ham at samsung.com>
Cc: Piort Bereza <p.bereza at samsung.com>
Cc: Karol Lewandowski <k.lewandowsk at samsung.com>
Cc: Lennart Poettering <lennart at poettering.net>
Cc: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Cc: Peter Hutterer <peter.hutterer at who-t.net>
Cc: walter harms <wharms at bfs.de>
Cc: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 Xtrans.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/Xtrans.c b/Xtrans.c
index 5860f3a..891edb4 100644
--- a/Xtrans.c
+++ b/Xtrans.c
@@ -48,6 +48,9 @@ from The Open Group.
  */
 
 #include <ctype.h>
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
 
 /*
  * The transport table contains a definition for every transport (protocol)
@@ -1037,6 +1040,75 @@ complete_network_count (void)
 }
 
 
+static int
+receive_listening_fds(char* port, XtransConnInfo* temp_ciptrs, int* count_ret)
+
+{
+#ifdef HAVE_SYSTEMD
+    XtransConnInfo	ciptr;
+    char buffer[8];
+    int  systemd_listen_fds, i;
+
+    systemd_listen_fds = sd_listen_fds(1);
+    if (systemd_listen_fds < 0)
+    {
+	return -1;
+    }
+    else if (systemd_listen_fds > 0)
+    {
+	snprintf(buffer, sizeof(buffer), ":%s", port);
+	for (i = 0; i < systemd_listen_fds && *count_ret < NUMTRANS; i++)
+	{
+	    struct sockaddr_storage a;
+	    int ti;
+	    const char* tn;
+	    socklen_t al;
+
+	    al = sizeof(a);
+	    if (getsockname(i + SD_LISTEN_FDS_START, (struct sockaddr*)&a, &al) < 0)
+		return -1;
+
+	    switch (a.ss_family)
+	    {
+	    case AF_UNIX:
+		ti = TRANS_SOCKET_UNIX_INDEX;
+		if (*((struct sockaddr_un*)&a)->sun_path == '\0' &&
+		    al > sizeof(sa_family_t))
+		    tn = "local";
+		else
+		    tn = "unix";
+		break;
+	    case AF_INET:
+		ti = TRANS_SOCKET_INET_INDEX;
+		tn = "inet";
+		break;
+#if defined(IPv6) && defined(AF_INET6)
+	    case AF_INET6:
+		ti = TRANS_SOCKET_INET6_INDEX;
+		tn = "inet6";
+		break;
+#endif /* IPv6 */
+	    default:
+		return -1;
+	    }
+
+	    if ((ciptr = TRANS(ReopenCOTSServer)(ti, i + SD_LISTEN_FDS_START,
+						 port))==NULL)
+		prmsg (1, "MakeAllCOTSServerListeners:"
+		       "Got NULL while trying to reopen socket received from systemd.\n");
+	    else
+	    {
+		prmsg (5, "MakeAllCOTSServerListeners: received listener for %s, %d\n",
+		       tn, ciptr->fd);
+		temp_ciptrs[(*count_ret)++] = ciptr;
+		TRANS(Received)(tn);
+	    }
+	}
+    }
+#endif /* HAVE_SYSTEMD */
+    return 0;
+}
+
 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
 extern int xquartz_launchd_fd;
 #endif
@@ -1069,12 +1141,16 @@ TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret,
     }
 #endif
 
+    if (receive_listening_fds(port, temp_ciptrs, count_ret) < 0)
+	return -1;
+
     for (i = 0; i < NUMTRANS; i++)
     {
 	Xtransport *trans = Xtransports[i].transport;
 	unsigned int flags = 0;
 
-	if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
+	if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN ||
+	    trans->flags&TRANS_RECEIVED)
 	    continue;
 
 	snprintf(buffer, sizeof(buffer), "%s/:%s",
-- 
1.7.9.5



More information about the xorg-devel mailing list