public void RegisterBuiltIn(string name, ClrFunction clrFunction) { if (BuiltIns.ContainsKey(name)) { throw new InvalidOperationException($"Built-in function '{name}' has already been registered."); } BuiltIns.Add(name, clrFunction); }
public async Task <bool> HandleCommand(string input, CancellationToken token) { try { var tokens = Tokenize(input); var command = tokens[0]; var argList = tokens.Skip(1).ToList(); var waitForProcess = true; var lastArg = argList.LastOrDefault(); if (lastArg == "&") { waitForProcess = false; argList.RemoveAt(argList.Count - 1); } var args = argList.ToArray(); if (BuiltIns.ContainsKey(command)) { return(BuiltIns[command](args)); } var filePath = $"/bin/{command}"; if (command.StartsWith("./") || command.StartsWith("../") || command.StartsWith("/")) { filePath = command; } if (Directory.Exists(filePath, true)) { Kernel.Instance.Terminal.WriteLine($"{filePath}: is a directory"); return(false); } if (File.Exists(filePath, true)) { var file = File.Get(filePath, true); if ((file.Attributes & FileAttributes.Executable) != 0) { var pid = Kernel.Instance.ProcessManager.ExecuteProgram( file.GetData(), filePath, null, Kernel.Instance.InteractionCancellation.Token, args ); if (waitForProcess) { ForegroundPid = pid; await Kernel.Instance.ProcessManager.WaitForProgram(pid, token); ForegroundPid = null; } return(true); } else { Kernel.Instance.Terminal.WriteLine($"CANNOT EXEC \uFF26{filePath}\uFF40: not an executable"); return(false); } } Kernel.Instance.Terminal.WriteLine($"\uFF26UNRECOGNIZED COMMAND AND NO EXECUTABLE FOUND\uFF40\n"); return(false); } catch (OperationCanceledException) { throw; } catch (Exception e) { Kernel.Instance.Terminal.WriteLine($"\uFF24ERROR:\n\uFF40{e.Message}\n"); } return(false); }