Samuel Sloniker
1 year ago
9 changed files with 202 additions and 64 deletions
@ -1,5 +0,0 @@ |
|||||||
import os |
|
||||||
|
|
||||||
imports = [ i[:-3] for i in os.listdir('/bin/') if i.endswith('.py') and not '__' in i ] |
|
||||||
for module in imports: |
|
||||||
exec(f'import bin.{module} as {module}') |
|
@ -1,6 +0,0 @@ |
|||||||
import circuitos |
|
||||||
|
|
||||||
class App(circuitos.App): |
|
||||||
def F_main(self): |
|
||||||
self.os.launch(*self.argv[1:]) |
|
||||||
self.exit() |
|
@ -1,16 +1,18 @@ |
|||||||
import circuitos |
|
||||||
import shlex |
import shlex |
||||||
|
|
||||||
class App(circuitos.App): |
def get_app_class(template): |
||||||
def F_main(self): |
class App(template): |
||||||
with open('/etc/init/start') as f: |
def F_main(self): |
||||||
lines = f.readlines() |
with open('/etc/init/start') as f: |
||||||
for line in lines: |
lines = f.readlines() |
||||||
if line.strip(): |
for line in lines: |
||||||
last_pid = self.os.launch(*shlex.split(line)) |
if line.strip(): |
||||||
|
last_pid = self.os.launch(*shlex.split(line)) |
||||||
|
|
||||||
self.transfer_console(last_pid) |
self.transfer_console(last_pid) |
||||||
self.next_function = 'loop' |
self.next_function = 'loop' |
||||||
|
|
||||||
def F_loop(self): |
def F_loop(self): |
||||||
pass |
pass |
||||||
|
|
||||||
|
return App |
||||||
|
@ -1,6 +1,7 @@ |
|||||||
import circuitos |
def get_app_class(template): |
||||||
|
class App(template): |
||||||
|
def F_main(self): |
||||||
|
self.os.kill(int(self.argv[1])) |
||||||
|
self.exit() |
||||||
|
|
||||||
class App(circuitos.App): |
return App |
||||||
def F_main(self): |
|
||||||
self.os.kill(int(self.argv[1])) |
|
||||||
self.exit() |
|
||||||
|
@ -1,10 +1,11 @@ |
|||||||
import circuitos |
def get_app_class(template): |
||||||
|
class App(template): |
||||||
|
def F_main(self): |
||||||
|
apps = self.os.apps |
||||||
|
for pid, app in apps.items(): |
||||||
|
args = app.argv[1:] |
||||||
|
name = app.name |
||||||
|
print(f'{pid} {name} {args}') |
||||||
|
self.exit() |
||||||
|
|
||||||
class App(circuitos.App): |
return App |
||||||
def F_main(self): |
|
||||||
apps = self.os.apps |
|
||||||
for pid, app in apps.items(): |
|
||||||
args = app.argv[1:] |
|
||||||
name = app.name |
|
||||||
print(f'{pid} {name} {args}') |
|
||||||
self.exit() |
|
||||||
|
@ -1,33 +1,35 @@ |
|||||||
import circuitos |
import circuitos.exceptions |
||||||
import shlex |
import shlex |
||||||
import console |
import console |
||||||
|
|
||||||
class App(circuitos.App): |
def get_app_class(template): |
||||||
def F_main(self): |
class App(template): |
||||||
self.jump('prompt') |
def F_main(self): |
||||||
|
self.jump('prompt') |
||||||
|
|
||||||
def F_prompt(self): |
def F_prompt(self): |
||||||
self.console.write(b'CicuitOS sh # ') |
self.console.write(b'CicuitOS sh # ') |
||||||
self.store['buf'] = [] |
self.store['buf'] = [] |
||||||
self.jump('input') |
self.jump('input') |
||||||
|
|
||||||
def F_input(self): |
def F_input(self): |
||||||
raw_line = console.read(self.console, self.store['buf']) |
raw_line = console.read(self.console, self.store['buf']) |
||||||
if raw_line is not None: |
if raw_line is not None: |
||||||
line = shlex.split(raw_line.decode('ascii')) |
line = shlex.split(raw_line.decode('ascii')) |
||||||
if line: |
if line: |
||||||
try: |
try: |
||||||
if line[0] == 'bg': |
if line[0] == 'bg': |
||||||
self.os.launch(*line[1:]) |
self.os.launch(*line[1:]) |
||||||
elif line[0] == 'exit': |
elif line[0] == 'exit': |
||||||
self.exit() |
self.exit() |
||||||
else: |
else: |
||||||
pid = self.os.launch(*line) |
pid = self.os.launch(*line) |
||||||
self.wait(pid) |
self.wait(pid) |
||||||
self.transfer_console(pid) |
self.transfer_console(pid) |
||||||
except circuitos.AppNotFound as e: |
except circuitos.exceptions.AppNotFound as e: |
||||||
print('error: app not found') |
print('error: app not found') |
||||||
self.jump('prompt') |
self.jump('prompt') |
||||||
|
|
||||||
def F_loop(self): |
def F_loop(self): |
||||||
pass |
pass |
||||||
|
return App |
||||||
|
@ -0,0 +1,106 @@ |
|||||||
|
import bin #this is at the end of the script in case any functions from bin |
||||||
|
#depend on anything here |
||||||
|
from circuitos.exceptions import * |
||||||
|
from circuitos.apploader import get_app |
||||||
|
import circuitos.apploader # apploader hack |
||||||
|
import time |
||||||
|
import usb_cdc |
||||||
|
|
||||||
|
class App: |
||||||
|
def __init__(self, os, pid, name, *argv): |
||||||
|
self.os = os |
||||||
|
self.pid = pid |
||||||
|
self.name = name |
||||||
|
self.store = {} |
||||||
|
self.next_function = 'main' |
||||||
|
self.run_at = -1 |
||||||
|
self.argv = (self,) + argv |
||||||
|
self.waiting_for = -1 |
||||||
|
|
||||||
|
def iterate(self): |
||||||
|
if time.monotonic() >= self.run_at and not self.waiting_for in self.os.apps: |
||||||
|
getattr(self, f'F_{self.next_function}')() |
||||||
|
|
||||||
|
@property |
||||||
|
def console(self): |
||||||
|
if self.pid == self.os.controllers[-1]: |
||||||
|
return self.os.console |
||||||
|
else: |
||||||
|
raise NotConsoleController(self.os.controllers[-1]) |
||||||
|
|
||||||
|
def transfer_console(self, recipient): |
||||||
|
if self.pid == self.os.controllers[-1]: |
||||||
|
self.os.controllers.append(recipient) |
||||||
|
else: |
||||||
|
raise NotConsoleController(self.os.controllers[-1]) |
||||||
|
|
||||||
|
def jump(self, function): |
||||||
|
self.next_function = function |
||||||
|
|
||||||
|
def sleep(self, seconds): |
||||||
|
self.run_at = time.monotonic() + seconds |
||||||
|
|
||||||
|
def exec(self, command, *argv): |
||||||
|
self.os.apps[self.pid] = get_app(command)(self.os, self.pid, command, *argv) |
||||||
|
|
||||||
|
def wait(self, pid): |
||||||
|
self.waiting_for = pid |
||||||
|
|
||||||
|
def end_wait(self): |
||||||
|
self.waiting_for = -1 |
||||||
|
|
||||||
|
def on_exit(self): |
||||||
|
pass |
||||||
|
|
||||||
|
def exit(self): |
||||||
|
del self.os.apps[self.pid] |
||||||
|
|
||||||
|
apploader.App = App # apploader hack |
||||||
|
|
||||||
|
class OS: |
||||||
|
def __init__(self): |
||||||
|
self.apps = {} |
||||||
|
self.next_new = 0 |
||||||
|
self.controllers = [0] |
||||||
|
self.console = usb_cdc.console |
||||||
|
usb_cdc.console.timeout = 0 |
||||||
|
self.next_pidi = 0 |
||||||
|
self.launch('init') |
||||||
|
|
||||||
|
def iterate(self): |
||||||
|
pid = list(self.apps.keys())[self.next_pidi] |
||||||
|
function = self.apps[pid].iterate |
||||||
|
|
||||||
|
function() |
||||||
|
|
||||||
|
try: |
||||||
|
self.apps[pid] |
||||||
|
# If this succeds, the app did not exit and next_pidi should |
||||||
|
# be incremented |
||||||
|
self.next_pidi += 1 |
||||||
|
except KeyError: |
||||||
|
# If self.apps[pid] failed, the app exited and next_pidi |
||||||
|
# should not be incremented |
||||||
|
pass |
||||||
|
self.next_pidi = self.next_pidi % len(self.apps) |
||||||
|
|
||||||
|
while not self.controllers[-1] in self.apps.keys(): |
||||||
|
self.controllers.pop() |
||||||
|
|
||||||
|
def launch(self, app, *argv): |
||||||
|
self.apps[self.next_new] = get_app(app)(self, self.next_new, app, *argv) |
||||||
|
self.next_new += 1 |
||||||
|
return self.next_new - 1 |
||||||
|
|
||||||
|
def kill(self, pid): |
||||||
|
try: |
||||||
|
del self.apps[pid] |
||||||
|
except KeyError: |
||||||
|
raise(NoSuchProcess(pid)) |
||||||
|
|
||||||
|
def run(): |
||||||
|
os = OS() |
||||||
|
while True: |
||||||
|
os.iterate() |
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@ |
|||||||
|
_cache = {} |
||||||
|
|
||||||
|
def get_app(app): |
||||||
|
try: |
||||||
|
return _cache[app] |
||||||
|
except KeyError: |
||||||
|
try: |
||||||
|
module = __import__(f'/bin/{app}') |
||||||
|
except AttributeError: |
||||||
|
raise AppNotFound(app) |
||||||
|
|
||||||
|
try: |
||||||
|
app_class = module.get_app_class(App) |
||||||
|
except AttributeError: |
||||||
|
raise InvalidApp(app) |
||||||
|
|
||||||
|
_cache[app] = app_class |
||||||
|
|
||||||
|
return app_class |
Loading…
Reference in new issue