summaryrefslogtreecommitdiff
path: root/src/Listen.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2018-10-30 18:37:32 +0100
committerMax Kellermann <max@musicpd.org>2018-10-30 22:14:54 +0100
commit56112a237ce9a86936d99d7e48eeaaf6e1fae041 (patch)
tree1caacb156b2115f84b6955e934b81a2e96a5db59 /src/Listen.cxx
parent64da9399ca1e26c038dcb46ee53c4b5375f5d553 (diff)
Listen: listen on $XDG_RUNTIME_DIR/mpd/socket by default
Diffstat (limited to 'src/Listen.cxx')
-rw-r--r--src/Listen.cxx63
1 files changed, 62 insertions, 1 deletions
diff --git a/src/Listen.cxx b/src/Listen.cxx
index 4d7b4f9e9..aeb890e0c 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -19,16 +19,20 @@
#include "config.h"
#include "Listen.hxx"
+#include "Log.hxx"
#include "client/Listener.hxx"
#include "config/Param.hxx"
#include "config/Data.hxx"
#include "config/Option.hxx"
#include "config/Net.hxx"
+#include "net/AllocatedSocketAddress.hxx"
#include "net/UniqueSocketDescriptor.hxx"
+#include "net/SocketUtil.hxx"
#include "system/Error.hxx"
#include "util/RuntimeError.hxx"
#include "fs/AllocatedPath.hxx"
+#include <sys/stat.h>
#include <string.h>
#include <assert.h>
@@ -61,6 +65,51 @@ listen_systemd_activation(ClientListener &listener)
#endif
+/**
+ * Listen on "$XDG_RUNTIME_DIR/mpd/socket" (if applicable).
+ *
+ * @return true if a listener socket was added
+ */
+static bool
+ListenXdgRuntimeDir(ClientListener &listener) noexcept
+{
+#if defined(_WIN32) || defined(ANDROID) || !defined(HAVE_UN)
+ (void)listener;
+ return false;
+#else
+ if (geteuid() == 0)
+ /* this MPD instance is a system-wide daemon; don't
+ use $XDG_RUNTIME_DIR */
+ return false;
+
+ Path xdg_runtime_dir = Path::FromFS(getenv("XDG_RUNTIME_DIR"));
+ if (xdg_runtime_dir.IsNull())
+ return false;
+
+ const auto mpd_runtime_dir = xdg_runtime_dir / Path::FromFS("mpd");
+ mkdir(mpd_runtime_dir.c_str(), 0700);
+
+ const auto socket_path = mpd_runtime_dir / Path::FromFS("socket");
+ unlink(socket_path.c_str());
+
+ AllocatedSocketAddress address;
+ address.SetLocal(socket_path.c_str());
+
+ try {
+ auto fd = socket_bind_listen(AF_LOCAL, SOCK_STREAM, 0,
+ address, 5);
+ chmod(socket_path.c_str(), 0600);
+ listener.AddFD(std::move(fd), std::move(address));
+ return true;
+ } catch (...) {
+ FormatError(std::current_exception(),
+ "Failed to listen on '%s' (not fatal)",
+ socket_path.c_str());
+ return false;
+ }
+#endif
+}
+
void
listen_global_init(const ConfigData &config, ClientListener &listener)
{
@@ -82,10 +131,14 @@ listen_global_init(const ConfigData &config, ClientListener &listener)
}
}
+ bool have_xdg_runtime_listener = false;
+
if (listener.IsEmpty()) {
/* no "bind_to_address" configured, bind the
configured port on all interfaces */
+ have_xdg_runtime_listener = ListenXdgRuntimeDir(listener);
+
try {
listener.AddPort(port);
} catch (...) {
@@ -93,7 +146,15 @@ listen_global_init(const ConfigData &config, ClientListener &listener)
}
}
- listener.Open();
+ try {
+ listener.Open();
+ } catch (...) {
+ if (have_xdg_runtime_listener)
+ LogError(std::current_exception(),
+ "Default TCP listener setup failed, but this is okay because we have a $XDG_RUNTIME_DIR listener");
+ else
+ throw;
+ }
listen_port = port;
}