From 11c62e583c48bbd47418a45af3d70cde947313fe Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 2 Mar 2014 02:01:09 +0000 Subject: [PATCH] Add -p 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. --- src/main.cc | 28 +++++++++++++++++++++++++++- src/remote.cc | 19 +++++++++++++++++++ src/remote.hh | 2 ++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/main.cc b/src/main.cc index 72a6f5a9..c53477ba 100644 --- a/src/main.cc +++ b/src/main.cc @@ -233,6 +233,31 @@ int run_client(const String& session, const String& init_command) 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; if (parser.has_option("e")) init_command = parser.option_value("e"); @@ -364,7 +389,8 @@ int main(int argc, char* argv[]) { "e", { true, "execute argument on initialisation" } }, { "n", { false, "do not source kakrc files on startup" } }, { "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 { diff --git a/src/remote.cc b/src/remote.cc index ca4ce665..cbad21f8 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -453,6 +453,25 @@ std::unique_ptr connect_to(const String& session, std::unique_ptr< return std::unique_ptr{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 // recieved. Everything recieved before is considered to be a command. diff --git a/src/remote.hh b/src/remote.hh index 4129691d..ac7a3cec 100644 --- a/src/remote.hh +++ b/src/remote.hh @@ -30,6 +30,8 @@ std::unique_ptr connect_to(const String& session, std::unique_ptr&& ui, const String& init_command); +void send_command(const String& session, const String& command); + struct Server : public Singleton { Server(String session_name);