mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-06 23:21:57 -07:00
XWayland: restore the abstract socket, and make it optional (#9615)
* Revert "xwayland: don't create an abstract unix domain socket on linux (#8874)" (#9574)
This reverts commit 2b01a5bcf6
.
* xwayland: make the abstract Unix domain socket optional (#9574)
* xwayland: extend the default permissions for a regular Unix domain socket (#9574)
* xwayland: a little refactoring for `createSocket`
This commit is contained in:
@@ -1319,6 +1319,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "xwayland:create_abstract_socket",
|
||||
.description = "Create the abstract Unix domain socket for XWayland",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* opengl:
|
||||
|
@@ -652,6 +652,7 @@ CConfigManager::CConfigManager() {
|
||||
registerConfigVar("xwayland:enabled", Hyprlang::INT{1});
|
||||
registerConfigVar("xwayland:use_nearest_neighbor", Hyprlang::INT{1});
|
||||
registerConfigVar("xwayland:force_zero_scaling", Hyprlang::INT{0});
|
||||
registerConfigVar("xwayland:create_abstract_socket", Hyprlang::INT{0});
|
||||
|
||||
registerConfigVar("opengl:nvidia_anti_flicker", Hyprlang::INT{1});
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "Server.hpp"
|
||||
#include "XWayland.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
@@ -32,31 +33,45 @@ constexpr int SOCKET_BACKLOG = 1;
|
||||
constexpr int MAX_SOCKET_RETRIES = 32;
|
||||
constexpr int LOCK_FILE_MODE = 0444;
|
||||
|
||||
static CFileDescriptor createSocket(struct sockaddr_un* addr, size_t path_size) {
|
||||
socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1;
|
||||
static CFileDescriptor createSocket(struct sockaddr_un* addr, size_t pathSize) {
|
||||
const bool isRegularSocket(addr->sun_path[0]);
|
||||
const char dbgSocketPathPrefix = isRegularSocket ? addr->sun_path[0] : '@';
|
||||
const char* const dbgSocketPathRem = addr->sun_path + 1;
|
||||
|
||||
socklen_t size = offsetof(struct sockaddr_un, sun_path) + pathSize + 1;
|
||||
CFileDescriptor fd{socket(AF_UNIX, SOCK_STREAM, 0)};
|
||||
if (!fd.isValid()) {
|
||||
Debug::log(ERR, "Failed to create socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1);
|
||||
Debug::log(ERR, "Failed to create socket {}{}", dbgSocketPathPrefix, dbgSocketPathRem);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!fd.setFlags(fd.getFlags() | FD_CLOEXEC)) {
|
||||
Debug::log(ERR, "Failed to set flags for socket {}{}", dbgSocketPathPrefix, dbgSocketPathRem);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (addr->sun_path[0])
|
||||
if (isRegularSocket)
|
||||
unlink(addr->sun_path);
|
||||
|
||||
if (bind(fd.get(), (struct sockaddr*)addr, size) < 0) {
|
||||
Debug::log(ERR, "Failed to bind socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1);
|
||||
if (addr->sun_path[0])
|
||||
Debug::log(ERR, "Failed to bind socket {}{}", dbgSocketPathPrefix, dbgSocketPathRem);
|
||||
if (isRegularSocket)
|
||||
unlink(addr->sun_path);
|
||||
return {};
|
||||
}
|
||||
|
||||
// Required for the correct functioning of `xhost` #9574
|
||||
// The operation is safe because XWayland controls socket access by itself
|
||||
// and rejects connections not matched by the `xhost` ACL
|
||||
if (isRegularSocket && chmod(addr->sun_path, 0666) < 0) {
|
||||
// We are only extending the default permissions,
|
||||
// and I don't see the reason to make a full stop in case of a failed operation.
|
||||
Debug::log(ERR, "Failed to set permission mode for socket {}{}", dbgSocketPathPrefix, dbgSocketPathRem);
|
||||
}
|
||||
|
||||
if (listen(fd.get(), SOCKET_BACKLOG) < 0) {
|
||||
Debug::log(ERR, "Failed to listen to socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1);
|
||||
if (addr->sun_path[0])
|
||||
Debug::log(ERR, "Failed to listen to socket {}{}", dbgSocketPathPrefix, dbgSocketPathRem);
|
||||
if (isRegularSocket)
|
||||
unlink(addr->sun_path);
|
||||
return {};
|
||||
}
|
||||
@@ -113,14 +128,32 @@ static std::string getSocketPath(int display, bool isLinux) {
|
||||
}
|
||||
|
||||
static bool openSockets(std::array<CFileDescriptor, 2>& sockets, int display) {
|
||||
static auto CREATEABSTRACTSOCKET = CConfigValue<Hyprlang::INT>("xwayland:create_abstract_socket");
|
||||
|
||||
if (!ensureSocketDirExists())
|
||||
return false;
|
||||
|
||||
sockaddr_un addr = {.sun_family = AF_UNIX};
|
||||
std::string path;
|
||||
|
||||
#ifdef __linux__
|
||||
if (*CREATEABSTRACTSOCKET) {
|
||||
// cursed...
|
||||
// but is kept as an option for better compatibility
|
||||
addr.sun_path[0] = 0;
|
||||
path = getSocketPath(display, true);
|
||||
strncpy(addr.sun_path + 1, path.c_str(), path.length() + 1);
|
||||
} else {
|
||||
path = getSocketPath(display, false);
|
||||
strncpy(addr.sun_path, path.c_str(), path.length() + 1);
|
||||
}
|
||||
#else
|
||||
if (*CREATEABSTRACTSOCKET) {
|
||||
Debug::log(WARN, "The abstract XWayland Unix domain socket might be used only on Linux systems. A regular one'll be created insted.");
|
||||
}
|
||||
path = getSocketPath(display, false);
|
||||
strncpy(addr.sun_path, path.c_str(), path.length() + 1);
|
||||
#endif
|
||||
|
||||
sockets[0] = CFileDescriptor{createSocket(&addr, path.length())};
|
||||
if (!sockets[0].isValid())
|
||||
@@ -220,13 +253,11 @@ CXWaylandServer::~CXWaylandServer() {
|
||||
safeRemove(lockPath);
|
||||
|
||||
std::string path;
|
||||
#ifdef __linux__
|
||||
path = getSocketPath(display, true);
|
||||
#else
|
||||
path = getSocketPath(display, false);
|
||||
#endif
|
||||
for (bool isLinux : {true, false}) {
|
||||
path = getSocketPath(display, isLinux);
|
||||
safeRemove(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CXWaylandServer::die() {
|
||||
if (display < 0)
|
||||
|
Reference in New Issue
Block a user