Support the +line syntax for clients as well.

Fix a crash on daemon quit as well.
This commit is contained in:
Maxime Coste 2017-01-21 12:14:44 +00:00
parent c6a7924b80
commit e8ee8c23d8
4 changed files with 58 additions and 28 deletions

View File

@ -22,8 +22,10 @@ void ClientManager::clear()
// So that clients destructor find the client manager empty
// so that local UI does not fork.
ClientList clients = std::move(m_clients);
clients.clear();
m_client_trash.clear();
m_free_windows.clear();
m_window_trash.clear();
}
String ClientManager::generate_name() const

View File

@ -454,12 +454,13 @@ void signal_handler(int signal)
abort();
}
int run_client(StringView session, StringView init_cmds, UIType ui_type)
int run_client(StringView session, StringView init_cmds,
Optional<BufferCoord> init_coord, UIType ui_type)
{
try
{
EventManager event_manager;
RemoteClient client{session, make_ui(ui_type), get_env_vars(), init_cmds};
RemoteClient client{session, make_ui(ui_type), get_env_vars(), init_cmds, init_coord};
while (true)
event_manager.handle_next_events(EventMode::Normal);
}
@ -473,7 +474,7 @@ int run_client(StringView session, StringView init_cmds, UIType ui_type)
}
int run_server(StringView session,
StringView init_cmds, BufferCoord init_coord,
StringView init_cmds, Optional<BufferCoord> init_coord,
bool ignore_kakrc, bool daemon, bool readonly, UIType ui_type,
ConstArrayView<StringView> files)
{
@ -812,6 +813,28 @@ int main(int argc, char* argv[])
(bool)parser.get_switch("q"));
}
Vector<StringView> files;
Optional<BufferCoord> init_coord;
for (auto& name : parser)
{
if (not name.empty() and name[0_byte] == '+')
{
auto colon = find(name, ':');
if (auto line = str_to_int_ifp({name.begin()+1, colon}))
{
init_coord = BufferCoord{
*line - 1,
colon != name.end() ?
str_to_int_ifp({colon+1, name.end()}).value_or(1) - 1
: 0
};
continue;
}
}
files.emplace_back(name);
}
if (auto server_session = parser.get_switch("c"))
{
for (auto opt : { "n", "s", "d", "ro" })
@ -823,32 +846,13 @@ int main(int argc, char* argv[])
}
}
String new_files;
for (auto name : parser)
for (auto name : files)
new_files += format("edit '{}';", escape(real_path(name), "'", '\\'));
return run_client(*server_session, new_files + init_cmds, ui_type);
return run_client(*server_session, new_files + init_cmds, init_coord, ui_type);
}
else
{
BufferCoord init_coord;
Vector<StringView> files;
for (auto& name : parser)
{
if (not name.empty() and name[0_byte] == '+')
{
auto colon = find(name, ':');
if (auto line = str_to_int_ifp({name.begin()+1, colon}))
{
init_coord.line = *line - 1;
if (colon != name.end())
init_coord.column = str_to_int_ifp({colon+1, name.end()}).value_or(1) - 1;
continue;
}
}
files.emplace_back(name);
}
StringView session = parser.get_switch("s").value_or(StringView{});
try
@ -864,7 +868,7 @@ int main(int argc, char* argv[])
raise(SIGTSTP);
return run_client(convert.session,
format("try %^buffer '{}'; select '{}'^; echo converted to client only mode",
escape(convert.buffer_name, "'^", '\\'), convert.selections), ui_type);
escape(convert.buffer_name, "'^", '\\'), convert.selections), {}, ui_type);
}
}
}

View File

@ -8,6 +8,7 @@
#include "event_manager.hh"
#include "file.hh"
#include "id_map.hh"
#include "optional.hh"
#include "user_interface.hh"
#include <sys/types.h>
@ -102,6 +103,14 @@ public:
}
}
template<typename T>
void write(const Optional<T>& val)
{
write((bool)val);
if (val)
write(*val);
}
void write(Color color)
{
write(color.color);
@ -219,6 +228,14 @@ public:
return res;
}
template<typename T>
Optional<T> read_optional()
{
if (not read<bool>())
return {};
return read<T>();
}
void reset()
{
m_stream.resize(0);
@ -511,7 +528,8 @@ bool check_session(StringView session)
}
RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
const EnvVarMap& env_vars, StringView init_command)
const EnvVarMap& env_vars, StringView init_command,
Optional<BufferCoord> init_coord)
: m_ui(std::move(ui))
{
int sock = connect_to(session);
@ -519,6 +537,7 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
{
MsgWriter msg{m_send_buffer, MessageType::Connect};
msg.write(init_command);
msg.write(init_coord);
msg.write(m_ui->dimensions());
msg.write(env_vars);
}
@ -652,12 +671,13 @@ private:
case MessageType::Connect:
{
auto init_cmds = m_reader.read<String>();
auto init_coord = m_reader.read_optional<BufferCoord>();
auto dimensions = m_reader.read<DisplayCoord>();
auto env_vars = m_reader.read_idmap<String, MemoryDomain::EnvVars>();
auto* ui = new RemoteUI{sock, dimensions};
if (auto* client = ClientManager::instance().create_client(
std::unique_ptr<UserInterface>(ui),
std::move(env_vars), init_cmds, {}))
std::move(env_vars), init_cmds, init_coord))
ui->set_client(client);
Server::instance().remove_accepter(this);

View File

@ -22,6 +22,9 @@ struct disconnected : runtime_error
class FDWatcher;
class UserInterface;
template<typename T> struct Optional;
struct BufferCoord;
using RemoteBuffer = Vector<char, MemoryDomain::Remote>;
// A remote client handle communication between a client running on the server
@ -30,7 +33,8 @@ class RemoteClient
{
public:
RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
const EnvVarMap& env_vars, StringView init_command);
const EnvVarMap& env_vars, StringView init_command,
Optional<BufferCoord> init_coord);
private:
std::unique_ptr<UserInterface> m_ui;