Modify network protocol to allow commands through the socket
This commit is contained in:
parent
17b861d78e
commit
e428a9757f
|
@ -712,7 +712,7 @@ struct Server : public Singleton<Server>
|
||||||
throw runtime_error("accept failed");
|
throw runtime_error("accept failed");
|
||||||
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
fcntl(sock, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
new FDWatcher{sock, handle_remote};
|
new ClientAccepter{sock};
|
||||||
};
|
};
|
||||||
m_listener.reset(new FDWatcher{listen_sock, accepter});
|
m_listener.reset(new FDWatcher{listen_sock, accepter});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "debug.hh"
|
#include "debug.hh"
|
||||||
#include "client_manager.hh"
|
#include "client_manager.hh"
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
|
#include "buffer_manager.hh"
|
||||||
|
#include "command_manager.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
@ -307,7 +309,7 @@ RemoteClient::RemoteClient(int socket, UserInterface* ui,
|
||||||
m_socket_watcher{socket, [this](FDWatcher&){ process_next_message(); }}
|
m_socket_watcher{socket, [this](FDWatcher&){ process_next_message(); }}
|
||||||
{
|
{
|
||||||
Message msg(socket);
|
Message msg(socket);
|
||||||
msg.write(init_command);
|
msg.write(init_command.c_str(), (int)init_command.length()+1);
|
||||||
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
|
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
|
||||||
msg.write(key);
|
msg.write(key);
|
||||||
|
|
||||||
|
@ -378,15 +380,46 @@ void RemoteClient::write_next_key()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_remote(FDWatcher& watcher)
|
ClientAccepter::ClientAccepter(int socket)
|
||||||
|
: m_socket_watcher(socket, [this](FDWatcher&) { handle_available_input(); }) {}
|
||||||
|
|
||||||
|
void ClientAccepter::handle_available_input()
|
||||||
|
{
|
||||||
|
int socket = m_socket_watcher.fd();
|
||||||
|
timeval tv{ 0, 0 };
|
||||||
|
fd_set rfds;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int res = ::read(socket, &c, 1);
|
||||||
|
if (res <= 0)
|
||||||
|
{
|
||||||
|
if (not m_buffer.empty()) try
|
||||||
|
{
|
||||||
|
Context context{};
|
||||||
|
CommandManager::instance().execute(m_buffer, context);
|
||||||
|
}
|
||||||
|
catch (runtime_error& e)
|
||||||
|
{
|
||||||
|
write_debug("error running command '" + m_buffer + "' : " + e.description());
|
||||||
|
}
|
||||||
|
delete this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == 0) // end of initial command stream, go to interactive ui mode
|
||||||
{
|
{
|
||||||
int socket = watcher.fd();
|
|
||||||
delete &watcher;
|
|
||||||
String init_command = read<String>(socket);
|
|
||||||
|
|
||||||
RemoteUI* ui = new RemoteUI{socket};
|
|
||||||
ClientManager::instance().create_client(
|
ClientManager::instance().create_client(
|
||||||
std::unique_ptr<UserInterface>{ui}, init_command);
|
std::unique_ptr<UserInterface>{new RemoteUI{socket}}, m_buffer);
|
||||||
|
delete this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_buffer += c;
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(socket, &rfds);
|
||||||
|
}
|
||||||
|
while (select(socket+1, &rfds, NULL, NULL, &tv) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,25 @@ namespace Kakoune
|
||||||
|
|
||||||
struct peer_disconnected {};
|
struct peer_disconnected {};
|
||||||
|
|
||||||
void handle_remote(FDWatcher& event);
|
// A client accepter handle a connection until it closes or a nul byte is
|
||||||
|
// recieved. Everything recieved before is considered to be a command.
|
||||||
|
//
|
||||||
|
// * When a nul byte is recieved, the socket is handed to a new Client along
|
||||||
|
// with the command.
|
||||||
|
// * When the connection is closed, the command is run in an empty context.
|
||||||
|
class ClientAccepter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientAccepter(int socket);
|
||||||
|
private:
|
||||||
|
void handle_available_input();
|
||||||
|
|
||||||
|
String m_buffer;
|
||||||
|
FDWatcher m_socket_watcher;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A remote client handle communication between a client running on the server
|
||||||
|
// and a user interface running on the local process.
|
||||||
class RemoteClient
|
class RemoteClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user