Add -p <session> option to kak, which forward commands on stdin to session

This allows using directly the kak binary in place of socat for piping commands
to a foreing session.
This commit is contained in:
Maxime Coste 2014-03-02 02:01:09 +00:00
parent e9442ea307
commit 11c62e583c
3 changed files with 48 additions and 1 deletions

View File

@ -233,6 +233,31 @@ int run_client(const String& session, const String& init_command)
int kakoune(const ParametersParser& parser) int kakoune(const ParametersParser& parser)
{ {
if (parser.has_option("p"))
{
for (auto opt : { "c", "n", "s", "d", "e" })
{
if (parser.has_option(opt))
{
fprintf(stderr, "error: -%s makes not sense with -p\n", opt);
return -1;
}
}
char buf[512];
String command;
while (ssize_t count = read(0, buf, 512))
{
if (count < 0)
{
fprintf(stderr, "error while reading stdin\n");
return -1;
}
command += String{buf, buf + count};
}
send_command(parser.option_value("p"), command);
return 0;
}
String init_command; String init_command;
if (parser.has_option("e")) if (parser.has_option("e"))
init_command = parser.option_value("e"); init_command = parser.option_value("e");
@ -364,7 +389,8 @@ int main(int argc, char* argv[])
{ "e", { true, "execute argument on initialisation" } }, { "e", { true, "execute argument on initialisation" } },
{ "n", { false, "do not source kakrc files on startup" } }, { "n", { false, "do not source kakrc files on startup" } },
{ "s", { true, "set session name" } }, { "s", { true, "set session name" } },
{ "d", { false, "run as a headless session (requires -s)" } } } { "d", { false, "run as a headless session (requires -s)" } },
{ "p", { true, "just send stdin as commands to the given session" } } }
}; };
try try
{ {

View File

@ -453,6 +453,25 @@ std::unique_ptr<RemoteClient> connect_to(const String& session, std::unique_ptr<
return std::unique_ptr<RemoteClient>{new RemoteClient{sock, std::move(ui), init_command}}; return std::unique_ptr<RemoteClient>{new RemoteClient{sock, std::move(ui), init_command}};
} }
void send_command(const String& session, const String& command)
{
auto filename = "/tmp/kak-" + session;
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
fcntl(sock, F_SETFD, FD_CLOEXEC);
sockaddr_un addr;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, filename.c_str(), sizeof(addr.sun_path) - 1);
if (connect(sock, (sockaddr*)&addr, sizeof(addr.sun_path)) == -1)
throw runtime_error("connect to " + filename + " failed");
{
Message msg(sock);
msg.write(command.c_str(), (int)command.length()+1);
}
close(sock);
}
// A client accepter handle a connection until it closes or a nul byte is // A client accepter handle a connection until it closes or a nul byte is
// recieved. Everything recieved before is considered to be a command. // recieved. Everything recieved before is considered to be a command.

View File

@ -30,6 +30,8 @@ std::unique_ptr<RemoteClient> connect_to(const String& session,
std::unique_ptr<UserInterface>&& ui, std::unique_ptr<UserInterface>&& ui,
const String& init_command); const String& init_command);
void send_command(const String& session, const String& command);
struct Server : public Singleton<Server> struct Server : public Singleton<Server>
{ {
Server(String session_name); Server(String session_name);