Browse Source

Newer version

master
Samuel Sloniker 1 year ago
parent
commit
a86caa7751
  1. 5
      bin/__init__.py
  2. 6
      bin/background.py
  3. 26
      bin/init.py
  4. 11
      bin/kill.py
  5. 19
      bin/ps.py
  6. 56
      bin/sh.py
  7. 106
      circuitos/__init__.py
  8. 19
      circuitos/apploader.py
  9. 18
      circuitos/exceptions.py

5
bin/__init__.py

@ -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}')

6
bin/background.py

@ -1,6 +0,0 @@
import circuitos
class App(circuitos.App):
def F_main(self):
self.os.launch(*self.argv[1:])
self.exit()

26
bin/init.py

@ -1,16 +1,18 @@
import circuitos
import shlex
class App(circuitos.App):
def F_main(self):
with open('/etc/init/start') as f:
lines = f.readlines()
for line in lines:
if line.strip():
last_pid = self.os.launch(*shlex.split(line))
def get_app_class(template):
class App(template):
def F_main(self):
with open('/etc/init/start') as f:
lines = f.readlines()
for line in lines:
if line.strip():
last_pid = self.os.launch(*shlex.split(line))
self.transfer_console(last_pid)
self.next_function = 'loop'
self.transfer_console(last_pid)
self.next_function = 'loop'
def F_loop(self):
pass
def F_loop(self):
pass
return App

11
bin/kill.py

@ -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):
def F_main(self):
self.os.kill(int(self.argv[1]))
self.exit()
return App

19
bin/ps.py

@ -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):
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()
return App

56
bin/sh.py

@ -1,33 +1,35 @@
import circuitos
import circuitos.exceptions
import shlex
import console
class App(circuitos.App):
def F_main(self):
self.jump('prompt')
def get_app_class(template):
class App(template):
def F_main(self):
self.jump('prompt')
def F_prompt(self):
self.console.write(b'CicuitOS sh # ')
self.store['buf'] = []
self.jump('input')
def F_prompt(self):
self.console.write(b'CicuitOS sh # ')
self.store['buf'] = []
self.jump('input')
def F_input(self):
raw_line = console.read(self.console, self.store['buf'])
if raw_line is not None:
line = shlex.split(raw_line.decode('ascii'))
if line:
try:
if line[0] == 'bg':
self.os.launch(*line[1:])
elif line[0] == 'exit':
self.exit()
else:
pid = self.os.launch(*line)
self.wait(pid)
self.transfer_console(pid)
except circuitos.AppNotFound as e:
print('error: app not found')
self.jump('prompt')
def F_input(self):
raw_line = console.read(self.console, self.store['buf'])
if raw_line is not None:
line = shlex.split(raw_line.decode('ascii'))
if line:
try:
if line[0] == 'bg':
self.os.launch(*line[1:])
elif line[0] == 'exit':
self.exit()
else:
pid = self.os.launch(*line)
self.wait(pid)
self.transfer_console(pid)
except circuitos.exceptions.AppNotFound as e:
print('error: app not found')
self.jump('prompt')
def F_loop(self):
pass
def F_loop(self):
pass
return App

106
circuitos/__init__.py

@ -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()

19
circuitos/apploader.py

@ -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

18
circuitos/exceptions.py

@ -0,0 +1,18 @@
class CircuitOSError(Exception):
pass
class NoSuchProcess(CircuitOSError):
pass
class AppNotFound(CircuitOSError):
pass
class InvalidApp(AppNotFound):
pass
class NotConsoleController(CircuitOSError):
pass
Loading…
Cancel
Save