summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu.herrb@laas.fr>2014-02-09 08:49:36 +0100
committerMatthieu Herrb <matthieu.herrb@laas.fr>2014-02-09 08:49:36 +0100
commit69579512bc9f7a4b1d4c52999a73b59a4e37300c (patch)
treee693803786688d1e386111c1b25a6d21c6560635
parent54787d6595083b9fd3e4dd220febe17821a1438c (diff)
parent3f0de269abe59353acbd7a5587d68ce0da91db67 (diff)
Merge remote-tracking branch 'origin/master' into obsd
-rw-r--r--Xtrans.c127
-rw-r--r--Xtrans.h8
-rw-r--r--Xtransint.h1
-rw-r--r--configure.ac2
4 files changed, 136 insertions, 2 deletions
diff --git a/Xtrans.c b/Xtrans.c
index b563bf3..4199c52 100644
--- a/Xtrans.c
+++ b/Xtrans.c
@@ -48,6 +48,10 @@ from The Open Group.
*/
#include <ctype.h>
+#ifdef HAVE_SYSTEMD_DAEMON
+#include <string.h>
+#include <systemd/sd-daemon.h>
+#endif
/*
* The transport table contains a definition for every transport (protocol)
@@ -747,6 +751,34 @@ TRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
}
int
+TRANS(Received) (const char * protocol)
+
+{
+ Xtransport *trans;
+ int i = 0, ret = 0;
+
+ prmsg (5, "Received(%s)\n", protocol);
+
+ if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+ {
+ prmsg (1,"Received: unable to find transport: %s\n",
+ protocol);
+
+ return -1;
+ }
+ if (trans->flags & TRANS_ALIAS) {
+ if (trans->nolisten)
+ while (trans->nolisten[i]) {
+ ret |= TRANS(Received)(trans->nolisten[i]);
+ i++;
+ }
+ }
+
+ trans->flags |= TRANS_RECEIVED;
+ return ret;
+}
+
+int
TRANS(NoListen) (const char * protocol)
{
@@ -773,6 +805,22 @@ TRANS(NoListen) (const char * protocol)
}
int
+TRANS(IsListening) (const char * protocol)
+{
+ Xtransport *trans;
+
+ if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+ {
+ prmsg (1,"TransIsListening: unable to find transport: %s\n",
+ protocol);
+
+ return 0;
+ }
+
+ return !(trans->flags & TRANS_NOLISTEN);
+}
+
+int
TRANS(ResetListener) (XtransConnInfo ciptr)
{
@@ -1026,6 +1074,79 @@ complete_network_count (void)
}
+static int
+receive_listening_fds(char* port, XtransConnInfo* temp_ciptrs, int* count_ret)
+
+{
+#ifdef HAVE_SYSTEMD_DAEMON
+ XtransConnInfo ciptr;
+ int i, systemd_listen_fds;
+
+ systemd_listen_fds = sd_listen_fds(1);
+ if (systemd_listen_fds < 0)
+ {
+ prmsg (1, "receive_listening_fds: sd_listen_fds error: %s\n",
+ strerror(-systemd_listen_fds));
+ return -1;
+ }
+
+ 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) {
+ prmsg (1, "receive_listening_fds: getsockname error: %s\n",
+ strerror(errno));
+ 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:
+ prmsg (1, "receive_listening_fds:"
+ "Got unknown socket address family\n");
+ return -1;
+ }
+
+ ciptr = TRANS(ReopenCOTSServer)(ti, i + SD_LISTEN_FDS_START, port);
+ if (!ciptr)
+ {
+ prmsg (1, "receive_listening_fds:"
+ "Got NULL while trying to reopen socket received from systemd.\n");
+ return -1;
+ }
+
+ prmsg (5, "receive_listening_fds: received listener for %s, %d\n",
+ tn, ciptr->fd);
+ temp_ciptrs[(*count_ret)++] = ciptr;
+ TRANS(Received)(tn);
+ }
+#endif /* HAVE_SYSTEMD_DAEMON */
+ return 0;
+}
+
#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
extern int xquartz_launchd_fd;
#endif
@@ -1058,12 +1179,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",
diff --git a/Xtrans.h b/Xtrans.h
index 69accd7..5807b67 100644
--- a/Xtrans.h
+++ b/Xtrans.h
@@ -303,10 +303,18 @@ int TRANS(CreateListener)(
unsigned int /* flags */
);
+int TRANS(Received) (
+ const char* /* protocol*/
+);
+
int TRANS(NoListen) (
const char* /* protocol*/
);
+int TRANS(IsListening) (
+ const char* /* protocol*/
+);
+
int TRANS(ResetListener)(
XtransConnInfo /* ciptr */
);
diff --git a/Xtransint.h b/Xtransint.h
index ec5a772..4c670b8 100644
--- a/Xtransint.h
+++ b/Xtransint.h
@@ -331,6 +331,7 @@ typedef struct _Xtransport_table {
#define TRANS_NOUNLINK (1<<4) /* Don't unlink transport endpoints */
#define TRANS_ABSTRACT (1<<5) /* Use abstract sockets if available */
#define TRANS_NOXAUTH (1<<6) /* Don't verify authentication (because it's secure some other way at the OS layer) */
+#define TRANS_RECEIVED (1<<7) /* The fd for this has already been opened by someone else. */
/* Flags to preserve when setting others */
#define TRANS_KEEPFLAGS (TRANS_NOUNLINK|TRANS_ABSTRACT)
diff --git a/configure.ac b/configure.ac
index 998fb06..6898c6d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
-AC_INIT([xtrans], [1.3.2],
+AC_INIT([xtrans], [1.3.3],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xtrans])
AC_CONFIG_SRCDIR([Makefile.am])