summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/pipe_cmd.py41
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)