summaryrefslogtreecommitdiffstats
path: root/shell/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'shell/src/lib.rs')
-rw-r--r--shell/src/lib.rs46
1 files changed, 45 insertions, 1 deletions
diff --git a/shell/src/lib.rs b/shell/src/lib.rs
index 6de056c..e500337 100644
--- a/shell/src/lib.rs
+++ b/shell/src/lib.rs
@@ -1253,9 +1253,53 @@ fn build_exports() -> rsapi::Exports {
1253/// Run `cmd` as an external PE32+ binary from /bin/cli/. Returns false 1253/// Run `cmd` as an external PE32+ binary from /bin/cli/. Returns false
1254/// when no external binary resolved (the caller falls back to built-ins). 1254/// when no external binary resolved (the caller falls back to built-ins).
1255fn exec_external(p: &Parsed) -> bool { 1255fn exec_external(p: &Parsed) -> bool {
1256 let Some(h) = rsnix::exec::resolve("cli", &p.cmd) else { 1256 // Try CLI first (blocking), then GUI (fire-and-forget).
1257 let cli_h = rsnix::exec::resolve("cli", &p.cmd);
1258 let gui_h = if cli_h.is_none() { rsnix::exec::resolve("gui", &p.cmd) } else { None };
1259
1260 if let Some(h) = cli_h {
1261 exec_cli(p, h)
1262 } else if let Some(h) = gui_h {
1263 exec_gui(p, h)
1264 } else {
1257 return false; 1265 return false;
1266 }
1267}
1268
1269fn exec_gui(p: &Parsed, h: usize) -> bool {
1270 // Fire-and-forget: spawn the GUI binary, return immediately.
1271 let bytes = match rsnix::exec::read_file(h) {
1272 Ok(b) => b,
1273 Err(_) => {
1274 term_err(&alloc::format!("{}: read failed", p.cmd));
1275 return true;
1276 }
1277 };
1278 let image = match rsnix::load::load_image(&bytes) {
1279 Ok(img) => img,
1280 Err(e) => {
1281 term_err(&alloc::format!("{}: cannot load ({:?})", p.cmd, e));
1282 return true;
1283 }
1258 }; 1284 };
1285 let mut argv: Vec<String> = Vec::with_capacity(p.args.len() + 1);
1286 argv.push(p.cmd.clone());
1287 argv.extend(p.args.iter().cloned());
1288 let name = alloc::format!("{}", p.cmd);
1289 let exports = Box::leak(Box::new(build_exports()));
1290 match rsnix::exec::spawn(image, exports, &argv, &name) {
1291 Ok(_id) => {
1292 // Fire-and-forget: do NOT wait for completion.
1293 // The binary runs its own event loop; when it exits,
1294 // the task is cleaned up by the scheduler.
1295 term_println(&alloc::format!("{}: started", p.cmd));
1296 }
1297 Err(_) => term_err(&alloc::format!("{}: cannot start", p.cmd)),
1298 }
1299 true
1300}
1301
1302fn exec_cli(p: &Parsed, h: usize) -> bool {
1259 let bytes = match rsnix::exec::read_file(h) { 1303 let bytes = match rsnix::exec::read_file(h) {
1260 Ok(b) => b, 1304 Ok(b) => b,
1261 Err(_) => { 1305 Err(_) => {