env.ha (1531B)
1 use errors; 2 use fmt; 3 use getopt; 4 use main; 5 use os::exec; 6 use os; 7 use strings; 8 9 export fn utilmain() (main::error | void) = { 10 const help: []getopt::help = [ 11 "set the environment for command invocation", 12 ('i', "ignore the parent environment"), 13 "[command [arguments...]]", 14 ]; 15 const cmd = getopt::parse(os::args, help...); 16 defer getopt::finish(&cmd); 17 18 let clear = false; 19 for (let i = 0z; i < len(cmd.opts); i += 1) { 20 switch (cmd.opts[i].0) { 21 case 'i' => 22 clear = true; 23 case => void; 24 }; 25 }; 26 27 let environ: []str = cmd.args, args: []str = []; 28 for (let i = 0z; i < len(cmd.args); i += 1) { 29 if (!strings::contains(cmd.args[i], '=')) { 30 environ = cmd.args[..i]; 31 args = cmd.args[i..]; 32 break; 33 }; 34 }; 35 36 if (len(args) == 0) { 37 return printenv(environ, clear); 38 }; 39 40 let cmd = match (exec::cmd(args[0], args[1..]...)) { 41 case let cmd: exec::command => 42 yield cmd; 43 case exec::nocmd => 44 fmt::errorfln("{}: command not found", args[0])!; 45 os::exit(127); 46 case let err: exec::error => 47 return err; 48 }; 49 if (clear) { 50 exec::clearenv(&cmd); 51 }; 52 for (let i = 0z; i < len(environ); i += 1) { 53 let env = strings::cut(environ[i], "="); 54 match (exec::setenv(&cmd, env.0, env.1)) { 55 case errors::invalid => 56 fmt::fatalf("Error: Invalid key '{}'", env.0); 57 case void => void; 58 }; 59 }; 60 exec::exec(&cmd); 61 }; 62 63 fn printenv(environ: []str, clear: bool) (void | main::error) = { 64 if (!clear) { 65 printenv(os::getenvs(), true)?; 66 }; 67 for (let i = 0z; i < len(environ); i += 1) { 68 fmt::println(environ[i])?; 69 }; 70 };