From b070abf90d48e019a27a6d65aa37ef6f0971b40e Mon Sep 17 00:00:00 2001 From: Lisa Milne Date: Mon, 27 Nov 2023 21:46:33 +1000 Subject: [PATCH] make the shell exit properly, and also handle children exiting properly --- clite/core.js | 13 ++++++++++++- clite/shell.js | 26 +++++++++++++++----------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/clite/core.js b/clite/core.js index 2da0da1..bfc4168 100644 --- a/clite/core.js +++ b/clite/core.js @@ -463,7 +463,7 @@ readme.txt:/usr/clite/readme:0:0:-rw-r--r--`; exit:null, // filled in by fork() include:null, // filled in by fork() }; - clite.lib.fork(env,io,init9); + var pid = clite.lib.fork(env,io,init9); } } function init9(env,io) { @@ -592,6 +592,17 @@ clite.proc = { clite.core.execSafeAsync(function() {w(pid)}); }); exitGroup(proc.gpid,pid); + if (pid == 1) { + clite.core.execSafeAsync(function() { + var fd = clite.io.open('/dev/initctl',false); + if (!fd) { + clite.core.reboot(); + return; + } + clite.io.write(fd,6); + clite.io.close(fd); + }); + } return true; } clite.proc.count = function() { diff --git a/clite/shell.js b/clite/shell.js index 5ffd373..49fa899 100644 --- a/clite/shell.js +++ b/clite/shell.js @@ -6,8 +6,8 @@ clite.commands.load('sh',function(args,env,io) { var stdlib = io.include('stdlib'); var term = io.include('term'); var clite = io.include('clite'); - var active_pid = 0; var prompt = '$ '; + var has_exited = false; var macro = { clear:function(args,io) { term.clear(); @@ -78,6 +78,13 @@ clite.commands.load('sh',function(args,env,io) { if (parts.length != 2) return; env[parts[0]] = parts[1]; + }, + exit:function(args,io) { + has_exited = true; + var ev = 0; + if (args.length > 1) + ev = parseInt(args[1]); + io.exit(ev); } }; @@ -124,12 +131,6 @@ clite.commands.load('sh',function(args,env,io) { } } - function active_exit(pid,v) { - if (pid != active_pid) - return; - inputRead(); - } - function resolvePATH(txt) { if (typeof env.PATH === 'undefined') env.PATH = '/bin'; @@ -275,12 +276,13 @@ clite.commands.load('sh',function(args,env,io) { stdin:io.stdin, stdout:io.stdout, stderr:io.stderr, - exit:active_exit, // filled in by fork() + exit:null, // filled in by fork() include:null, // filled in by fork() }; // check for a macro // then either run the macro or expand the program to be executed via PATH if (typeof macro[args[0]] != 'undefined') { + fio.exit = io.exit; var r = macro[args[0]](args,fio); if (interactive) inputRead(); @@ -315,12 +317,13 @@ clite.commands.load('sh',function(args,env,io) { io.exit(-3); } } - active_pid = stdlib.fork(env,fio,execFunc); - if (active_pid == 0) { + var pid = stdlib.fork(env,fio,execFunc); + if (pid == 0) { stdio.write(io.stderr,'Shell: internal error'); if (interactive) inputRead(); } + stdlib.waitpid(pid,inputRead); } function inputControl(key) { @@ -346,10 +349,11 @@ clite.commands.load('sh',function(args,env,io) { return; } - active_pid = 0; run(str,true); } function inputRead() { + if (has_exited) + return; // generate the prompt var p = env.PS1; if (typeof p === 'undefined')