aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--unix/x0vncserver/CMakeLists.txt6
-rw-r--r--unix/x0vncserver/x0vncserver.cxx81
-rw-r--r--unix/x0vncserver/x0vncserver.man4
4 files changed, 65 insertions, 29 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e8d8d85d..6028fadf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -301,6 +301,9 @@ if(UNIX AND NOT APPLE)
endif()
endif()
+# check for systemd support (socket activation)
+pkg_check_modules(LIBSYSTEMD libsystemd)
+
# Generate config.h and make sure the source finds it
configure_file(config.h.in config.h)
add_definitions(-DHAVE_CONFIG_H)
diff --git a/unix/x0vncserver/CMakeLists.txt b/unix/x0vncserver/CMakeLists.txt
index 31da5118..08b346f1 100644
--- a/unix/x0vncserver/CMakeLists.txt
+++ b/unix/x0vncserver/CMakeLists.txt
@@ -21,6 +21,12 @@ target_include_directories(x0vncserver PUBLIC ${CMAKE_SOURCE_DIR}/unix)
target_include_directories(x0vncserver PUBLIC ${CMAKE_SOURCE_DIR}/common)
target_link_libraries(x0vncserver tx rfb network rdr unixcommon)
+# systemd support (socket activation)
+if (LIBSYSTEMD_FOUND)
+ add_definitions(-DHAVE_SYSTEMD_H)
+ target_link_libraries(x0vncserver ${LIBSYSTEMD_LIBRARIES})
+endif()
+
if(X11_FOUND AND X11_XTest_LIB)
add_definitions(-DHAVE_XTEST)
target_link_libraries(x0vncserver ${X11_XTest_LIB})
diff --git a/unix/x0vncserver/x0vncserver.cxx b/unix/x0vncserver/x0vncserver.cxx
index f87eb61e..5e9a7a57 100644
--- a/unix/x0vncserver/x0vncserver.cxx
+++ b/unix/x0vncserver/x0vncserver.cxx
@@ -38,6 +38,9 @@
#include <rfb/Timer.h>
#include <network/TcpSocket.h>
#include <network/UnixSocket.h>
+#ifdef HAVE_SYSTEMD_H
+# include <systemd/sd-daemon.h>
+#endif
#include <signal.h>
#include <X11/X.h>
@@ -113,6 +116,25 @@ static void CleanupSignalHandler(int /*sig*/)
caughtSignal = true;
}
+#ifdef HAVE_SYSTEMD_H
+static int createSystemdListeners(std::list<SocketListener*> *listeners)
+{
+ int count = sd_listen_fds(0);
+
+ for (int i = 0; i < count; ++i) {
+ /* systemd sockets start at FD 3 */
+ listeners->push_back(new TcpListener(3 + i));
+ }
+
+ return count;
+}
+#else
+static int createSystemdListeners(std::list<SocketListener*> *)
+{
+ return 0;
+}
+#endif
+
class FileTcpFilter : public TcpFilter
{
@@ -300,35 +322,40 @@ int main(int argc, char** argv)
VNCServerST server(desktopName, &desktop);
- if (rfbunixpath.getValueStr()[0] != '\0') {
- listeners.push_back(new network::UnixListener(rfbunixpath, rfbunixmode));
- vlog.info("Listening on %s (mode %04o)", (const char*)rfbunixpath, (int)rfbunixmode);
- }
-
- if ((int)rfbport != -1) {
- std::list<network::SocketListener*> tcp_listeners;
- const char *addr = interface;
-
- if (strcasecmp(addr, "all") == 0)
- addr = 0;
- if (localhostOnly)
- createLocalTcpListeners(&tcp_listeners, (int)rfbport);
- else
- createTcpListeners(&tcp_listeners, addr, (int)rfbport);
-
- if (!tcp_listeners.empty()) {
- listeners.splice (listeners.end(), tcp_listeners);
- vlog.info("Listening for VNC connections on %s interface(s), port %d",
- localhostOnly ? "local" : (const char*)interface,
- (int)rfbport);
+ if (createSystemdListeners(&listeners)) {
+ // When systemd is in charge of listeners, do not listen to anything else
+ vlog.info("Listening on systemd sockets");
+ } else {
+ if (rfbunixpath.getValueStr()[0] != '\0') {
+ listeners.push_back(new network::UnixListener(rfbunixpath, rfbunixmode));
+ vlog.info("Listening on %s (mode %04o)", (const char*)rfbunixpath, (int)rfbunixmode);
}
- FileTcpFilter fileTcpFilter(hostsFile);
- if (strlen(hostsFile) != 0)
- for (std::list<SocketListener*>::iterator i = listeners.begin();
- i != listeners.end();
- i++)
- (*i)->setFilter(&fileTcpFilter);
+ if ((int)rfbport != -1) {
+ std::list<network::SocketListener*> tcp_listeners;
+ const char *addr = interface;
+
+ if (strcasecmp(addr, "all") == 0)
+ addr = 0;
+ if (localhostOnly)
+ createLocalTcpListeners(&tcp_listeners, (int)rfbport);
+ else
+ createTcpListeners(&tcp_listeners, addr, (int)rfbport);
+
+ if (!tcp_listeners.empty()) {
+ listeners.splice (listeners.end(), tcp_listeners);
+ vlog.info("Listening for VNC connections on %s interface(s), port %d",
+ localhostOnly ? "local" : (const char*)interface,
+ (int)rfbport);
+ }
+
+ FileTcpFilter fileTcpFilter(hostsFile);
+ if (strlen(hostsFile) != 0)
+ for (std::list<SocketListener*>::iterator i = listeners.begin();
+ i != listeners.end();
+ i++)
+ (*i)->setFilter(&fileTcpFilter);
+ }
}
if (listeners.empty()) {
diff --git a/unix/x0vncserver/x0vncserver.man b/unix/x0vncserver/x0vncserver.man
index 35953865..0ba195ad 100644
--- a/unix/x0vncserver/x0vncserver.man
+++ b/unix/x0vncserver/x0vncserver.man
@@ -61,7 +61,7 @@ DISPLAY environment variable.
Specifies the TCP port on which x0vncserver listens for connections from
viewers (the protocol used in VNC is called RFB - "remote framebuffer").
The default port is 5900. Specify \fB-1\fP to disable listening on a TCP
-port.
+port. Ignored when activated by a systemd socket.
.
.TP
.B \-UseIPv4
@@ -74,7 +74,7 @@ Use IPv6 for incoming and outgoing connections. Default is on.
.TP
.B \-rfbunixpath \fIpath\fP
Specifies the path of a Unix domain socket on which x0vncserver listens for
-connections from viewers.
+connections from viewers. Ignored when activated by a systemd socket.
.
.TP
.B \-rfbunixmode \fImode\fP