diff options
Diffstat (limited to 'plugins/pipe_cmd.py')
-rw-r--r-- | plugins/pipe_cmd.py | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/plugins/pipe_cmd.py b/plugins/pipe_cmd.py index f554a71d..762501ae 100644 --- a/plugins/pipe_cmd.py +++ b/plugins/pipe_cmd.py @@ -6,10 +6,10 @@ This plugins allows commands to be sent to poezio via a named pipe. from plugin import BasePlugin -import threading import os import stat import logging +import asyncio log = logging.getLogger(__name__) @@ -25,19 +25,30 @@ class Plugin(BasePlugin): os.mkfifo(self.pipename) if not stat.S_ISFIFO(os.stat(self.pipename).st_mode): - log.error("File %s is not a fifo file" % self.pipename) - raise TypeError - - thread = threading.Thread(target=self.main_loop) - thread.setDaemon(True) - thread.start() - - def main_loop(self): - while not self.stop: - fd = open(self.pipename, 'r') - line = fd.read().strip() - self.api.run_command(line) - fd.close() + raise TypeError("File %s is not a fifo file" % self.pipename) + + self.fd = os.open(self.pipename, os.O_RDONLY|os.O_NONBLOCK) + + self.data = b"" + asyncio.get_event_loop().add_reader(self.fd, self.read_from_fifo) + + def read_from_fifo(self): + data = os.read(self.fd, 512) + if not data: + # EOF, close the fifo. And reopen it + asyncio.get_event_loop().remove_reader(self.fd) + os.close(self.fd) + self.fd = os.open(self.pipename, os.O_RDONLY|os.O_NONBLOCK) + asyncio.get_event_loop().add_reader(self.fd, self.read_from_fifo) + self.data = b'' + else: + self.data += data + l = self.data.split(b'\n', 1) + if len(l) == 2: + line, self.data = l + log.debug("run: %s" % (line.decode().strip())) + self.api.run_command(line.decode().strip()) def cleanup(self): - self.stop = True + asyncio.get_event_loop().remove_reader(self.fd) + os.close(self.fd) |