mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
wait, waitpid, waitall, and get the shell using them
This commit is contained in:
parent
7ac6f677be
commit
39ebcdc049
3 changed files with 134 additions and 16 deletions
|
|
@ -173,7 +173,7 @@ Options:
|
|||
// check if we're on a webserver
|
||||
if (!remote) {
|
||||
var u = stdlib.uname();
|
||||
if (u && u.hostname != 'localhost')
|
||||
if (u && u.nodename != 'localhost')
|
||||
remote = true;
|
||||
}
|
||||
|
||||
|
|
@ -230,8 +230,10 @@ Options:
|
|||
pending--;
|
||||
return;
|
||||
}
|
||||
if (!remote && st.type == stdio.types.FT_REMOTE)
|
||||
if (!remote && st.type == stdio.types.FT_REMOTE) {
|
||||
pending--;
|
||||
return;
|
||||
}
|
||||
var fd = stdio.open(file,fcb);
|
||||
if (!fd) {
|
||||
stdio.write(io.stderr,'cannot open file: '+file);
|
||||
|
|
|
|||
139
clite/core.js
139
clite/core.js
|
|
@ -8,7 +8,7 @@ var clite = {
|
|||
try{
|
||||
f();
|
||||
} catch(e) {
|
||||
clite.log.write(e.message);
|
||||
clite.log.write(e.message+':'+e.lineNumber);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -17,7 +17,7 @@ var clite = {
|
|||
try{
|
||||
setTimeout(f,10);
|
||||
} catch(e) {
|
||||
clite.log.write(e.message);
|
||||
clite.log.write(e.message+':'+e.lineNumber);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -409,6 +409,7 @@ readme.txt:/usr/clite/readme:0:0:-rw-r--r--`;
|
|||
// should really have init/getty exec the shell with the env data etc
|
||||
var env = clite.user.getEnv();
|
||||
var io = {
|
||||
pid:0,
|
||||
stdin:clite.io.open('/dev/tty',false),
|
||||
stdout:clite.io.open('/dev/tty',false),
|
||||
stderr:clite.io.open('/dev/tty',false),
|
||||
|
|
@ -433,7 +434,8 @@ clite.proc = {
|
|||
var vfsapi = vfs;
|
||||
var data = {
|
||||
nextid:1,
|
||||
procs:[]
|
||||
procs:[],
|
||||
groups:[]
|
||||
};
|
||||
|
||||
function getProc(pid) {
|
||||
|
|
@ -458,13 +460,58 @@ clite.proc = {
|
|||
});
|
||||
return index;
|
||||
}
|
||||
function mapCPID(cpid) {
|
||||
//clite.log.write('mapCPID('+cpid+') -> '+data.groups.length);
|
||||
if (data.groups.length < 1) {
|
||||
addGroup(1);
|
||||
return 1;
|
||||
}
|
||||
var parent = getProc(cpid);
|
||||
if (parent && parent.gpid != cpid)
|
||||
return parent.gpid;
|
||||
return cpid;
|
||||
}
|
||||
function getGroup(cpid) {
|
||||
for (var i=0; i<data.groups.length; i++) {
|
||||
if (data.groups[i].gpid == cpid)
|
||||
return data.groups[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function addGroup(cpid) {
|
||||
if (getGroup(cpid))
|
||||
return;
|
||||
data.groups.push({gpid:cpid,waitAny:[],waitAll:[]});
|
||||
}
|
||||
function exitGroup(cpid,pid) {
|
||||
var group = getGroup(cpid);
|
||||
if (!group)
|
||||
return false;
|
||||
group.waitAny.forEach(function(w) {
|
||||
w(pid);
|
||||
});
|
||||
var c = 0;
|
||||
data.procs.forEach(function(p) {
|
||||
// we want a count of child processes, so ignore the controlling process
|
||||
if (p.gpid == cpid && p.pid != cpid)
|
||||
c++;
|
||||
});
|
||||
if (c > 0)
|
||||
return true;
|
||||
group.waitAll.forEach(function(w) {
|
||||
w(pid);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
clite.proc.add = function(fn) {
|
||||
clite.proc.add = function(cpid,fn) {
|
||||
if (typeof fn !== 'function')
|
||||
return 0;
|
||||
var proc = Object.create({
|
||||
gpid:mapCPID(cpid),
|
||||
pid:data.nextid++,
|
||||
func:fn
|
||||
func:fn,
|
||||
waits:[]
|
||||
});
|
||||
data.procs.push(proc);
|
||||
vfsapi.mkFile('/proc/'+proc.pid);
|
||||
|
|
@ -492,11 +539,56 @@ clite.proc = {
|
|||
return false;
|
||||
data.procs.splice(i,1);
|
||||
vfsapi.remove('/proc/'+pid);
|
||||
proc.waits.forEach(function(w) {
|
||||
clite.core.execSafeAsync(function() {w(pid)});
|
||||
});
|
||||
exitGroup(proc.gpid,pid);
|
||||
return true;
|
||||
}
|
||||
clite.proc.count = function() {
|
||||
return data.procs.length;
|
||||
}
|
||||
clite.proc.addWait = function(pid,w) {
|
||||
var proc = getProc(pid);
|
||||
if (!proc) {
|
||||
clite.core.execSafeAsync(function() {w(pid)});
|
||||
return false;
|
||||
}
|
||||
proc.waits.push(w);
|
||||
return true;
|
||||
}
|
||||
clite.proc.addWaitGroupAny = function(pid,w) {
|
||||
var cpid = mapCPID(pid);
|
||||
var group = getGroup(cpid);
|
||||
if (!group) {
|
||||
clite.core.execSafeAsync(function() {w(pid)});
|
||||
return true;
|
||||
}
|
||||
group.waitAny.push(w);
|
||||
return true;
|
||||
}
|
||||
clite.proc.addWaitGroupAll = function(pid,w) {
|
||||
var cpid = mapCPID(pid);
|
||||
var group = getGroup(cpid);
|
||||
if (!group) {
|
||||
clite.core.execSafeAsync(function() {w(pid)});
|
||||
return false;
|
||||
}
|
||||
group.waitAll.push(w);
|
||||
return true;
|
||||
}
|
||||
clite.proc.addGroup = function(pid) {
|
||||
var proc = getProc(pid);
|
||||
if (!proc)
|
||||
return false;
|
||||
if (proc.gpid == pid)
|
||||
return true;
|
||||
proc.gpid = pid;
|
||||
if (getGroup(pid))
|
||||
return true;
|
||||
addGroup(pid);
|
||||
return true;
|
||||
}
|
||||
clite.proc.init = null;
|
||||
return true;
|
||||
},
|
||||
|
|
@ -1273,12 +1365,6 @@ clite.term = {
|
|||
return;
|
||||
f.parentNode.removeChild(f);
|
||||
},
|
||||
hasInput:function() {
|
||||
var f = document.getElementById('form');
|
||||
if (!f)
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
writeLine:function(txt) {
|
||||
var a = document.createElement('article');
|
||||
a.innerHTML = clite.lib.htmlEncode(txt);
|
||||
|
|
@ -1286,6 +1372,8 @@ clite.term = {
|
|||
if (!t)
|
||||
return;
|
||||
t.appendChild(a);
|
||||
if (document.getElementById('form'))
|
||||
clite.term.genForm();
|
||||
t.scrollTop = t.scrollHeight;
|
||||
},
|
||||
genForm:function() {
|
||||
|
|
@ -1640,10 +1728,11 @@ clite.lib = {
|
|||
return o;
|
||||
},
|
||||
fork:function(env,io,call) {
|
||||
var pid = clite.proc.add(call);
|
||||
var pid = clite.proc.add(io.pid,call);
|
||||
if (!pid)
|
||||
return 0;
|
||||
var nio = Object.create(io);
|
||||
nio.pid = pid;
|
||||
nio.exit = function(v) {
|
||||
clite.lib.exit(pid,v);
|
||||
try{
|
||||
|
|
@ -1653,7 +1742,17 @@ clite.lib = {
|
|||
nio.include = function(name) {
|
||||
switch (name) {
|
||||
case 'stdlib':
|
||||
return Object.create(clite.lib.api);
|
||||
var stdlib = Object.create(clite.lib.api);
|
||||
stdlib.wait = function(cb) {
|
||||
return clite.lib.wait(nio.pid,cb);
|
||||
}
|
||||
stdlib.waitpid = function(pid,cb) {
|
||||
return clite.lib.waitpid(nio.pid,pid,cb);
|
||||
}
|
||||
stdlib.waitall = function(cb) {
|
||||
return clite.lib.waitall(nio.pid,cb);
|
||||
}
|
||||
return stdlib;
|
||||
break;
|
||||
case 'stdio':
|
||||
var stdio = Object.create(clite.io);
|
||||
|
|
@ -1707,6 +1806,20 @@ clite.lib = {
|
|||
},
|
||||
getgid:function() {
|
||||
return clite.user.getGID();
|
||||
},
|
||||
// wait for any child process to exit
|
||||
wait:function(cpid,cb) {
|
||||
return clite.proc.addWaitGroupAny(cpid,cb);
|
||||
},
|
||||
// wait for the process 'pid' to exit
|
||||
waitpid:function(cpid,pid,cb) {
|
||||
if (pid < 0)
|
||||
return clite.lib.wait(cpid,cb);
|
||||
return clite.proc.addWait(pid,cb);
|
||||
},
|
||||
// wait for all child processes to exit
|
||||
waitall:function(cpid,cb) {
|
||||
return clite.proc.addWaitGroupAll(cpid,cb);
|
||||
}
|
||||
}
|
||||
clite.lib.api = { // this is passed to programs via include('stdlib')
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ clite.commands.load('sh',function(args,env,io) {
|
|||
// prepare io (stdin,stdout,stderr)
|
||||
// TODO: check for io redirects and piping, then setup stdio accordingly
|
||||
var fio = {
|
||||
pid:io.pid,
|
||||
stdin:io.stdin,
|
||||
stdout:io.stdout,
|
||||
stderr:io.stderr,
|
||||
|
|
@ -303,7 +304,9 @@ clite.commands.load('sh',function(args,env,io) {
|
|||
}
|
||||
}
|
||||
|
||||
inputRead();
|
||||
// TODO: something something waitall()
|
||||
stdlib.waitall(inputRead);
|
||||
//inputRead();
|
||||
|
||||
return null;
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue