Use $XDG_RUNTIME_DIR

Falls back on old mechanism if `XDG_RUNTIME_DIR` is not set.

The ability to specify a session as "<user>/<name>" was removed, since
it isn't possible to compute the value of `XDG_RUNTIME_DIR` for another
user, we wouldn't have access to it if we could, and it would be awkward
to support this feature only when `XDG_RUNTIME_DIR` is unset.  Also,
`rename-session` did not work when another user's session was specified.

Closes #3019
This commit is contained in:
Jason Felice 2019-07-29 13:38:11 -04:00
parent 1c6aa9baed
commit 0e4a4acf61
2 changed files with 30 additions and 17 deletions

View File

@ -537,18 +537,35 @@ String get_user_name()
return getenv("USER");
}
void make_session_directory()
{
StringView xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
if (xdg_runtime_dir.empty())
{
// set sticky bit on the shared kakoune directory
make_directory(format("{}/kakoune", tmpdir()), 01777);
make_directory(format("{}/kakoune/{}", tmpdir(), get_user_name()), 0711);
}
else
make_directory(format("{}/kakoune", xdg_runtime_dir), 0711);
}
String session_path(StringView session)
{
if (contains(session, '/'))
throw runtime_error{"session names cannot have slashes"};
StringView xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
if (xdg_runtime_dir.empty())
return format("{}/kakoune/{}/{}", tmpdir(), get_user_name(), session);
else
return format("{}/kakoune/{}", xdg_runtime_dir, session);
}
static sockaddr_un session_addr(StringView session)
{
sockaddr_un addr;
addr.sun_family = AF_UNIX;
auto slash_count = std::count(session.begin(), session.end(), '/');
if (slash_count > 1)
throw runtime_error{"session names are either <user>/<name> or <name>"};
else if (slash_count == 1)
format_to(addr.sun_path, "{}/kakoune/{}", tmpdir(), session);
else
format_to(addr.sun_path, "{}/kakoune/{}/{}", tmpdir(),
get_user_name(), session);
strcpy(addr.sun_path, session_path(session).c_str());
return addr;
}
@ -784,9 +801,7 @@ Server::Server(String session_name)
fcntl(listen_sock, F_SETFD, FD_CLOEXEC);
sockaddr_un addr = session_addr(m_session);
// set sticky bit on the shared kakoune directory
make_directory(format("{}/kakoune", tmpdir()), 01777);
make_directory(split_path(addr.sun_path).first, 0711);
make_session_directory();
// Do not give any access to the socket to other users by default
auto old_mask = umask(0077);
@ -819,10 +834,8 @@ bool Server::rename_session(StringView name)
if (not all_of(name, is_identifier))
throw runtime_error{format("invalid session name: '{}'", name)};
String old_socket_file = format("{}/kakoune/{}/{}", tmpdir(),
get_user_name(), m_session);
String new_socket_file = format("{}/kakoune/{}/{}", tmpdir(),
get_user_name(), name);
String old_socket_file = session_path(m_session);
String new_socket_file = session_path(name);
if (file_exists(new_socket_file))
return false;
@ -838,8 +851,7 @@ void Server::close_session(bool do_unlink)
{
if (do_unlink)
{
String socket_file = format("{}/kakoune/{}/{}", tmpdir(),
get_user_name(), m_session);
String socket_file = session_path(m_session);
unlink(socket_file.c_str());
}
m_listener->close_fd();

View File

@ -45,6 +45,7 @@ private:
void send_command(StringView session, StringView command);
String get_user_name();
String session_path(StringView session);
struct Server : public Singleton<Server>
{