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

Signed-off-by: Łukasz Stelmach <[email protected]>
Cc: Kyungmin Park <[email protected]>
Cc: MyungJoo Ham <[email protected]>
Cc: Piort Bereza <[email protected]>
Cc: Karol Lewandowski <[email protected]>
Cc: Lennart Poettering <[email protected]>
Cc: Zbigniew Jędrzejewski-Szmek <[email protected]>
Cc: Peter Hutterer <[email protected]>
Cc: walter harms <[email protected]>
---
 Xtrans.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/Xtrans.c b/Xtrans.c
index 5860f3a..fb6541d 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)
@@ -1053,6 +1056,10 @@ TRANS(MakeAllCOTSServerListeners) (char *port, int 
*partial, int *count_ret,
 #if defined(IPv6) && defined(AF_INET6)
     int                ipv6_succ = 0;
 #endif
+#ifdef HAVE_SYSTEMD
+    int                systemd_listen_fds;
+#endif /* HAVE_SYSTEMD */
+
     prmsg (2,"MakeAllCOTSServerListeners(%s,%p)\n",
           port ? port : "NULL", ciptrs_ret);
 
@@ -1068,13 +1075,73 @@ TRANS(MakeAllCOTSServerListeners) (char *port, int 
*partial, int *count_ret,
             temp_ciptrs[(*count_ret)++] = ciptr;
     }
 #endif
+#ifdef HAVE_SYSTEMD
+    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; 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);
+           }
+       }
+       memset(buffer, 0, sizeof(buffer));
+    }
+#endif /* HAVE_SYSTEMD */
 
     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

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to