Route output from backend through frontend
This commit is contained in:
parent
e8e4257baa
commit
c7a773958d
2 changed files with 64 additions and 24 deletions
|
@ -1049,7 +1049,8 @@ void eventloop(void) {
|
|||
// Read a command
|
||||
read_command();
|
||||
} else if (pollfds[0].revents & POLLHUP) {
|
||||
// Quit
|
||||
// Quit on frontend exiting
|
||||
warnx("Frontend exited unexpectedly");
|
||||
running = false;
|
||||
} else {
|
||||
errx(1, "Got poll event %hd on stdin\n", pollfds[0].revents);
|
||||
|
@ -1063,6 +1064,9 @@ void eventloop(void) {
|
|||
if (pollfds[1].revents & POLLIN) {
|
||||
// Process a frame
|
||||
process_frame();
|
||||
} else if (pollfds[1].revents & POLLERR) {
|
||||
// Lost connection
|
||||
errx(1, "Network went down");
|
||||
} else {
|
||||
errx(1, "Got poll event %hd on packet socket\n", pollfds[1].revents);
|
||||
}
|
||||
|
@ -1121,13 +1125,8 @@ int main(int argc, char **argv) {
|
|||
memcpy(own_mac, ifr.ifr_hwaddr.sa_data, sizeof(own_mac));
|
||||
|
||||
// Print it out
|
||||
char own_mac_str[18];
|
||||
format_mac(own_mac, own_mac_str);
|
||||
if (printf("%s\n", own_mac_str) == -1) {
|
||||
err(1, "printf");
|
||||
}
|
||||
if (fflush(stdout) == EOF) {
|
||||
err(1, "fflush");
|
||||
if (write(1, own_mac, 6) != 6) {
|
||||
err(1, "write");
|
||||
}
|
||||
|
||||
// Initialize the message id cache
|
||||
|
|
63
ethermess.py
63
ethermess.py
|
@ -73,6 +73,15 @@ def writeall(f, b):
|
|||
while written < len(b):
|
||||
written += f.write(b[written:])
|
||||
|
||||
def readall(f, length):
|
||||
read = bytearray()
|
||||
while len(read) < length:
|
||||
data = f.read(length - len(read))
|
||||
if data is None:
|
||||
raise ConnectionError('Could not satisfy read of %i bytes' % length)
|
||||
read.extend(data)
|
||||
return bytes(read)
|
||||
|
||||
def parse_mac(text):
|
||||
parts = text.split(':')
|
||||
if len(parts) != 6:
|
||||
|
@ -85,19 +94,34 @@ def parse_mac(text):
|
|||
|
||||
return parsed
|
||||
|
||||
def format_mac(mac):
|
||||
return ':'.join(mac[i:i+1].hex() for i in range(len(mac)))
|
||||
|
||||
class PollBasedThread(threading.Thread):
|
||||
def run(self):
|
||||
while True:
|
||||
restart = False
|
||||
self.initialize()
|
||||
|
||||
poll = select.poll()
|
||||
for f in self.pollin:
|
||||
poll.register(f, select.POLLIN)
|
||||
|
||||
self.initialize()
|
||||
|
||||
running = True
|
||||
while running:
|
||||
while running and not restart:
|
||||
for fd, event in poll.poll():
|
||||
if self.poll_loop(fd, event) != None:
|
||||
command = self.poll_loop(fd, event)
|
||||
if command == None:
|
||||
pass
|
||||
elif command == 'quit':
|
||||
running = False
|
||||
elif command == 'restart':
|
||||
restart = True
|
||||
else:
|
||||
raise ValueError("poll_loop() needs to return either None, 'quit', or 'restart'")
|
||||
|
||||
if not restart:
|
||||
break
|
||||
|
||||
self.finalize()
|
||||
|
||||
|
@ -111,15 +135,26 @@ class PollBasedThread(threading.Thread):
|
|||
...
|
||||
|
||||
class Backend(PollBasedThread):
|
||||
def __init__(self, interface, writes_channel, control_channel):
|
||||
def __init__(self, interface, nick, writes_channel, control_channel):
|
||||
self.interface = interface
|
||||
self.nick = nick
|
||||
self.writes_channel = writes_channel
|
||||
self.control_channel = control_channel
|
||||
self.pollin = [self.writes_channel, self.control_channel]
|
||||
super().__init__()
|
||||
|
||||
def initialize(self):
|
||||
self.proc = subprocess.Popen(['sudo', libexec_dir + '/ethermess-backend', self.interface], stdin = subprocess.PIPE, stdout = sys.stdout, stderr = sys.stderr, bufsize = 0)
|
||||
self.proc = subprocess.Popen(['sudo', libexec_dir + '/ethermess-backend', self.interface], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = sys.stderr, bufsize = 0)
|
||||
self.pollin = [self.writes_channel, self.control_channel, self.proc.stdout]
|
||||
|
||||
# Tell the backend the status and nick
|
||||
status = 0
|
||||
nick = self.nick.encode('utf-8')
|
||||
writeall(self.proc.stdin, bytes([status, len(nick)]) + nick)
|
||||
|
||||
# Read our MAC
|
||||
self.mac = readall(self.proc.stdout, 6)
|
||||
|
||||
print('Own mac: %s' % format_mac(self.mac))
|
||||
|
||||
def poll_loop(self, fd, event):
|
||||
if fd == self.writes_channel.fileno() and event & select.POLLIN:
|
||||
|
@ -134,6 +169,15 @@ class Backend(PollBasedThread):
|
|||
else:
|
||||
raise Exception('Unreachable')
|
||||
|
||||
elif fd == self.proc.stdout.fileno() and event & select.POLLIN:
|
||||
data = self.proc.stdout.read(1024)
|
||||
sys.stdout.buffer.write(data)
|
||||
sys.stdout.flush()
|
||||
|
||||
elif fd == self.proc.stdout.fileno() and event & select.POLLHUP:
|
||||
print('Backend exited')
|
||||
return 'quit'
|
||||
|
||||
else:
|
||||
raise Exception('Unreachable')
|
||||
|
||||
|
@ -183,8 +227,5 @@ control_channel = Channel()
|
|||
|
||||
_, interface, nick = sys.argv
|
||||
|
||||
nick = nick.encode('utf-8')
|
||||
writes_channel.send((bytes([0, len(nick)]) + nick))
|
||||
|
||||
Backend(interface, writes_channel, control_channel).start()
|
||||
Backend(interface, nick, writes_channel, control_channel).start()
|
||||
Input(writes_channel, control_channel).start()
|
||||
|
|
Loading…
Reference in a new issue