RunBuiltinOrCommand runs a builtin or a command, returning true if it ran, and the output string if running in output mode.
(cmdIO *exec.CmdIO, errOk, output bool, cmd string, args ...string)
| 92 | // RunBuiltinOrCommand runs a builtin or a command, returning true if it ran, |
| 93 | // and the output string if running in output mode. |
| 94 | func (sh *Shell) RunBuiltinOrCommand(cmdIO *exec.CmdIO, errOk, output bool, cmd string, args ...string) (bool, string) { |
| 95 | out := "" |
| 96 | cmdFun, hasCmd := sh.Commands[cmd] |
| 97 | bltFun, hasBlt := sh.Builtins[cmd] |
| 98 | |
| 99 | if !hasCmd && !hasBlt { |
| 100 | return false, out |
| 101 | } |
| 102 | |
| 103 | if hasCmd { |
| 104 | sh.commandArgs.Push(args) |
| 105 | sh.isCommand.Push(true) |
| 106 | } |
| 107 | |
| 108 | // note: we need to set both os. and wrapper versions, so it works the same |
| 109 | // in compiled vs. interpreted mode |
| 110 | oldsh := sh.Config.StdIO.Set(&cmdIO.StdIO) |
| 111 | oldwrap := sh.StdIOWrappers.SetWrappers(&cmdIO.StdIO) |
| 112 | oldstd := cmdIO.SetToOS() |
| 113 | if output { |
| 114 | obuf := &bytes.Buffer{} |
| 115 | // os.Stdout = obuf // needs a file |
| 116 | sh.Config.StdIO.Out = obuf |
| 117 | sh.StdIOWrappers.SetWrappedOut(obuf) |
| 118 | cmdIO.PushOut(obuf) |
| 119 | if hasCmd { |
| 120 | cmdFun(args...) |
| 121 | } else { |
| 122 | sh.AddError(bltFun(cmdIO, args...)) |
| 123 | } |
| 124 | out = strings.TrimSuffix(obuf.String(), "\n") |
| 125 | } else { |
| 126 | if hasCmd { |
| 127 | cmdFun(args...) |
| 128 | } else { |
| 129 | sh.AddError(bltFun(cmdIO, args...)) |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | if hasCmd { |
| 134 | sh.isCommand.Pop() |
| 135 | sh.commandArgs.Pop() |
| 136 | } |
| 137 | oldstd.SetToOS() |
| 138 | sh.StdIOWrappers.SetWrappers(oldwrap) |
| 139 | sh.Config.StdIO = *oldsh |
| 140 | |
| 141 | return true, out |
| 142 | } |
| 143 | |
| 144 | func (sh *Shell) HandleArgErr(errok bool, err error) error { |
| 145 | if err == nil { |
no test coverage detected