diff --git a/clite/core.js b/clite/core.js index f74cd5e..53b16e1 100644 --- a/clite/core.js +++ b/clite/core.js @@ -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 `; } diff --git a/clite/libstdio.js b/clite/libstdio.js index 85e5cff..d131975 100644 --- a/clite/libstdio.js +++ b/clite/libstdio.js @@ -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); diff --git a/clite/shell.js b/clite/shell.js index 3cf5f24..4cda1ed 100644 --- a/clite/shell.js +++ b/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(); });