· 8 years ago · Mar 14, 2018, 02:30 PM
1false
2{
3 [ "/kernel/common/xwos/modules/sandbox/timers.lua" ] = {
4 "-- This file is part of xwos.",
5 "--",
6 "-- xwos is free software: you can redistribute it and/or modify",
7 "-- it under the terms of the GNU General Public License as published by",
8 "-- the Free Software Foundation, either version 3 of the License, or",
9 "-- (at your option) any later version.",
10 "--",
11 "-- xwos is distributed in the hope that it will be useful,",
12 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
13 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
14 "-- GNU General Public License for more details.",
15 "--",
16 "-- You should have received a copy of the GNU General Public License",
17 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
18 "",
19 "-----------------------",
20 "-- @module xwos.modules.sandbox.timers",
21 "local M = {}",
22 "",
23 "local kernel -- xwos.kernel#xwos.kernel",
24 "",
25 "-----------------------",
26 "-- injects the kernel",
27 "-- @function [parent=#xwos.modules.sandbox.timers] setKernel",
28 "-- @param xwos.kernel#xwos.kernel k the kernel",
29 "M.setKernel = function(k)",
30 " kernel = k",
31 "end -- function setKernel",
32 "",
33 "-------------------------------",
34 "-- creates a new timer",
35 "-- @function [parent=#xwos.modules.sandbox.timers] new",
36 "-- @param #number id the timer number",
37 "-- @param xwos.processes#xwos.process proc",
38 "-- @return #xwos.timer",
39 "M.new = function(id, proc)",
40 " --------------------------------",
41 " -- timer type",
42 " -- @type xwos.timer",
43 " local R = {}",
44 " ",
45 " --------------------------------",
46 " -- @field [parent=#xwos.timer] #number id the timer id",
47 " R.id = id",
48 " ",
49 " --------------------------------",
50 " -- @field [parent=#xwos.timer] #number id the timer id",
51 " R.proc = proc",
52 " ",
53 " --------------------------------",
54 " -- Remove the timer from timer table",
55 " -- @function [parent=#xwos.timer] remove",
56 " R.remove = function()",
57 " M[R.id] = nil",
58 " end -- function remove",
59 " ",
60 " -- TODO remove discarded timers on process termination",
61 " ",
62 " -- store timer",
63 " M[R.id] = R",
64 " ",
65 " return R",
66 "end -- function new",
67 "",
68 "return M",
69 },
70 [ "/kernel/common/xwos/modules/security/init.lua" ] = {
71 "-- This file is part of xwos.",
72 "--",
73 "-- xwos is free software: you can redistribute it and/or modify",
74 "-- it under the terms of the GNU General Public License as published by",
75 "-- the Free Software Foundation, either version 3 of the License, or",
76 "-- (at your option) any later version.",
77 "--",
78 "-- xwos is distributed in the hope that it will be useful,",
79 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
80 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
81 "-- GNU General Public License for more details.",
82 "--",
83 "-- You should have received a copy of the GNU General Public License",
84 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
85 "",
86 "-----------------------",
87 "-- @module xwos.modules.security",
88 "local M = {}",
89 "",
90 "local kernel -- xwos.kernel#xwos.kernel",
91 "",
92 "local function crProfile(name)",
93 " -----------------------",
94 " -- Security profile",
95 " -- @type secprofile",
96 " local R = {}",
97 " ",
98 " -----------------------",
99 " -- Returns the profile name",
100 " -- @function [parent=#secprofile] name",
101 " -- @return #string profile name",
102 " R.name = function()",
103 " return name",
104 " end -- function name",
105 " ",
106 " -----------------------",
107 " -- Checks if access to given api method is granted",
108 " -- @function [parent=#secprofile] checkApi",
109 " -- @return #string api",
110 " -- @return #string method",
111 " R.checkApi = function(api, method)",
112 " return true -- TODO some meaningful implementation",
113 " end -- function checkApi",
114 " ",
115 " -----------------------",
116 " -- Checks if access to given acl node is granted",
117 " -- @function [parent=#secprofile] checkAccess",
118 " -- @return #string aclKey",
119 " R.checkAccess = function(aclKey)",
120 " return true -- TODO some meaningful implementation",
121 " end -- function checkAccess",
122 " return R",
123 "end -- function crProfile",
124 "",
125 "local profiles = {",
126 " root = crProfile(\"root\"),",
127 " admin = crProfile(\"admin\"),",
128 " user = crProfile(\"user\"),",
129 " guest = crProfile(\"guest\")",
130 "}",
131 "",
132 "---------------------------------",
133 "-- @function [parent=#xwos.modules.security] preboot",
134 "-- @param xwos.kernel#xwos.kernel k",
135 "M.preboot = function(k)",
136 " k.debug(\"preboot security\")",
137 " kernel = k",
138 "end -- function preboot",
139 "",
140 "---------------------------------",
141 "-- @function [parent=#xwos.modules.security] boot",
142 "-- @param xwos.kernel#xwos.kernel k",
143 "M.boot = function(k)",
144 " k.debug(\"boot security\")",
145 "end -- function boot",
146 "",
147 "---------------------------------",
148 "-- returns a security profile with given name",
149 "-- @function [parent=#xwos.modules.security] profile",
150 "-- @param #string name",
151 "-- @return #secprofile",
152 "M.profile = function(name)",
153 " return profiles[name]",
154 "end -- function boot",
155 "",
156 "---------------------------------",
157 "-- Creates a new security profile with given name",
158 "-- @function [parent=#xwos.modules.security] profile",
159 "-- @param #string name",
160 "-- @return #secprofile",
161 "M.createProfile = function(name)",
162 " -- TODO some meaningful implementation",
163 " local res = profiles[name]",
164 " if res == nil then",
165 " res = crProfile(name)",
166 " profiles[name] = res",
167 " end -- if profile",
168 " return res",
169 "end -- function createProfile",
170 "",
171 "return M",
172 },
173 [ "/kernel/common/xwos/modules/sandbox/evqueue.lua" ] = {
174 "-- This file is part of xwos.",
175 "--",
176 "-- xwos is free software: you can redistribute it and/or modify",
177 "-- it under the terms of the GNU General Public License as published by",
178 "-- the Free Software Foundation, either version 3 of the License, or",
179 "-- (at your option) any later version.",
180 "--",
181 "-- xwos is distributed in the hope that it will be useful,",
182 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
183 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
184 "-- GNU General Public License for more details.",
185 "--",
186 "-- You should have received a copy of the GNU General Public License",
187 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
188 "",
189 "-----------------------",
190 "-- @module xwos.modules.sandbox.evqueue",
191 "local M = {}",
192 "",
193 "local kernel -- xwos.kernel#xwos.kernel",
194 "",
195 "local originsert = table.insert",
196 "",
197 "-----------------------",
198 "-- injects the kernel",
199 "-- @function [parent=#xwos.modules.sandbox.evqueue] setKernel",
200 "-- @param xwos.kernel#xwos.kernel k the kernel",
201 "M.setKernel = function(k)",
202 " kernel = k",
203 "end -- function setKernel",
204 "",
205 "-----------------------",
206 "-- Process and distribute event from event queue (part of pullEvent etc.)",
207 "-- @function [parent=#xwos.modules.sandbox.evqueue] processEvt",
208 "-- @param #number lpid the local pid for logging",
209 "-- @param xwos.process#xwos.process proc the process invoking this method; may be nil for kernel process",
210 "-- @param #table event the event to deliver",
211 "-- @param #string filter optional filter passed to pullEvent",
212 "M.processEvt = function(lpid, proc, event, filter)",
213 " if event[1] == nil then",
214 " return nil",
215 " end -- if event",
216 " kernel.debug(\"[PID\"..lpid..\"] got event \", kernel.oldGlob.unpack(event))",
217 " ",
218 " if kernel.eventLog then",
219 " -- TODO are we able to pass non serializable data through events?",
220 " -- this may cause problems at this point",
221 " local str = kernel.oldGlob.os.day() .. \"-\" .. kernel.oldGlob.os.time() \" EVENT: \".. kernel.oldGlob.textutils.serialize(event)",
222 " local f = kernel.oldGlob.fs.open(\"/core/log/event-log.txt\", kernel.oldGlob.fs.exists(\"/core/log/event-log.txt\") and \"a\" or \"w\")",
223 " f.writeLine(str)",
224 " f.close()",
225 " end -- if eventLog",
226 " ",
227 " local consumed = false",
228 " ",
229 " if event[1] == \"timer\" then",
230 " local timer = kernel.modules.instances.sandbox.timers[event[2]]",
231 " if timer ~= nil then",
232 " if timer.proc == proc then",
233 " if filter == nil or event[1]==filter then",
234 " kernel.debug(\"[PID\"..lpid..\"] returning event \", kernel.oldGlob.unpack(event))",
235 " return event",
236 " else -- if filter",
237 " kernel.debug(\"[PID\"..lpid..\"] discard event because of filter\", kernel.oldGlob.unpack(event))",
238 " consumed = true",
239 " end -- if filter",
240 " else -- if proc",
241 " kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to pid \"..timer.proc.pid, kernel.oldGlob.unpack(event))",
242 " originsert(timer.proc.evqueue, event)",
243 " timer.proc.wakeup()",
244 " consumed = true",
245 " end -- if not proc",
246 " end -- if timer",
247 " -- fallthrough: distribute unknown timer event to all processes",
248 " end -- if timer",
249 " ",
250 " if event[1] == \"xwos_wakeup\" then",
251 " consumed = true",
252 " kernel.debug(\"[PID\"..lpid..\"] wakeup received\")",
253 " if event[2] ~= lpid then",
254 " kernel.debug(\"[PID\"..lpid..\"] wrong pid, redistribute\")",
255 " kernel.oldGlob.os.queueEvent(kernel.oldGlob.unpack(event))",
256 " end -- if pid",
257 " end -- if xwos_wakeup",
258 " ",
259 " if event[1] == \"xwos_terminate\" then",
260 " consumed = true",
261 " kernel.debug(\"[PID\"..lpid..\"] terminate received\")",
262 " if event[2] ~= lpid then",
263 " kernel.debug(\"[PID\"..lpid..\"] wrong pid, redistribute\")",
264 " kernel.oldGlob.os.queueEvent(kernel.oldGlob.unpack(event))",
265 " else -- if pid",
266 " kernel.oldGlob.error('requesting process termination')",
267 " end -- if pid",
268 " end -- if xwos_terminate",
269 " ",
270 " if event[1] == \"xwos_terminated\" then",
271 " consumed = true",
272 " kernel.debug(\"[PID\"..lpid..\"] terminated received\")",
273 " if filter == \"xwos_terminated\" then",
274 " kernel.debug(\"[PID\"..lpid..\"] returning event \", kernel.oldGlob.unpack(event))",
275 " return event",
276 " end -- if filter",
277 " for k, v in kernel.oldGlob.pairs(kernel.processes) do",
278 " if kernel.oldGlob.type(v) == \"table\" and v.pid == event[2] and v.joined > 0 then",
279 " kernel.debug(\"[PID\"..lpid..\"] redistributing to all other processes because at least one process called join of \"..v.pid)",
280 " ",
281 " for k2, v2 in kernel.oldGlob.pairs(kernel.processes) do",
282 " if kernel.oldGlob.type(v2) == \"table\" and v2 ~= proc and v2.procstate~= \"finished\" then",
283 " kernel.debug(\"[PID\"..lpid..\"] redistributing because at least one process called join of \"..v2.pid)",
284 " originsert(v2.evqueue, event)",
285 " v2.wakeup()",
286 " end --",
287 " end -- for processes",
288 " end --",
289 " end -- for processes",
290 " end -- if xwos_terminated",
291 " ",
292 " if event[1] == \"char\" or event[1] == \"key\" or event[1] == \"paste\" or event[1] == \"key_up\" then",
293 " consumed = true",
294 " kernel.debug(\"[PID\"..lpid..\"] user input received\")",
295 " if kernel.modules.instances.sandbox.procinput.current.proc ~= nil then",
296 " kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to user input pid \"..kernel.modules.instances.sandbox.procinput.current.proc.pid)",
297 " originsert(kernel.modules.instances.sandbox.procinput.current.proc.evqueue, event)",
298 " kernel.modules.instances.sandbox.procinput.current.proc.wakeup()",
299 " else",
300 " -- TODO what to do with input if no one likes it?",
301 " -- think about special key bindings fetched from background processes",
302 " -- currently we silently discard that kind of input",
303 " end -- ",
304 " end -- if char",
305 " ",
306 " -- distribute event to all processes",
307 " if not consumed then",
308 " for k, v in kernel.oldGlob.pairs(kernel.processes) do",
309 " if kernel.oldGlob.type(v) == \"table\" and v.procstate ~= \"finished\" then",
310 " kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to all pids \"..v.pid, kernel.oldGlob.unpack(event))",
311 " originsert(v.evqueue, event)",
312 " v.wakeup()",
313 " end -- if not finished",
314 " end -- for processes",
315 " end -- if consumed",
316 " ",
317 " return nil",
318 "end -- function processEvt",
319 "",
320 "return M",
321 },
322 [ "/kernel/common/xwos/test2.lua" ] = {
323 "-- This file is part of xwos.",
324 "--",
325 "-- xwos is free software: you can redistribute it and/or modify",
326 "-- it under the terms of the GNU General Public License as published by",
327 "-- the Free Software Foundation, either version 3 of the License, or",
328 "-- (at your option) any later version.",
329 "--",
330 "-- xwos is distributed in the hope that it will be useful,",
331 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
332 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
333 "-- GNU General Public License for more details.",
334 "--",
335 "-- You should have received a copy of the GNU General Public License",
336 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
337 "",
338 "local a = function()",
339 " print(\"a\")",
340 " end",
341 " a()",
342 },
343 [ "/kernel/common/xwos/test.lua" ] = {
344 "-- This file is part of xwos.",
345 "--",
346 "-- xwos is free software: you can redistribute it and/or modify",
347 "-- it under the terms of the GNU General Public License as published by",
348 "-- the Free Software Foundation, either version 3 of the License, or",
349 "-- (at your option) any later version.",
350 "--",
351 "-- xwos is distributed in the hope that it will be useful,",
352 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
353 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
354 "-- GNU General Public License for more details.",
355 "--",
356 "-- You should have received a copy of the GNU General Public License",
357 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
358 "",
359 "require('/rom/xwos/kernel/common/xwos/test2')",
360 " print(\"foo\")",
361 },
362 [ "/kernel/common/xwos/modulesmgr.lua" ] = {
363 "-- This file is part of xwos.",
364 "--",
365 "-- xwos is free software: you can redistribute it and/or modify",
366 "-- it under the terms of the GNU General Public License as published by",
367 "-- the Free Software Foundation, either version 3 of the License, or",
368 "-- (at your option) any later version.",
369 "--",
370 "-- xwos is distributed in the hope that it will be useful,",
371 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
372 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
373 "-- GNU General Public License for more details.",
374 "--",
375 "-- You should have received a copy of the GNU General Public License",
376 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
377 "",
378 "local kernel -- xwos.kernel#xwos.kernel",
379 "local moduleOrder = {}",
380 "",
381 "--------------------------------",
382 "-- local kernel modules",
383 "-- @type xwos.modulesmgr",
384 "local M = {}",
385 "",
386 "-------------------------------",
387 "-- the module instances",
388 "-- @type xwos.modulesmgr.instances",
389 "-- @field [parent=#xwos.modulesmgr] #xwos.modulesmgr.instances instances",
390 "M.instances = {}",
391 "",
392 "-------------------------------",
393 "-- sandbox kernel module",
394 "-- @field [parent=#xwos.modulesmgr.instances] xwos.modulesmgr.sandbox#xwos.modulesmgr.sandbox sandbox",
395 "",
396 "-------------------------------",
397 "-- security kernel module",
398 "-- @field [parent=#xwos.modulesmgr.instances] xwos.modulesmgr.security#xwos.modulesmgr.security security",
399 "",
400 "--------------------------------",
401 "-- @function [parent=#xwos.modulesmgr] preboot",
402 "-- @param xwos.kernel#xwos.kernel k the kernel",
403 "M.preboot = function(k)",
404 " kernel = k",
405 " -- load settings with kernel module boot order",
406 " moduleOrder = kernel.require(\"moduleOrder\")",
407 " -- helper to load kernel modules from given directory",
408 " local loadKernelModules = function(dir)",
409 " local path = dir .. \"/xwos/modules\"",
410 " kernel.debug(\"loading kernel modules from \" .. path)",
411 " if kernel.oldGlob.fs.isDir(path) then",
412 " for i, v in kernel.oldGlob.pairs(kernel.oldGlob.fs.list(path)) do",
413 " kernel.debug(\"loading kernel module from \" .. path .. \"/\" .. v)",
414 " M.instances[v] = kernel.oldGlob.require(path .. \"/\" .. v)",
415 " end -- for list",
416 " end -- if isdir",
417 " end -- function loadKernelModules",
418 " ",
419 " -- load kernel modules",
420 " for k, v in kernel.oldGlob.pairs(kernel.kernelpaths) do",
421 " loadKernelModules(v)",
422 " end -- for kernelpaths",
423 "",
424 " for i, v in pairs(moduleOrder) do",
425 " if M.instances[v] ~= nil then",
426 " kernel.debug(\"preboot kernel module\",v)",
427 " M.instances[v].preboot(kernel)",
428 " end -- if exists",
429 " end -- for moduleOrder",
430 " for i, v in pairs(M.instances) do",
431 " if not table.contains(moduleOrder, i) then",
432 " kernel.debug(\"preboot kernel module\",v)",
433 " v.preboot(kernel)",
434 " end -- if not contains",
435 " end -- for modules",
436 "end -- function preboot",
437 "",
438 "--------------------------------",
439 "-- @function [parent=#xwos.modulesmgr] boot",
440 "-- @param xwos.kernel#xwos.kernel k the kernel",
441 "M.boot = function(k)",
442 " for i, v in pairs(moduleOrder) do",
443 " if M.instances[v] ~= nil then",
444 " kernel.debug(\"boot kernel module\",v)",
445 " M.instances[v].boot(kernel)",
446 " end -- if exists",
447 " end -- for moduleOrder",
448 " for i, v in pairs(M.instances) do",
449 " if not table.contains(moduleOrder, i) then",
450 " kernel.debug(\"boot kernel module\",v)",
451 " v.boot(kernel)",
452 " end -- if not contains",
453 " end -- for modules",
454 "end -- function preboot",
455 "",
456 "return M",
457 },
458 [ "/kernel/common/xwos/startup.lua" ] = {
459 "-- This file is part of xwos.",
460 "--",
461 "-- xwos is free software: you can redistribute it and/or modify",
462 "-- it under the terms of the GNU General Public License as published by",
463 "-- the Free Software Foundation, either version 3 of the License, or",
464 "-- (at your option) any later version.",
465 "--",
466 "-- xwos is distributed in the hope that it will be useful,",
467 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
468 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
469 "-- GNU General Public License for more details.",
470 "--",
471 "-- You should have received a copy of the GNU General Public License",
472 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
473 "",
474 "--------------------------------",
475 "-- Default startup script",
476 "-- @module xwos.startup",
477 "local M = {}",
478 "",
479 "-------------------",
480 "-- The installer",
481 "-- @function [parent=#xwos.startup] run",
482 "-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
483 "M.installer = function(kernel)",
484 " local installerData = { lang = nil }",
485 " print()",
486 " print(\"starting installer...\")",
487 " ",
488 " kernel.print(\"read: \", read)",
489 " kernel.print(\"read0: \", getfenv(0).read)",
490 " kernel.print(\"read1: \", getfenv(1).read)",
491 " kernel.print(\"read6: \", getfenv(6).read)",
492 " kernel.print(\"read7: \", getfenv(7).read)",
493 " kernel.print(\"read8: \", getfenv(8).read)",
494 " print()",
495 " print(\"********* XW-OS ********** INSTALLER\")",
496 " local langs = {",
497 " \"en\" -- TODO support language packs",
498 " }",
499 " while installerData.lang == nil do",
500 " print(\"\")",
501 " print(\"Choose your language:\")",
502 " local input = read()",
503 " if table.contains(langs, input) then",
504 " installerData.lang = input",
505 " else -- if contains",
506 " print(\"Invalid language. Currently supported: \")",
507 " for k, v in pairs(langs) do",
508 " write(v)",
509 " write(\" \")",
510 " end -- for langs",
511 " print(\"\")",
512 " end -- if not contains",
513 " end -- while not lang",
514 " ",
515 " local admin = {}",
516 " print(\"\")",
517 " print(\"Enter your administrators email address:\")",
518 " admin.mail = read()",
519 " print(\"\")",
520 " print(\"Enter your administrators login name:\")",
521 " admin.login = read()",
522 " while admin.pass == nil do",
523 " print(\"\")",
524 " print(\"Enter your administrators password:\")",
525 " local pass1 = read()",
526 " print(\"\")",
527 " print(\"Retype your administrators password:\")",
528 " local pass2 = read()",
529 " ",
530 " if pass1 ~= pass2 then",
531 " print(\"\")",
532 " print(\"The passwords do not match...\")",
533 " else -- if not pass equals",
534 " admin.pass = pass1",
535 " end -- if pass equals",
536 " end -- while not pass",
537 " ",
538 " local user = {}",
539 " print(\"\")",
540 " print(\"Enter your users email address:\")",
541 " user.mail = read()",
542 " print(\"\")",
543 " print(\"Enter your users login name:\")",
544 " user.login = read()",
545 " while user.pass == nil do",
546 " print(\"\")",
547 " print(\"Enter your users password:\")",
548 " local pass1 = read()",
549 " print(\"\")",
550 " print(\"Retype your users password:\")",
551 " local pass2 = read()",
552 " ",
553 " if pass1 ~= pass2 then",
554 " print(\"\")",
555 " print(\"The passwords do not match...\")",
556 " else -- if not pass equals",
557 " user.pass = pass1",
558 " end -- if pass equals",
559 " end -- while not pass",
560 " ",
561 " print(\"\")",
562 " print(\"\")",
563 " print(\"***** starting installation\")",
564 " print(\"\")",
565 " print(\"Creating root...\")",
566 " local proot = kernel.modules.security.createProfile(\"root\")",
567 " print(\"Creating administrator...\")",
568 " local padmin = kernel.modules.security.createProfile(\"admin\")",
569 " print(\"Creating user...\")",
570 " local puser = kernel.modules.security.createProfile(\"user\")",
571 " print(\"Creating guest (inactive)...\")",
572 " local pguest = kernel.modules.security.createProfile(\"guest\")",
573 " ",
574 " -- TODO start gui on primary terminal",
575 " -- TODO create a wizard",
576 " ",
577 " -- TODO failing installer should set kernel.shutdown = true",
578 " ",
579 " kernel.writeSecureData('core/install.dat', textutils.serialize(installerData))",
580 "end -- function installer",
581 "",
582 "-------------------",
583 "-- The login processing",
584 "-- @function [parent=#xwos.startup] run",
585 "-- @param #string installData",
586 "-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
587 "M.login = function(installData, kernel)",
588 " print()",
589 " print(\"starting login...\")",
590 " ",
591 " -- for gui see http://harryfelton.web44.net/titanium/guide/download",
592 " -- lua minifier: https://gitlab.com/hbomb79/Titanium/blob/develop/bin/Minify.lua",
593 " ",
594 " -- TODO start gui on primary terminal",
595 "end -- function installer",
596 "",
597 "-------------------",
598 "-- Startup processing script",
599 "-- @function [parent=#xwos.startup] run",
600 "-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
601 "M.run = function(kernel)",
602 " local installData = kernel.readSecureData('core/install.dat')",
603 " kernel.debug(\"[start] checking installation\")",
604 " if installData == nil then",
605 " kernel.debug(\"[start] starting installer\")",
606 " M.installer(kernel)",
607 " end -- if not installed",
608 " ",
609 " while not kernel.shutdown do",
610 " kernel.debug(\"[start] starting login\")",
611 " M.login(textutils.unserialize(installData), kernel)",
612 " end -- while not shutdown",
613 "end -- function run",
614 "",
615 "return M",
616 },
617 [ "/kernel/1/8/moduleOrder.lua" ] = {
618 "-- This file is part of xwos.",
619 "--",
620 "-- xwos is free software: you can redistribute it and/or modify",
621 "-- it under the terms of the GNU General Public License as published by",
622 "-- the Free Software Foundation, either version 3 of the License, or",
623 "-- (at your option) any later version.",
624 "--",
625 "-- xwos is distributed in the hope that it will be useful,",
626 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
627 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
628 "-- GNU General Public License for more details.",
629 "--",
630 "-- You should have received a copy of the GNU General Public License",
631 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
632 "",
633 "return {",
634 " \"sandbox\",",
635 " \"security\"",
636 "}",
637 },
638 [ "/kernel/common/xwos/kernel.lua" ] = {
639 "-- This file is part of xwos.",
640 "--",
641 "-- xwos is free software: you can redistribute it and/or modify",
642 "-- it under the terms of the GNU General Public License as published by",
643 "-- the Free Software Foundation, either version 3 of the License, or",
644 "-- (at your option) any later version.",
645 "--",
646 "-- xwos is distributed in the hope that it will be useful,",
647 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
648 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
649 "-- GNU General Public License for more details.",
650 "--",
651 "-- You should have received a copy of the GNU General Public License",
652 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
653 "",
654 "local origGetfenv = getfenv",
655 "local origSetfenv = setfenv",
656 "local origsetmeta = setmetatable",
657 "local origtype = type",
658 "local origpairs = pairs",
659 "local origload = load",
660 "local origpcall = pcall",
661 "local origprint = print",
662 "local origtostring = tostring",
663 "",
664 "local origTable = table",
665 "table = {}",
666 "for k,v in origpairs(origTable) do",
667 " table[k] = v",
668 "end -- for table",
669 "",
670 "-------------------------------------",
671 "-- Creates a new clone; only first level of table will be cloned, no deep clone; no metadata clone",
672 "-- @function [parent=#table] clone",
673 "-- @param #table src",
674 "-- @return #table new copy",
675 "table.clone = function(src)",
676 " local r = {}",
677 " for k, v in origpairs(src) do",
678 " r[k] = v",
679 " end -- for src",
680 " return r",
681 "end -- function table.clone",
682 "",
683 "-------------------------------------",
684 "-- @function [parent=#table] contains",
685 "-- @param #table haystack",
686 "-- @param #any needle",
687 "-- @return #boolean success",
688 "table.contains = function(haystack, needle)",
689 " for k, v in origpairs(haystack) do",
690 " if (v == needle) then",
691 " return true",
692 " end -- if equals",
693 " end -- for haystack",
694 " return false",
695 "end -- function table.contains",
696 "",
697 "-------------------------------------",
698 "-- @function [parent=#table] indexOf",
699 "-- @param #table haystack",
700 "-- @param #any needle",
701 "-- @return #number index of given element or nil if not found",
702 "table.indexOf = function(haystack, needle)",
703 " for k, v in origpairs(haystack) do",
704 " if (v == needle) then",
705 " return k",
706 " end -- if equals",
707 " end -- for haystack",
708 " return nil",
709 "end -- function table.indexOf",
710 "",
711 "-------------------------------------",
712 "-- @function [parent=#table] removeValue",
713 "-- @param #table haystack",
714 "-- @param #any needle",
715 "-- @return #boolean true if element was found and removed",
716 "table.removeValue = function(haystack, needle)",
717 " for k, v in origpairs(haystack) do",
718 " if (v == needle) then",
719 " haystack[k] = nil",
720 " return true",
721 " end -- if equals",
722 " end -- for haystack",
723 " return false",
724 "end -- function table.removeValue",
725 "",
726 "-------------------------------------",
727 "-- @function [parent=#table] containsKey",
728 "-- @param #table haystack",
729 "-- @param #any needle",
730 "-- @return #boolean success",
731 "table.containsKey = function(haystack, needle)",
732 " return haystack[needle] ~= nil",
733 "end -- function table.containsKey",
734 "",
735 "--------------------------------",
736 "-- local kernel",
737 "-- @type xwos.kernel",
738 "local M = {}",
739 "",
740 "local bootSequence = {",
741 " debug = function()",
742 " M.kernelDebug = true",
743 " M.print(\"activating kernel debug mode...\")",
744 " end, -- function debug",
745 " ",
746 " eventLog = function()",
747 " M.eventLog = true",
748 " M.print(\"activating kernel event log...\")",
749 " end -- function eventLog",
750 "}",
751 "",
752 "--------------------------------",
753 "-- Boot kernel",
754 "-- @function [parent=#xwos.kernel] boot",
755 "-- @param #string ver kernel version number",
756 "-- @param #table kernelpaths the paths to look for kernel files",
757 "-- @param #function krequire require function to include kernel files",
758 "-- @param global#global args the command line arguments",
759 "M.boot = function(ver, kernelpaths, krequire, oldGlob, args)",
760 " --------------------------------",
761 " -- @field [parent=#xwos.kernel] #table kernelpaths the paths for including kernel",
762 " M.kernelpaths = kernelpaths",
763 " --------------------------------",
764 " -- @field [parent=#xwos.kernel] #string version the kernel version",
765 " M.version = ver",
766 " --------------------------------",
767 " -- @field [parent=#xwos.kernel] #table the built in environment factories (installed from modules)",
768 " M.envFactories = {}",
769 " --------------------------------",
770 " -- @field [parent=#xwos.kernel] global#global oldGlob the old globals",
771 " M.oldGlob = oldGlob -- TODO type (global#global) does not work?",
772 " M.oldGlob._ENV = nil",
773 " --M.oldGlob.package = nil",
774 " M.oldGlob._G = nil",
775 " M.oldGlob.shell = nil",
776 " M.oldGlob.multishell = nil",
777 " --------------------------------",
778 " -- @field [parent=#xwos.kernel] #table args the command line args invoking the kernel",
779 " M.args = args or {}",
780 "",
781 " -------------------------------",
782 " -- @field [parent=#xwos.kernel] #boolean kernelDebug true for kernel debugging; activated through script invocation/argument (\"xwos debug\")",
783 " M.kernelDebug = false",
784 "",
785 " -------------------------------",
786 " -- @field [parent=#xwos.kernel] #boolean eventLog true for event logging; activated through script invocation/argument (\"xwos eventLog\")",
787 " M.eventLog = false",
788 " ",
789 " -- parse arguments",
790 " for i, v in origpairs(M.args) do",
791 " if bootSequence[v] ~= nil then",
792 " bootSequence[v]()",
793 " else -- exists",
794 " M.print(\"Ignoring unknown argument \" .. v)",
795 " end -- not exists",
796 " end -- for arg",
797 " ",
798 " --------------------------------",
799 " -- Require for kernel scripts",
800 " -- @function [parent=#xwos.kernel] require",
801 " -- @param #string path the path",
802 " M.require = krequire",
803 " ",
804 " M.debug(\"loading process management\")",
805 " --------------------------------",
806 " -- @field [parent=#xwos.kernel] xwos.processes#xwos.processes processes the known xwos processes",
807 " M.processes = M.require('xwos/processes')",
808 " ",
809 " M.debug(\"loading module management\")",
810 " --------------------------------",
811 " -- @field [parent=#xwos.kernel] xwos.modulesmgr#xwos.modulesmgr modules the kernel modules",
812 " M.modules = M.require('xwos/modulesmgr')",
813 " ",
814 " M.debug(\"booting modules\")",
815 " M.modules.preboot(M)",
816 " M.modules.boot(M)",
817 " ",
818 " --------------------------------",
819 " -- @field [parent=#xwos.kernel] #global nenv the new environment for processes",
820 " M.nenv = {}",
821 " M.debug(\"preparing sandbox for root process\", M.nenv)",
822 " local nenvmt = {",
823 " __index = function(table, key)",
824 " local e = origGetfenv(0)",
825 " if (e == M.nenv) then return nil end",
826 " return e[key]",
827 " end -- function __index",
828 " }",
829 " origsetmeta(M.nenv, nenvmt)",
830 " origSetfenv(nenvmt.__index, M.nenv)",
831 " local function wrapfenv(table, env, blacklist)",
832 " local R = {}",
833 " for k,v in origpairs(table) do",
834 " local t = origtype(v)",
835 " if t == \"function\" then",
836 " if blacklist[k] == nil then",
837 " R[k] = origGetfenv(v)",
838 " -- print(\"setfenv\", k, R[k])",
839 " origpcall(origSetfenv, v, env) -- pcall because changing internal functions will fail (silently ingore it)",
840 " end -- if blacklist",
841 " end -- if function",
842 " if t == \"table\" and blacklist[k] ~= \"*\" then",
843 " -- print(\"setfenv table \", k)",
844 " R[k] = wrapfenv(v, env, blacklist[k] or {})",
845 " end -- if table",
846 " end -- for table",
847 " return R",
848 " end -- function wrapfenv",
849 " --------------------------------",
850 " -- @field [parent=#xwos.kernel] #table oldfenv the old fenv for global functions",
851 " M.oldfenv = wrapfenv(oldGlob, M.nenv, {",
852 " getfenv=true,",
853 " setfenv=true,",
854 " shell={run=true, clearAlias=true, dir=true, getRunningProgram=true},",
855 " package=\"*\",",
856 " bit32={bxor=true},",
857 " redstone={getBundledOutput=true}",
858 " })",
859 " M.debug(\"boot finished\")",
860 "end -- function boot",
861 "",
862 "--------------------------------",
863 "-- Startup xwos",
864 "-- @function [parent=#xwos.kernel] startup",
865 "M.startup = function()",
866 " local nenv = {}",
867 " M.debug(\"preparing new environment for root process\", nenv)",
868 " for k,v in origpairs(M.oldGlob) do",
869 " nenv[k] = v",
870 " end -- for oldGlob",
871 " nenv.print = function(...) -- TODO remove",
872 " M.oldGlob.print(\"->\", ...)",
873 " end -- function print",
874 " ",
875 " M.debug(\"creating root process\")",
876 " local proc = M.processes.new(nil, M, nenv, M.envFactories) -- TODO factories from root profile (per profile factories)",
877 " local startupData = M.readSecureData('core/startup.dat', \"/rom/xwos/kernel/common/xwos/testsleep.lua\") -- TODO startup script",
878 " M.debug(\"spawning thread with startup script \" .. startupData)",
879 " proc.spawn(startupData)",
880 " proc.join(nil)",
881 " ",
882 " M.debug(\"cleanup root process sandbox\")",
883 " -- cleanup",
884 " local function unwrapfenv(table, old)",
885 " for k,v in origpairs(table) do",
886 " local t = origtype(v)",
887 " if old[k] ~= nil then",
888 " if t == \"function\" then",
889 " -- print(\"setfenv\", k, old[k])",
890 " origpcall(origSetfenv, v, old[k]) -- pcall because changing internal functions will fail (silently ingore it)",
891 " end -- if function",
892 " if t == \"table\" then",
893 " unwrapfenv(v, old[k])",
894 " end -- if table",
895 " end -- if old",
896 " end -- for table",
897 " end -- function unwrapfenv",
898 " unwrapfenv(M.oldGlob, M.oldfenv)",
899 " ",
900 " table = origTable",
901 " ",
902 " M.debug(\"last actions before shutdown\")",
903 " if proc.result[1] then",
904 " origprint(\"Good bye...\")",
905 " else -- if result",
906 " origprint(\"ERR: \", proc.result[2])",
907 " end -- if result",
908 "end -- function startup",
909 "",
910 "-------------------------------",
911 "-- debug log message",
912 "-- @function [parent=#xwos.kernel] debug",
913 "-- @param ... print message arguments",
914 "M.debug = function(...)",
915 " if M.kernelDebug then",
916 " M.print(...)",
917 " end -- if kernelDebug",
918 "end -- function debug",
919 "",
920 "-------------------------------",
921 "-- print info message",
922 "-- @function [parent=#xwos.kernel] print",
923 "-- @param ... print message arguments",
924 "M.print = function(...)",
925 " M.oldGlob.print(...) -- TODO wrap to kernel display",
926 " if (M.kernelDebug) then",
927 " local f = M.oldGlob.fs.open(\"/core/log/debug-log.txt\", M.oldGlob.fs.exists(\"/core/log/debug-log.txt\") and \"a\" or \"w\")",
928 " local str = M.oldGlob.os.day()..\"-\"..M.oldGlob.os.time()..\" \"",
929 " for k, v in origpairs({...}) do",
930 " str = str .. origtostring(v) .. \" \"",
931 " end -- for ...",
932 " f.writeLine(str)",
933 " f.close()",
934 " end -- if kernelDebug",
935 "end -- function print",
936 "",
937 "-------------------------------",
938 "-- read data file from secured kernel storage",
939 "-- @function [parent=#xwos.kernel] readSecureData",
940 "-- @param #string path the file to read",
941 "-- @param #string def optional default data",
942 "-- @return #string the file content or nil if file does not exist",
943 "M.readSecureData = function(path, def)",
944 " local f = \"/xwos/private/\" .. path",
945 " if not M.oldGlob.fs.exists(f) then",
946 " return def",
947 " end -- if not exists",
948 " local h = M.oldGlob.fs.open(f, \"r\")",
949 " local res = h.readall()",
950 " h.close()",
951 " return res",
952 "end -- function readSecureData",
953 "",
954 "-------------------------------",
955 "-- write data file to secured kernel storage",
956 "-- @function [parent=#xwos.kernel] writeSecureData",
957 "-- @param #string path the file to write",
958 "-- @param #string data new data",
959 "M.writeSecureData = function(path, data)",
960 " local f = \"/xwos/private/\" .. path",
961 " local h = M.oldGlob.fs.open(f, \"w\")",
962 " h.write(data)",
963 " h.close()",
964 "end -- function readSecureData",
965 "",
966 "return M",
967 },
968 [ "/kernel/common/xwos/modules/sandbox/procinput.lua" ] = {
969 "-- This file is part of xwos.",
970 "--",
971 "-- xwos is free software: you can redistribute it and/or modify",
972 "-- it under the terms of the GNU General Public License as published by",
973 "-- the Free Software Foundation, either version 3 of the License, or",
974 "-- (at your option) any later version.",
975 "--",
976 "-- xwos is distributed in the hope that it will be useful,",
977 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
978 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
979 "-- GNU General Public License for more details.",
980 "--",
981 "-- You should have received a copy of the GNU General Public License",
982 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
983 "",
984 "-----------------------",
985 "-- @module xwos.modules.sandbox.procinput",
986 "local M = {}",
987 "",
988 "local kernel -- xwos.kernel#xwos.kernel",
989 "",
990 "-- TODO refactor following to some linked stack type",
991 "-----------------------",
992 "-- @type pinput",
993 "",
994 "----------------------------------",
995 "-- @field [parent=#pinput] #pinput prev the previous input",
996 " ",
997 "-----------------------",
998 "-- @field [parent=#pinput] xwos.processes#xwos.process proc the input process",
999 "",
1000 "-----------------------",
1001 "-- @field [parent=#xwos.modules.sandbox.procinput] #pinput current the current process input (front process)",
1002 "M.current = nil",
1003 "",
1004 "-----------------------",
1005 "-- injects the kernel",
1006 "-- @function [parent=#xwos.modules.sandbox.procinput] setKernel",
1007 "-- @param xwos.kernel#xwos.kernel k the kernel",
1008 "M.setKernel = function(k)",
1009 " kernel = k",
1010 "end -- function setKernel",
1011 "",
1012 "M.acquire = function(proc)",
1013 " -- first invocation has no kernel",
1014 " if kernel ~= nil and proc ~= nil then",
1015 " kernel.debug(\"[PID\"..proc.pid..\"] fetching user input (front process)\")",
1016 " end -- if kernel",
1017 " local r = {}",
1018 " ---------------------",
1019 " -- release input if proc blocks it",
1020 " -- @function [parent=#pinput] release",
1021 " -- @param xwos.processes#xwos.process proc2 process to release the env",
1022 " r.release = function(proc2)",
1023 " if r.proc == proc2 then",
1024 " kernel.debug(\"[PID\"..proc2.pid..\"] releasing user input (front process)\")",
1025 " M.current = r.prev",
1026 " while M.current.proc ~= nil and M.current.proc.procstate == \"finished\" do",
1027 " M.current = M.current.prev",
1028 " end -- while finished",
1029 " if M.current.proc ~= nil then",
1030 " kernel.debug(\"[PID\"..proc2.pid..\"] switched user input to \"..M.current.proc.pid..\" (front process)\")",
1031 " end -- if proc",
1032 " end -- if proc",
1033 " end -- function release",
1034 " r.prev = M.current",
1035 " r.proc = proc",
1036 " M.current = r",
1037 "end -- function acquire",
1038 "",
1039 "M.acquire(nil)",
1040 "",
1041 "return M",
1042 },
1043 [ "/kernel/common/xwos/testsleep.lua" ] = {
1044 "-- This file is part of xwos.",
1045 "--",
1046 "-- xwos is free software: you can redistribute it and/or modify",
1047 "-- it under the terms of the GNU General Public License as published by",
1048 "-- the Free Software Foundation, either version 3 of the License, or",
1049 "-- (at your option) any later version.",
1050 "--",
1051 "-- xwos is distributed in the hope that it will be useful,",
1052 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
1053 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1054 "-- GNU General Public License for more details.",
1055 "--",
1056 "-- You should have received a copy of the GNU General Public License",
1057 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
1058 "",
1059 " local function func1()",
1060 " print(\"[1]pid=\",pid)",
1061 " print(\"[1]Hello World!\")",
1062 " sleep(5)",
1063 " print(\"[1]Hello again\");",
1064 " end",
1065 " local function func2()",
1066 " print(\"[2]pid=\",pid)",
1067 " sleep(5)",
1068 " print(\"[2]Hello World!\")",
1069 " sleep(5)",
1070 " print(\"[2]Hello again\");",
1071 " end",
1072 " print(\"[0]pid=\",pid)",
1073 " local proc1 = xwos.pmr.createThread()",
1074 " local proc2 = xwos.pmr.createThread()",
1075 " proc1.spawn(func1)",
1076 " proc2.spawn(func2)",
1077 " proc1.join()",
1078 " proc2.join()",
1079 " print(\"Ending\")",
1080 },
1081 [ "/kernel/common/xwos/modules/sandbox/init.lua" ] = {
1082 "-- This file is part of xwos.",
1083 "--",
1084 "-- xwos is free software: you can redistribute it and/or modify",
1085 "-- it under the terms of the GNU General Public License as published by",
1086 "-- the Free Software Foundation, either version 3 of the License, or",
1087 "-- (at your option) any later version.",
1088 "--",
1089 "-- xwos is distributed in the hope that it will be useful,",
1090 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
1091 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1092 "-- GNU General Public License for more details.",
1093 "--",
1094 "-- You should have received a copy of the GNU General Public License",
1095 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
1096 "",
1097 "-----------------------",
1098 "-- @module xwos.modules.sandbox",
1099 "local M = {}",
1100 "",
1101 "local kernel -- xwos.kernel#xwos.kernel",
1102 "local originsert = table.insert",
1103 "",
1104 "---------------------------------",
1105 "-- @function [parent=#xwos.modules.sandbox] preboot",
1106 "-- @param xwos.kernel#xwos.kernel k",
1107 "M.preboot = function(k)",
1108 " k.debug(\"preboot sandbox\")",
1109 " kernel = k",
1110 " ",
1111 " -----------------------",
1112 " -- process input type with mapping to previous input",
1113 " -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.procinput#xwos.modules.sandbox.procinput procinput the input process management",
1114 " M.procinput = kernel.require(\"xwos/modules/sandbox/procinput\")",
1115 " M.procinput.setKernel(kernel)",
1116 " ",
1117 " -----------------------",
1118 " -- timers started from processes",
1119 " -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.timers#xwos.modules.sandbox.timers timers the timer management",
1120 " M.timers = kernel.require(\"xwos/modules/sandbox/timers\")",
1121 " M.timers.setKernel(kernel)",
1122 " ",
1123 " -----------------------",
1124 " -- event queue handling",
1125 " -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.evqueue#xwos.modules.sandbox.evqueue evqueue event queue management",
1126 " M.evqueue = kernel.require(\"xwos/modules/sandbox/evqueue\")",
1127 " M.evqueue.setKernel(kernel)",
1128 "",
1129 "end -- function preboot",
1130 "",
1131 "----------------------",
1132 "-- @param xwos.processes#xwos.process proc the underlying process",
1133 "-- @param #global env the global process environment",
1134 "local envFactory = function(proc, env)",
1135 " kernel.debug(\"[PID\"..proc.pid..\"] preparing env\", env)",
1136 " env.pid = proc.pid",
1137 "",
1138 " -- TODO this is partly original code from bios.",
1139 " -- we need to redeclare it to get into wrapped os.**** methods",
1140 " -- maybe in future we find a solution to not redeclare it here",
1141 " local biosRead = function( _sReplaceChar, _tHistory, _fnComplete, _sDefault )",
1142 " if _sReplaceChar ~= nil and type( _sReplaceChar ) ~= \"string\" then",
1143 " error( \"bad argument #1 (expected string, got \" .. type( _sReplaceChar ) .. \")\", 2 ) ",
1144 " end",
1145 " if _tHistory ~= nil and type( _tHistory ) ~= \"table\" then",
1146 " error( \"bad argument #2 (expected table, got \" .. type( _tHistory ) .. \")\", 2 ) ",
1147 " end",
1148 " if _fnComplete ~= nil and type( _fnComplete ) ~= \"function\" then",
1149 " error( \"bad argument #3 (expected function, got \" .. type( _fnComplete ) .. \")\", 2 ) ",
1150 " end",
1151 " if _sDefault ~= nil and type( _sDefault ) ~= \"string\" then",
1152 " error( \"bad argument #4 (expected string, got \" .. type( _sDefault ) .. \")\", 2 ) ",
1153 " end",
1154 " term.setCursorBlink( true )",
1155 " ",
1156 " local sLine",
1157 " if type( _sDefault ) == \"string\" then",
1158 " sLine = _sDefault",
1159 " else",
1160 " sLine = \"\"",
1161 " end",
1162 " local nHistoryPos",
1163 " local nPos = #sLine",
1164 " if _sReplaceChar then",
1165 " _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )",
1166 " end",
1167 " ",
1168 " local tCompletions",
1169 " local nCompletion",
1170 " local function recomplete()",
1171 " if _fnComplete and nPos == string.len(sLine) then",
1172 " tCompletions = _fnComplete( sLine )",
1173 " if tCompletions and #tCompletions > 0 then",
1174 " nCompletion = 1",
1175 " else",
1176 " nCompletion = nil",
1177 " end",
1178 " else",
1179 " tCompletions = nil",
1180 " nCompletion = nil",
1181 " end",
1182 " end",
1183 " ",
1184 " local function uncomplete()",
1185 " tCompletions = nil",
1186 " nCompletion = nil",
1187 " end",
1188 " ",
1189 " local w = term.getSize()",
1190 " local sx = term.getCursorPos()",
1191 " ",
1192 " local function redraw( _bClear )",
1193 " local nScroll = 0",
1194 " if sx + nPos >= w then",
1195 " nScroll = (sx + nPos) - w",
1196 " end",
1197 " ",
1198 " local cx,cy = term.getCursorPos()",
1199 " term.setCursorPos( sx, cy )",
1200 " local sReplace = (_bClear and \" \") or _sReplaceChar",
1201 " if sReplace then",
1202 " term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )",
1203 " else",
1204 " term.write( string.sub( sLine, nScroll + 1 ) )",
1205 " end",
1206 " ",
1207 " if nCompletion then",
1208 " local sCompletion = tCompletions[ nCompletion ]",
1209 " local oldText, oldBg",
1210 " if not _bClear then",
1211 " oldText = term.getTextColor()",
1212 " oldBg = term.getBackgroundColor()",
1213 " term.setTextColor( colors.white )",
1214 " term.setBackgroundColor( colors.gray )",
1215 " end",
1216 " if sReplace then",
1217 " term.write( string.rep( sReplace, string.len( sCompletion ) ) )",
1218 " else",
1219 " term.write( sCompletion )",
1220 " end",
1221 " if not _bClear then",
1222 " term.setTextColor( oldText )",
1223 " term.setBackgroundColor( oldBg )",
1224 " end",
1225 " end",
1226 " ",
1227 " term.setCursorPos( sx + nPos - nScroll, cy )",
1228 " end",
1229 " ",
1230 " local function clear()",
1231 " redraw( true )",
1232 " end",
1233 " ",
1234 " recomplete()",
1235 " redraw()",
1236 " ",
1237 " local function acceptCompletion()",
1238 " if nCompletion then",
1239 " -- Clear",
1240 " clear()",
1241 " ",
1242 " -- Find the common prefix of all the other suggestions which start with the same letter as the current one",
1243 " local sCompletion = tCompletions[ nCompletion ]",
1244 " sLine = sLine .. sCompletion",
1245 " nPos = string.len( sLine )",
1246 " ",
1247 " -- Redraw",
1248 " recomplete()",
1249 " redraw()",
1250 " end",
1251 " end",
1252 " while true do",
1253 " local sEvent, param = os.pullEvent()",
1254 " if sEvent == \"char\" then",
1255 " -- Typed key",
1256 " clear()",
1257 " sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )",
1258 " nPos = nPos + 1",
1259 " recomplete()",
1260 " redraw()",
1261 " ",
1262 " elseif sEvent == \"paste\" then",
1263 " -- Pasted text",
1264 " clear()",
1265 " sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )",
1266 " nPos = nPos + string.len( param )",
1267 " recomplete()",
1268 " redraw()",
1269 " ",
1270 " elseif sEvent == \"key\" then",
1271 " if param == keys.enter then",
1272 " -- Enter",
1273 " if nCompletion then",
1274 " clear()",
1275 " uncomplete()",
1276 " redraw()",
1277 " end",
1278 " break",
1279 " ",
1280 " elseif param == keys.left then",
1281 " -- Left",
1282 " if nPos > 0 then",
1283 " clear()",
1284 " nPos = nPos - 1",
1285 " recomplete()",
1286 " redraw()",
1287 " end",
1288 " ",
1289 " elseif param == keys.right then",
1290 " -- Right ",
1291 " if nPos < string.len(sLine) then",
1292 " -- Move right",
1293 " clear()",
1294 " nPos = nPos + 1",
1295 " recomplete()",
1296 " redraw()",
1297 " else",
1298 " -- Accept autocomplete",
1299 " acceptCompletion()",
1300 " end",
1301 " ",
1302 " elseif param == keys.up or param == keys.down then",
1303 " -- Up or down",
1304 " if nCompletion then",
1305 " -- Cycle completions",
1306 " clear()",
1307 " if param == keys.up then",
1308 " nCompletion = nCompletion - 1",
1309 " if nCompletion < 1 then",
1310 " nCompletion = #tCompletions",
1311 " end",
1312 " elseif param == keys.down then",
1313 " nCompletion = nCompletion + 1",
1314 " if nCompletion > #tCompletions then",
1315 " nCompletion = 1",
1316 " end",
1317 " end",
1318 " redraw()",
1319 " ",
1320 " elseif _tHistory then",
1321 " -- Cycle history",
1322 " clear()",
1323 " if param == keys.up then",
1324 " -- Up",
1325 " if nHistoryPos == nil then",
1326 " if #_tHistory > 0 then",
1327 " nHistoryPos = #_tHistory",
1328 " end",
1329 " elseif nHistoryPos > 1 then",
1330 " nHistoryPos = nHistoryPos - 1",
1331 " end",
1332 " else",
1333 " -- Down",
1334 " if nHistoryPos == #_tHistory then",
1335 " nHistoryPos = nil",
1336 " elseif nHistoryPos ~= nil then",
1337 " nHistoryPos = nHistoryPos + 1",
1338 " end ",
1339 " end",
1340 " if nHistoryPos then",
1341 " sLine = _tHistory[nHistoryPos]",
1342 " nPos = string.len( sLine ) ",
1343 " else",
1344 " sLine = \"\"",
1345 " nPos = 0",
1346 " end",
1347 " uncomplete()",
1348 " redraw()",
1349 " ",
1350 " end",
1351 " ",
1352 " elseif param == keys.backspace then",
1353 " -- Backspace",
1354 " if nPos > 0 then",
1355 " clear()",
1356 " sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )",
1357 " nPos = nPos - 1",
1358 " recomplete()",
1359 " redraw()",
1360 " end",
1361 " ",
1362 " elseif param == keys.home then",
1363 " -- Home",
1364 " if nPos > 0 then",
1365 " clear()",
1366 " nPos = 0",
1367 " recomplete()",
1368 " redraw()",
1369 " end",
1370 " ",
1371 " elseif param == keys.delete then",
1372 " -- Delete",
1373 " if nPos < string.len(sLine) then",
1374 " clear()",
1375 " sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 ) ",
1376 " recomplete()",
1377 " redraw()",
1378 " end",
1379 " ",
1380 " elseif param == keys[\"end\"] then",
1381 " -- End",
1382 " if nPos < string.len(sLine ) then",
1383 " clear()",
1384 " nPos = string.len(sLine)",
1385 " recomplete()",
1386 " redraw()",
1387 " end",
1388 " ",
1389 " elseif param == keys.tab then",
1390 " -- Tab (accept autocomplete)",
1391 " acceptCompletion()",
1392 " ",
1393 " end",
1394 " ",
1395 " elseif sEvent == \"term_resize\" then",
1396 " -- Terminal resized",
1397 " w = term.getSize()",
1398 " redraw()",
1399 " ",
1400 " end",
1401 " end",
1402 " ",
1403 " local cx, cy = term.getCursorPos()",
1404 " term.setCursorBlink( false )",
1405 " term.setCursorPos( w + 1, cy )",
1406 " print()",
1407 " ",
1408 " return sLine",
1409 " end -- function biosRead",
1410 "",
1411 " env.read = function( _sReplaceChar, _tHistory, _fnComplete, _sDefault )",
1412 " proc.acquireInput()",
1413 " local res = {pcall(biosRead, _sReplaceChar,_tHistory,_fnComplete,_sDefault)}",
1414 " proc.releaseInput()",
1415 " if res[1] then",
1416 " return res[2]",
1417 " end -- if res",
1418 " error(res[2])",
1419 " end -- function read",
1420 " ",
1421 " env.sleep = function(nTime)",
1422 " kernel.debug(\"[PID\"..proc.pid..\"] sleep\", nTime, kernel.oldGlob.getfenv(0), kernel.oldGlob.getfenv(env.sleep))",
1423 " if nTime ~= nil and type( nTime ) ~= \"number\" then",
1424 " error( \"bad argument #1 (expected number, got \" .. type( nTime ) .. \")\", 2 ) ",
1425 " end",
1426 " local timer = os.startTimer( nTime or 0 )",
1427 " repeat",
1428 " local sEvent, param = os.pullEvent( \"timer\" )",
1429 " until param == timer",
1430 " end -- function sleep",
1431 " ",
1432 " -- clone os to manipulate it",
1433 " env.os = table.clone(env.os)",
1434 " env.os.sleep = function(nTime)",
1435 " sleep(nTime)",
1436 " end -- function os.sleep",
1437 " ",
1438 " env.os.startTimer = function(s)",
1439 " kernel.debug(\"[PID\"..proc.pid..\"] os.startTimer\", s)",
1440 " local timer = kernel.oldGlob.os.startTimer(s)",
1441 " kernel.modules.instances.sandbox.timers.new(timer, proc)",
1442 " return timer",
1443 " end -- function os.startTimer",
1444 " env.os.pullEventRaw = function(filter)",
1445 " kernel.debug(\"[PID\"..proc.pid..\"] os.pullEventRaw\", filter)",
1446 " while true do",
1447 " for k,v in kernel.oldGlob.ipairs(proc.evqueue) do",
1448 " proc.evqueue[k] = nil",
1449 " if filter == nil or v[1]==filter then",
1450 " kernel.debug(\"[PID\"..proc.pid..\"] returning event from local event queue\", kernel.oldGlob.unpack(v))",
1451 " return kernel.oldGlob.unpack(v)",
1452 " else -- if filter",
1453 " kernel.debug(\"[PID\"..proc.pid..\"] discard event from local event queue because of filter\", kernel.oldGlob.unpack(v))",
1454 " end -- if filter",
1455 " end -- for evqueue",
1456 " ",
1457 " kernel.debug(\"[PID\"..proc.pid..\"] invoke os.pullEventRaw\", filter)",
1458 " local event = M.evqueue.processEvt(proc.pid, proc, {kernel.oldGlob.os.pullEventRaw()}, filter)",
1459 " if event ~= nil then",
1460 " return kernel.oldGlob.unpack(event)",
1461 " end -- if event",
1462 " end -- endless loop",
1463 " end -- function os.pullEventRaw",
1464 " env.os.pullEvent = function(filter)",
1465 " kernel.debug(\"[PID\"..proc.pid..\"] os.pullEvent\", filter)",
1466 " local eventData = {proc.env.os.pullEventRaw(filter)}",
1467 " if eventData[1] == \"terminate\" then",
1468 " kernel.oldGlob.error( \"Terminated\", 0 )",
1469 " end",
1470 " return kernel.oldGlob.unpack(eventData)",
1471 " end -- function os.pullEvent",
1472 " ---------------------------------------",
1473 " -- operating system access",
1474 " -- @type xwos",
1475 " -- @field [parent=#global] #xwos xwos predefined operating system accessor",
1476 " env.xwos = {}",
1477 " ---------------------------------------",
1478 " -- debugging output",
1479 " -- @function [parent=#xwos] debug",
1480 " -- @param #string msg",
1481 " env.xwos.debug = function(msg)",
1482 " -- TODO find a way to pass variables etc.",
1483 " -- check for possible sandbox breaks during tostring",
1484 " if kernel.oldGlob.type(msg) ~= \"string\" then",
1485 " error(\"Wrong argument type (only strings allowed)\")",
1486 " else -- if not string",
1487 " kernel.debug(msg)",
1488 " end -- if string",
1489 " end -- function debug",
1490 " ---------------------------------------",
1491 " -- process manager",
1492 " -- @type xwos.pmr",
1493 " -- @field [parent=#xwos] #xwos.pmr pmr process manager",
1494 " env.xwos.pmr = {}",
1495 " -- TODO demon child threads (threads to be fnished before process ends)",
1496 " -- TODO on terminate main process terminat all child threads",
1497 " ---------------------------------------",
1498 " -- create a new child thread",
1499 " -- @function [parent=#xwos.pmr] createThread",
1500 " -- @param #table newenv the environment of the new thread",
1501 " -- @return #xwos.pmr.thread",
1502 " env.xwos.pmr.createThread = function(newenv)",
1503 " local nenv = {}",
1504 " for k,v in kernel.oldGlob.pairs(kernel.oldGlob) do",
1505 " nenv[k] = v",
1506 " end -- for oldGlob",
1507 " local function wrap(target, src)",
1508 " for k,v in kernel.oldGlob.pairs(src) do",
1509 " if kernel.oldGlob.type(v) == \"table\" and kernel.oldGlob.type(target[k]) == \"table\" then",
1510 " wrap(v, target[k])",
1511 " else -- if tables",
1512 " target[k] = v",
1513 " end -- if tables",
1514 " end -- for src",
1515 " end -- function wrap",
1516 " if newenv ~= nil then",
1517 " wrap(nenv, newenv)",
1518 " end -- if nenv",
1519 " local nproc = kernel.processes.new(proc, kernel, env, kernel.envFactories)",
1520 " ---------------------------------------",
1521 " -- the new thread",
1522 " -- @type xwos.pmr.thread",
1523 " local R = {}",
1524 " ---------------------------------------",
1525 " -- join thread and wait for finish",
1526 " -- @function [parent=#xwos.pmr.thread] join",
1527 " R.join = function()",
1528 " nproc.join(proc)",
1529 " end -- function join",
1530 " ---------------------------------------",
1531 " -- terminate thread",
1532 " -- @function [parent=#xwos.pmr.thread] terminate",
1533 " R.termninate = function()",
1534 " nproc.termninate()",
1535 " end -- function termninate",
1536 " ---------------------------------------",
1537 " -- spawn thread and invoke function",
1538 " -- @function [parent=#xwos.pmr.thread] spawn",
1539 " -- @param #function func the function to invoke",
1540 " -- @param ... arguments",
1541 " R.spawn = function(func, ...)",
1542 " nproc.spawn(func, ...)",
1543 " end -- function termninate",
1544 " -- TODO do we need this? we are declaring the functions already inside process thread with correct fenv",
1545 " kernel.oldGlob.setfenv(R.join, kernel.nenv)",
1546 " kernel.oldGlob.setfenv(R.terminate, kernel.nenv)",
1547 " kernel.oldGlob.setfenv(R.spawn, kernel.nenv)",
1548 " return R",
1549 " end -- function createThread",
1550 " ",
1551 " env.dofile = function(_sFile)",
1552 " if type( _sFile ) ~= \"string\" then",
1553 " error( \"bad argument #1 (expected string, got \" .. type( _sFile ) .. \")\", 2 )",
1554 " end",
1555 " local fnFile, e = loadfile( _sFile, kernel.nenv )",
1556 " if fnFile then",
1557 " return fnFile()",
1558 " else",
1559 " error( e, 2 )",
1560 " end",
1561 " end -- dofile",
1562 " ",
1563 " -- TODO do we need this? we are declaring the functions already inside process thread with correct fenv",
1564 " kernel.oldGlob.setfenv(biosRead, kernel.nenv)",
1565 " kernel.oldGlob.setfenv(env.read, kernel.nenv)",
1566 " kernel.oldGlob.setfenv(env.sleep, kernel.nenv)",
1567 " kernel.oldGlob.setfenv(env.dofile, kernel.nenv)",
1568 " kernel.oldGlob.setfenv(env.os.sleep, kernel.nenv)",
1569 " kernel.oldGlob.setfenv(env.os.startTimer, kernel.nenv)",
1570 " kernel.oldGlob.setfenv(env.os.pullEventRaw, kernel.nenv)",
1571 " kernel.oldGlob.setfenv(env.os.pullEvent, kernel.nenv)",
1572 " kernel.oldGlob.setfenv(env.xwos.debug, kernel.nenv)",
1573 " kernel.oldGlob.setfenv(env.xwos.pmr.createThread, kernel.nenv)",
1574 "end -- function envFactory",
1575 "",
1576 "---------------------------------",
1577 "-- @function [parent=#xwos.modules.sandbox] boot",
1578 "-- @param xwos.kernel#xwos.kernel k",
1579 "M.boot = function(k)",
1580 " k.debug(\"boot sandbox\")",
1581 " ",
1582 " kernel.envFactories.sandbox = envFactory",
1583 "end -- function boot",
1584 "",
1585 "-- wrap lua console and wrap programs...",
1586 "",
1587 "---- global functions",
1588 "--orig.print = print",
1589 "--orig.write = write",
1590 "--orig.load = load",
1591 "--orig.read = read",
1592 "--orig.error = error",
1593 "--orig.printError = printError",
1594 "---- relevant for sandbox",
1595 "--orig.dofile = dofile",
1596 "--orig.loadfile = loadfile",
1597 "--orig.loadstring = loadstring",
1598 "--orig.rawset = rawset",
1599 "--orig.rawget = rawget",
1600 "--",
1601 "---- computercraft apis",
1602 "--orig.redstone = redstone",
1603 "--orig.rs = rs -- alias for redstone",
1604 "--orig.rednet = rednet",
1605 "--orig.fs = fs",
1606 "--orig.gps = gps",
1607 "--orig.disk = disk",
1608 "--orig.http = http",
1609 "--orig.os = os",
1610 "--orig.commands = commands",
1611 "--orig.io = io",
1612 "--orig.multishell = multishell",
1613 "--orig.peripheral = peripheral",
1614 "--orig.settings = settings",
1615 "--orig.shell = shell",
1616 "--orig.turtle = turtle",
1617 "--orig.pocket = pocket",
1618 "--",
1619 "---- terminal management",
1620 "--orig.term = term",
1621 "--orig.paintutils = paintutils",
1622 "--orig.textutils = textutils",
1623 "--orig.window = window",
1624 "--",
1625 "---- threads etc.",
1626 "--orig.parallel = parallel",
1627 "--orig.setfenv = setfenv",
1628 "--orig.getfenv = getfenv",
1629 "--orig.xpcall = xpcall",
1630 "--orig.pcall = pcall",
1631 "--orig.coroutine = coroutine",
1632 "--",
1633 "-- Events:",
1634 "-- alarm http://computercraft.info/wiki/Alarm_(event)",
1635 "-- char http://computercraft.info/wiki/Char_(event)",
1636 "-- disk http://computercraft.info/wiki/Disk_(event)",
1637 "-- disk_eject http://computercraft.info/wiki/Disk_eject_(event)",
1638 "-- http_failure http://computercraft.info/wiki/Http_failure_(event)",
1639 "-- http_success http://computercraft.info/wiki/Http_success_(event)",
1640 "-- key http://computercraft.info/wiki/Key_(event)",
1641 "-- key_up http://computercraft.info/wiki/Key_up_(event)",
1642 "-- modem_message http://computercraft.info/wiki/Modem_message_(event) http://computercraft.info/wiki/Modem_(API)",
1643 "-- monitor_resize http://computercraft.info/wiki/Monitor_resize_(event)",
1644 "-- monitor_touch http://computercraft.info/wiki/Monitor_touch_(event)",
1645 "-- mouse_click http://computercraft.info/wiki/Mouse_click_(event)",
1646 "-- mouse_drag http://computercraft.info/wiki/Mouse_drag_(event)",
1647 "-- mouse_scroll http://computercraft.info/wiki/Mouse_scroll_(event)",
1648 "-- mouse_up http://computercraft.info/wiki/Mouse_up_(event)",
1649 "-- paste http://computercraft.info/wiki/Paste_(event)",
1650 "-- peripheral http://computercraft.info/wiki/Peripheral_(event)",
1651 "-- peripheral_detach http://computercraft.info/wiki/Peripheral_detach_(event)",
1652 "-- rednet_message http://computercraft.info/wiki/Rednet_message_(event) http://computercraft.info/wiki/Rednet_(API)",
1653 "-- redstone http://computercraft.info/wiki/Redstone_(event)",
1654 "-- task_complete http://computercraft.info/wiki/Task_complete_(event)",
1655 "-- term_resize http://computercraft.info/wiki/Term_resize(Event) http://computercraft.info/wiki/Term_(API)",
1656 "-- terminate http://computercraft.info/wiki/Terminate_(event)",
1657 "-- timer http://computercraft.info/wiki/Timer_(event)",
1658 "-- turtle_inventory http://computercraft.info/wiki/Turtle_inventory_(event)",
1659 "",
1660 "return M",
1661 "",
1662 "",
1663 "",
1664 "",
1665 "",
1666 "",
1667 },
1668 [ "/core" ] = true,
1669 [ "/xwos.lua" ] = {
1670 "-- This file is part of xwos.",
1671 "--",
1672 "-- xwos is free software: you can redistribute it and/or modify",
1673 "-- it under the terms of the GNU General Public License as published by",
1674 "-- the Free Software Foundation, either version 3 of the License, or",
1675 "-- (at your option) any later version.",
1676 "--",
1677 "-- xwos is distributed in the hope that it will be useful,",
1678 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
1679 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1680 "-- GNU General Public License for more details.",
1681 "--",
1682 "-- You should have received a copy of the GNU General Public License",
1683 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
1684 "",
1685 "term.clear()",
1686 "",
1687 "local tArgs = {...}",
1688 "",
1689 "local myver = \"0.0.1\" -- TODO manipulate through maven build",
1690 "local osvs = os.version()",
1691 "local osvIter = string.gmatch(osvs, \"%S+\")",
1692 "local osn = osvIter()",
1693 "local osv = osvIter()",
1694 "",
1695 "local kernelpaths = { \"\", \"/xwos/kernel/common\" }",
1696 "local kernels = {}",
1697 "kernels[\"CraftOS\"] = {}",
1698 "kernels[\"CraftOS\"][\"1.8\"] = \"/xwos/kernel/1/8\"",
1699 "",
1700 "print(\"** booting XW-OS........\")",
1701 "print(\"** XW-OS version \" .. myver)",
1702 "print(\"** Copyright © 2018 by xworlds.eu.\")",
1703 "print(\"** All rights reserved.\")",
1704 "",
1705 "-- check if already booted",
1706 "if xwos then",
1707 " print()",
1708 " print(\"FAILED... We are already running XW-OS...\")",
1709 " return nil",
1710 "end -- if already booted",
1711 "",
1712 "-- check if valid operating system",
1713 "if kernels[osn] == nil or kernels[osn][osv] == nil then",
1714 " print()",
1715 " print(\"FAILED... running on unknown operating system or version...\")",
1716 " print(\"OS-version we got: \" .. osvs)",
1717 " print(\"Currently we require CraftOS at version 1.8\")",
1718 " return nil",
1719 "end -- if valid",
1720 "",
1721 "-- kernel file loader",
1722 "kernelpaths[1] = kernels[osn][osv]",
1723 "",
1724 "-- prepare first sandboxing for kernel",
1725 "local old2 = getfenv(2)",
1726 "local old1 = getfenv(1)",
1727 "if old2 ~= _G or old1.require == nil then",
1728 " print()",
1729 " print(\"FAILED... please run XW-OS in startup script or on root console...\")",
1730 " print(\"Running inside other operating systems may not be supported...\")",
1731 " return nil",
1732 "end -- if not globals",
1733 "local oldGlob = {}",
1734 "for k, v in pairs(_G) do",
1735 " oldGlob[k] = v",
1736 "end -- for _G",
1737 "for k, v in pairs(old2) do",
1738 " oldGlob[k] = v",
1739 "end -- for _G",
1740 "for k, v in pairs(old1) do",
1741 " oldGlob[k] = v",
1742 "end -- for _G",
1743 "",
1744 "-- create an explicit copy of globals",
1745 "local newGlob = {}",
1746 "for k, v in oldGlob.pairs(oldGlob) do",
1747 " newGlob[k] = v",
1748 "end -- for _G",
1749 "",
1750 "-- redirect require for kernel loading",
1751 "-- using functions from oldGlob for security reasons",
1752 "local function krequire(path)",
1753 " for k, v in oldGlob.pairs(kernelpaths) do",
1754 " local target = v .. \"/\" .. oldGlob.string.gsub(path, \"%.\", \"/\")",
1755 " local targetFile = target .. \".lua\"",
1756 " if oldGlob.fs.exists(targetFile) then",
1757 " local res = oldGlob.require(target)",
1758 " -- print(\"loaded file \"..target)",
1759 " return res",
1760 " end -- if file exists",
1761 " end -- for kernelpaths",
1762 " return nil",
1763 "end -- function require",
1764 "",
1765 "setfenv(1, newGlob)",
1766 "local state, err = pcall(function()",
1767 " local kernel = krequire('xwos.kernel') -- xwos.kernel#xwos.kernel",
1768 " ",
1769 " kernel.boot(myver, kernelpaths, krequire, oldGlob, tArgs)",
1770 " kernel.startup()",
1771 " end -- function ex",
1772 ")",
1773 "setfenv(1, old1)",
1774 "",
1775 "if not state then",
1776 " error(err)",
1777 "end",
1778 },
1779 [ "/kernel/common/xwos/processes.lua" ] = {
1780 "-- This file is part of xwos.",
1781 "--",
1782 "-- xwos is free software: you can redistribute it and/or modify",
1783 "-- it under the terms of the GNU General Public License as published by",
1784 "-- the Free Software Foundation, either version 3 of the License, or",
1785 "-- (at your option) any later version.",
1786 "--",
1787 "-- xwos is distributed in the hope that it will be useful,",
1788 "-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
1789 "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1790 "-- GNU General Public License for more details.",
1791 "--",
1792 "-- You should have received a copy of the GNU General Public License",
1793 "-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
1794 "",
1795 "local cocreate = coroutine.create",
1796 "local coresume = coroutine.resume",
1797 "local origGetfenv = getfenv",
1798 "local origSetfenv = setfenv",
1799 "local origsetmeta = setmetatable",
1800 "local origtype = type",
1801 "local origdofile = dofile",
1802 "local origloadfile = loadfile",
1803 "local origpcall = pcall",
1804 "local origpackage = package",
1805 "local origprint = print",
1806 "local origerror = error",
1807 "local origser = textutils.serialize",
1808 "local origpairs = pairs",
1809 "local origyield = coroutine.yield",
1810 "local originsert = table.insert",
1811 "",
1812 "local kernel -- xwos.kernel#xwos.kernel",
1813 "",
1814 "--------------------------------",
1815 "-- local process environments",
1816 "-- @type xwos.processes",
1817 "local processes = {}",
1818 "",
1819 "--------------------------------",
1820 "-- next pid to use for new processes",
1821 "local nextPid = 0",
1822 "",
1823 "--------------------------------",
1824 "-- creates a new process",
1825 "-- @function [parent=#xwos.processes] new",
1826 "-- @param p the parent process",
1827 "-- @param xwos.kernel#xwos.kernel k the kernel table",
1828 "-- @param #global env the global process environment",
1829 "-- @param #table factories functions with signature (proc, env) to initialize the new process or environment",
1830 "-- @return #xwos.process",
1831 "processes.new = function(p, k, env, factories)",
1832 " kernel = k",
1833 " --------------------------------",
1834 " -- process type",
1835 " -- @type xwos.process",
1836 " local R = {}",
1837 " ",
1838 " --------------------------------",
1839 " -- @field [parent=#xwos.process] #number pid the process id",
1840 " R.pid = nextPid",
1841 " nextPid = nextPid + 1",
1842 " ",
1843 " --------------------------------------",
1844 " -- @field [parent=#xwos.process] #table evqueue the process local event queue",
1845 " R.evqueue = {}",
1846 " ",
1847 " ------------------------------------------",
1848 " -- @field [parent=#xwos.process] #number joined number of processes having called method join",
1849 " R.joined = 0",
1850 " ",
1851 " --------------------------------",
1852 " -- @field [parent=#xwos.process] #string procstate the process state; \"initializing\", \"running\" or \"terminated\"",
1853 " R.procstate = \"initializing\"",
1854 " kernel.debug(\"[PID\"..R.pid..\"] pocstate = initializing\")",
1855 " ",
1856 " --------------------------------",
1857 " -- @field [parent=#xwos.process] #xwos.process parent the parent process",
1858 " R.parent = p",
1859 " ",
1860 " --------------------------------",
1861 " -- @field [parent=#xwos.process] #global env the process environment",
1862 " R.env = { pid = R.pid }",
1863 " kernel.debug(\"[PID\"..R.pid..\"] environments\", env)",
1864 " local nenvmt = {",
1865 " __index = function(table, key)",
1866 " local res = env[key]",
1867 " if res == nil then",
1868 " if R.parent ~= nil then",
1869 " -- parent should at least lead to PID 0. PID 0 already should contain all the visible and public globals all processes are allowed to use",
1870 " res = R.parent.env[key]",
1871 " end -- if parent",
1872 " end -- if not res (env)",
1873 " return res",
1874 " end -- function __index",
1875 " }",
1876 " origsetmeta(R.env, nenvmt)",
1877 " origSetfenv(nenvmt.__index, R.env)",
1878 " ",
1879 " --------------------------------------",
1880 " -- acquire input (front process)",
1881 " -- @function [parent=#xwos.process] acquireInput",
1882 " R.acquireInput = function()",
1883 " -- TODO is a stack always good?",
1884 " -- switching between processes (alt+tab in windows) is not meant to build a stack of input",
1885 " -- a stack of input will represent some kind of modal dialog over other modal dialog where closing one will pop up the previous one",
1886 " -- think about it...",
1887 " kernel.modules.instances.sandbox.procinput.acquire(R)",
1888 " end -- function acquireInput",
1889 " ",
1890 " ------------------------------------------",
1891 " -- joins process and awaits it termination",
1892 " -- @function [parent=#process] join",
1893 " -- @param #xwos.process cproc calling process",
1894 " R.join = function(cproc)",
1895 " local cpid = \"*\"",
1896 " if cproc ~= nil then",
1897 " cpid = cproc.pid",
1898 " end -- if cproc",
1899 " kernel.debug(\"[PID\"..cpid..\"] joining\")",
1900 " R.joined = R.joined + 1",
1901 " while R.procstate ~= \"finished\" do",
1902 " kernel.debug(\"[PID\"..cpid..\"] waiting for finished of \"..R.pid..\" (state=\"..R.procstate..\")\")",
1903 " local event = kernel.modules.instances.sandbox.evqueue.processEvt(cpid, cproc, {origyield()}, \"xwos_terminated\")",
1904 " if event ~= nil and event[2] ~= R.pid then",
1905 " for k, v in kernel.oldGlob.pairs(processes) do",
1906 " if kernel.oldGlob.type(v)==\"table\" and v.pid == event[2] and v.joined > 0 then",
1907 " kernel.debug(\"[PID\"..cpid..\"] redistributing to all other processes because at least one process called join of \"..R.pid)",
1908 " ",
1909 " for k2, v2 in kernel.oldGlob.pairs(kernel.processes) do",
1910 " if kernel.oldGlob.type(v2) == \"table\" and v2 ~= cproc and v2.procstate~= \"finished\" then",
1911 " kernel.debug(\"[PID\"..cpid..\"] redistributing because at least one process called join of \"..R.pid)",
1912 " originsert(v2.evqueue, event)",
1913 " v2.wakeup()",
1914 " end --",
1915 " end -- for processes",
1916 " end --",
1917 " end -- for processes",
1918 " end -- if pid",
1919 " end",
1920 " kernel.debug(\"[PID\"..cpid..\"] received finish notification or \"..R.pid)",
1921 " R.joined = R.joined - 1",
1922 " end -- function join",
1923 " ",
1924 " --------------------------------------",
1925 " -- release input (front process)",
1926 " -- @function [parent=#xwos.process] releaseInput",
1927 " R.releaseInput = function()",
1928 " kernel.modules.instances.sandbox.procinput.current.release(R)",
1929 " end -- function acquireInput",
1930 " ",
1931 " --------------------------------------",
1932 " -- wakeup process in reaction to events on local event queue",
1933 " -- @function [parent=#xwos.process] wakeup",
1934 " R.wakeup = function()",
1935 " if R.co ~= nil and R.procstate ~= \"finished\" then",
1936 " kernel.debug(\"[PID\"..R.pid..\"] wakeup requested\")",
1937 " kernel.oldGlob.coroutine.resume(R.co)",
1938 " end -- if proc",
1939 " end -- function wakeup",
1940 " ",
1941 " --------------------------------------",
1942 " -- request process to terminate",
1943 " -- @function [parent=#xwos.process] terminate",
1944 " R.terminate = function()",
1945 " kernel.oldGlob.os.queueEvent(\"xwos_terminate\", R.pid)",
1946 " end -- function wakeup",
1947 " ",
1948 " --------------------------------",
1949 " -- Remove the process from process table",
1950 " -- @function [parent=#xwos.process] remove",
1951 " R.remove = function()",
1952 " kernel.debug(\"[PID\"..R.pid..\"] removing from process table\")",
1953 " processes[R.pid] = nil",
1954 " end -- function remove",
1955 " ",
1956 " --------------------------------",
1957 " -- Spawn the process (invoke function)",
1958 " -- @function [parent=#xwos.process] spawn",
1959 " -- @param #function func the function to invoke",
1960 " -- @param ... the arguments for given function",
1961 " R.spawn = function(func, ...)",
1962 " local env0 = kernel.nenv",
1963 " kernel.debug(\"[PID\"..R.pid..\"] prepare spawn\")",
1964 " -- TODO ... may contain functions and objects with metatables; this may cause problems by mxing environments",
1965 " -- establish an alternative for IPC (inter process communication)",
1966 " local res = {origpcall(origser, {...})}-- this will cause an error if serializing forbidden types (functions etc.)",
1967 " if not res[1] then",
1968 " kernel.debug(\"[PID\"..R.pid..\"] ERR:\", res[2])",
1969 " kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
1970 " R.result = res",
1971 " R.procstate = \"finished\"",
1972 " kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
1973 " return",
1974 " end -- if not res",
1975 " ",
1976 " local spawn0 = function(...)",
1977 " kernel.debug(\"[PID\"..R.pid..\"] pocstate = running\")",
1978 " R.procstate = \"running\"",
1979 " kernel.debug(\"[PID\"..R.pid..\"] using env\", R.env, env0)",
1980 " origSetfenv(0, R.env)",
1981 " for k, v in origpairs(factories) do",
1982 " kernel.debug(\"[PID\"..R.pid..\"] invoke factory\", k, v)",
1983 " v(R, R.env)",
1984 " end -- for factories",
1985 " if origtype(func) == \"string\" then",
1986 " local func2 = function(...)",
1987 " kernel.debug(\"[PID\"..R.pid..\"] doFile\", func)",
1988 " local fnFile, e = origloadfile(func, kernel.nenv)",
1989 " if fnFile then",
1990 " return fnFile()",
1991 " else -- if res",
1992 " origerror( e, 2 )",
1993 " end -- if not res",
1994 " return origdofile(func, ...)",
1995 " end -- function func2",
1996 " origSetfenv(func2, kernel.nenv)",
1997 " --------------------------------",
1998 " -- @field [parent=#xwos.process] #table result the return state from process function",
1999 " R.result = {origpcall(func2, ...)}",
2000 " else -- if string",
2001 " kernel.debug(\"[PID\"..R.pid..\"] invoke function\", func)",
2002 " R.result = {origpcall(func, ...)}",
2003 " end -- if string",
2004 " kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
2005 " if not R.result[1] then",
2006 " kernel.debug(\"[PID\"..R.pid..\"] ERR:\", R.result[2])",
2007 " end -- if not res",
2008 " R.procstate = \"finished\"",
2009 " kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
2010 " end -- function spawn0",
2011 " R.env.getfenv = function(n)",
2012 " -- TODO: Hide kernel.nenv because one may decide to manipulate it to inject variables into other threads :-(",
2013 " local t = origtype(n)",
2014 " if t == \"number\" then",
2015 " if n == 0 then",
2016 " return kernel.nenv",
2017 " end -- if 0",
2018 " end -- if number",
2019 " return origGetfenv(n)",
2020 " end -- function get",
2021 " R.env.setfenv = function(n, v)",
2022 " -- TODO maybe we can compare current fenv with THIS nenv and nenv from kernel;",
2023 " -- if matches we deny changing the fenv",
2024 " -- if not matches we allow changing because it was loaded inside process",
2025 " ",
2026 " -- do not allow changing fenv at all",
2027 " -- simply return current one",
2028 " return R.env.getfenv(n, v)",
2029 " end -- function setfenv",
2030 " kernel.debug(\"[PID\"..R.pid..\"] prepare package\")",
2031 " R.env.package = {}",
2032 " -- taken from bios.lua; must be overriden because of env",
2033 " -- TODO maybe we find a better solution than copying all the stuff",
2034 " R.env.package.loaded = {",
2035 " -- _G = _G,",
2036 " bit32 = bit32,",
2037 " coroutine = coroutine, -- TODO wrap",
2038 " math = math,",
2039 " package = R.env.package,",
2040 " string = string,",
2041 " table = table,",
2042 " }",
2043 " -- TODO paths",
2044 " R.env.package.path = \"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\"",
2045 " if turtle then",
2046 " R.env.package.path = R.env.package.path..\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\"",
2047 " elseif command then",
2048 " R.env.package.path = R.env.package.path..\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\"",
2049 " end",
2050 " R.env.package.config = \"/\\n;\\n?\\n!\\n-\"",
2051 " R.env.package.preload = {}",
2052 " local loader1 = function( name )",
2053 " if package.preload[name] then",
2054 " return package.preload[name]",
2055 " else",
2056 " return nil, \"no field package.preload['\" .. name .. \"']\"",
2057 " end",
2058 " end -- function loader1",
2059 " local loader2 = function( name )",
2060 " local fname = string.gsub(name, \"%.\", \"/\")",
2061 " local sError = \"\"",
2062 " for pattern in string.gmatch(package.path, \"[^;]+\") do",
2063 " local sPath = string.gsub(pattern, \"%?\", fname)",
2064 " if sPath:sub(1,1) ~= \"/\" then",
2065 " sPath = fs.combine(sDir, sPath)",
2066 " end",
2067 " if fs.exists(sPath) and not fs.isDir(sPath) then",
2068 " local fnFile, sError = loadfile( sPath, nenv ) -- inject our new env",
2069 " if fnFile then",
2070 " return fnFile, sPath",
2071 " else",
2072 " return nil, sError",
2073 " end",
2074 " else",
2075 " if #sError > 0 then",
2076 " sError = sError .. \"\\n\"",
2077 " end",
2078 " sError = sError .. \"no file '\" .. sPath .. \"'\"",
2079 " end",
2080 " end",
2081 " return nil, sError",
2082 " end -- function loader2",
2083 " R.env.package.loaders = {",
2084 " loader1,",
2085 " loader2",
2086 " }",
2087 " ",
2088 " local sentinel = {}",
2089 " R.env.require = function( name )",
2090 " if type( name ) ~= \"string\" then",
2091 " error( \"bad argument #1 (expected string, got \" .. type( name ) .. \")\", 2 )",
2092 " end",
2093 " if package.loaded[name] == sentinel then",
2094 " error(\"Loop detected requiring '\" .. name .. \"'\", 0)",
2095 " end",
2096 " if package.loaded[name] then",
2097 " return package.loaded[name]",
2098 " end",
2099 " ",
2100 " local sError = \"Error loading module '\" .. name .. \"':\"",
2101 " for n,searcher in ipairs(package.loaders) do",
2102 " local loader, err = searcher(name)",
2103 " if loader then",
2104 " package.loaded[name] = sentinel",
2105 " local result = loader( err )",
2106 " if result ~= nil then",
2107 " package.loaded[name] = result",
2108 " return result",
2109 " else",
2110 " package.loaded[name] = true",
2111 " return true",
2112 " end",
2113 " else",
2114 " sError = sError .. \"\\n\" .. err",
2115 " end",
2116 " end",
2117 " error(sError, 2)",
2118 " end -- function require",
2119 " ",
2120 " kernel.debug(\"[PID\"..R.pid..\"] setting new env\", env0)",
2121 " origSetfenv(spawn0, env0)",
2122 " origSetfenv(loader1, env0)",
2123 " origSetfenv(loader2, env0)",
2124 " origSetfenv(R.env.require, env0)",
2125 " origSetfenv(R.env.getfenv, env0)",
2126 " origSetfenv(R.env.setfenv, env0)",
2127 " --------------------------------",
2128 " -- @field [parent=#xwos.process] coroutine#coroutine co the coroutine",
2129 " R.co = cocreate(spawn0)",
2130 " local res = {coresume(R.co, ...)}",
2131 " if not res[1] then",
2132 " kernel.debug(\"[PID\"..R.pid..\"] ERR:\", res[2])",
2133 " kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
2134 " R.result = res",
2135 " R.procstate = \"finished\"",
2136 " kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
2137 " end -- if not res",
2138 " end -- function spawn",
2139 " ",
2140 " processes[R.pid] = R",
2141 " kernel.debug(\"[PID\"..R.pid..\"] returning new process\")",
2142 " return R",
2143 "end -- function new",
2144 "",
2145 "return processes",
2146 },
2147}