Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.0KB

  1. local gpus,screens,ttyn,pids = {}, {}, 0, {}
  2. local basepid = nil
  3. local shell = require "shell"
  4. local vtansi = require "vtansi"
  5. local function scan()
  6. local w,di = pcall(computer.getDeviceInfo)
  7. if w then
  8. for a,t in pairs(component.list()) do
  9. if t == "gpu" then
  10. gpus[a] = gpus[a] or {false, tonumber(di[a].capacity)}
  11. elseif t == "screen" then
  12. screens[a] = screens[a] or {false, tonumber(di[a].capacity)}
  13. end
  14. end
  15. else
  16. dprint("no getDevInfo")
  17. for a,t in pairs(component.list()) do
  18. if t == "gpu" then
  19. gpus[a] = gpus[a] or {false, 8000}
  20. elseif t == "screen" then
  21. screens[a] = screens[a] or {false, 8000}
  22. end
  23. end
  24. end
  25. end
  26. local function nextScreen(n)
  27. local rt = {}
  28. for k,v in pairs(screens) do
  29. if not v[1] then
  30. rt[v[2]] = rt[v[2]] or k
  31. end
  32. end
  33. return rt[n] or rt[8000] or rt[2000] or rt[600]
  34. end
  35. local function spawnShell(fin,fout)
  36. io.input(fin)
  37. io.output(fout):setvbuf("no")
  38. print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
  39. return os.spawn(function() local w,r = pcall(shell.interactive) if not w then syslog(r) end end, "shell: "..tostring(fin))
  40. end
  41. local function allocate()
  42. for k,v in pairs(gpus) do
  43. dprint(k)
  44. local sA = nextScreen(v[2])
  45. if v[1] == false and sA then
  46. local r,w = vtansi.vtsession(k,sA)
  47. devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
  48. gpus[k][1] = true
  49. screens[sA][1] = true
  50. pids["tty"..tostring(ttyn)] = {-1}
  51. ttyn = ttyn + 1
  52. end
  53. end
  54. end
  55. function start()
  56. basepid = os.spawn(function()
  57. scan()
  58. allocate()
  59. dprint("screens ready")
  60. while true do
  61. coroutine.yield()
  62. for k,v in pairs(pids) do
  63. if not os.taskInfo(v[1]) then
  64. dprint("Spawning new shell for "..k)
  65. pids[k][1] = spawnShell(v[2] or "/dev/"..k, v[3] or "/dev/"..k)
  66. pids[k][2], pids[k][3] = pids[k][2] or io.input(), pids[k][3] or io.output()
  67. end
  68. end
  69. end
  70. end,"getty")
  71. return basepid
  72. end
  73. function stop()
  74. os.kill(basepid)
  75. basepid = nil
  76. end
  77. return {start=start,stop=stop}