poezio/src/fifo.py

72 lines
2 KiB
Python
Raw Normal View History

"""
Defines the Fifo class
This fifo allows simple communication between a remote poezio
and a local computer, with ssh+cat.
"""
import logging
log = logging.getLogger(__name__)
import os
import threading
class OpenTrick(threading.Thread):
"""
A threaded trick to make the open for writing succeed.
A fifo cannot be opened for writing if it has not been
yet opened by the other hand for reading.
So, we just open the fifo for reading and we do not close
it afterwards, because if the other reader disconnects,
we will receive a SIGPIPE. And we do not want that.
(we never read anything from it, obviously)
"""
def __init__(self, path):
threading.Thread.__init__(self)
self.path = path
self.fd = None
def run(self):
self.fd = open(self.path, 'r', encoding='utf-8')
class Fifo(object):
"""
Just a simple file handler, writing and reading in a fifo.
Mode is either 'r' or 'w', just like the mode for the open()
function.
"""
def __init__(self, path, mode):
self.trick = None
if not os.path.exists(path):
os.mkfifo(path)
if mode == 'w':
self.trick = OpenTrick(path)
# that thread will wait until we open it for writing
self.trick.start()
self.fd = open(path, mode, encoding='utf-8')
def write(self, data):
"""
Try to write on the fifo. If that fails, this means
that nothing has that fifo opened, so the writing is useless,
so we just return (and display an error telling that, somewhere).
"""
self.fd.write(data)
self.fd.flush()
def readline(self):
"Read a line from the fifo"
return self.fd.readline()
def __del__(self):
"Close opened fds"
try:
self.fd.close()
if self.trick:
self.trick.fd.close()
except:
log.error('Unable to close descriptors for the fifo',
exc_info=True)