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 a command
|
||||||
read_command();
|
read_command();
|
||||||
} else if (pollfds[0].revents & POLLHUP) {
|
} else if (pollfds[0].revents & POLLHUP) {
|
||||||
// Quit
|
// Quit on frontend exiting
|
||||||
|
warnx("Frontend exited unexpectedly");
|
||||||
running = false;
|
running = false;
|
||||||
} else {
|
} else {
|
||||||
errx(1, "Got poll event %hd on stdin\n", pollfds[0].revents);
|
errx(1, "Got poll event %hd on stdin\n", pollfds[0].revents);
|
||||||
|
@ -1063,6 +1064,9 @@ void eventloop(void) {
|
||||||
if (pollfds[1].revents & POLLIN) {
|
if (pollfds[1].revents & POLLIN) {
|
||||||
// Process a frame
|
// Process a frame
|
||||||
process_frame();
|
process_frame();
|
||||||
|
} else if (pollfds[1].revents & POLLERR) {
|
||||||
|
// Lost connection
|
||||||
|
errx(1, "Network went down");
|
||||||
} else {
|
} else {
|
||||||
errx(1, "Got poll event %hd on packet socket\n", pollfds[1].revents);
|
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));
|
memcpy(own_mac, ifr.ifr_hwaddr.sa_data, sizeof(own_mac));
|
||||||
|
|
||||||
// Print it out
|
// Print it out
|
||||||
char own_mac_str[18];
|
if (write(1, own_mac, 6) != 6) {
|
||||||
format_mac(own_mac, own_mac_str);
|
err(1, "write");
|
||||||
if (printf("%s\n", own_mac_str) == -1) {
|
|
||||||
err(1, "printf");
|
|
||||||
}
|
|
||||||
if (fflush(stdout) == EOF) {
|
|
||||||
err(1, "fflush");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the message id cache
|
// Initialize the message id cache
|
||||||
|
|
63
ethermess.py
63
ethermess.py
|
@ -73,6 +73,15 @@ def writeall(f, b):
|
||||||
while written < len(b):
|
while written < len(b):
|
||||||
written += f.write(b[written:])
|
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):
|
def parse_mac(text):
|
||||||
parts = text.split(':')
|
parts = text.split(':')
|
||||||
if len(parts) != 6:
|
if len(parts) != 6:
|
||||||
|
@ -85,19 +94,34 @@ def parse_mac(text):
|
||||||
|
|
||||||
return parsed
|
return parsed
|
||||||
|
|
||||||
|
def format_mac(mac):
|
||||||
|
return ':'.join(mac[i:i+1].hex() for i in range(len(mac)))
|
||||||
|
|
||||||
class PollBasedThread(threading.Thread):
|
class PollBasedThread(threading.Thread):
|
||||||
def run(self):
|
def run(self):
|
||||||
|
while True:
|
||||||
|
restart = False
|
||||||
|
self.initialize()
|
||||||
|
|
||||||
poll = select.poll()
|
poll = select.poll()
|
||||||
for f in self.pollin:
|
for f in self.pollin:
|
||||||
poll.register(f, select.POLLIN)
|
poll.register(f, select.POLLIN)
|
||||||
|
|
||||||
self.initialize()
|
|
||||||
|
|
||||||
running = True
|
running = True
|
||||||
while running:
|
while running and not restart:
|
||||||
for fd, event in poll.poll():
|
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
|
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()
|
self.finalize()
|
||||||
|
|
||||||
|
@ -111,15 +135,26 @@ class PollBasedThread(threading.Thread):
|
||||||
...
|
...
|
||||||
|
|
||||||
class Backend(PollBasedThread):
|
class Backend(PollBasedThread):
|
||||||
def __init__(self, interface, writes_channel, control_channel):
|
def __init__(self, interface, nick, writes_channel, control_channel):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
|
self.nick = nick
|
||||||
self.writes_channel = writes_channel
|
self.writes_channel = writes_channel
|
||||||
self.control_channel = control_channel
|
self.control_channel = control_channel
|
||||||
self.pollin = [self.writes_channel, self.control_channel]
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def initialize(self):
|
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):
|
def poll_loop(self, fd, event):
|
||||||
if fd == self.writes_channel.fileno() and event & select.POLLIN:
|
if fd == self.writes_channel.fileno() and event & select.POLLIN:
|
||||||
|
@ -134,6 +169,15 @@ class Backend(PollBasedThread):
|
||||||
else:
|
else:
|
||||||
raise Exception('Unreachable')
|
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:
|
else:
|
||||||
raise Exception('Unreachable')
|
raise Exception('Unreachable')
|
||||||
|
|
||||||
|
@ -183,8 +227,5 @@ control_channel = Channel()
|
||||||
|
|
||||||
_, interface, nick = sys.argv
|
_, interface, nick = sys.argv
|
||||||
|
|
||||||
nick = nick.encode('utf-8')
|
Backend(interface, nick, writes_channel, control_channel).start()
|
||||||
writes_channel.send((bytes([0, len(nick)]) + nick))
|
|
||||||
|
|
||||||
Backend(interface, writes_channel, control_channel).start()
|
|
||||||
Input(writes_channel, control_channel).start()
|
Input(writes_channel, control_channel).start()
|
||||||
|
|
Loading…
Reference in a new issue