Check session valididty on kak -l and support kak -clear for clearing the dead ones

Fixes #689
This commit is contained in:
Maxime Coste 2016-06-06 19:28:56 +01:00
parent 4747ba6be9
commit c73e64882c
4 changed files with 36 additions and 5 deletions

View File

@ -224,7 +224,13 @@ Just running *kak* launch a new kak session with a client on local terminal.
acting as a remote control. acting as a remote control.
* `-f <keys>`: Work as a filter, read every file given on the command line * `-f <keys>`: Work as a filter, read every file given on the command line
and stdin if piped in, and apply given keys on each. and stdin if piped in, and apply given keys on each.
* `-l`: list existing sessions * `-ui <userinterface>`: use given user interface, `<userinterface>` can be
- `ncurses`: default terminal user interface
- `dummy`: empty user interface not displaying anything
- `json`: json-rpc based user interface that writes json on stdout and
read keystrokes as json on stdin.
* `-l`: list existing sessions, and check the dead ones
* `-clear`: clear dead sessions socket files
At startup, if `-n` is not specified, Kakoune will try to source the file At startup, if `-n` is not specified, Kakoune will try to source the file
`../share/kak/kakrc` relative to the kak binary. This kak file will then try `../share/kak/kakrc` relative to the kak binary. This kak file will then try

View File

@ -731,7 +731,8 @@ int main(int argc, char* argv[])
{ "f", { true, "act as a filter, executing given keys on given files" } }, { "f", { true, "act as a filter, executing given keys on given files" } },
{ "q", { false, "in filter mode, be quiet about errors applying keys" } }, { "q", { false, "in filter mode, be quiet about errors applying keys" } },
{ "ui", { true, "set the type of user interface to use (ncurses, dummy, or json)" } }, { "ui", { true, "set the type of user interface to use (ncurses, dummy, or json)" } },
{ "l", { false, "list existing sessions" } } } { "l", { false, "list existing sessions" } },
{ "clear", { false, "clear dead sessions" } } }
}; };
try try
{ {
@ -741,12 +742,26 @@ int main(int argc, char* argv[])
ParametersParser parser(params, param_desc); ParametersParser parser(params, param_desc);
if (parser.get_switch("l")) const bool list_sessions = (bool)parser.get_switch("l");
const bool clear_sessions = (bool)parser.get_switch("clear");
if (list_sessions or clear_sessions)
{ {
for (auto& file : list_files(format("/tmp/kakoune/{}/", getpwuid(geteuid())->pw_name))) StringView username = getpwuid(geteuid())->pw_name;
write_stdout(format("{}\n", file)); for (auto& session : list_files(format("/tmp/kakoune/{}/", username)))
{
const bool valid = check_session(session);
if (list_sessions)
write_stdout(format("{}{}\n", session, valid ? "" : " (dead)"));
if (not valid and clear_sessions)
{
char socket_file[128];
format_to(socket_file, "/tmp/kakoune/{}/{}", username, session);
unlink(socket_file);
}
}
return 0; return 0;
} }
if (auto session = parser.get_switch("p")) if (auto session = parser.get_switch("p"))
{ {
for (auto opt : { "c", "n", "s", "d", "e" }) for (auto opt : { "c", "n", "s", "d", "e" })

View File

@ -436,6 +436,14 @@ static int connect_to(StringView session)
return sock; return sock;
} }
bool check_session(StringView session)
{
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
auto close_sock = on_scope_end([sock]{ close(sock); });
sockaddr_un addr = session_addr(session);
return connect(sock, (sockaddr*)&addr, sizeof(addr.sun_path)) != -1;
}
RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui, RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
const EnvVarMap& env_vars, StringView init_command) const EnvVarMap& env_vars, StringView init_command)
: m_ui(std::move(ui)) : m_ui(std::move(ui))

View File

@ -59,6 +59,8 @@ private:
Vector<std::unique_ptr<Accepter>> m_accepters; Vector<std::unique_ptr<Accepter>> m_accepters;
}; };
bool check_session(StringView session);
} }
#endif // remote_hh_INCLUDED #endif // remote_hh_INCLUDED