diff --git a/clite/core.js b/clite/core.js index d2a0c5c..ee2e26a 100644 --- a/clite/core.js +++ b/clite/core.js @@ -600,7 +600,7 @@ clite.proc = { return; data.groups.push({gpid:cpid,waitAny:[],waitAll:[]}); } - function exitGroup(cpid,pid) { + function exitGroup(cpid,pid,ev) { var group = getGroup(cpid); if (!group) return false; @@ -617,7 +617,7 @@ clite.proc = { if (c > 0) return true; group.waitAll.forEach(function(w) { - w(pid); + w(pid,ev); }); group.waitAll = []; return true; @@ -658,7 +658,7 @@ clite.proc = { n.data.content += 'command: '+cl+'\n'; return true; } - clite.proc.exit = function(pid) { + clite.proc.exit = function(pid,ev) { var i = getProcIndex(pid); if (i<0) return false; @@ -668,9 +668,9 @@ clite.proc = { data.procs.splice(i,1); vfsapi.remove(0,'/proc/'+pid); proc.waits.forEach(function(w) { - clite.core.execSafeAsync(function() {w(pid)}); + clite.core.execSafeAsync(function() {w(pid,ev)}); }); - exitGroup(proc.gpid,pid); + exitGroup(proc.gpid,pid,ev); // special case, reboot if pid 1 exits if (pid == 1) { clite.core.execSafeAsync(function() { @@ -2727,7 +2727,6 @@ clite.lib = { fd = clite.io.open(io.pid,e,clite.io.flags.O_RDONLY|clite.io.flags.O_EXEC|clite.io.flags.O_SYNC); if (!fd) return -6; - args = [args[0],path]; ft = clite.lib.getFileType(fd); } if (ft != clite.io.types.FT_BINARY) { @@ -2751,7 +2750,7 @@ clite.lib = { }, exit:function(pid,v) { if (pid > -1) - clite.proc.exit(pid); + clite.proc.exit(pid,v); } } diff --git a/clite/shell.js b/clite/shell.js index dab688c..157ad58 100644 --- a/clite/shell.js +++ b/clite/shell.js @@ -10,6 +10,7 @@ clite.commands.load('sh',function(args,env,io) { var macro = { clear:function(args,io) { term.clear(); + return 0; }, cd:function(args,io) { var dir = env.HOME; @@ -18,60 +19,68 @@ clite.commands.load('sh',function(args,env,io) { var fd = stdio.open(dir,stdio.flags.O_SEARCH|stdio.flags.O_DIRECTORY); if (!fd) { stdio.fprintf(io.stderr,'invalid directory: %s\n',dir); - return; + return 1; } stdio.close(fd); env.PWD = dir; + return 0; }, pwd:function(args,io) { stdio.fprintf(io.stdout,'%s\n',env.PWD); + return 0; }, echo:function(args,io) { args.shift(); var txt = args.join(' ')+'\n'; stdio.write(io.stdout,txt); + return 0; }, which:function(args,io) { if (args.length <2) - return; + return 1; if (typeof macro[args[1]] != 'undefined') { - return; + return 1; }else{ var path = resolvePATH(args[1]); if (!path) - return; + return 1; stdio.fprintf(io.stdout,'%s is %s\n',args[1],path); } + return 0; }, type:function(args,io) { if (args.length <2) - return; + return 1; if (typeof macro[args[1]] != 'undefined') { stdio.fprintf(io.stdout,'%s is a shell builtin\n',args[1]); }else{ var path = resolvePATH(args[1]); if (!path) - return; + return 1; stdio.fprintf(io.stdout,'%s is %s\n',args[1],path); } + return 0; }, whoami:function(args,io) { stdio.fprintf(io.stdout,'%s\n',env.USER); + return 0; }, alias:function(args,io) { stdio.fprintf(io.stdout,'unimplemented\n'); + return 0; }, export:function(args,io) { if (args.length == 1) { Object.keys(env).forEach(function(key) { stdio.fprintf(io.stdout,'%s=%s\n',key,env[key]); }); - return; + return 0; } var parts = args[1].split('='); if (parts.length != 2) - return; + return 0; env[parts[0]] = parts[1]; + return 0; }, exit:function(args,io) { has_exited = true; @@ -79,6 +88,7 @@ clite.commands.load('sh',function(args,env,io) { if (args.length > 1) ev = parseInt(args[1]); io.exit(ev); + return 0; } }; @@ -150,7 +160,8 @@ clite.commands.load('sh',function(args,env,io) { }, prepFile:function(fd) { var data = stdio.readAll(fd); - stdio.close(fd); + if (fd != io.stdin) + stdio.close(fd); if (!data) { parser.run(); return; @@ -195,6 +206,12 @@ clite.commands.load('sh',function(args,env,io) { return; } parser.internal.parseFile(f); + }, + stdin:function() { + parser.callback = function() { + io.exit(0); + } + parser.internal.prepFile(io.stdin); } }; @@ -346,6 +363,7 @@ Options: if (typeof macro[args[0]] != 'undefined') { fio.exit = io.exit; var r = macro[args[0]](args,fio); + env['?'] = r.toString(); if (typeof cb === 'function') cb(); return; @@ -354,15 +372,19 @@ Options: var path = resolvePATH(args[0]); if (!path) { stdio.fprintf(io.stderr,'Shell: unknown command: %s\n',args[0]); + env['?'] = '1'; if (typeof cb === 'function') cb(); return; } + var shenv = env; + function execFunc(env,io) { var r = stdlib.exec(path,args,env,io); if (r > 0) return; + shenv['?'] = '1'; if (r == -1) { stdlib.fprintf(io.stderr,'Shell: unknown command: %s\n',args[0]); @@ -402,13 +424,17 @@ Options: var pid = stdlib.fork(env,fio,execFunc); if (pid == 0) { stdio.write(io.stderr,'Shell: internal error\n'); + env['?'] = '1'; if (typeof cb === 'function') cb(); return; } if (typeof cb === 'function') - stdlib.waitpid(pid,cb); + stdlib.waitpid(pid,function(pid,ev) { + env['?'] = ev.toString(); + cb(); + }); } function writePrompt() { @@ -524,6 +550,18 @@ Options: } } + // TODO: hacks r uglee + if (!f && args[0] != '/bin/sh' && args[0] != 'sh') { + f = clite.resolvePath(args[0]); + if (!f) + return 1; + // make the arguments readable by the shell script + env['#'] = args.length.toString(); + for (var i=0; i