mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
improved shell script parser
This commit is contained in:
parent
409470d0bc
commit
376d425330
3 changed files with 94 additions and 40 deletions
|
|
@ -326,8 +326,7 @@ guest:x:1:
|
|||
clite.log.write('shell config failure');
|
||||
return false;
|
||||
}
|
||||
n.data.content =`
|
||||
#!/bin/sh
|
||||
n.data.content =`#!/bin/sh
|
||||
cat /etc/greeting
|
||||
`;
|
||||
n.perms = '-rwxr-xr-x';
|
||||
|
|
@ -924,8 +923,7 @@ clite.user = {
|
|||
n.perms = '-rwx------';
|
||||
n.uid = 1;
|
||||
n.gid = 1;
|
||||
n.data.content = `
|
||||
#!/bin/sh
|
||||
n.data.content = `#!/bin/sh
|
||||
cat -l /usr/share/introduction
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ return Object.create({
|
|||
},
|
||||
|
||||
stat:function(path) {
|
||||
var fd = clite.io.open(io.pid,path,clite.io.flags.O_RDONLY);
|
||||
var fd = clite.io.open(io.pid,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NONBLOCK);
|
||||
if (!fd)
|
||||
return null;
|
||||
var st = clite.io.fstatat(io.pid,fd,0);
|
||||
|
|
@ -69,7 +69,7 @@ return Object.create({
|
|||
},
|
||||
|
||||
lstat:function(path) {
|
||||
var fd = clite.io.open(io.pid,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NOFOLLOW);
|
||||
var fd = clite.io.open(io.pid,path,clite.io.flags.O_RDONLY|clite.io.flags.O_NOFOLLOW|clite.io.flags.O_NONBLOCK);
|
||||
if (!fd)
|
||||
return null;
|
||||
var st = clite.io.fstatat(io.pid,fd,clite.io.flags.AT_SYMLINK_NOFOLLOW);
|
||||
|
|
|
|||
124
clite/shell.js
124
clite/shell.js
|
|
@ -123,7 +123,80 @@ clite.commands.load('sh',function(args,env,io) {
|
|||
history.current = '';
|
||||
history.index = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var parser = {
|
||||
files:[],
|
||||
callback:null,
|
||||
queue:function(file) {
|
||||
parser.files.push(file);
|
||||
},
|
||||
internal:{
|
||||
lines:[],
|
||||
parseFile:function(f) {
|
||||
var fn = clite.resolvePath(f);
|
||||
if (fn == null) {
|
||||
parser.run();
|
||||
return;
|
||||
}
|
||||
var st = stdio.stat(fn);
|
||||
if (st == null || st.type != stdio.types.FT_SCRIPT) {
|
||||
parser.run();
|
||||
return;
|
||||
}
|
||||
var fd = stdio.open(fn,stdio.flags.O_RDONLY,parser.internal.prepFile);
|
||||
if (!fd)
|
||||
parser.run();
|
||||
},
|
||||
prepFile:function(fd) {
|
||||
var data = stdio.readAll(fd);
|
||||
stdio.close(fd);
|
||||
if (!data) {
|
||||
parser.run();
|
||||
return;
|
||||
}
|
||||
parser.internal.lines = data.split('\n');
|
||||
if (parser.internal.lines.length < 1) {
|
||||
parser.run();
|
||||
return;
|
||||
}
|
||||
parser.internal.parseLine();
|
||||
},
|
||||
parseLine:function() {
|
||||
var l = parser.internal.lines.shift();
|
||||
if (l == null) {
|
||||
parser.run();
|
||||
return;
|
||||
}
|
||||
if (l[0] == '#') {
|
||||
parser.internal.parseLine();
|
||||
return;
|
||||
}
|
||||
run(l,parser.internal.parseLine);
|
||||
}
|
||||
},
|
||||
exit:function() {
|
||||
if (typeof parser.callback === 'function') {
|
||||
try{
|
||||
parser.callback();
|
||||
} catch(err) {
|
||||
stdio.write(io.stderr,'Shell: internal error in parser\n');
|
||||
io.exit(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
run:function(cb) {
|
||||
if (typeof cb === 'function')
|
||||
parser.callback = cb;
|
||||
var f = parser.files.shift();
|
||||
if (!f) {
|
||||
parser.exit();
|
||||
return;
|
||||
}
|
||||
parser.internal.parseFile(f);
|
||||
}
|
||||
};
|
||||
|
||||
function help() {
|
||||
stdio.write(io.stdout,`
|
||||
|
|
@ -245,19 +318,10 @@ Options:
|
|||
return c+add;
|
||||
}
|
||||
|
||||
function parseScript(fd) {
|
||||
var l;
|
||||
while ((l = stdio.readLine(fd)) != null) {
|
||||
if (l[0] == '#')
|
||||
continue;
|
||||
run(l,false);
|
||||
}
|
||||
}
|
||||
|
||||
function run(txt,interactive) {
|
||||
function run(txt,cb) {
|
||||
if (txt.length < 1) {
|
||||
if (interactive)
|
||||
inputRead();
|
||||
if (typeof cb === 'function')
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
history.add(txt);
|
||||
|
|
@ -282,16 +346,16 @@ Options:
|
|||
if (typeof macro[args[0]] != 'undefined') {
|
||||
fio.exit = io.exit;
|
||||
var r = macro[args[0]](args,fio);
|
||||
if (interactive)
|
||||
inputRead();
|
||||
if (typeof cb === 'function')
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
var path = resolvePATH(args[0]);
|
||||
if (!path) {
|
||||
stdio.fprintf(io.stderr,'Shell: unknown command: %s\n',args[0]);
|
||||
if (interactive)
|
||||
inputRead();
|
||||
if (typeof cb === 'function')
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -318,13 +382,13 @@ Options:
|
|||
var pid = stdlib.fork(env,fio,execFunc);
|
||||
if (pid == 0) {
|
||||
stdio.write(io.stderr,'Shell: internal error\n');
|
||||
if (interactive)
|
||||
inputRead();
|
||||
if (typeof cb === 'function')
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
// TODO: if we're not interactive, we still want to waitpid
|
||||
if (interactive)
|
||||
stdlib.waitpid(pid,inputRead);
|
||||
|
||||
if (typeof cb === 'function')
|
||||
stdlib.waitpid(pid,cb);
|
||||
}
|
||||
|
||||
function writePrompt() {
|
||||
|
|
@ -362,7 +426,7 @@ Options:
|
|||
break;
|
||||
case '\n': // enter
|
||||
term.ttyctrl('raw',false);
|
||||
run(c,true);
|
||||
run(c,inputRead);
|
||||
c = '';
|
||||
cc = 0;
|
||||
return;
|
||||
|
|
@ -463,17 +527,9 @@ Options:
|
|||
// otherwise we have an interactive shell
|
||||
// so run /etc/shrc and ~/.shrc
|
||||
}else{
|
||||
var fd = stdio.open('/etc/shrc',stdio.flags.O_RDONLY|stdio.flags.O_SYNC);
|
||||
if (fd) {
|
||||
parseScript(fd);
|
||||
stdio.close(fd);
|
||||
}
|
||||
fd = stdio.open(env.HOME+'/.shrc',stdio.flags.O_RDONLY|stdio.flags.O_SYNC);
|
||||
if (fd) {
|
||||
parseScript(fd);
|
||||
stdio.close(fd);
|
||||
}
|
||||
stdlib.waitall(function() {
|
||||
parser.queue('/etc/shrc');
|
||||
parser.queue(env.HOME+'/.shrc');
|
||||
parser.run(function() {
|
||||
history.clear();
|
||||
inputRead();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue