monkeyfarmer.py: Ensure that we capture and repeat stderr

In order that we can process stderr in monkey-see-monkey-do
we need to capture it in the farmer and re-echo it through
Python's stderr object

Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
This commit is contained in:
Daniel Silverstone 2020-01-10 22:18:48 +00:00
parent ccffb95f03
commit a29ed7c083
No known key found for this signature in database
GPG Key ID: C30DF439F2987D74

View File

@ -32,6 +32,44 @@ import socket
import subprocess import subprocess
import time import time
import errno import errno
import sys
class StderrEcho(asyncore.dispatcher):
def __init__(self, sockend):
asyncore.dispatcher.__init__(self, sock=sockend)
self.incoming = b""
def handle_connect(self):
pass
def handle_close(self):
# the pipe to the monkey process has closed
self.close()
def handle_read(self):
try:
got = self.recv(8192)
if not got:
return
except socket.error as error:
if error.errno == errno.EAGAIN or error.errno == errno.EWOULDBLOCK:
return
else:
raise
self.incoming += got
if b"\n" in self.incoming:
lines = self.incoming.split(b"\n")
self.incoming = lines.pop()
for line in lines:
try:
line = line.decode('utf-8')
except UnicodeDecodeError:
print("WARNING: Unicode decode error")
line = line.decode('utf-8', 'replace')
sys.stderr.write("{}\n".format(line))
class MonkeyFarmer(asyncore.dispatcher): class MonkeyFarmer(asyncore.dispatcher):
@ -42,6 +80,10 @@ class MonkeyFarmer(asyncore.dispatcher):
asyncore.dispatcher.__init__(self, sock=mine) asyncore.dispatcher.__init__(self, sock=mine)
(mine2, monkeyserr) = socket.socketpair()
self._errwrapper = StderrEcho(mine2)
if wrapper is not None: if wrapper is not None:
new_cmd = list(wrapper) new_cmd = list(wrapper)
new_cmd.extend(monkey_cmd) new_cmd.extend(monkey_cmd)
@ -51,9 +93,11 @@ class MonkeyFarmer(asyncore.dispatcher):
monkey_cmd, monkey_cmd,
stdin=monkeys, stdin=monkeys,
stdout=monkeys, stdout=monkeys,
close_fds=[mine]) stderr=monkeyserr,
close_fds=[mine, mine2])
monkeys.close() monkeys.close()
monkeyserr.close()
self.buffer = b"" self.buffer = b""
self.incoming = b"" self.incoming = b""